1 // 2 // Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2016 SAP SE. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // 27 // PPC64 Architecture Description File 28 // 29 30 //----------REGISTER DEFINITION BLOCK------------------------------------------ 31 // This information is used by the matcher and the register allocator to 32 // describe individual registers and classes of registers within the target 33 // architecture. 34 register %{ 35 //----------Architecture Description Register Definitions---------------------- 36 // General Registers 37 // "reg_def" name (register save type, C convention save type, 38 // ideal register type, encoding); 39 // 40 // Register Save Types: 41 // 42 // NS = No-Save: The register allocator assumes that these registers 43 // can be used without saving upon entry to the method, & 44 // that they do not need to be saved at call sites. 45 // 46 // SOC = Save-On-Call: The register allocator assumes that these registers 47 // can be used without saving upon entry to the method, 48 // but that they must be saved at call sites. 49 // These are called "volatiles" on ppc. 50 // 51 // SOE = Save-On-Entry: The register allocator assumes that these registers 52 // must be saved before using them upon entry to the 53 // method, but they do not need to be saved at call 54 // sites. 55 // These are called "nonvolatiles" on ppc. 56 // 57 // AS = Always-Save: The register allocator assumes that these registers 58 // must be saved before using them upon entry to the 59 // method, & that they must be saved at call sites. 60 // 61 // Ideal Register Type is used to determine how to save & restore a 62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 64 // 65 // The encoding number is the actual bit-pattern placed into the opcodes. 66 // 67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI 68 // Supplement Version 1.7 as of 2003-10-29. 69 // 70 // For each 64-bit register we must define two registers: the register 71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half', 72 // e.g. R3_H, which is needed by the allocator, but is not used 73 // for stores, loads, etc. 74 75 // ---------------------------- 76 // Integer/Long Registers 77 // ---------------------------- 78 79 // PPC64 has 32 64-bit integer registers. 80 81 // types: v = volatile, nv = non-volatile, s = system 82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs 83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() ); 84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP 85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() ); 86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC 87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() ); 88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret 89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() ); 90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2 91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() ); 92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3 93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() ); 94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4 95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() ); 96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5 97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() ); 98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6 99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() ); 100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7 101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() ); 102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8 103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next()); 104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch 105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next()); 106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch 107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next()); 108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id 109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next()); 110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv 111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next()); 112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv 113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next()); 114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv 115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next()); 116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv 117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next()); 118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv 119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next()); 120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv 121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next()); 122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv 123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next()); 124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv 125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next()); 126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv 127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next()); 128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv 129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next()); 130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv 131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next()); 132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv 133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next()); 134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv 135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next()); 136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv 137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next()); 138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv 139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next()); 140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv 141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next()); 142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv 143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next()); 144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv 145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next()); 146 147 148 // ---------------------------- 149 // Float/Double Registers 150 // ---------------------------- 151 152 // Double Registers 153 // The rules of ADL require that double registers be defined in pairs. 154 // Each pair must be two 32-bit values, but not necessarily a pair of 155 // single float registers. In each pair, ADLC-assigned register numbers 156 // must be adjacent, with the lower number even. Finally, when the 157 // CPU stores such a register pair to memory, the word associated with 158 // the lower ADLC-assigned number must be stored to the lower address. 159 160 // PPC64 has 32 64-bit floating-point registers. Each can store a single 161 // or double precision floating-point value. 162 163 // types: v = volatile, nv = non-volatile, s = system 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch 165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret 167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2 169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3 171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4 173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5 175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6 177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7 179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8 181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9 183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10 185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next()); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11 187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next()); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12 189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next()); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13 191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next()); 192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv 193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next()); 194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv 195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next()); 196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv 197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next()); 198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv 199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next()); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv 201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next()); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv 203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next()); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv 205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next()); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv 207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next()); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv 209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next()); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv 211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next()); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv 213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next()); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv 215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next()); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv 217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next()); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv 219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next()); 220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv 221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next()); 222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv 223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next()); 224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv 225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next()); 226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv 227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next()); 228 229 // ---------------------------- 230 // Special Registers 231 // ---------------------------- 232 233 // Condition Codes Flag Registers 234 235 // PPC64 has 8 condition code "registers" which are all contained 236 // in the CR register. 237 238 // types: v = volatile, nv = non-volatile, s = system 239 reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v 240 reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v 241 reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv 242 reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv 243 reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv 244 reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v 245 reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v 246 reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg()); // v 247 248 // Special registers of PPC64 249 250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v 251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v 252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v 253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v 254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v 255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v 256 257 258 // ---------------------------- 259 // Specify priority of register selection within phases of register 260 // allocation. Highest priority is first. A useful heuristic is to 261 // give registers a low priority when they are required by machine 262 // instructions, like EAX and EDX on I486, and choose no-save registers 263 // before save-on-call, & save-on-call before save-on-entry. Registers 264 // which participate in fixed calling sequences should come last. 265 // Registers which are used as pairs must fall on an even boundary. 266 267 // It's worth about 1% on SPEC geomean to get this right. 268 269 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 270 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 271 // R3_num. Therefore, R3_num may not be (and in reality is not) 272 // the same as R3->encoding()! Furthermore, we cannot make any 273 // assumptions on ordering, e.g. R3_num may be less than R2_num. 274 // Additionally, the function 275 // static enum RC rc_class(OptoReg::Name reg ) 276 // maps a given <register>_num value to its chunk type (except for flags) 277 // and its current implementation relies on chunk0 and chunk1 having a 278 // size of 64 each. 279 280 // If you change this allocation class, please have a look at the 281 // default values for the parameters RoundRobinIntegerRegIntervalStart 282 // and RoundRobinFloatRegIntervalStart 283 284 alloc_class chunk0 ( 285 // Chunk0 contains *all* 64 integer registers halves. 286 287 // "non-volatile" registers 288 R14, R14_H, 289 R15, R15_H, 290 R17, R17_H, 291 R18, R18_H, 292 R19, R19_H, 293 R20, R20_H, 294 R21, R21_H, 295 R22, R22_H, 296 R23, R23_H, 297 R24, R24_H, 298 R25, R25_H, 299 R26, R26_H, 300 R27, R27_H, 301 R28, R28_H, 302 R29, R29_H, 303 R30, R30_H, 304 R31, R31_H, 305 306 // scratch/special registers 307 R11, R11_H, 308 R12, R12_H, 309 310 // argument registers 311 R10, R10_H, 312 R9, R9_H, 313 R8, R8_H, 314 R7, R7_H, 315 R6, R6_H, 316 R5, R5_H, 317 R4, R4_H, 318 R3, R3_H, 319 320 // special registers, not available for allocation 321 R16, R16_H, // R16_thread 322 R13, R13_H, // system thread id 323 R2, R2_H, // may be used for TOC 324 R1, R1_H, // SP 325 R0, R0_H // R0 (scratch) 326 ); 327 328 // If you change this allocation class, please have a look at the 329 // default values for the parameters RoundRobinIntegerRegIntervalStart 330 // and RoundRobinFloatRegIntervalStart 331 332 alloc_class chunk1 ( 333 // Chunk1 contains *all* 64 floating-point registers halves. 334 335 // scratch register 336 F0, F0_H, 337 338 // argument registers 339 F13, F13_H, 340 F12, F12_H, 341 F11, F11_H, 342 F10, F10_H, 343 F9, F9_H, 344 F8, F8_H, 345 F7, F7_H, 346 F6, F6_H, 347 F5, F5_H, 348 F4, F4_H, 349 F3, F3_H, 350 F2, F2_H, 351 F1, F1_H, 352 353 // non-volatile registers 354 F14, F14_H, 355 F15, F15_H, 356 F16, F16_H, 357 F17, F17_H, 358 F18, F18_H, 359 F19, F19_H, 360 F20, F20_H, 361 F21, F21_H, 362 F22, F22_H, 363 F23, F23_H, 364 F24, F24_H, 365 F25, F25_H, 366 F26, F26_H, 367 F27, F27_H, 368 F28, F28_H, 369 F29, F29_H, 370 F30, F30_H, 371 F31, F31_H 372 ); 373 374 alloc_class chunk2 ( 375 // Chunk2 contains *all* 8 condition code registers. 376 377 CCR0, 378 CCR1, 379 CCR2, 380 CCR3, 381 CCR4, 382 CCR5, 383 CCR6, 384 CCR7 385 ); 386 387 alloc_class chunk3 ( 388 // special registers 389 // These registers are not allocated, but used for nodes generated by postalloc expand. 390 SR_XER, 391 SR_LR, 392 SR_CTR, 393 SR_VRSAVE, 394 SR_SPEFSCR, 395 SR_PPR 396 ); 397 398 //-------Architecture Description Register Classes----------------------- 399 400 // Several register classes are automatically defined based upon 401 // information in this architecture description. 402 403 // 1) reg_class inline_cache_reg ( as defined in frame section ) 404 // 2) reg_class compiler_method_oop_reg ( as defined in frame section ) 405 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 406 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 407 // 408 409 // ---------------------------- 410 // 32 Bit Register Classes 411 // ---------------------------- 412 413 // We specify registers twice, once as read/write, and once read-only. 414 // We use the read-only registers for source operands. With this, we 415 // can include preset read only registers in this class, as a hard-coded 416 // '0'-register. (We used to simulate this on ppc.) 417 418 // 32 bit registers that can be read and written i.e. these registers 419 // can be dest (or src) of normal instructions. 420 reg_class bits32_reg_rw( 421 /*R0*/ // R0 422 /*R1*/ // SP 423 R2, // TOC 424 R3, 425 R4, 426 R5, 427 R6, 428 R7, 429 R8, 430 R9, 431 R10, 432 R11, 433 R12, 434 /*R13*/ // system thread id 435 R14, 436 R15, 437 /*R16*/ // R16_thread 438 R17, 439 R18, 440 R19, 441 R20, 442 R21, 443 R22, 444 R23, 445 R24, 446 R25, 447 R26, 448 R27, 449 R28, 450 /*R29,*/ // global TOC 451 R30, 452 R31 453 ); 454 455 // 32 bit registers that can only be read i.e. these registers can 456 // only be src of all instructions. 457 reg_class bits32_reg_ro( 458 /*R0*/ // R0 459 /*R1*/ // SP 460 R2 // TOC 461 R3, 462 R4, 463 R5, 464 R6, 465 R7, 466 R8, 467 R9, 468 R10, 469 R11, 470 R12, 471 /*R13*/ // system thread id 472 R14, 473 R15, 474 /*R16*/ // R16_thread 475 R17, 476 R18, 477 R19, 478 R20, 479 R21, 480 R22, 481 R23, 482 R24, 483 R25, 484 R26, 485 R27, 486 R28, 487 /*R29,*/ 488 R30, 489 R31 490 ); 491 492 reg_class rscratch1_bits32_reg(R11); 493 reg_class rscratch2_bits32_reg(R12); 494 reg_class rarg1_bits32_reg(R3); 495 reg_class rarg2_bits32_reg(R4); 496 reg_class rarg3_bits32_reg(R5); 497 reg_class rarg4_bits32_reg(R6); 498 499 // ---------------------------- 500 // 64 Bit Register Classes 501 // ---------------------------- 502 // 64-bit build means 64-bit pointers means hi/lo pairs 503 504 reg_class rscratch1_bits64_reg(R11_H, R11); 505 reg_class rscratch2_bits64_reg(R12_H, R12); 506 reg_class rarg1_bits64_reg(R3_H, R3); 507 reg_class rarg2_bits64_reg(R4_H, R4); 508 reg_class rarg3_bits64_reg(R5_H, R5); 509 reg_class rarg4_bits64_reg(R6_H, R6); 510 // Thread register, 'written' by tlsLoadP, see there. 511 reg_class thread_bits64_reg(R16_H, R16); 512 513 reg_class r19_bits64_reg(R19_H, R19); 514 515 // 64 bit registers that can be read and written i.e. these registers 516 // can be dest (or src) of normal instructions. 517 reg_class bits64_reg_rw( 518 /*R0_H, R0*/ // R0 519 /*R1_H, R1*/ // SP 520 R2_H, R2, // TOC 521 R3_H, R3, 522 R4_H, R4, 523 R5_H, R5, 524 R6_H, R6, 525 R7_H, R7, 526 R8_H, R8, 527 R9_H, R9, 528 R10_H, R10, 529 R11_H, R11, 530 R12_H, R12, 531 /*R13_H, R13*/ // system thread id 532 R14_H, R14, 533 R15_H, R15, 534 /*R16_H, R16*/ // R16_thread 535 R17_H, R17, 536 R18_H, R18, 537 R19_H, R19, 538 R20_H, R20, 539 R21_H, R21, 540 R22_H, R22, 541 R23_H, R23, 542 R24_H, R24, 543 R25_H, R25, 544 R26_H, R26, 545 R27_H, R27, 546 R28_H, R28, 547 /*R29_H, R29,*/ 548 R30_H, R30, 549 R31_H, R31 550 ); 551 552 // 64 bit registers used excluding r2, r11 and r12 553 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses 554 // r2, r11 and r12 internally. 555 reg_class bits64_reg_leaf_call( 556 /*R0_H, R0*/ // R0 557 /*R1_H, R1*/ // SP 558 /*R2_H, R2*/ // TOC 559 R3_H, R3, 560 R4_H, R4, 561 R5_H, R5, 562 R6_H, R6, 563 R7_H, R7, 564 R8_H, R8, 565 R9_H, R9, 566 R10_H, R10, 567 /*R11_H, R11*/ 568 /*R12_H, R12*/ 569 /*R13_H, R13*/ // system thread id 570 R14_H, R14, 571 R15_H, R15, 572 /*R16_H, R16*/ // R16_thread 573 R17_H, R17, 574 R18_H, R18, 575 R19_H, R19, 576 R20_H, R20, 577 R21_H, R21, 578 R22_H, R22, 579 R23_H, R23, 580 R24_H, R24, 581 R25_H, R25, 582 R26_H, R26, 583 R27_H, R27, 584 R28_H, R28, 585 /*R29_H, R29,*/ 586 R30_H, R30, 587 R31_H, R31 588 ); 589 590 // Used to hold the TOC to avoid collisions with expanded DynamicCall 591 // which uses r19 as inline cache internally and expanded LeafCall which uses 592 // r2, r11 and r12 internally. 593 reg_class bits64_constant_table_base( 594 /*R0_H, R0*/ // R0 595 /*R1_H, R1*/ // SP 596 /*R2_H, R2*/ // TOC 597 R3_H, R3, 598 R4_H, R4, 599 R5_H, R5, 600 R6_H, R6, 601 R7_H, R7, 602 R8_H, R8, 603 R9_H, R9, 604 R10_H, R10, 605 /*R11_H, R11*/ 606 /*R12_H, R12*/ 607 /*R13_H, R13*/ // system thread id 608 R14_H, R14, 609 R15_H, R15, 610 /*R16_H, R16*/ // R16_thread 611 R17_H, R17, 612 R18_H, R18, 613 /*R19_H, R19*/ 614 R20_H, R20, 615 R21_H, R21, 616 R22_H, R22, 617 R23_H, R23, 618 R24_H, R24, 619 R25_H, R25, 620 R26_H, R26, 621 R27_H, R27, 622 R28_H, R28, 623 /*R29_H, R29,*/ 624 R30_H, R30, 625 R31_H, R31 626 ); 627 628 // 64 bit registers that can only be read i.e. these registers can 629 // only be src of all instructions. 630 reg_class bits64_reg_ro( 631 /*R0_H, R0*/ // R0 632 R1_H, R1, 633 R2_H, R2, // TOC 634 R3_H, R3, 635 R4_H, R4, 636 R5_H, R5, 637 R6_H, R6, 638 R7_H, R7, 639 R8_H, R8, 640 R9_H, R9, 641 R10_H, R10, 642 R11_H, R11, 643 R12_H, R12, 644 /*R13_H, R13*/ // system thread id 645 R14_H, R14, 646 R15_H, R15, 647 R16_H, R16, // R16_thread 648 R17_H, R17, 649 R18_H, R18, 650 R19_H, R19, 651 R20_H, R20, 652 R21_H, R21, 653 R22_H, R22, 654 R23_H, R23, 655 R24_H, R24, 656 R25_H, R25, 657 R26_H, R26, 658 R27_H, R27, 659 R28_H, R28, 660 /*R29_H, R29,*/ // TODO: let allocator handle TOC!! 661 R30_H, R30, 662 R31_H, R31 663 ); 664 665 666 // ---------------------------- 667 // Special Class for Condition Code Flags Register 668 669 reg_class int_flags( 670 /*CCR0*/ // scratch 671 /*CCR1*/ // scratch 672 /*CCR2*/ // nv! 673 /*CCR3*/ // nv! 674 /*CCR4*/ // nv! 675 CCR5, 676 CCR6, 677 CCR7 678 ); 679 680 reg_class int_flags_ro( 681 CCR0, 682 CCR1, 683 CCR2, 684 CCR3, 685 CCR4, 686 CCR5, 687 CCR6, 688 CCR7 689 ); 690 691 reg_class int_flags_CR0(CCR0); 692 reg_class int_flags_CR1(CCR1); 693 reg_class int_flags_CR6(CCR6); 694 reg_class ctr_reg(SR_CTR); 695 696 // ---------------------------- 697 // Float Register Classes 698 // ---------------------------- 699 700 reg_class flt_reg( 701 F0, 702 F1, 703 F2, 704 F3, 705 F4, 706 F5, 707 F6, 708 F7, 709 F8, 710 F9, 711 F10, 712 F11, 713 F12, 714 F13, 715 F14, // nv! 716 F15, // nv! 717 F16, // nv! 718 F17, // nv! 719 F18, // nv! 720 F19, // nv! 721 F20, // nv! 722 F21, // nv! 723 F22, // nv! 724 F23, // nv! 725 F24, // nv! 726 F25, // nv! 727 F26, // nv! 728 F27, // nv! 729 F28, // nv! 730 F29, // nv! 731 F30, // nv! 732 F31 // nv! 733 ); 734 735 // Double precision float registers have virtual `high halves' that 736 // are needed by the allocator. 737 reg_class dbl_reg( 738 F0, F0_H, 739 F1, F1_H, 740 F2, F2_H, 741 F3, F3_H, 742 F4, F4_H, 743 F5, F5_H, 744 F6, F6_H, 745 F7, F7_H, 746 F8, F8_H, 747 F9, F9_H, 748 F10, F10_H, 749 F11, F11_H, 750 F12, F12_H, 751 F13, F13_H, 752 F14, F14_H, // nv! 753 F15, F15_H, // nv! 754 F16, F16_H, // nv! 755 F17, F17_H, // nv! 756 F18, F18_H, // nv! 757 F19, F19_H, // nv! 758 F20, F20_H, // nv! 759 F21, F21_H, // nv! 760 F22, F22_H, // nv! 761 F23, F23_H, // nv! 762 F24, F24_H, // nv! 763 F25, F25_H, // nv! 764 F26, F26_H, // nv! 765 F27, F27_H, // nv! 766 F28, F28_H, // nv! 767 F29, F29_H, // nv! 768 F30, F30_H, // nv! 769 F31, F31_H // nv! 770 ); 771 772 %} 773 774 //----------DEFINITION BLOCK--------------------------------------------------- 775 // Define name --> value mappings to inform the ADLC of an integer valued name 776 // Current support includes integer values in the range [0, 0x7FFFFFFF] 777 // Format: 778 // int_def <name> ( <int_value>, <expression>); 779 // Generated Code in ad_<arch>.hpp 780 // #define <name> (<expression>) 781 // // value == <int_value> 782 // Generated code in ad_<arch>.cpp adlc_verification() 783 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 784 // 785 definitions %{ 786 // The default cost (of an ALU instruction). 787 int_def DEFAULT_COST_LOW ( 30, 30); 788 int_def DEFAULT_COST ( 100, 100); 789 int_def HUGE_COST (1000000, 1000000); 790 791 // Memory refs 792 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 793 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 794 795 // Branches are even more expensive. 796 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 797 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 798 %} 799 800 801 //----------SOURCE BLOCK------------------------------------------------------- 802 // This is a block of C++ code which provides values, functions, and 803 // definitions necessary in the rest of the architecture description. 804 source_hpp %{ 805 // Header information of the source block. 806 // Method declarations/definitions which are used outside 807 // the ad-scope can conveniently be defined here. 808 // 809 // To keep related declarations/definitions/uses close together, 810 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 811 812 // Returns true if Node n is followed by a MemBar node that 813 // will do an acquire. If so, this node must not do the acquire 814 // operation. 815 bool followed_by_acquire(const Node *n); 816 %} 817 818 source %{ 819 820 // Should the Matcher clone shifts on addressing modes, expecting them 821 // to be subsumed into complex addressing expressions or compute them 822 // into registers? 823 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 824 return clone_base_plus_offset_address(m, mstack, address_visited); 825 } 826 827 void Compile::reshape_address(AddPNode* addp) { 828 } 829 830 // Optimize load-acquire. 831 // 832 // Check if acquire is unnecessary due to following operation that does 833 // acquire anyways. 834 // Walk the pattern: 835 // 836 // n: Load.acq 837 // | 838 // MemBarAcquire 839 // | | 840 // Proj(ctrl) Proj(mem) 841 // | | 842 // MemBarRelease/Volatile 843 // 844 bool followed_by_acquire(const Node *load) { 845 assert(load->is_Load(), "So far implemented only for loads."); 846 847 // Find MemBarAcquire. 848 const Node *mba = NULL; 849 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 850 const Node *out = load->fast_out(i); 851 if (out->Opcode() == Op_MemBarAcquire) { 852 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 853 mba = out; 854 break; 855 } 856 } 857 if (!mba) return false; 858 859 // Find following MemBar node. 860 // 861 // The following node must be reachable by control AND memory 862 // edge to assure no other operations are in between the two nodes. 863 // 864 // So first get the Proj node, mem_proj, to use it to iterate forward. 865 Node *mem_proj = NULL; 866 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 867 mem_proj = mba->fast_out(i); // Throw out-of-bounds if proj not found 868 assert(mem_proj->is_Proj(), "only projections here"); 869 ProjNode *proj = mem_proj->as_Proj(); 870 if (proj->_con == TypeFunc::Memory && 871 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 872 break; 873 } 874 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 875 876 // Search MemBar behind Proj. If there are other memory operations 877 // behind the Proj we lost. 878 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 879 Node *x = mem_proj->fast_out(j); 880 // Proj might have an edge to a store or load node which precedes the membar. 881 if (x->is_Mem()) return false; 882 883 // On PPC64 release and volatile are implemented by an instruction 884 // that also has acquire semantics. I.e. there is no need for an 885 // acquire before these. 886 int xop = x->Opcode(); 887 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 888 // Make sure we're not missing Call/Phi/MergeMem by checking 889 // control edges. The control edge must directly lead back 890 // to the MemBarAcquire 891 Node *ctrl_proj = x->in(0); 892 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 893 return true; 894 } 895 } 896 } 897 898 return false; 899 } 900 901 #define __ _masm. 902 903 // Tertiary op of a LoadP or StoreP encoding. 904 #define REGP_OP true 905 906 // **************************************************************************** 907 908 // REQUIRED FUNCTIONALITY 909 910 // !!!!! Special hack to get all type of calls to specify the byte offset 911 // from the start of the call to the point where the return address 912 // will point. 913 914 // PPC port: Removed use of lazy constant construct. 915 916 int MachCallStaticJavaNode::ret_addr_offset() { 917 // It's only a single branch-and-link instruction. 918 return 4; 919 } 920 921 int MachCallDynamicJavaNode::ret_addr_offset() { 922 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 923 // postalloc expanded calls if we use inline caches and do not update method data. 924 if (UseInlineCaches) 925 return 4; 926 927 int vtable_index = this->_vtable_index; 928 if (vtable_index < 0) { 929 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 930 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 931 return 12; 932 } else { 933 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 934 return 24; 935 } 936 } 937 938 int MachCallRuntimeNode::ret_addr_offset() { 939 #if defined(ABI_ELFv2) 940 return 28; 941 #else 942 return 40; 943 #endif 944 } 945 946 //============================================================================= 947 948 // condition code conversions 949 950 static int cc_to_boint(int cc) { 951 return Assembler::bcondCRbiIs0 | (cc & 8); 952 } 953 954 static int cc_to_inverse_boint(int cc) { 955 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 956 } 957 958 static int cc_to_biint(int cc, int flags_reg) { 959 return (flags_reg << 2) | (cc & 3); 960 } 961 962 //============================================================================= 963 964 // Compute padding required for nodes which need alignment. The padding 965 // is the number of bytes (not instructions) which will be inserted before 966 // the instruction. The padding must match the size of a NOP instruction. 967 968 // 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 int Matcher::vector_ideal_reg(int size) { 2057 assert(MaxVectorSize == 8 && size == 8, ""); 2058 return Op_RegL; 2059 } 2060 2061 const int Matcher::vector_shift_count_ideal_reg(int size) { 2062 fatal("vector shift is not supported"); 2063 return Node::NotAMachineReg; 2064 } 2065 2066 // Limits on vector size (number of elements) loaded into vector. 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 // Needed to postalloc expand loadConN: ConN is loaded as ConI 5846 // leaving the upper 32 bits with sign-extension bits. 5847 // This clears these bits: dst = src & 0xFFFFFFFF. 5848 // TODO: Eventually call this maskN_regN_FFFFFFFF. 5849 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 5850 effect(DEF dst, USE src); 5851 predicate(false); 5852 5853 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 5854 size(4); 5855 ins_encode %{ 5856 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5857 __ clrldi($dst$$Register, $src$$Register, 0x20); 5858 %} 5859 ins_pipe(pipe_class_default); 5860 %} 5861 5862 // Optimize DecodeN for disjoint base. 5863 // Load base of compressed oops into a register 5864 instruct loadBase(iRegLdst dst) %{ 5865 effect(DEF dst); 5866 5867 format %{ "LoadConst $dst, heapbase" %} 5868 ins_encode %{ 5869 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5870 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 5871 %} 5872 ins_pipe(pipe_class_default); 5873 %} 5874 5875 // Loading ConN must be postalloc expanded so that edges between 5876 // the nodes are safe. They may not interfere with a safepoint. 5877 // GL TODO: This needs three instructions: better put this into the constant pool. 5878 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 5879 match(Set dst src); 5880 ins_cost(DEFAULT_COST*2); 5881 5882 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5883 postalloc_expand %{ 5884 MachNode *m1 = new loadConN_hiNode(); 5885 MachNode *m2 = new loadConN_loNode(); 5886 MachNode *m3 = new clearMs32bNode(); 5887 m1->add_req(NULL); 5888 m2->add_req(NULL, m1); 5889 m3->add_req(NULL, m2); 5890 m1->_opnds[0] = op_dst; 5891 m1->_opnds[1] = op_src; 5892 m2->_opnds[0] = op_dst; 5893 m2->_opnds[1] = op_dst; 5894 m2->_opnds[2] = op_src; 5895 m3->_opnds[0] = op_dst; 5896 m3->_opnds[1] = op_dst; 5897 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5898 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5899 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5900 nodes->push(m1); 5901 nodes->push(m2); 5902 nodes->push(m3); 5903 %} 5904 %} 5905 5906 // We have seen a safepoint between the hi and lo parts, and this node was handled 5907 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 5908 // not a narrow oop. 5909 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 5910 match(Set dst src); 5911 effect(DEF dst, USE src); 5912 ins_cost(DEFAULT_COST); 5913 5914 format %{ "LIS $dst, $src \t// narrow klass hi" %} 5915 size(4); 5916 ins_encode %{ 5917 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5918 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 5919 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 5920 %} 5921 ins_pipe(pipe_class_default); 5922 %} 5923 5924 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 5925 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5926 match(Set dst src1); 5927 effect(TEMP src2); 5928 ins_cost(DEFAULT_COST); 5929 5930 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 5931 size(4); 5932 ins_encode %{ 5933 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5934 __ clrldi($dst$$Register, $src2$$Register, 0x20); 5935 %} 5936 ins_pipe(pipe_class_default); 5937 %} 5938 5939 // This needs a match rule so that build_oop_map knows this is 5940 // not a narrow oop. 5941 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5942 match(Set dst src1); 5943 effect(TEMP src2); 5944 ins_cost(DEFAULT_COST); 5945 5946 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 5947 size(4); 5948 ins_encode %{ 5949 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5950 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 5951 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5952 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 5953 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 5954 5955 __ relocate(rspec, 1); 5956 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 5957 %} 5958 ins_pipe(pipe_class_default); 5959 %} 5960 5961 // Loading ConNKlass must be postalloc expanded so that edges between 5962 // the nodes are safe. They may not interfere with a safepoint. 5963 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 5964 match(Set dst src); 5965 ins_cost(DEFAULT_COST*2); 5966 5967 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5968 postalloc_expand %{ 5969 // Load high bits into register. Sign extended. 5970 MachNode *m1 = new loadConNKlass_hiNode(); 5971 m1->add_req(NULL); 5972 m1->_opnds[0] = op_dst; 5973 m1->_opnds[1] = op_src; 5974 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5975 nodes->push(m1); 5976 5977 MachNode *m2 = m1; 5978 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 5979 // Value might be 1-extended. Mask out these bits. 5980 m2 = new loadConNKlass_maskNode(); 5981 m2->add_req(NULL, m1); 5982 m2->_opnds[0] = op_dst; 5983 m2->_opnds[1] = op_src; 5984 m2->_opnds[2] = op_dst; 5985 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5986 nodes->push(m2); 5987 } 5988 5989 MachNode *m3 = new loadConNKlass_loNode(); 5990 m3->add_req(NULL, m2); 5991 m3->_opnds[0] = op_dst; 5992 m3->_opnds[1] = op_src; 5993 m3->_opnds[2] = op_dst; 5994 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5995 nodes->push(m3); 5996 %} 5997 %} 5998 5999 // 0x1 is used in object initialization (initial object header). 6000 // No constant pool entries required. 6001 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6002 match(Set dst src); 6003 6004 format %{ "LI $dst, $src \t// ptr" %} 6005 size(4); 6006 ins_encode %{ 6007 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6008 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6009 %} 6010 ins_pipe(pipe_class_default); 6011 %} 6012 6013 // Expand node for constant pool load: small offset. 6014 // The match rule is needed to generate the correct bottom_type(), 6015 // however this node should never match. The use of predicate is not 6016 // possible since ADLC forbids predicates for chain rules. The higher 6017 // costs do not prevent matching in this case. For that reason the 6018 // operand immP_NM with predicate(false) is used. 6019 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6020 match(Set dst src); 6021 effect(TEMP toc); 6022 6023 ins_num_consts(1); 6024 6025 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6026 size(4); 6027 ins_encode( enc_load_long_constP(dst, src, toc) ); 6028 ins_pipe(pipe_class_memory); 6029 %} 6030 6031 // Expand node for constant pool load: large offset. 6032 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6033 effect(DEF dst, USE src, USE toc); 6034 predicate(false); 6035 6036 ins_num_consts(1); 6037 ins_field_const_toc_offset(int); 6038 6039 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6040 size(4); 6041 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6042 ins_pipe(pipe_class_default); 6043 %} 6044 6045 // Expand node for constant pool load: large offset. 6046 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6047 match(Set dst src); 6048 effect(TEMP base); 6049 6050 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6051 6052 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6053 size(4); 6054 ins_encode %{ 6055 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6056 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6057 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6058 %} 6059 ins_pipe(pipe_class_memory); 6060 %} 6061 6062 // Load pointer constant from constant table. Expand in case an 6063 // offset > 16 bit is needed. 6064 // Adlc adds toc node MachConstantTableBase. 6065 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6066 match(Set dst src); 6067 ins_cost(MEMORY_REF_COST); 6068 6069 // This rule does not use "expand" because then 6070 // the result type is not known to be an Oop. An ADLC 6071 // enhancement will be needed to make that work - not worth it! 6072 6073 // If this instruction rematerializes, it prolongs the live range 6074 // of the toc node, causing illegal graphs. 6075 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6076 ins_cannot_rematerialize(true); 6077 6078 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6079 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6080 %} 6081 6082 // Expand node for constant pool load: small offset. 6083 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6084 effect(DEF dst, USE src, USE toc); 6085 ins_cost(MEMORY_REF_COST); 6086 6087 ins_num_consts(1); 6088 6089 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6090 size(4); 6091 ins_encode %{ 6092 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6093 address float_address = __ float_constant($src$$constant); 6094 if (float_address == NULL) { 6095 ciEnv::current()->record_out_of_memory_failure(); 6096 return; 6097 } 6098 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6099 %} 6100 ins_pipe(pipe_class_memory); 6101 %} 6102 6103 // Expand node for constant pool load: large offset. 6104 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6105 effect(DEF dst, USE src, USE toc); 6106 ins_cost(MEMORY_REF_COST); 6107 6108 ins_num_consts(1); 6109 6110 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6111 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6112 "ADDIS $toc, $toc, -offset_hi"%} 6113 size(12); 6114 ins_encode %{ 6115 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6116 FloatRegister Rdst = $dst$$FloatRegister; 6117 Register Rtoc = $toc$$Register; 6118 address float_address = __ float_constant($src$$constant); 6119 if (float_address == NULL) { 6120 ciEnv::current()->record_out_of_memory_failure(); 6121 return; 6122 } 6123 int offset = __ offset_to_method_toc(float_address); 6124 int hi = (offset + (1<<15))>>16; 6125 int lo = offset - hi * (1<<16); 6126 6127 __ addis(Rtoc, Rtoc, hi); 6128 __ lfs(Rdst, lo, Rtoc); 6129 __ addis(Rtoc, Rtoc, -hi); 6130 %} 6131 ins_pipe(pipe_class_memory); 6132 %} 6133 6134 // Adlc adds toc node MachConstantTableBase. 6135 instruct loadConF_Ex(regF dst, immF src) %{ 6136 match(Set dst src); 6137 ins_cost(MEMORY_REF_COST); 6138 6139 // See loadConP. 6140 ins_cannot_rematerialize(true); 6141 6142 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6143 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6144 %} 6145 6146 // Expand node for constant pool load: small offset. 6147 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6148 effect(DEF dst, USE src, USE toc); 6149 ins_cost(MEMORY_REF_COST); 6150 6151 ins_num_consts(1); 6152 6153 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6154 size(4); 6155 ins_encode %{ 6156 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6157 address float_address = __ double_constant($src$$constant); 6158 if (float_address == NULL) { 6159 ciEnv::current()->record_out_of_memory_failure(); 6160 return; 6161 } 6162 int offset = __ offset_to_method_toc(float_address); 6163 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6164 %} 6165 ins_pipe(pipe_class_memory); 6166 %} 6167 6168 // Expand node for constant pool load: large offset. 6169 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6170 effect(DEF dst, USE src, USE toc); 6171 ins_cost(MEMORY_REF_COST); 6172 6173 ins_num_consts(1); 6174 6175 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6176 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6177 "ADDIS $toc, $toc, -offset_hi" %} 6178 size(12); 6179 ins_encode %{ 6180 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6181 FloatRegister Rdst = $dst$$FloatRegister; 6182 Register Rtoc = $toc$$Register; 6183 address float_address = __ double_constant($src$$constant); 6184 if (float_address == NULL) { 6185 ciEnv::current()->record_out_of_memory_failure(); 6186 return; 6187 } 6188 int offset = __ offset_to_method_toc(float_address); 6189 int hi = (offset + (1<<15))>>16; 6190 int lo = offset - hi * (1<<16); 6191 6192 __ addis(Rtoc, Rtoc, hi); 6193 __ lfd(Rdst, lo, Rtoc); 6194 __ addis(Rtoc, Rtoc, -hi); 6195 %} 6196 ins_pipe(pipe_class_memory); 6197 %} 6198 6199 // Adlc adds toc node MachConstantTableBase. 6200 instruct loadConD_Ex(regD dst, immD src) %{ 6201 match(Set dst src); 6202 ins_cost(MEMORY_REF_COST); 6203 6204 // See loadConP. 6205 ins_cannot_rematerialize(true); 6206 6207 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6208 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6209 %} 6210 6211 // Prefetch instructions. 6212 // Must be safe to execute with invalid address (cannot fault). 6213 6214 // Special prefetch versions which use the dcbz instruction. 6215 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6216 match(PrefetchAllocation (AddP mem src)); 6217 predicate(AllocatePrefetchStyle == 3); 6218 ins_cost(MEMORY_REF_COST); 6219 6220 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6221 size(4); 6222 ins_encode %{ 6223 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6224 __ dcbz($src$$Register, $mem$$base$$Register); 6225 %} 6226 ins_pipe(pipe_class_memory); 6227 %} 6228 6229 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6230 match(PrefetchAllocation mem); 6231 predicate(AllocatePrefetchStyle == 3); 6232 ins_cost(MEMORY_REF_COST); 6233 6234 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6235 size(4); 6236 ins_encode %{ 6237 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6238 __ dcbz($mem$$base$$Register); 6239 %} 6240 ins_pipe(pipe_class_memory); 6241 %} 6242 6243 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6244 match(PrefetchAllocation (AddP mem src)); 6245 predicate(AllocatePrefetchStyle != 3); 6246 ins_cost(MEMORY_REF_COST); 6247 6248 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6249 size(4); 6250 ins_encode %{ 6251 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6252 __ dcbtst($src$$Register, $mem$$base$$Register); 6253 %} 6254 ins_pipe(pipe_class_memory); 6255 %} 6256 6257 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6258 match(PrefetchAllocation mem); 6259 predicate(AllocatePrefetchStyle != 3); 6260 ins_cost(MEMORY_REF_COST); 6261 6262 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6263 size(4); 6264 ins_encode %{ 6265 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6266 __ dcbtst($mem$$base$$Register); 6267 %} 6268 ins_pipe(pipe_class_memory); 6269 %} 6270 6271 //----------Store Instructions------------------------------------------------- 6272 6273 // Store Byte 6274 instruct storeB(memory mem, iRegIsrc src) %{ 6275 match(Set mem (StoreB mem src)); 6276 ins_cost(MEMORY_REF_COST); 6277 6278 format %{ "STB $src, $mem \t// byte" %} 6279 size(4); 6280 ins_encode %{ 6281 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6282 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6283 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6284 %} 6285 ins_pipe(pipe_class_memory); 6286 %} 6287 6288 // Store Char/Short 6289 instruct storeC(memory mem, iRegIsrc src) %{ 6290 match(Set mem (StoreC mem src)); 6291 ins_cost(MEMORY_REF_COST); 6292 6293 format %{ "STH $src, $mem \t// short" %} 6294 size(4); 6295 ins_encode %{ 6296 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6297 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6298 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6299 %} 6300 ins_pipe(pipe_class_memory); 6301 %} 6302 6303 // Store Integer 6304 instruct storeI(memory mem, iRegIsrc src) %{ 6305 match(Set mem (StoreI mem src)); 6306 ins_cost(MEMORY_REF_COST); 6307 6308 format %{ "STW $src, $mem" %} 6309 size(4); 6310 ins_encode( enc_stw(src, mem) ); 6311 ins_pipe(pipe_class_memory); 6312 %} 6313 6314 // ConvL2I + StoreI. 6315 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6316 match(Set mem (StoreI mem (ConvL2I src))); 6317 ins_cost(MEMORY_REF_COST); 6318 6319 format %{ "STW l2i($src), $mem" %} 6320 size(4); 6321 ins_encode( enc_stw(src, mem) ); 6322 ins_pipe(pipe_class_memory); 6323 %} 6324 6325 // Store Long 6326 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6327 match(Set mem (StoreL mem src)); 6328 ins_cost(MEMORY_REF_COST); 6329 6330 format %{ "STD $src, $mem \t// long" %} 6331 size(4); 6332 ins_encode( enc_std(src, mem) ); 6333 ins_pipe(pipe_class_memory); 6334 %} 6335 6336 // Store super word nodes. 6337 6338 // Store Aligned Packed Byte long register to memory 6339 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6340 predicate(n->as_StoreVector()->memory_size() == 8); 6341 match(Set mem (StoreVector mem src)); 6342 ins_cost(MEMORY_REF_COST); 6343 6344 format %{ "STD $mem, $src \t// packed8B" %} 6345 size(4); 6346 ins_encode( enc_std(src, mem) ); 6347 ins_pipe(pipe_class_memory); 6348 %} 6349 6350 // Store Compressed Oop 6351 instruct storeN(memory dst, iRegN_P2N src) %{ 6352 match(Set dst (StoreN dst src)); 6353 ins_cost(MEMORY_REF_COST); 6354 6355 format %{ "STW $src, $dst \t// compressed oop" %} 6356 size(4); 6357 ins_encode( enc_stw(src, dst) ); 6358 ins_pipe(pipe_class_memory); 6359 %} 6360 6361 // Store Compressed KLass 6362 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6363 match(Set dst (StoreNKlass dst src)); 6364 ins_cost(MEMORY_REF_COST); 6365 6366 format %{ "STW $src, $dst \t// compressed klass" %} 6367 size(4); 6368 ins_encode( enc_stw(src, dst) ); 6369 ins_pipe(pipe_class_memory); 6370 %} 6371 6372 // Store Pointer 6373 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6374 match(Set dst (StoreP dst src)); 6375 ins_cost(MEMORY_REF_COST); 6376 6377 format %{ "STD $src, $dst \t// ptr" %} 6378 size(4); 6379 ins_encode( enc_std(src, dst) ); 6380 ins_pipe(pipe_class_memory); 6381 %} 6382 6383 // Store Float 6384 instruct storeF(memory mem, regF src) %{ 6385 match(Set mem (StoreF mem src)); 6386 ins_cost(MEMORY_REF_COST); 6387 6388 format %{ "STFS $src, $mem" %} 6389 size(4); 6390 ins_encode( enc_stfs(src, mem) ); 6391 ins_pipe(pipe_class_memory); 6392 %} 6393 6394 // Store Double 6395 instruct storeD(memory mem, regD src) %{ 6396 match(Set mem (StoreD mem src)); 6397 ins_cost(MEMORY_REF_COST); 6398 6399 format %{ "STFD $src, $mem" %} 6400 size(4); 6401 ins_encode( enc_stfd(src, mem) ); 6402 ins_pipe(pipe_class_memory); 6403 %} 6404 6405 //----------Store Instructions With Zeros-------------------------------------- 6406 6407 // Card-mark for CMS garbage collection. 6408 // This cardmark does an optimization so that it must not always 6409 // do a releasing store. For this, it gets the address of 6410 // CMSCollectorCardTableModRefBSExt::_requires_release as input. 6411 // (Using releaseFieldAddr in the match rule is a hack.) 6412 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6413 match(Set mem (StoreCM mem releaseFieldAddr)); 6414 effect(TEMP crx); 6415 predicate(false); 6416 ins_cost(MEMORY_REF_COST); 6417 6418 // See loadConP. 6419 ins_cannot_rematerialize(true); 6420 6421 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6422 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6423 ins_pipe(pipe_class_memory); 6424 %} 6425 6426 // Card-mark for CMS garbage collection. 6427 // This cardmark does an optimization so that it must not always 6428 // do a releasing store. For this, it needs the constant address of 6429 // CMSCollectorCardTableModRefBSExt::_requires_release. 6430 // This constant address is split off here by expand so we can use 6431 // adlc / matcher functionality to load it from the constant section. 6432 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6433 match(Set mem (StoreCM mem zero)); 6434 predicate(UseConcMarkSweepGC); 6435 6436 expand %{ 6437 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableModRefBSExt::requires_release_address() */ %} 6438 iRegLdst releaseFieldAddress; 6439 flagsReg crx; 6440 loadConL_Ex(releaseFieldAddress, baseImm); 6441 storeCM_CMS(mem, releaseFieldAddress, crx); 6442 %} 6443 %} 6444 6445 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6446 match(Set mem (StoreCM mem zero)); 6447 predicate(UseG1GC); 6448 ins_cost(MEMORY_REF_COST); 6449 6450 ins_cannot_rematerialize(true); 6451 6452 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6453 size(8); 6454 ins_encode %{ 6455 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6456 __ li(R0, 0); 6457 //__ release(); // G1: oops are allowed to get visible after dirty marking 6458 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6459 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6460 %} 6461 ins_pipe(pipe_class_memory); 6462 %} 6463 6464 // Convert oop pointer into compressed form. 6465 6466 // Nodes for postalloc expand. 6467 6468 // Shift node for expand. 6469 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6470 // The match rule is needed to make it a 'MachTypeNode'! 6471 match(Set dst (EncodeP src)); 6472 predicate(false); 6473 6474 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6475 size(4); 6476 ins_encode %{ 6477 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6478 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6479 %} 6480 ins_pipe(pipe_class_default); 6481 %} 6482 6483 // Add node for expand. 6484 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6485 // The match rule is needed to make it a 'MachTypeNode'! 6486 match(Set dst (EncodeP src)); 6487 predicate(false); 6488 6489 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6490 ins_encode %{ 6491 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6492 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6493 %} 6494 ins_pipe(pipe_class_default); 6495 %} 6496 6497 // Conditional sub base. 6498 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6499 // The match rule is needed to make it a 'MachTypeNode'! 6500 match(Set dst (EncodeP (Binary crx src1))); 6501 predicate(false); 6502 6503 format %{ "BEQ $crx, done\n\t" 6504 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6505 "done:" %} 6506 ins_encode %{ 6507 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6508 Label done; 6509 __ beq($crx$$CondRegister, done); 6510 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6511 __ bind(done); 6512 %} 6513 ins_pipe(pipe_class_default); 6514 %} 6515 6516 // Power 7 can use isel instruction 6517 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6518 // The match rule is needed to make it a 'MachTypeNode'! 6519 match(Set dst (EncodeP (Binary crx src1))); 6520 predicate(false); 6521 6522 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6523 size(4); 6524 ins_encode %{ 6525 // This is a Power7 instruction for which no machine description exists. 6526 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6527 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6528 %} 6529 ins_pipe(pipe_class_default); 6530 %} 6531 6532 // Disjoint narrow oop base. 6533 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6534 match(Set dst (EncodeP src)); 6535 predicate(Universe::narrow_oop_base_disjoint()); 6536 6537 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6538 size(4); 6539 ins_encode %{ 6540 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6541 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 6542 %} 6543 ins_pipe(pipe_class_default); 6544 %} 6545 6546 // shift != 0, base != 0 6547 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6548 match(Set dst (EncodeP src)); 6549 effect(TEMP crx); 6550 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6551 Universe::narrow_oop_shift() != 0 && 6552 Universe::narrow_oop_base_overlaps()); 6553 6554 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 6555 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 6556 %} 6557 6558 // shift != 0, base != 0 6559 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 6560 match(Set dst (EncodeP src)); 6561 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 6562 Universe::narrow_oop_shift() != 0 && 6563 Universe::narrow_oop_base_overlaps()); 6564 6565 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 6566 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 6567 %} 6568 6569 // shift != 0, base == 0 6570 // TODO: This is the same as encodeP_shift. Merge! 6571 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 6572 match(Set dst (EncodeP src)); 6573 predicate(Universe::narrow_oop_shift() != 0 && 6574 Universe::narrow_oop_base() ==0); 6575 6576 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 6577 size(4); 6578 ins_encode %{ 6579 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6580 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6581 %} 6582 ins_pipe(pipe_class_default); 6583 %} 6584 6585 // Compressed OOPs with narrow_oop_shift == 0. 6586 // shift == 0, base == 0 6587 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 6588 match(Set dst (EncodeP src)); 6589 predicate(Universe::narrow_oop_shift() == 0); 6590 6591 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 6592 // variable size, 0 or 4. 6593 ins_encode %{ 6594 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6595 __ mr_if_needed($dst$$Register, $src$$Register); 6596 %} 6597 ins_pipe(pipe_class_default); 6598 %} 6599 6600 // Decode nodes. 6601 6602 // Shift node for expand. 6603 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 6604 // The match rule is needed to make it a 'MachTypeNode'! 6605 match(Set dst (DecodeN src)); 6606 predicate(false); 6607 6608 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 6609 size(4); 6610 ins_encode %{ 6611 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6612 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6613 %} 6614 ins_pipe(pipe_class_default); 6615 %} 6616 6617 // Add node for expand. 6618 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 6619 // The match rule is needed to make it a 'MachTypeNode'! 6620 match(Set dst (DecodeN src)); 6621 predicate(false); 6622 6623 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 6624 ins_encode %{ 6625 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6626 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6627 %} 6628 ins_pipe(pipe_class_default); 6629 %} 6630 6631 // conditianal add base for expand 6632 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 6633 // The match rule is needed to make it a 'MachTypeNode'! 6634 // NOTICE that the rule is nonsense - we just have to make sure that: 6635 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6636 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6637 match(Set dst (DecodeN (Binary crx src))); 6638 predicate(false); 6639 6640 format %{ "BEQ $crx, done\n\t" 6641 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 6642 "done:" %} 6643 ins_encode %{ 6644 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6645 Label done; 6646 __ beq($crx$$CondRegister, done); 6647 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6648 __ bind(done); 6649 %} 6650 ins_pipe(pipe_class_default); 6651 %} 6652 6653 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6654 // The match rule is needed to make it a 'MachTypeNode'! 6655 // NOTICE that the rule is nonsense - we just have to make sure that: 6656 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6657 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6658 match(Set dst (DecodeN (Binary crx src1))); 6659 predicate(false); 6660 6661 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 6662 size(4); 6663 ins_encode %{ 6664 // This is a Power7 instruction for which no machine description exists. 6665 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6666 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6667 %} 6668 ins_pipe(pipe_class_default); 6669 %} 6670 6671 // shift != 0, base != 0 6672 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6673 match(Set dst (DecodeN src)); 6674 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6675 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6676 Universe::narrow_oop_shift() != 0 && 6677 Universe::narrow_oop_base() != 0); 6678 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 6679 effect(TEMP crx); 6680 6681 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 6682 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 6683 %} 6684 6685 // shift != 0, base == 0 6686 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 6687 match(Set dst (DecodeN src)); 6688 predicate(Universe::narrow_oop_shift() != 0 && 6689 Universe::narrow_oop_base() == 0); 6690 6691 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 6692 size(4); 6693 ins_encode %{ 6694 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6695 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6696 %} 6697 ins_pipe(pipe_class_default); 6698 %} 6699 6700 // Optimize DecodeN for disjoint base. 6701 // Shift narrow oop and or it into register that already contains the heap base. 6702 // Base == dst must hold, and is assured by construction in postaloc_expand. 6703 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 6704 match(Set dst (DecodeN src)); 6705 effect(TEMP base); 6706 predicate(false); 6707 6708 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 6709 size(4); 6710 ins_encode %{ 6711 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 6712 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 6713 %} 6714 ins_pipe(pipe_class_default); 6715 %} 6716 6717 // Optimize DecodeN for disjoint base. 6718 // This node requires only one cycle on the critical path. 6719 // We must postalloc_expand as we can not express use_def effects where 6720 // the used register is L and the def'ed register P. 6721 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 6722 match(Set dst (DecodeN src)); 6723 effect(TEMP_DEF dst); 6724 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6725 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6726 Universe::narrow_oop_base_disjoint()); 6727 ins_cost(DEFAULT_COST); 6728 6729 format %{ "MOV $dst, heapbase \t\n" 6730 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 6731 postalloc_expand %{ 6732 loadBaseNode *n1 = new loadBaseNode(); 6733 n1->add_req(NULL); 6734 n1->_opnds[0] = op_dst; 6735 6736 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6737 n2->add_req(n_region, n_src, n1); 6738 n2->_opnds[0] = op_dst; 6739 n2->_opnds[1] = op_src; 6740 n2->_opnds[2] = op_dst; 6741 n2->_bottom_type = _bottom_type; 6742 6743 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6744 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6745 6746 nodes->push(n1); 6747 nodes->push(n2); 6748 %} 6749 %} 6750 6751 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6752 match(Set dst (DecodeN src)); 6753 effect(TEMP_DEF dst, TEMP crx); 6754 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6755 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6756 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 6757 ins_cost(3 * DEFAULT_COST); 6758 6759 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 6760 postalloc_expand %{ 6761 loadBaseNode *n1 = new loadBaseNode(); 6762 n1->add_req(NULL); 6763 n1->_opnds[0] = op_dst; 6764 6765 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 6766 n_compare->add_req(n_region, n_src); 6767 n_compare->_opnds[0] = op_crx; 6768 n_compare->_opnds[1] = op_src; 6769 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 6770 6771 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6772 n2->add_req(n_region, n_src, n1); 6773 n2->_opnds[0] = op_dst; 6774 n2->_opnds[1] = op_src; 6775 n2->_opnds[2] = op_dst; 6776 n2->_bottom_type = _bottom_type; 6777 6778 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 6779 n_cond_set->add_req(n_region, n_compare, n2); 6780 n_cond_set->_opnds[0] = op_dst; 6781 n_cond_set->_opnds[1] = op_crx; 6782 n_cond_set->_opnds[2] = op_dst; 6783 n_cond_set->_bottom_type = _bottom_type; 6784 6785 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 6786 ra_->set_oop(n_cond_set, true); 6787 6788 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6789 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 6790 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6791 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6792 6793 nodes->push(n1); 6794 nodes->push(n_compare); 6795 nodes->push(n2); 6796 nodes->push(n_cond_set); 6797 %} 6798 %} 6799 6800 // src != 0, shift != 0, base != 0 6801 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 6802 match(Set dst (DecodeN src)); 6803 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6804 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6805 Universe::narrow_oop_shift() != 0 && 6806 Universe::narrow_oop_base() != 0); 6807 ins_cost(2 * DEFAULT_COST); 6808 6809 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 6810 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 6811 %} 6812 6813 // Compressed OOPs with narrow_oop_shift == 0. 6814 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 6815 match(Set dst (DecodeN src)); 6816 predicate(Universe::narrow_oop_shift() == 0); 6817 ins_cost(DEFAULT_COST); 6818 6819 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 6820 // variable size, 0 or 4. 6821 ins_encode %{ 6822 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6823 __ mr_if_needed($dst$$Register, $src$$Register); 6824 %} 6825 ins_pipe(pipe_class_default); 6826 %} 6827 6828 // Convert compressed oop into int for vectors alignment masking. 6829 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 6830 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6831 predicate(Universe::narrow_oop_shift() == 0); 6832 ins_cost(DEFAULT_COST); 6833 6834 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 6835 // variable size, 0 or 4. 6836 ins_encode %{ 6837 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6838 __ mr_if_needed($dst$$Register, $src$$Register); 6839 %} 6840 ins_pipe(pipe_class_default); 6841 %} 6842 6843 // Convert klass pointer into compressed form. 6844 6845 // Nodes for postalloc expand. 6846 6847 // Shift node for expand. 6848 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 6849 // The match rule is needed to make it a 'MachTypeNode'! 6850 match(Set dst (EncodePKlass src)); 6851 predicate(false); 6852 6853 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6854 size(4); 6855 ins_encode %{ 6856 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6857 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6858 %} 6859 ins_pipe(pipe_class_default); 6860 %} 6861 6862 // Add node for expand. 6863 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6864 // The match rule is needed to make it a 'MachTypeNode'! 6865 match(Set dst (EncodePKlass (Binary base src))); 6866 predicate(false); 6867 6868 format %{ "SUB $dst, $base, $src \t// encode" %} 6869 size(4); 6870 ins_encode %{ 6871 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 6872 __ subf($dst$$Register, $base$$Register, $src$$Register); 6873 %} 6874 ins_pipe(pipe_class_default); 6875 %} 6876 6877 // Disjoint narrow oop base. 6878 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6879 match(Set dst (EncodePKlass src)); 6880 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 6881 6882 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6883 size(4); 6884 ins_encode %{ 6885 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6886 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 6887 %} 6888 ins_pipe(pipe_class_default); 6889 %} 6890 6891 // shift != 0, base != 0 6892 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 6893 match(Set dst (EncodePKlass (Binary base src))); 6894 predicate(false); 6895 6896 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6897 postalloc_expand %{ 6898 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 6899 n1->add_req(n_region, n_base, n_src); 6900 n1->_opnds[0] = op_dst; 6901 n1->_opnds[1] = op_base; 6902 n1->_opnds[2] = op_src; 6903 n1->_bottom_type = _bottom_type; 6904 6905 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 6906 n2->add_req(n_region, n1); 6907 n2->_opnds[0] = op_dst; 6908 n2->_opnds[1] = op_dst; 6909 n2->_bottom_type = _bottom_type; 6910 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6911 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6912 6913 nodes->push(n1); 6914 nodes->push(n2); 6915 %} 6916 %} 6917 6918 // shift != 0, base != 0 6919 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 6920 match(Set dst (EncodePKlass src)); 6921 //predicate(Universe::narrow_klass_shift() != 0 && 6922 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 6923 6924 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6925 ins_cost(DEFAULT_COST*2); // Don't count constant. 6926 expand %{ 6927 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 6928 iRegLdst base; 6929 loadConL_Ex(base, baseImm); 6930 encodePKlass_not_null_Ex(dst, base, src); 6931 %} 6932 %} 6933 6934 // Decode nodes. 6935 6936 // Shift node for expand. 6937 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 6938 // The match rule is needed to make it a 'MachTypeNode'! 6939 match(Set dst (DecodeNKlass src)); 6940 predicate(false); 6941 6942 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 6943 size(4); 6944 ins_encode %{ 6945 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6946 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6947 %} 6948 ins_pipe(pipe_class_default); 6949 %} 6950 6951 // Add node for expand. 6952 6953 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6954 // The match rule is needed to make it a 'MachTypeNode'! 6955 match(Set dst (DecodeNKlass (Binary base src))); 6956 predicate(false); 6957 6958 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 6959 size(4); 6960 ins_encode %{ 6961 // TODO: PPC port $archOpcode(ppc64Opcode_add); 6962 __ add($dst$$Register, $base$$Register, $src$$Register); 6963 %} 6964 ins_pipe(pipe_class_default); 6965 %} 6966 6967 // src != 0, shift != 0, base != 0 6968 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 6969 match(Set dst (DecodeNKlass (Binary base src))); 6970 //effect(kill src); // We need a register for the immediate result after shifting. 6971 predicate(false); 6972 6973 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 6974 postalloc_expand %{ 6975 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 6976 n1->add_req(n_region, n_base, n_src); 6977 n1->_opnds[0] = op_dst; 6978 n1->_opnds[1] = op_base; 6979 n1->_opnds[2] = op_src; 6980 n1->_bottom_type = _bottom_type; 6981 6982 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 6983 n2->add_req(n_region, n1); 6984 n2->_opnds[0] = op_dst; 6985 n2->_opnds[1] = op_dst; 6986 n2->_bottom_type = _bottom_type; 6987 6988 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6989 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6990 6991 nodes->push(n1); 6992 nodes->push(n2); 6993 %} 6994 %} 6995 6996 // src != 0, shift != 0, base != 0 6997 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 6998 match(Set dst (DecodeNKlass src)); 6999 // predicate(Universe::narrow_klass_shift() != 0 && 7000 // Universe::narrow_klass_base() != 0); 7001 7002 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7003 7004 ins_cost(DEFAULT_COST*2); // Don't count constant. 7005 expand %{ 7006 // We add first, then we shift. Like this, we can get along with one register less. 7007 // But we have to load the base pre-shifted. 7008 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7009 iRegLdst base; 7010 loadConL_Ex(base, baseImm); 7011 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7012 %} 7013 %} 7014 7015 //----------MemBar Instructions----------------------------------------------- 7016 // Memory barrier flavors 7017 7018 instruct membar_acquire() %{ 7019 match(LoadFence); 7020 ins_cost(4*MEMORY_REF_COST); 7021 7022 format %{ "MEMBAR-acquire" %} 7023 size(4); 7024 ins_encode %{ 7025 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7026 __ acquire(); 7027 %} 7028 ins_pipe(pipe_class_default); 7029 %} 7030 7031 instruct unnecessary_membar_acquire() %{ 7032 match(MemBarAcquire); 7033 ins_cost(0); 7034 7035 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7036 size(0); 7037 ins_encode( /*empty*/ ); 7038 ins_pipe(pipe_class_default); 7039 %} 7040 7041 instruct membar_acquire_lock() %{ 7042 match(MemBarAcquireLock); 7043 ins_cost(0); 7044 7045 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7046 size(0); 7047 ins_encode( /*empty*/ ); 7048 ins_pipe(pipe_class_default); 7049 %} 7050 7051 instruct membar_release() %{ 7052 match(MemBarRelease); 7053 match(StoreFence); 7054 ins_cost(4*MEMORY_REF_COST); 7055 7056 format %{ "MEMBAR-release" %} 7057 size(4); 7058 ins_encode %{ 7059 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7060 __ release(); 7061 %} 7062 ins_pipe(pipe_class_default); 7063 %} 7064 7065 instruct membar_storestore() %{ 7066 match(MemBarStoreStore); 7067 ins_cost(4*MEMORY_REF_COST); 7068 7069 format %{ "MEMBAR-store-store" %} 7070 size(4); 7071 ins_encode %{ 7072 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7073 __ membar(Assembler::StoreStore); 7074 %} 7075 ins_pipe(pipe_class_default); 7076 %} 7077 7078 instruct membar_release_lock() %{ 7079 match(MemBarReleaseLock); 7080 ins_cost(0); 7081 7082 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7083 size(0); 7084 ins_encode( /*empty*/ ); 7085 ins_pipe(pipe_class_default); 7086 %} 7087 7088 instruct membar_volatile() %{ 7089 match(MemBarVolatile); 7090 ins_cost(4*MEMORY_REF_COST); 7091 7092 format %{ "MEMBAR-volatile" %} 7093 size(4); 7094 ins_encode %{ 7095 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7096 __ fence(); 7097 %} 7098 ins_pipe(pipe_class_default); 7099 %} 7100 7101 // This optimization is wrong on PPC. The following pattern is not supported: 7102 // MemBarVolatile 7103 // ^ ^ 7104 // | | 7105 // CtrlProj MemProj 7106 // ^ ^ 7107 // | | 7108 // | Load 7109 // | 7110 // MemBarVolatile 7111 // 7112 // The first MemBarVolatile could get optimized out! According to 7113 // Vladimir, this pattern can not occur on Oracle platforms. 7114 // However, it does occur on PPC64 (because of membars in 7115 // inline_unsafe_load_store). 7116 // 7117 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7118 // Don't forget to look at the implementation of post_store_load_barrier again, 7119 // we did other fixes in that method. 7120 //instruct unnecessary_membar_volatile() %{ 7121 // match(MemBarVolatile); 7122 // predicate(Matcher::post_store_load_barrier(n)); 7123 // ins_cost(0); 7124 // 7125 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7126 // size(0); 7127 // ins_encode( /*empty*/ ); 7128 // ins_pipe(pipe_class_default); 7129 //%} 7130 7131 instruct membar_CPUOrder() %{ 7132 match(MemBarCPUOrder); 7133 ins_cost(0); 7134 7135 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7136 size(0); 7137 ins_encode( /*empty*/ ); 7138 ins_pipe(pipe_class_default); 7139 %} 7140 7141 //----------Conditional Move--------------------------------------------------- 7142 7143 // Cmove using isel. 7144 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7145 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7146 predicate(VM_Version::has_isel()); 7147 ins_cost(DEFAULT_COST); 7148 7149 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7150 size(4); 7151 ins_encode %{ 7152 // This is a Power7 instruction for which no machine description 7153 // exists. Anyways, the scheduler should be off on Power7. 7154 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7155 int cc = $cmp$$cmpcode; 7156 __ isel($dst$$Register, $crx$$CondRegister, 7157 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7158 %} 7159 ins_pipe(pipe_class_default); 7160 %} 7161 7162 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7163 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7164 predicate(!VM_Version::has_isel()); 7165 ins_cost(DEFAULT_COST+BRANCH_COST); 7166 7167 ins_variable_size_depending_on_alignment(true); 7168 7169 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7170 // Worst case is branch + move + stop, no stop without scheduler 7171 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7172 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7173 ins_pipe(pipe_class_default); 7174 %} 7175 7176 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7177 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7178 ins_cost(DEFAULT_COST+BRANCH_COST); 7179 7180 ins_variable_size_depending_on_alignment(true); 7181 7182 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7183 // Worst case is branch + move + stop, no stop without scheduler 7184 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7185 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7186 ins_pipe(pipe_class_default); 7187 %} 7188 7189 // Cmove using isel. 7190 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7191 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7192 predicate(VM_Version::has_isel()); 7193 ins_cost(DEFAULT_COST); 7194 7195 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7196 size(4); 7197 ins_encode %{ 7198 // This is a Power7 instruction for which no machine description 7199 // exists. Anyways, the scheduler should be off on Power7. 7200 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7201 int cc = $cmp$$cmpcode; 7202 __ isel($dst$$Register, $crx$$CondRegister, 7203 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7204 %} 7205 ins_pipe(pipe_class_default); 7206 %} 7207 7208 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7209 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7210 predicate(!VM_Version::has_isel()); 7211 ins_cost(DEFAULT_COST+BRANCH_COST); 7212 7213 ins_variable_size_depending_on_alignment(true); 7214 7215 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7216 // Worst case is branch + move + stop, no stop without scheduler. 7217 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7218 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7219 ins_pipe(pipe_class_default); 7220 %} 7221 7222 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7223 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7224 ins_cost(DEFAULT_COST+BRANCH_COST); 7225 7226 ins_variable_size_depending_on_alignment(true); 7227 7228 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7229 // Worst case is branch + move + stop, no stop without scheduler. 7230 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7231 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7232 ins_pipe(pipe_class_default); 7233 %} 7234 7235 // Cmove using isel. 7236 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7237 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7238 predicate(VM_Version::has_isel()); 7239 ins_cost(DEFAULT_COST); 7240 7241 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7242 size(4); 7243 ins_encode %{ 7244 // This is a Power7 instruction for which no machine description 7245 // exists. Anyways, the scheduler should be off on Power7. 7246 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7247 int cc = $cmp$$cmpcode; 7248 __ isel($dst$$Register, $crx$$CondRegister, 7249 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7250 %} 7251 ins_pipe(pipe_class_default); 7252 %} 7253 7254 // Conditional move for RegN. Only cmov(reg, reg). 7255 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7256 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7257 predicate(!VM_Version::has_isel()); 7258 ins_cost(DEFAULT_COST+BRANCH_COST); 7259 7260 ins_variable_size_depending_on_alignment(true); 7261 7262 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7263 // Worst case is branch + move + stop, no stop without scheduler. 7264 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7265 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7266 ins_pipe(pipe_class_default); 7267 %} 7268 7269 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7270 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7271 ins_cost(DEFAULT_COST+BRANCH_COST); 7272 7273 ins_variable_size_depending_on_alignment(true); 7274 7275 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7276 // Worst case is branch + move + stop, no stop without scheduler. 7277 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7278 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7279 ins_pipe(pipe_class_default); 7280 %} 7281 7282 // Cmove using isel. 7283 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7284 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7285 predicate(VM_Version::has_isel()); 7286 ins_cost(DEFAULT_COST); 7287 7288 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7289 size(4); 7290 ins_encode %{ 7291 // This is a Power7 instruction for which no machine description 7292 // exists. Anyways, the scheduler should be off on Power7. 7293 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7294 int cc = $cmp$$cmpcode; 7295 __ isel($dst$$Register, $crx$$CondRegister, 7296 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7297 %} 7298 ins_pipe(pipe_class_default); 7299 %} 7300 7301 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7302 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7303 predicate(!VM_Version::has_isel()); 7304 ins_cost(DEFAULT_COST+BRANCH_COST); 7305 7306 ins_variable_size_depending_on_alignment(true); 7307 7308 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7309 // Worst case is branch + move + stop, no stop without scheduler. 7310 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7311 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7312 ins_pipe(pipe_class_default); 7313 %} 7314 7315 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7316 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7317 ins_cost(DEFAULT_COST+BRANCH_COST); 7318 7319 ins_variable_size_depending_on_alignment(true); 7320 7321 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7322 // Worst case is branch + move + stop, no stop without scheduler. 7323 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7324 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7325 ins_pipe(pipe_class_default); 7326 %} 7327 7328 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7329 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7330 ins_cost(DEFAULT_COST+BRANCH_COST); 7331 7332 ins_variable_size_depending_on_alignment(true); 7333 7334 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7335 // Worst case is branch + move + stop, no stop without scheduler. 7336 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7337 ins_encode %{ 7338 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7339 Label done; 7340 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7341 // Branch if not (cmp crx). 7342 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7343 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7344 // TODO PPC port __ endgroup_if_needed(_size == 12); 7345 __ bind(done); 7346 %} 7347 ins_pipe(pipe_class_default); 7348 %} 7349 7350 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7351 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7352 ins_cost(DEFAULT_COST+BRANCH_COST); 7353 7354 ins_variable_size_depending_on_alignment(true); 7355 7356 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7357 // Worst case is branch + move + stop, no stop without scheduler. 7358 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7359 ins_encode %{ 7360 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7361 Label done; 7362 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7363 // Branch if not (cmp crx). 7364 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7365 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7366 // TODO PPC port __ endgroup_if_needed(_size == 12); 7367 __ bind(done); 7368 %} 7369 ins_pipe(pipe_class_default); 7370 %} 7371 7372 //----------Conditional_store-------------------------------------------------- 7373 // Conditional-store of the updated heap-top. 7374 // Used during allocation of the shared heap. 7375 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7376 7377 // As compareAndSwapL, but return flag register instead of boolean value in 7378 // int register. 7379 // Used by sun/misc/AtomicLongCSImpl.java. 7380 // Mem_ptr must be a memory operand, else this node does not get 7381 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7382 // can be rematerialized which leads to errors. 7383 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7384 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7385 effect(TEMP cr0); 7386 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7387 ins_encode %{ 7388 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7389 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7390 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7391 noreg, NULL, true); 7392 %} 7393 ins_pipe(pipe_class_default); 7394 %} 7395 7396 // As compareAndSwapP, but return flag register instead of boolean value in 7397 // int register. 7398 // This instruction is matched if UseTLAB is off. 7399 // Mem_ptr must be a memory operand, else this node does not get 7400 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7401 // can be rematerialized which leads to errors. 7402 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7403 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7404 ins_cost(2*MEMORY_REF_COST); 7405 7406 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7407 ins_encode %{ 7408 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7409 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7410 %} 7411 ins_pipe(pipe_class_memory); 7412 %} 7413 7414 // Implement LoadPLocked. Must be ordered against changes of the memory location 7415 // by storePConditional. 7416 // Don't know whether this is ever used. 7417 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7418 match(Set dst (LoadPLocked mem)); 7419 ins_cost(2*MEMORY_REF_COST); 7420 7421 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7422 size(4); 7423 ins_encode %{ 7424 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7425 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7426 %} 7427 ins_pipe(pipe_class_memory); 7428 %} 7429 7430 //----------Compare-And-Swap--------------------------------------------------- 7431 7432 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7433 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7434 // matched. 7435 7436 // Strong versions: 7437 7438 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7439 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7440 predicate(VM_Version::has_lqarx()); 7441 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7442 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7443 ins_encode %{ 7444 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7445 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7446 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7447 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7448 $res$$Register, true); 7449 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7450 __ isync(); 7451 } else { 7452 __ sync(); 7453 } 7454 %} 7455 ins_pipe(pipe_class_default); 7456 %} 7457 7458 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7459 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7460 predicate(!VM_Version::has_lqarx()); 7461 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7462 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7463 ins_encode %{ 7464 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7465 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7466 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7467 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7468 $res$$Register, true); 7469 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7470 __ isync(); 7471 } else { 7472 __ sync(); 7473 } 7474 %} 7475 ins_pipe(pipe_class_default); 7476 %} 7477 7478 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7479 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7480 predicate(VM_Version::has_lqarx()); 7481 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7482 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7483 ins_encode %{ 7484 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7485 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7486 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7487 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7488 $res$$Register, true); 7489 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7490 __ isync(); 7491 } else { 7492 __ sync(); 7493 } 7494 %} 7495 ins_pipe(pipe_class_default); 7496 %} 7497 7498 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7499 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7500 predicate(!VM_Version::has_lqarx()); 7501 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7502 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7503 ins_encode %{ 7504 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7505 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7506 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7507 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7508 $res$$Register, true); 7509 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7510 __ isync(); 7511 } else { 7512 __ sync(); 7513 } 7514 %} 7515 ins_pipe(pipe_class_default); 7516 %} 7517 7518 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7519 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7520 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7521 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7522 ins_encode %{ 7523 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7524 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7525 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7526 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7527 $res$$Register, true); 7528 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7529 __ isync(); 7530 } else { 7531 __ sync(); 7532 } 7533 %} 7534 ins_pipe(pipe_class_default); 7535 %} 7536 7537 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7538 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7539 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7540 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7541 ins_encode %{ 7542 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7543 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7544 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7545 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7546 $res$$Register, true); 7547 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7548 __ isync(); 7549 } else { 7550 __ sync(); 7551 } 7552 %} 7553 ins_pipe(pipe_class_default); 7554 %} 7555 7556 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7557 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 7558 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7559 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7560 ins_encode %{ 7561 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7562 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7563 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7564 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7565 $res$$Register, NULL, true); 7566 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7567 __ isync(); 7568 } else { 7569 __ sync(); 7570 } 7571 %} 7572 ins_pipe(pipe_class_default); 7573 %} 7574 7575 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7576 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 7577 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7578 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7579 ins_encode %{ 7580 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7581 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7582 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7583 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7584 $res$$Register, NULL, true); 7585 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7586 __ isync(); 7587 } else { 7588 __ sync(); 7589 } 7590 %} 7591 ins_pipe(pipe_class_default); 7592 %} 7593 7594 // Weak versions: 7595 7596 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7597 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7598 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7599 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7600 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7601 ins_encode %{ 7602 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7603 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7604 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7605 MacroAssembler::MemBarNone, 7606 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7607 %} 7608 ins_pipe(pipe_class_default); 7609 %} 7610 7611 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7612 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7613 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7614 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7615 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7616 ins_encode %{ 7617 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7618 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7619 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7620 MacroAssembler::MemBarNone, 7621 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7622 %} 7623 ins_pipe(pipe_class_default); 7624 %} 7625 7626 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7627 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7628 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7629 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7630 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7631 ins_encode %{ 7632 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7633 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7634 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7635 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7636 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7637 %} 7638 ins_pipe(pipe_class_default); 7639 %} 7640 7641 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7642 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7643 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7644 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7645 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7646 ins_encode %{ 7647 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7648 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7649 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7650 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7651 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7652 %} 7653 ins_pipe(pipe_class_default); 7654 %} 7655 7656 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7657 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7658 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7659 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7660 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7661 ins_encode %{ 7662 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7663 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7664 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7665 MacroAssembler::MemBarNone, 7666 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7667 %} 7668 ins_pipe(pipe_class_default); 7669 %} 7670 7671 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7672 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7673 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7674 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7675 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7676 ins_encode %{ 7677 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7678 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7679 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7680 MacroAssembler::MemBarNone, 7681 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7682 %} 7683 ins_pipe(pipe_class_default); 7684 %} 7685 7686 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7687 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7688 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7689 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7690 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7691 ins_encode %{ 7692 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7693 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7694 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7695 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7696 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7697 %} 7698 ins_pipe(pipe_class_default); 7699 %} 7700 7701 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7702 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7703 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7704 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7705 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7706 ins_encode %{ 7707 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7708 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7709 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7710 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7711 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7712 %} 7713 ins_pipe(pipe_class_default); 7714 %} 7715 7716 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7717 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7718 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7719 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7720 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7721 ins_encode %{ 7722 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7723 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7724 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7725 MacroAssembler::MemBarNone, 7726 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7727 %} 7728 ins_pipe(pipe_class_default); 7729 %} 7730 7731 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7732 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7733 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7734 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7735 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7736 ins_encode %{ 7737 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7738 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7739 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7740 // value is never passed to caller. 7741 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7742 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7743 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7744 %} 7745 ins_pipe(pipe_class_default); 7746 %} 7747 7748 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7749 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7750 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7751 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7752 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7753 ins_encode %{ 7754 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7755 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7756 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7757 MacroAssembler::MemBarNone, 7758 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7759 %} 7760 ins_pipe(pipe_class_default); 7761 %} 7762 7763 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7764 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7765 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7766 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7767 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7768 ins_encode %{ 7769 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7770 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7771 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7772 // value is never passed to caller. 7773 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7774 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7775 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7776 %} 7777 ins_pipe(pipe_class_default); 7778 %} 7779 7780 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7781 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7782 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7783 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7784 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7785 ins_encode %{ 7786 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7787 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7788 // value is never passed to caller. 7789 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7790 MacroAssembler::MemBarNone, 7791 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7792 %} 7793 ins_pipe(pipe_class_default); 7794 %} 7795 7796 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7797 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7798 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7799 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7800 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 7801 ins_encode %{ 7802 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7803 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7804 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7805 // value is never passed to caller. 7806 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7807 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7808 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7809 %} 7810 ins_pipe(pipe_class_default); 7811 %} 7812 7813 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7814 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7815 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7816 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7817 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7818 ins_encode %{ 7819 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7820 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7821 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7822 MacroAssembler::MemBarNone, 7823 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7824 %} 7825 ins_pipe(pipe_class_default); 7826 %} 7827 7828 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7829 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7830 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7831 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7832 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7833 ins_encode %{ 7834 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7835 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7836 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7837 // value is never passed to caller. 7838 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7839 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7840 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7841 %} 7842 ins_pipe(pipe_class_default); 7843 %} 7844 7845 // CompareAndExchange 7846 7847 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7848 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7849 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7850 effect(TEMP_DEF res, TEMP cr0); 7851 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7852 ins_encode %{ 7853 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7854 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7855 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7856 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7857 noreg, true); 7858 %} 7859 ins_pipe(pipe_class_default); 7860 %} 7861 7862 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7863 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7864 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7865 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7866 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7867 ins_encode %{ 7868 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7869 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7870 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7871 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7872 noreg, true); 7873 %} 7874 ins_pipe(pipe_class_default); 7875 %} 7876 7877 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7878 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7879 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7880 effect(TEMP_DEF res, TEMP cr0); 7881 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7882 ins_encode %{ 7883 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7884 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7885 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7886 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7887 noreg, true); 7888 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7889 __ isync(); 7890 } else { 7891 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7892 __ sync(); 7893 } 7894 %} 7895 ins_pipe(pipe_class_default); 7896 %} 7897 7898 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7899 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7900 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7901 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7902 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7903 ins_encode %{ 7904 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7905 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7906 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7907 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7908 noreg, true); 7909 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7910 __ isync(); 7911 } else { 7912 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7913 __ sync(); 7914 } 7915 %} 7916 ins_pipe(pipe_class_default); 7917 %} 7918 7919 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7920 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7921 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7922 effect(TEMP_DEF res, TEMP cr0); 7923 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7924 ins_encode %{ 7925 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7926 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7927 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7928 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7929 noreg, true); 7930 %} 7931 ins_pipe(pipe_class_default); 7932 %} 7933 7934 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7935 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7936 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7937 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7938 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7939 ins_encode %{ 7940 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7941 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7942 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7943 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7944 noreg, true); 7945 %} 7946 ins_pipe(pipe_class_default); 7947 %} 7948 7949 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7950 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7951 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7952 effect(TEMP_DEF res, TEMP cr0); 7953 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7954 ins_encode %{ 7955 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7956 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7957 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7958 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7959 noreg, true); 7960 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7961 __ isync(); 7962 } else { 7963 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7964 __ sync(); 7965 } 7966 %} 7967 ins_pipe(pipe_class_default); 7968 %} 7969 7970 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7971 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7972 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7973 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7974 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7975 ins_encode %{ 7976 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7977 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7978 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7979 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7980 noreg, true); 7981 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7982 __ isync(); 7983 } else { 7984 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7985 __ sync(); 7986 } 7987 %} 7988 ins_pipe(pipe_class_default); 7989 %} 7990 7991 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7992 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 7993 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7994 effect(TEMP_DEF res, TEMP cr0); 7995 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 7996 ins_encode %{ 7997 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7998 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7999 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8000 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8001 noreg, true); 8002 %} 8003 ins_pipe(pipe_class_default); 8004 %} 8005 8006 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8007 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8008 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8009 effect(TEMP_DEF res, TEMP cr0); 8010 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8011 ins_encode %{ 8012 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8013 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8014 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8015 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8016 noreg, true); 8017 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8018 __ isync(); 8019 } else { 8020 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8021 __ sync(); 8022 } 8023 %} 8024 ins_pipe(pipe_class_default); 8025 %} 8026 8027 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8028 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8029 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8030 effect(TEMP_DEF res, TEMP cr0); 8031 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8032 ins_encode %{ 8033 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8034 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8035 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8036 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8037 noreg, true); 8038 %} 8039 ins_pipe(pipe_class_default); 8040 %} 8041 8042 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8043 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8044 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8045 effect(TEMP_DEF res, TEMP cr0); 8046 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8047 ins_encode %{ 8048 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8049 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8050 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8051 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8052 noreg, true); 8053 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8054 __ isync(); 8055 } else { 8056 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8057 __ sync(); 8058 } 8059 %} 8060 ins_pipe(pipe_class_default); 8061 %} 8062 8063 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8064 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8065 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8066 effect(TEMP_DEF res, TEMP cr0); 8067 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8068 ins_encode %{ 8069 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8070 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8071 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8072 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8073 noreg, NULL, true); 8074 %} 8075 ins_pipe(pipe_class_default); 8076 %} 8077 8078 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8079 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8080 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8081 effect(TEMP_DEF res, TEMP cr0); 8082 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8083 ins_encode %{ 8084 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8085 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8086 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8087 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8088 noreg, NULL, true); 8089 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8090 __ isync(); 8091 } else { 8092 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8093 __ sync(); 8094 } 8095 %} 8096 ins_pipe(pipe_class_default); 8097 %} 8098 8099 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8100 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8101 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8102 effect(TEMP_DEF res, TEMP cr0); 8103 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8104 ins_encode %{ 8105 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8106 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8107 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8108 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8109 noreg, NULL, true); 8110 %} 8111 ins_pipe(pipe_class_default); 8112 %} 8113 8114 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8115 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8116 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8117 effect(TEMP_DEF res, TEMP cr0); 8118 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8119 ins_encode %{ 8120 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8121 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8122 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8123 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8124 noreg, NULL, true); 8125 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8126 __ isync(); 8127 } else { 8128 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8129 __ sync(); 8130 } 8131 %} 8132 ins_pipe(pipe_class_default); 8133 %} 8134 8135 // Special RMW 8136 8137 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8138 match(Set res (GetAndAddB mem_ptr src)); 8139 predicate(VM_Version::has_lqarx()); 8140 effect(TEMP_DEF res, TEMP cr0); 8141 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8142 ins_encode %{ 8143 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8144 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8145 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8146 __ isync(); 8147 } else { 8148 __ sync(); 8149 } 8150 %} 8151 ins_pipe(pipe_class_default); 8152 %} 8153 8154 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8155 match(Set res (GetAndAddB mem_ptr src)); 8156 predicate(!VM_Version::has_lqarx()); 8157 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8158 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8159 ins_encode %{ 8160 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8161 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8162 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8163 __ isync(); 8164 } else { 8165 __ sync(); 8166 } 8167 %} 8168 ins_pipe(pipe_class_default); 8169 %} 8170 8171 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8172 match(Set res (GetAndAddS mem_ptr src)); 8173 predicate(VM_Version::has_lqarx()); 8174 effect(TEMP_DEF res, TEMP cr0); 8175 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8176 ins_encode %{ 8177 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8178 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8179 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8180 __ isync(); 8181 } else { 8182 __ sync(); 8183 } 8184 %} 8185 ins_pipe(pipe_class_default); 8186 %} 8187 8188 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8189 match(Set res (GetAndAddS mem_ptr src)); 8190 predicate(!VM_Version::has_lqarx()); 8191 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8192 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8193 ins_encode %{ 8194 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8195 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8196 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8197 __ isync(); 8198 } else { 8199 __ sync(); 8200 } 8201 %} 8202 ins_pipe(pipe_class_default); 8203 %} 8204 8205 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8206 match(Set res (GetAndAddI mem_ptr src)); 8207 effect(TEMP_DEF res, TEMP cr0); 8208 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8209 ins_encode %{ 8210 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8211 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8212 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8213 __ isync(); 8214 } else { 8215 __ sync(); 8216 } 8217 %} 8218 ins_pipe(pipe_class_default); 8219 %} 8220 8221 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8222 match(Set res (GetAndAddL mem_ptr src)); 8223 effect(TEMP_DEF res, TEMP cr0); 8224 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8225 ins_encode %{ 8226 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8227 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8228 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8229 __ isync(); 8230 } else { 8231 __ sync(); 8232 } 8233 %} 8234 ins_pipe(pipe_class_default); 8235 %} 8236 8237 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8238 match(Set res (GetAndSetB mem_ptr src)); 8239 predicate(VM_Version::has_lqarx()); 8240 effect(TEMP_DEF res, TEMP cr0); 8241 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8242 ins_encode %{ 8243 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8244 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8245 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8246 __ isync(); 8247 } else { 8248 __ sync(); 8249 } 8250 %} 8251 ins_pipe(pipe_class_default); 8252 %} 8253 8254 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8255 match(Set res (GetAndSetB mem_ptr src)); 8256 predicate(!VM_Version::has_lqarx()); 8257 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8258 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8259 ins_encode %{ 8260 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8261 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8262 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8263 __ isync(); 8264 } else { 8265 __ sync(); 8266 } 8267 %} 8268 ins_pipe(pipe_class_default); 8269 %} 8270 8271 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8272 match(Set res (GetAndSetS mem_ptr src)); 8273 predicate(VM_Version::has_lqarx()); 8274 effect(TEMP_DEF res, TEMP cr0); 8275 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8276 ins_encode %{ 8277 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8278 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8279 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8280 __ isync(); 8281 } else { 8282 __ sync(); 8283 } 8284 %} 8285 ins_pipe(pipe_class_default); 8286 %} 8287 8288 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8289 match(Set res (GetAndSetS mem_ptr src)); 8290 predicate(!VM_Version::has_lqarx()); 8291 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8292 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8293 ins_encode %{ 8294 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8295 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8296 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8297 __ isync(); 8298 } else { 8299 __ sync(); 8300 } 8301 %} 8302 ins_pipe(pipe_class_default); 8303 %} 8304 8305 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8306 match(Set res (GetAndSetI mem_ptr src)); 8307 effect(TEMP_DEF res, TEMP cr0); 8308 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8309 ins_encode %{ 8310 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8311 MacroAssembler::cmpxchgx_hint_atomic_update()); 8312 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8313 __ isync(); 8314 } else { 8315 __ sync(); 8316 } 8317 %} 8318 ins_pipe(pipe_class_default); 8319 %} 8320 8321 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8322 match(Set res (GetAndSetL mem_ptr src)); 8323 effect(TEMP_DEF res, TEMP cr0); 8324 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8325 ins_encode %{ 8326 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8327 MacroAssembler::cmpxchgx_hint_atomic_update()); 8328 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8329 __ isync(); 8330 } else { 8331 __ sync(); 8332 } 8333 %} 8334 ins_pipe(pipe_class_default); 8335 %} 8336 8337 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8338 match(Set res (GetAndSetP mem_ptr src)); 8339 effect(TEMP_DEF res, TEMP cr0); 8340 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8341 ins_encode %{ 8342 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8343 MacroAssembler::cmpxchgx_hint_atomic_update()); 8344 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8345 __ isync(); 8346 } else { 8347 __ sync(); 8348 } 8349 %} 8350 ins_pipe(pipe_class_default); 8351 %} 8352 8353 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8354 match(Set res (GetAndSetN mem_ptr src)); 8355 effect(TEMP_DEF res, TEMP cr0); 8356 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8357 ins_encode %{ 8358 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8359 MacroAssembler::cmpxchgx_hint_atomic_update()); 8360 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8361 __ isync(); 8362 } else { 8363 __ sync(); 8364 } 8365 %} 8366 ins_pipe(pipe_class_default); 8367 %} 8368 8369 //----------Arithmetic Instructions-------------------------------------------- 8370 // Addition Instructions 8371 8372 // Register Addition 8373 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8374 match(Set dst (AddI src1 src2)); 8375 format %{ "ADD $dst, $src1, $src2" %} 8376 size(4); 8377 ins_encode %{ 8378 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8379 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8380 %} 8381 ins_pipe(pipe_class_default); 8382 %} 8383 8384 // Expand does not work with above instruct. (??) 8385 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8386 // no match-rule 8387 effect(DEF dst, USE src1, USE src2); 8388 format %{ "ADD $dst, $src1, $src2" %} 8389 size(4); 8390 ins_encode %{ 8391 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8392 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8393 %} 8394 ins_pipe(pipe_class_default); 8395 %} 8396 8397 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8398 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8399 ins_cost(DEFAULT_COST*3); 8400 8401 expand %{ 8402 // FIXME: we should do this in the ideal world. 8403 iRegIdst tmp1; 8404 iRegIdst tmp2; 8405 addI_reg_reg(tmp1, src1, src2); 8406 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8407 addI_reg_reg(dst, tmp1, tmp2); 8408 %} 8409 %} 8410 8411 // Immediate Addition 8412 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8413 match(Set dst (AddI src1 src2)); 8414 format %{ "ADDI $dst, $src1, $src2" %} 8415 size(4); 8416 ins_encode %{ 8417 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8418 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8419 %} 8420 ins_pipe(pipe_class_default); 8421 %} 8422 8423 // Immediate Addition with 16-bit shifted operand 8424 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8425 match(Set dst (AddI src1 src2)); 8426 format %{ "ADDIS $dst, $src1, $src2" %} 8427 size(4); 8428 ins_encode %{ 8429 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8430 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8431 %} 8432 ins_pipe(pipe_class_default); 8433 %} 8434 8435 // Long Addition 8436 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8437 match(Set dst (AddL src1 src2)); 8438 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8439 size(4); 8440 ins_encode %{ 8441 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8442 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8443 %} 8444 ins_pipe(pipe_class_default); 8445 %} 8446 8447 // Expand does not work with above instruct. (??) 8448 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8449 // no match-rule 8450 effect(DEF dst, USE src1, USE src2); 8451 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8452 size(4); 8453 ins_encode %{ 8454 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8455 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8456 %} 8457 ins_pipe(pipe_class_default); 8458 %} 8459 8460 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8461 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8462 ins_cost(DEFAULT_COST*3); 8463 8464 expand %{ 8465 // FIXME: we should do this in the ideal world. 8466 iRegLdst tmp1; 8467 iRegLdst tmp2; 8468 addL_reg_reg(tmp1, src1, src2); 8469 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8470 addL_reg_reg(dst, tmp1, tmp2); 8471 %} 8472 %} 8473 8474 // AddL + ConvL2I. 8475 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8476 match(Set dst (ConvL2I (AddL src1 src2))); 8477 8478 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8479 size(4); 8480 ins_encode %{ 8481 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8482 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8483 %} 8484 ins_pipe(pipe_class_default); 8485 %} 8486 8487 // No constant pool entries required. 8488 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8489 match(Set dst (AddL src1 src2)); 8490 8491 format %{ "ADDI $dst, $src1, $src2" %} 8492 size(4); 8493 ins_encode %{ 8494 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8495 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8496 %} 8497 ins_pipe(pipe_class_default); 8498 %} 8499 8500 // Long Immediate Addition with 16-bit shifted operand. 8501 // No constant pool entries required. 8502 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8503 match(Set dst (AddL src1 src2)); 8504 8505 format %{ "ADDIS $dst, $src1, $src2" %} 8506 size(4); 8507 ins_encode %{ 8508 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8509 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8510 %} 8511 ins_pipe(pipe_class_default); 8512 %} 8513 8514 // Pointer Register Addition 8515 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8516 match(Set dst (AddP src1 src2)); 8517 format %{ "ADD $dst, $src1, $src2" %} 8518 size(4); 8519 ins_encode %{ 8520 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8521 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8522 %} 8523 ins_pipe(pipe_class_default); 8524 %} 8525 8526 // Pointer Immediate Addition 8527 // No constant pool entries required. 8528 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8529 match(Set dst (AddP src1 src2)); 8530 8531 format %{ "ADDI $dst, $src1, $src2" %} 8532 size(4); 8533 ins_encode %{ 8534 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8535 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8536 %} 8537 ins_pipe(pipe_class_default); 8538 %} 8539 8540 // Pointer Immediate Addition with 16-bit shifted operand. 8541 // No constant pool entries required. 8542 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8543 match(Set dst (AddP src1 src2)); 8544 8545 format %{ "ADDIS $dst, $src1, $src2" %} 8546 size(4); 8547 ins_encode %{ 8548 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8549 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8550 %} 8551 ins_pipe(pipe_class_default); 8552 %} 8553 8554 //--------------------- 8555 // Subtraction Instructions 8556 8557 // Register Subtraction 8558 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8559 match(Set dst (SubI src1 src2)); 8560 format %{ "SUBF $dst, $src2, $src1" %} 8561 size(4); 8562 ins_encode %{ 8563 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8564 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8565 %} 8566 ins_pipe(pipe_class_default); 8567 %} 8568 8569 // Immediate Subtraction 8570 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 8571 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 8572 8573 // SubI from constant (using subfic). 8574 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 8575 match(Set dst (SubI src1 src2)); 8576 format %{ "SUBI $dst, $src1, $src2" %} 8577 8578 size(4); 8579 ins_encode %{ 8580 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 8581 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 8582 %} 8583 ins_pipe(pipe_class_default); 8584 %} 8585 8586 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 8587 // positive integers and 0xF...F for negative ones. 8588 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 8589 // no match-rule, false predicate 8590 effect(DEF dst, USE src); 8591 predicate(false); 8592 8593 format %{ "SRAWI $dst, $src, #31" %} 8594 size(4); 8595 ins_encode %{ 8596 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 8597 __ srawi($dst$$Register, $src$$Register, 0x1f); 8598 %} 8599 ins_pipe(pipe_class_default); 8600 %} 8601 8602 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 8603 match(Set dst (AbsI src)); 8604 ins_cost(DEFAULT_COST*3); 8605 8606 expand %{ 8607 iRegIdst tmp1; 8608 iRegIdst tmp2; 8609 signmask32I_regI(tmp1, src); 8610 xorI_reg_reg(tmp2, tmp1, src); 8611 subI_reg_reg(dst, tmp2, tmp1); 8612 %} 8613 %} 8614 8615 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 8616 match(Set dst (SubI zero src2)); 8617 format %{ "NEG $dst, $src2" %} 8618 size(4); 8619 ins_encode %{ 8620 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8621 __ neg($dst$$Register, $src2$$Register); 8622 %} 8623 ins_pipe(pipe_class_default); 8624 %} 8625 8626 // Long subtraction 8627 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8628 match(Set dst (SubL src1 src2)); 8629 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 8630 size(4); 8631 ins_encode %{ 8632 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8633 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8634 %} 8635 ins_pipe(pipe_class_default); 8636 %} 8637 8638 // SubL + convL2I. 8639 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8640 match(Set dst (ConvL2I (SubL src1 src2))); 8641 8642 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 8643 size(4); 8644 ins_encode %{ 8645 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8646 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8647 %} 8648 ins_pipe(pipe_class_default); 8649 %} 8650 8651 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8652 // positive longs and 0xF...F for negative ones. 8653 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 8654 // no match-rule, false predicate 8655 effect(DEF dst, USE src); 8656 predicate(false); 8657 8658 format %{ "SRADI $dst, $src, #63" %} 8659 size(4); 8660 ins_encode %{ 8661 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8662 __ sradi($dst$$Register, $src$$Register, 0x3f); 8663 %} 8664 ins_pipe(pipe_class_default); 8665 %} 8666 8667 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8668 // positive longs and 0xF...F for negative ones. 8669 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 8670 // no match-rule, false predicate 8671 effect(DEF dst, USE src); 8672 predicate(false); 8673 8674 format %{ "SRADI $dst, $src, #63" %} 8675 size(4); 8676 ins_encode %{ 8677 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8678 __ sradi($dst$$Register, $src$$Register, 0x3f); 8679 %} 8680 ins_pipe(pipe_class_default); 8681 %} 8682 8683 // Long negation 8684 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 8685 match(Set dst (SubL zero src2)); 8686 format %{ "NEG $dst, $src2 \t// long" %} 8687 size(4); 8688 ins_encode %{ 8689 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8690 __ neg($dst$$Register, $src2$$Register); 8691 %} 8692 ins_pipe(pipe_class_default); 8693 %} 8694 8695 // NegL + ConvL2I. 8696 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 8697 match(Set dst (ConvL2I (SubL zero src2))); 8698 8699 format %{ "NEG $dst, $src2 \t// long + l2i" %} 8700 size(4); 8701 ins_encode %{ 8702 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8703 __ neg($dst$$Register, $src2$$Register); 8704 %} 8705 ins_pipe(pipe_class_default); 8706 %} 8707 8708 // Multiplication Instructions 8709 // Integer Multiplication 8710 8711 // Register Multiplication 8712 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8713 match(Set dst (MulI src1 src2)); 8714 ins_cost(DEFAULT_COST); 8715 8716 format %{ "MULLW $dst, $src1, $src2" %} 8717 size(4); 8718 ins_encode %{ 8719 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 8720 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 8721 %} 8722 ins_pipe(pipe_class_default); 8723 %} 8724 8725 // Immediate Multiplication 8726 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8727 match(Set dst (MulI src1 src2)); 8728 ins_cost(DEFAULT_COST); 8729 8730 format %{ "MULLI $dst, $src1, $src2" %} 8731 size(4); 8732 ins_encode %{ 8733 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8734 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8735 %} 8736 ins_pipe(pipe_class_default); 8737 %} 8738 8739 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8740 match(Set dst (MulL src1 src2)); 8741 ins_cost(DEFAULT_COST); 8742 8743 format %{ "MULLD $dst $src1, $src2 \t// long" %} 8744 size(4); 8745 ins_encode %{ 8746 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 8747 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 8748 %} 8749 ins_pipe(pipe_class_default); 8750 %} 8751 8752 // Multiply high for optimized long division by constant. 8753 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8754 match(Set dst (MulHiL src1 src2)); 8755 ins_cost(DEFAULT_COST); 8756 8757 format %{ "MULHD $dst $src1, $src2 \t// long" %} 8758 size(4); 8759 ins_encode %{ 8760 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 8761 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 8762 %} 8763 ins_pipe(pipe_class_default); 8764 %} 8765 8766 // Immediate Multiplication 8767 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8768 match(Set dst (MulL src1 src2)); 8769 ins_cost(DEFAULT_COST); 8770 8771 format %{ "MULLI $dst, $src1, $src2" %} 8772 size(4); 8773 ins_encode %{ 8774 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8775 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8776 %} 8777 ins_pipe(pipe_class_default); 8778 %} 8779 8780 // Integer Division with Immediate -1: Negate. 8781 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 8782 match(Set dst (DivI src1 src2)); 8783 ins_cost(DEFAULT_COST); 8784 8785 format %{ "NEG $dst, $src1 \t// /-1" %} 8786 size(4); 8787 ins_encode %{ 8788 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8789 __ neg($dst$$Register, $src1$$Register); 8790 %} 8791 ins_pipe(pipe_class_default); 8792 %} 8793 8794 // Integer Division with constant, but not -1. 8795 // We should be able to improve this by checking the type of src2. 8796 // It might well be that src2 is known to be positive. 8797 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8798 match(Set dst (DivI src1 src2)); 8799 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 8800 ins_cost(2*DEFAULT_COST); 8801 8802 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 8803 size(4); 8804 ins_encode %{ 8805 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 8806 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 8807 %} 8808 ins_pipe(pipe_class_default); 8809 %} 8810 8811 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 8812 effect(USE_DEF dst, USE src1, USE crx); 8813 predicate(false); 8814 8815 ins_variable_size_depending_on_alignment(true); 8816 8817 format %{ "CMOVE $dst, neg($src1), $crx" %} 8818 // Worst case is branch + move + stop, no stop without scheduler. 8819 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8820 ins_encode %{ 8821 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8822 Label done; 8823 __ bne($crx$$CondRegister, done); 8824 __ neg($dst$$Register, $src1$$Register); 8825 // TODO PPC port __ endgroup_if_needed(_size == 12); 8826 __ bind(done); 8827 %} 8828 ins_pipe(pipe_class_default); 8829 %} 8830 8831 // Integer Division with Registers not containing constants. 8832 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8833 match(Set dst (DivI src1 src2)); 8834 ins_cost(10*DEFAULT_COST); 8835 8836 expand %{ 8837 immI16 imm %{ (int)-1 %} 8838 flagsReg tmp1; 8839 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8840 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8841 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8842 %} 8843 %} 8844 8845 // Long Division with Immediate -1: Negate. 8846 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 8847 match(Set dst (DivL src1 src2)); 8848 ins_cost(DEFAULT_COST); 8849 8850 format %{ "NEG $dst, $src1 \t// /-1, long" %} 8851 size(4); 8852 ins_encode %{ 8853 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8854 __ neg($dst$$Register, $src1$$Register); 8855 %} 8856 ins_pipe(pipe_class_default); 8857 %} 8858 8859 // Long Division with constant, but not -1. 8860 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8861 match(Set dst (DivL src1 src2)); 8862 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 8863 ins_cost(2*DEFAULT_COST); 8864 8865 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 8866 size(4); 8867 ins_encode %{ 8868 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 8869 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 8870 %} 8871 ins_pipe(pipe_class_default); 8872 %} 8873 8874 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 8875 effect(USE_DEF dst, USE src1, USE crx); 8876 predicate(false); 8877 8878 ins_variable_size_depending_on_alignment(true); 8879 8880 format %{ "CMOVE $dst, neg($src1), $crx" %} 8881 // Worst case is branch + move + stop, no stop without scheduler. 8882 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8883 ins_encode %{ 8884 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8885 Label done; 8886 __ bne($crx$$CondRegister, done); 8887 __ neg($dst$$Register, $src1$$Register); 8888 // TODO PPC port __ endgroup_if_needed(_size == 12); 8889 __ bind(done); 8890 %} 8891 ins_pipe(pipe_class_default); 8892 %} 8893 8894 // Long Division with Registers not containing constants. 8895 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8896 match(Set dst (DivL src1 src2)); 8897 ins_cost(10*DEFAULT_COST); 8898 8899 expand %{ 8900 immL16 imm %{ (int)-1 %} 8901 flagsReg tmp1; 8902 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8903 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8904 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8905 %} 8906 %} 8907 8908 // Integer Remainder with registers. 8909 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8910 match(Set dst (ModI src1 src2)); 8911 ins_cost(10*DEFAULT_COST); 8912 8913 expand %{ 8914 immI16 imm %{ (int)-1 %} 8915 flagsReg tmp1; 8916 iRegIdst tmp2; 8917 iRegIdst tmp3; 8918 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8919 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8920 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8921 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8922 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8923 %} 8924 %} 8925 8926 // Long Remainder with registers 8927 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8928 match(Set dst (ModL src1 src2)); 8929 ins_cost(10*DEFAULT_COST); 8930 8931 expand %{ 8932 immL16 imm %{ (int)-1 %} 8933 flagsReg tmp1; 8934 iRegLdst tmp2; 8935 iRegLdst tmp3; 8936 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8937 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8938 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8939 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8940 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8941 %} 8942 %} 8943 8944 // Integer Shift Instructions 8945 8946 // Register Shift Left 8947 8948 // Clear all but the lowest #mask bits. 8949 // Used to normalize shift amounts in registers. 8950 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 8951 // no match-rule, false predicate 8952 effect(DEF dst, USE src, USE mask); 8953 predicate(false); 8954 8955 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 8956 size(4); 8957 ins_encode %{ 8958 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 8959 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 8960 %} 8961 ins_pipe(pipe_class_default); 8962 %} 8963 8964 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8965 // no match-rule, false predicate 8966 effect(DEF dst, USE src1, USE src2); 8967 predicate(false); 8968 8969 format %{ "SLW $dst, $src1, $src2" %} 8970 size(4); 8971 ins_encode %{ 8972 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 8973 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 8974 %} 8975 ins_pipe(pipe_class_default); 8976 %} 8977 8978 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8979 match(Set dst (LShiftI src1 src2)); 8980 ins_cost(DEFAULT_COST*2); 8981 expand %{ 8982 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 8983 iRegIdst tmpI; 8984 maskI_reg_imm(tmpI, src2, mask); 8985 lShiftI_reg_reg(dst, src1, tmpI); 8986 %} 8987 %} 8988 8989 // Register Shift Left Immediate 8990 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 8991 match(Set dst (LShiftI src1 src2)); 8992 8993 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 8994 size(4); 8995 ins_encode %{ 8996 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 8997 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 8998 %} 8999 ins_pipe(pipe_class_default); 9000 %} 9001 9002 // AndI with negpow2-constant + LShiftI 9003 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9004 match(Set dst (LShiftI (AndI src1 src2) src3)); 9005 predicate(UseRotateAndMaskInstructionsPPC64); 9006 9007 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9008 size(4); 9009 ins_encode %{ 9010 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9011 long src2 = $src2$$constant; 9012 long src3 = $src3$$constant; 9013 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9014 if (maskbits >= 32) { 9015 __ li($dst$$Register, 0); // addi 9016 } else { 9017 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9018 } 9019 %} 9020 ins_pipe(pipe_class_default); 9021 %} 9022 9023 // RShiftI + AndI with negpow2-constant + LShiftI 9024 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9025 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9026 predicate(UseRotateAndMaskInstructionsPPC64); 9027 9028 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9029 size(4); 9030 ins_encode %{ 9031 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9032 long src2 = $src2$$constant; 9033 long src3 = $src3$$constant; 9034 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9035 if (maskbits >= 32) { 9036 __ li($dst$$Register, 0); // addi 9037 } else { 9038 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9039 } 9040 %} 9041 ins_pipe(pipe_class_default); 9042 %} 9043 9044 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9045 // no match-rule, false predicate 9046 effect(DEF dst, USE src1, USE src2); 9047 predicate(false); 9048 9049 format %{ "SLD $dst, $src1, $src2" %} 9050 size(4); 9051 ins_encode %{ 9052 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9053 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9054 %} 9055 ins_pipe(pipe_class_default); 9056 %} 9057 9058 // Register Shift Left 9059 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9060 match(Set dst (LShiftL src1 src2)); 9061 ins_cost(DEFAULT_COST*2); 9062 expand %{ 9063 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9064 iRegIdst tmpI; 9065 maskI_reg_imm(tmpI, src2, mask); 9066 lShiftL_regL_regI(dst, src1, tmpI); 9067 %} 9068 %} 9069 9070 // Register Shift Left Immediate 9071 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9072 match(Set dst (LShiftL src1 src2)); 9073 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9074 size(4); 9075 ins_encode %{ 9076 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9077 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9078 %} 9079 ins_pipe(pipe_class_default); 9080 %} 9081 9082 // If we shift more than 32 bits, we need not convert I2L. 9083 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9084 match(Set dst (LShiftL (ConvI2L src1) src2)); 9085 ins_cost(DEFAULT_COST); 9086 9087 size(4); 9088 format %{ "SLDI $dst, i2l($src1), $src2" %} 9089 ins_encode %{ 9090 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9091 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9092 %} 9093 ins_pipe(pipe_class_default); 9094 %} 9095 9096 // Shift a postivie int to the left. 9097 // Clrlsldi clears the upper 32 bits and shifts. 9098 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9099 match(Set dst (LShiftL (ConvI2L src1) src2)); 9100 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9101 9102 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9103 size(4); 9104 ins_encode %{ 9105 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9106 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9107 %} 9108 ins_pipe(pipe_class_default); 9109 %} 9110 9111 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9112 // no match-rule, false predicate 9113 effect(DEF dst, USE src1, USE src2); 9114 predicate(false); 9115 9116 format %{ "SRAW $dst, $src1, $src2" %} 9117 size(4); 9118 ins_encode %{ 9119 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9120 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9121 %} 9122 ins_pipe(pipe_class_default); 9123 %} 9124 9125 // Register Arithmetic Shift Right 9126 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9127 match(Set dst (RShiftI src1 src2)); 9128 ins_cost(DEFAULT_COST*2); 9129 expand %{ 9130 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9131 iRegIdst tmpI; 9132 maskI_reg_imm(tmpI, src2, mask); 9133 arShiftI_reg_reg(dst, src1, tmpI); 9134 %} 9135 %} 9136 9137 // Register Arithmetic Shift Right Immediate 9138 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9139 match(Set dst (RShiftI src1 src2)); 9140 9141 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9142 size(4); 9143 ins_encode %{ 9144 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9145 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9146 %} 9147 ins_pipe(pipe_class_default); 9148 %} 9149 9150 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9151 // no match-rule, false predicate 9152 effect(DEF dst, USE src1, USE src2); 9153 predicate(false); 9154 9155 format %{ "SRAD $dst, $src1, $src2" %} 9156 size(4); 9157 ins_encode %{ 9158 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9159 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9160 %} 9161 ins_pipe(pipe_class_default); 9162 %} 9163 9164 // Register Shift Right Arithmetic Long 9165 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9166 match(Set dst (RShiftL src1 src2)); 9167 ins_cost(DEFAULT_COST*2); 9168 9169 expand %{ 9170 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9171 iRegIdst tmpI; 9172 maskI_reg_imm(tmpI, src2, mask); 9173 arShiftL_regL_regI(dst, src1, tmpI); 9174 %} 9175 %} 9176 9177 // Register Shift Right Immediate 9178 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9179 match(Set dst (RShiftL src1 src2)); 9180 9181 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9182 size(4); 9183 ins_encode %{ 9184 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9185 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9186 %} 9187 ins_pipe(pipe_class_default); 9188 %} 9189 9190 // RShiftL + ConvL2I 9191 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9192 match(Set dst (ConvL2I (RShiftL src1 src2))); 9193 9194 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9195 size(4); 9196 ins_encode %{ 9197 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9198 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9199 %} 9200 ins_pipe(pipe_class_default); 9201 %} 9202 9203 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9204 // no match-rule, false predicate 9205 effect(DEF dst, USE src1, USE src2); 9206 predicate(false); 9207 9208 format %{ "SRW $dst, $src1, $src2" %} 9209 size(4); 9210 ins_encode %{ 9211 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9212 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9213 %} 9214 ins_pipe(pipe_class_default); 9215 %} 9216 9217 // Register Shift Right 9218 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9219 match(Set dst (URShiftI src1 src2)); 9220 ins_cost(DEFAULT_COST*2); 9221 9222 expand %{ 9223 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9224 iRegIdst tmpI; 9225 maskI_reg_imm(tmpI, src2, mask); 9226 urShiftI_reg_reg(dst, src1, tmpI); 9227 %} 9228 %} 9229 9230 // Register Shift Right Immediate 9231 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9232 match(Set dst (URShiftI src1 src2)); 9233 9234 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9235 size(4); 9236 ins_encode %{ 9237 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9238 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9239 %} 9240 ins_pipe(pipe_class_default); 9241 %} 9242 9243 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9244 // no match-rule, false predicate 9245 effect(DEF dst, USE src1, USE src2); 9246 predicate(false); 9247 9248 format %{ "SRD $dst, $src1, $src2" %} 9249 size(4); 9250 ins_encode %{ 9251 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9252 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9253 %} 9254 ins_pipe(pipe_class_default); 9255 %} 9256 9257 // Register Shift Right 9258 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9259 match(Set dst (URShiftL src1 src2)); 9260 ins_cost(DEFAULT_COST*2); 9261 9262 expand %{ 9263 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9264 iRegIdst tmpI; 9265 maskI_reg_imm(tmpI, src2, mask); 9266 urShiftL_regL_regI(dst, src1, tmpI); 9267 %} 9268 %} 9269 9270 // Register Shift Right Immediate 9271 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9272 match(Set dst (URShiftL src1 src2)); 9273 9274 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9275 size(4); 9276 ins_encode %{ 9277 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9278 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9279 %} 9280 ins_pipe(pipe_class_default); 9281 %} 9282 9283 // URShiftL + ConvL2I. 9284 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9285 match(Set dst (ConvL2I (URShiftL src1 src2))); 9286 9287 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9288 size(4); 9289 ins_encode %{ 9290 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9291 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9292 %} 9293 ins_pipe(pipe_class_default); 9294 %} 9295 9296 // Register Shift Right Immediate with a CastP2X 9297 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9298 match(Set dst (URShiftL (CastP2X src1) src2)); 9299 9300 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9301 size(4); 9302 ins_encode %{ 9303 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9304 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9305 %} 9306 ins_pipe(pipe_class_default); 9307 %} 9308 9309 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9310 match(Set dst (ConvL2I (ConvI2L src))); 9311 9312 format %{ "EXTSW $dst, $src \t// int->int" %} 9313 size(4); 9314 ins_encode %{ 9315 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9316 __ extsw($dst$$Register, $src$$Register); 9317 %} 9318 ins_pipe(pipe_class_default); 9319 %} 9320 9321 //----------Rotate Instructions------------------------------------------------ 9322 9323 // Rotate Left by 8-bit immediate 9324 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9325 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9326 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9327 9328 format %{ "ROTLWI $dst, $src, $lshift" %} 9329 size(4); 9330 ins_encode %{ 9331 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9332 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9333 %} 9334 ins_pipe(pipe_class_default); 9335 %} 9336 9337 // Rotate Right by 8-bit immediate 9338 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9339 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9340 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9341 9342 format %{ "ROTRWI $dst, $rshift" %} 9343 size(4); 9344 ins_encode %{ 9345 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9346 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9347 %} 9348 ins_pipe(pipe_class_default); 9349 %} 9350 9351 //----------Floating Point Arithmetic Instructions----------------------------- 9352 9353 // Add float single precision 9354 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9355 match(Set dst (AddF src1 src2)); 9356 9357 format %{ "FADDS $dst, $src1, $src2" %} 9358 size(4); 9359 ins_encode %{ 9360 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9361 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9362 %} 9363 ins_pipe(pipe_class_default); 9364 %} 9365 9366 // Add float double precision 9367 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9368 match(Set dst (AddD src1 src2)); 9369 9370 format %{ "FADD $dst, $src1, $src2" %} 9371 size(4); 9372 ins_encode %{ 9373 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9374 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9375 %} 9376 ins_pipe(pipe_class_default); 9377 %} 9378 9379 // Sub float single precision 9380 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9381 match(Set dst (SubF src1 src2)); 9382 9383 format %{ "FSUBS $dst, $src1, $src2" %} 9384 size(4); 9385 ins_encode %{ 9386 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9387 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9388 %} 9389 ins_pipe(pipe_class_default); 9390 %} 9391 9392 // Sub float double precision 9393 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9394 match(Set dst (SubD src1 src2)); 9395 format %{ "FSUB $dst, $src1, $src2" %} 9396 size(4); 9397 ins_encode %{ 9398 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9399 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9400 %} 9401 ins_pipe(pipe_class_default); 9402 %} 9403 9404 // Mul float single precision 9405 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9406 match(Set dst (MulF src1 src2)); 9407 format %{ "FMULS $dst, $src1, $src2" %} 9408 size(4); 9409 ins_encode %{ 9410 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9411 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9412 %} 9413 ins_pipe(pipe_class_default); 9414 %} 9415 9416 // Mul float double precision 9417 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9418 match(Set dst (MulD src1 src2)); 9419 format %{ "FMUL $dst, $src1, $src2" %} 9420 size(4); 9421 ins_encode %{ 9422 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9423 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9424 %} 9425 ins_pipe(pipe_class_default); 9426 %} 9427 9428 // Div float single precision 9429 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9430 match(Set dst (DivF src1 src2)); 9431 format %{ "FDIVS $dst, $src1, $src2" %} 9432 size(4); 9433 ins_encode %{ 9434 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9435 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9436 %} 9437 ins_pipe(pipe_class_default); 9438 %} 9439 9440 // Div float double precision 9441 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9442 match(Set dst (DivD src1 src2)); 9443 format %{ "FDIV $dst, $src1, $src2" %} 9444 size(4); 9445 ins_encode %{ 9446 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9447 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9448 %} 9449 ins_pipe(pipe_class_default); 9450 %} 9451 9452 // Absolute float single precision 9453 instruct absF_reg(regF dst, regF src) %{ 9454 match(Set dst (AbsF src)); 9455 format %{ "FABS $dst, $src \t// float" %} 9456 size(4); 9457 ins_encode %{ 9458 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9459 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9460 %} 9461 ins_pipe(pipe_class_default); 9462 %} 9463 9464 // Absolute float double precision 9465 instruct absD_reg(regD dst, regD src) %{ 9466 match(Set dst (AbsD src)); 9467 format %{ "FABS $dst, $src \t// double" %} 9468 size(4); 9469 ins_encode %{ 9470 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9471 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9472 %} 9473 ins_pipe(pipe_class_default); 9474 %} 9475 9476 instruct negF_reg(regF dst, regF src) %{ 9477 match(Set dst (NegF src)); 9478 format %{ "FNEG $dst, $src \t// float" %} 9479 size(4); 9480 ins_encode %{ 9481 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9482 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9483 %} 9484 ins_pipe(pipe_class_default); 9485 %} 9486 9487 instruct negD_reg(regD dst, regD src) %{ 9488 match(Set dst (NegD src)); 9489 format %{ "FNEG $dst, $src \t// double" %} 9490 size(4); 9491 ins_encode %{ 9492 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9493 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9494 %} 9495 ins_pipe(pipe_class_default); 9496 %} 9497 9498 // AbsF + NegF. 9499 instruct negF_absF_reg(regF dst, regF src) %{ 9500 match(Set dst (NegF (AbsF src))); 9501 format %{ "FNABS $dst, $src \t// float" %} 9502 size(4); 9503 ins_encode %{ 9504 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9505 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9506 %} 9507 ins_pipe(pipe_class_default); 9508 %} 9509 9510 // AbsD + NegD. 9511 instruct negD_absD_reg(regD dst, regD src) %{ 9512 match(Set dst (NegD (AbsD src))); 9513 format %{ "FNABS $dst, $src \t// double" %} 9514 size(4); 9515 ins_encode %{ 9516 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9517 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9518 %} 9519 ins_pipe(pipe_class_default); 9520 %} 9521 9522 // VM_Version::has_fsqrt() decides if this node will be used. 9523 // Sqrt float double precision 9524 instruct sqrtD_reg(regD dst, regD src) %{ 9525 match(Set dst (SqrtD src)); 9526 format %{ "FSQRT $dst, $src" %} 9527 size(4); 9528 ins_encode %{ 9529 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 9530 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 9531 %} 9532 ins_pipe(pipe_class_default); 9533 %} 9534 9535 // Single-precision sqrt. 9536 instruct sqrtF_reg(regF dst, regF src) %{ 9537 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 9538 predicate(VM_Version::has_fsqrts()); 9539 ins_cost(DEFAULT_COST); 9540 9541 format %{ "FSQRTS $dst, $src" %} 9542 size(4); 9543 ins_encode %{ 9544 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 9545 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 9546 %} 9547 ins_pipe(pipe_class_default); 9548 %} 9549 9550 instruct roundDouble_nop(regD dst) %{ 9551 match(Set dst (RoundDouble dst)); 9552 ins_cost(0); 9553 9554 format %{ " -- \t// RoundDouble not needed - empty" %} 9555 size(0); 9556 // PPC results are already "rounded" (i.e., normal-format IEEE). 9557 ins_encode( /*empty*/ ); 9558 ins_pipe(pipe_class_default); 9559 %} 9560 9561 instruct roundFloat_nop(regF dst) %{ 9562 match(Set dst (RoundFloat dst)); 9563 ins_cost(0); 9564 9565 format %{ " -- \t// RoundFloat not needed - empty" %} 9566 size(0); 9567 // PPC results are already "rounded" (i.e., normal-format IEEE). 9568 ins_encode( /*empty*/ ); 9569 ins_pipe(pipe_class_default); 9570 %} 9571 9572 //----------Logical Instructions----------------------------------------------- 9573 9574 // And Instructions 9575 9576 // Register And 9577 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9578 match(Set dst (AndI src1 src2)); 9579 format %{ "AND $dst, $src1, $src2" %} 9580 size(4); 9581 ins_encode %{ 9582 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9583 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9584 %} 9585 ins_pipe(pipe_class_default); 9586 %} 9587 9588 // Left shifted Immediate And 9589 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 9590 match(Set dst (AndI src1 src2)); 9591 effect(KILL cr0); 9592 format %{ "ANDIS $dst, $src1, $src2.hi" %} 9593 size(4); 9594 ins_encode %{ 9595 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 9596 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 9597 %} 9598 ins_pipe(pipe_class_default); 9599 %} 9600 9601 // Immediate And 9602 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 9603 match(Set dst (AndI src1 src2)); 9604 effect(KILL cr0); 9605 9606 format %{ "ANDI $dst, $src1, $src2" %} 9607 size(4); 9608 ins_encode %{ 9609 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9610 // FIXME: avoid andi_ ? 9611 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9612 %} 9613 ins_pipe(pipe_class_default); 9614 %} 9615 9616 // Immediate And where the immediate is a negative power of 2. 9617 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 9618 match(Set dst (AndI src1 src2)); 9619 format %{ "ANDWI $dst, $src1, $src2" %} 9620 size(4); 9621 ins_encode %{ 9622 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9623 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 9624 %} 9625 ins_pipe(pipe_class_default); 9626 %} 9627 9628 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 9629 match(Set dst (AndI src1 src2)); 9630 format %{ "ANDWI $dst, $src1, $src2" %} 9631 size(4); 9632 ins_encode %{ 9633 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9634 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9635 %} 9636 ins_pipe(pipe_class_default); 9637 %} 9638 9639 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 9640 match(Set dst (AndI src1 src2)); 9641 predicate(UseRotateAndMaskInstructionsPPC64); 9642 format %{ "ANDWI $dst, $src1, $src2" %} 9643 size(4); 9644 ins_encode %{ 9645 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9646 __ rlwinm($dst$$Register, $src1$$Register, 0, 9647 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 9648 %} 9649 ins_pipe(pipe_class_default); 9650 %} 9651 9652 // Register And Long 9653 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9654 match(Set dst (AndL src1 src2)); 9655 ins_cost(DEFAULT_COST); 9656 9657 format %{ "AND $dst, $src1, $src2 \t// long" %} 9658 size(4); 9659 ins_encode %{ 9660 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9661 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9662 %} 9663 ins_pipe(pipe_class_default); 9664 %} 9665 9666 // Immediate And long 9667 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 9668 match(Set dst (AndL src1 src2)); 9669 effect(KILL cr0); 9670 9671 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 9672 size(4); 9673 ins_encode %{ 9674 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9675 // FIXME: avoid andi_ ? 9676 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9677 %} 9678 ins_pipe(pipe_class_default); 9679 %} 9680 9681 // Immediate And Long where the immediate is a negative power of 2. 9682 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 9683 match(Set dst (AndL src1 src2)); 9684 format %{ "ANDDI $dst, $src1, $src2" %} 9685 size(4); 9686 ins_encode %{ 9687 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9688 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 9689 %} 9690 ins_pipe(pipe_class_default); 9691 %} 9692 9693 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9694 match(Set dst (AndL src1 src2)); 9695 format %{ "ANDDI $dst, $src1, $src2" %} 9696 size(4); 9697 ins_encode %{ 9698 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9699 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9700 %} 9701 ins_pipe(pipe_class_default); 9702 %} 9703 9704 // AndL + ConvL2I. 9705 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9706 match(Set dst (ConvL2I (AndL src1 src2))); 9707 ins_cost(DEFAULT_COST); 9708 9709 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 9710 size(4); 9711 ins_encode %{ 9712 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9713 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9714 %} 9715 ins_pipe(pipe_class_default); 9716 %} 9717 9718 // Or Instructions 9719 9720 // Register Or 9721 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9722 match(Set dst (OrI src1 src2)); 9723 format %{ "OR $dst, $src1, $src2" %} 9724 size(4); 9725 ins_encode %{ 9726 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9727 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9728 %} 9729 ins_pipe(pipe_class_default); 9730 %} 9731 9732 // Expand does not work with above instruct. (??) 9733 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9734 // no match-rule 9735 effect(DEF dst, USE src1, USE src2); 9736 format %{ "OR $dst, $src1, $src2" %} 9737 size(4); 9738 ins_encode %{ 9739 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9740 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9741 %} 9742 ins_pipe(pipe_class_default); 9743 %} 9744 9745 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9746 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 9747 ins_cost(DEFAULT_COST*3); 9748 9749 expand %{ 9750 // FIXME: we should do this in the ideal world. 9751 iRegIdst tmp1; 9752 iRegIdst tmp2; 9753 orI_reg_reg(tmp1, src1, src2); 9754 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 9755 orI_reg_reg(dst, tmp1, tmp2); 9756 %} 9757 %} 9758 9759 // Immediate Or 9760 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9761 match(Set dst (OrI src1 src2)); 9762 format %{ "ORI $dst, $src1, $src2" %} 9763 size(4); 9764 ins_encode %{ 9765 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9766 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 9767 %} 9768 ins_pipe(pipe_class_default); 9769 %} 9770 9771 // Register Or Long 9772 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9773 match(Set dst (OrL src1 src2)); 9774 ins_cost(DEFAULT_COST); 9775 9776 size(4); 9777 format %{ "OR $dst, $src1, $src2 \t// long" %} 9778 ins_encode %{ 9779 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9780 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9781 %} 9782 ins_pipe(pipe_class_default); 9783 %} 9784 9785 // OrL + ConvL2I. 9786 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9787 match(Set dst (ConvL2I (OrL src1 src2))); 9788 ins_cost(DEFAULT_COST); 9789 9790 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 9791 size(4); 9792 ins_encode %{ 9793 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9794 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9795 %} 9796 ins_pipe(pipe_class_default); 9797 %} 9798 9799 // Immediate Or long 9800 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 9801 match(Set dst (OrL src1 con)); 9802 ins_cost(DEFAULT_COST); 9803 9804 format %{ "ORI $dst, $src1, $con \t// long" %} 9805 size(4); 9806 ins_encode %{ 9807 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9808 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 9809 %} 9810 ins_pipe(pipe_class_default); 9811 %} 9812 9813 // Xor Instructions 9814 9815 // Register Xor 9816 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9817 match(Set dst (XorI src1 src2)); 9818 format %{ "XOR $dst, $src1, $src2" %} 9819 size(4); 9820 ins_encode %{ 9821 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9822 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9823 %} 9824 ins_pipe(pipe_class_default); 9825 %} 9826 9827 // Expand does not work with above instruct. (??) 9828 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9829 // no match-rule 9830 effect(DEF dst, USE src1, USE src2); 9831 format %{ "XOR $dst, $src1, $src2" %} 9832 size(4); 9833 ins_encode %{ 9834 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9835 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9836 %} 9837 ins_pipe(pipe_class_default); 9838 %} 9839 9840 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9841 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 9842 ins_cost(DEFAULT_COST*3); 9843 9844 expand %{ 9845 // FIXME: we should do this in the ideal world. 9846 iRegIdst tmp1; 9847 iRegIdst tmp2; 9848 xorI_reg_reg(tmp1, src1, src2); 9849 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 9850 xorI_reg_reg(dst, tmp1, tmp2); 9851 %} 9852 %} 9853 9854 // Immediate Xor 9855 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9856 match(Set dst (XorI src1 src2)); 9857 format %{ "XORI $dst, $src1, $src2" %} 9858 size(4); 9859 ins_encode %{ 9860 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 9861 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 9862 %} 9863 ins_pipe(pipe_class_default); 9864 %} 9865 9866 // Register Xor Long 9867 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9868 match(Set dst (XorL src1 src2)); 9869 ins_cost(DEFAULT_COST); 9870 9871 format %{ "XOR $dst, $src1, $src2 \t// long" %} 9872 size(4); 9873 ins_encode %{ 9874 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9875 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9876 %} 9877 ins_pipe(pipe_class_default); 9878 %} 9879 9880 // XorL + ConvL2I. 9881 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9882 match(Set dst (ConvL2I (XorL src1 src2))); 9883 ins_cost(DEFAULT_COST); 9884 9885 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 9886 size(4); 9887 ins_encode %{ 9888 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9889 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9890 %} 9891 ins_pipe(pipe_class_default); 9892 %} 9893 9894 // Immediate Xor Long 9895 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 9896 match(Set dst (XorL src1 src2)); 9897 ins_cost(DEFAULT_COST); 9898 9899 format %{ "XORI $dst, $src1, $src2 \t// long" %} 9900 size(4); 9901 ins_encode %{ 9902 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 9903 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 9904 %} 9905 ins_pipe(pipe_class_default); 9906 %} 9907 9908 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9909 match(Set dst (XorI src1 src2)); 9910 ins_cost(DEFAULT_COST); 9911 9912 format %{ "NOT $dst, $src1 ($src2)" %} 9913 size(4); 9914 ins_encode %{ 9915 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 9916 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 9917 %} 9918 ins_pipe(pipe_class_default); 9919 %} 9920 9921 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9922 match(Set dst (XorL src1 src2)); 9923 ins_cost(DEFAULT_COST); 9924 9925 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 9926 size(4); 9927 ins_encode %{ 9928 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 9929 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 9930 %} 9931 ins_pipe(pipe_class_default); 9932 %} 9933 9934 // And-complement 9935 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 9936 match(Set dst (AndI (XorI src1 src2) src3)); 9937 ins_cost(DEFAULT_COST); 9938 9939 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 9940 size(4); 9941 ins_encode( enc_andc(dst, src3, src1) ); 9942 ins_pipe(pipe_class_default); 9943 %} 9944 9945 // And-complement 9946 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9947 // no match-rule, false predicate 9948 effect(DEF dst, USE src1, USE src2); 9949 predicate(false); 9950 9951 format %{ "ANDC $dst, $src1, $src2" %} 9952 size(4); 9953 ins_encode %{ 9954 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 9955 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 9956 %} 9957 ins_pipe(pipe_class_default); 9958 %} 9959 9960 //----------Moves between int/long and float/double---------------------------- 9961 // 9962 // The following rules move values from int/long registers/stack-locations 9963 // to float/double registers/stack-locations and vice versa, without doing any 9964 // conversions. These rules are used to implement the bit-conversion methods 9965 // of java.lang.Float etc., e.g. 9966 // int floatToIntBits(float value) 9967 // float intBitsToFloat(int bits) 9968 // 9969 // Notes on the implementation on ppc64: 9970 // We only provide rules which move between a register and a stack-location, 9971 // because we always have to go through memory when moving between a float 9972 // register and an integer register. 9973 9974 //---------- Chain stack slots between similar types -------- 9975 9976 // These are needed so that the rules below can match. 9977 9978 // Load integer from stack slot 9979 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 9980 match(Set dst src); 9981 ins_cost(MEMORY_REF_COST); 9982 9983 format %{ "LWZ $dst, $src" %} 9984 size(4); 9985 ins_encode( enc_lwz(dst, src) ); 9986 ins_pipe(pipe_class_memory); 9987 %} 9988 9989 // Store integer to stack slot 9990 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 9991 match(Set dst src); 9992 ins_cost(MEMORY_REF_COST); 9993 9994 format %{ "STW $src, $dst \t// stk" %} 9995 size(4); 9996 ins_encode( enc_stw(src, dst) ); // rs=rt 9997 ins_pipe(pipe_class_memory); 9998 %} 9999 10000 // Load long from stack slot 10001 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10002 match(Set dst src); 10003 ins_cost(MEMORY_REF_COST); 10004 10005 format %{ "LD $dst, $src \t// long" %} 10006 size(4); 10007 ins_encode( enc_ld(dst, src) ); 10008 ins_pipe(pipe_class_memory); 10009 %} 10010 10011 // Store long to stack slot 10012 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10013 match(Set dst src); 10014 ins_cost(MEMORY_REF_COST); 10015 10016 format %{ "STD $src, $dst \t// long" %} 10017 size(4); 10018 ins_encode( enc_std(src, dst) ); // rs=rt 10019 ins_pipe(pipe_class_memory); 10020 %} 10021 10022 //----------Moves between int and float 10023 10024 // Move float value from float stack-location to integer register. 10025 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10026 match(Set dst (MoveF2I src)); 10027 ins_cost(MEMORY_REF_COST); 10028 10029 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10030 size(4); 10031 ins_encode( enc_lwz(dst, src) ); 10032 ins_pipe(pipe_class_memory); 10033 %} 10034 10035 // Move float value from float register to integer stack-location. 10036 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10037 match(Set dst (MoveF2I src)); 10038 ins_cost(MEMORY_REF_COST); 10039 10040 format %{ "STFS $src, $dst \t// MoveF2I" %} 10041 size(4); 10042 ins_encode( enc_stfs(src, dst) ); 10043 ins_pipe(pipe_class_memory); 10044 %} 10045 10046 // Move integer value from integer stack-location to float register. 10047 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10048 match(Set dst (MoveI2F src)); 10049 ins_cost(MEMORY_REF_COST); 10050 10051 format %{ "LFS $dst, $src \t// MoveI2F" %} 10052 size(4); 10053 ins_encode %{ 10054 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10055 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10056 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10057 %} 10058 ins_pipe(pipe_class_memory); 10059 %} 10060 10061 // Move integer value from integer register to float stack-location. 10062 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10063 match(Set dst (MoveI2F src)); 10064 ins_cost(MEMORY_REF_COST); 10065 10066 format %{ "STW $src, $dst \t// MoveI2F" %} 10067 size(4); 10068 ins_encode( enc_stw(src, dst) ); 10069 ins_pipe(pipe_class_memory); 10070 %} 10071 10072 //----------Moves between long and float 10073 10074 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10075 // no match-rule, false predicate 10076 effect(DEF dst, USE src); 10077 predicate(false); 10078 10079 format %{ "storeD $src, $dst \t// STACK" %} 10080 size(4); 10081 ins_encode( enc_stfd(src, dst) ); 10082 ins_pipe(pipe_class_default); 10083 %} 10084 10085 //----------Moves between long and double 10086 10087 // Move double value from double stack-location to long register. 10088 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10089 match(Set dst (MoveD2L src)); 10090 ins_cost(MEMORY_REF_COST); 10091 size(4); 10092 format %{ "LD $dst, $src \t// MoveD2L" %} 10093 ins_encode( enc_ld(dst, src) ); 10094 ins_pipe(pipe_class_memory); 10095 %} 10096 10097 // Move double value from double register to long stack-location. 10098 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10099 match(Set dst (MoveD2L src)); 10100 effect(DEF dst, USE src); 10101 ins_cost(MEMORY_REF_COST); 10102 10103 format %{ "STFD $src, $dst \t// MoveD2L" %} 10104 size(4); 10105 ins_encode( enc_stfd(src, dst) ); 10106 ins_pipe(pipe_class_memory); 10107 %} 10108 10109 // Move long value from long stack-location to double register. 10110 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10111 match(Set dst (MoveL2D src)); 10112 ins_cost(MEMORY_REF_COST); 10113 10114 format %{ "LFD $dst, $src \t// MoveL2D" %} 10115 size(4); 10116 ins_encode( enc_lfd(dst, src) ); 10117 ins_pipe(pipe_class_memory); 10118 %} 10119 10120 // Move long value from long register to double stack-location. 10121 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10122 match(Set dst (MoveL2D src)); 10123 ins_cost(MEMORY_REF_COST); 10124 10125 format %{ "STD $src, $dst \t// MoveL2D" %} 10126 size(4); 10127 ins_encode( enc_std(src, dst) ); 10128 ins_pipe(pipe_class_memory); 10129 %} 10130 10131 //----------Register Move Instructions----------------------------------------- 10132 10133 // Replicate for Superword 10134 10135 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10136 predicate(false); 10137 effect(DEF dst, USE src); 10138 10139 format %{ "MR $dst, $src \t// replicate " %} 10140 // variable size, 0 or 4. 10141 ins_encode %{ 10142 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10143 __ mr_if_needed($dst$$Register, $src$$Register); 10144 %} 10145 ins_pipe(pipe_class_default); 10146 %} 10147 10148 //----------Cast instructions (Java-level type cast)--------------------------- 10149 10150 // Cast Long to Pointer for unsafe natives. 10151 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10152 match(Set dst (CastX2P src)); 10153 10154 format %{ "MR $dst, $src \t// Long->Ptr" %} 10155 // variable size, 0 or 4. 10156 ins_encode %{ 10157 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10158 __ mr_if_needed($dst$$Register, $src$$Register); 10159 %} 10160 ins_pipe(pipe_class_default); 10161 %} 10162 10163 // Cast Pointer to Long for unsafe natives. 10164 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10165 match(Set dst (CastP2X src)); 10166 10167 format %{ "MR $dst, $src \t// Ptr->Long" %} 10168 // variable size, 0 or 4. 10169 ins_encode %{ 10170 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10171 __ mr_if_needed($dst$$Register, $src$$Register); 10172 %} 10173 ins_pipe(pipe_class_default); 10174 %} 10175 10176 instruct castPP(iRegPdst dst) %{ 10177 match(Set dst (CastPP dst)); 10178 format %{ " -- \t// castPP of $dst" %} 10179 size(0); 10180 ins_encode( /*empty*/ ); 10181 ins_pipe(pipe_class_default); 10182 %} 10183 10184 instruct castII(iRegIdst dst) %{ 10185 match(Set dst (CastII dst)); 10186 format %{ " -- \t// castII of $dst" %} 10187 size(0); 10188 ins_encode( /*empty*/ ); 10189 ins_pipe(pipe_class_default); 10190 %} 10191 10192 instruct checkCastPP(iRegPdst dst) %{ 10193 match(Set dst (CheckCastPP dst)); 10194 format %{ " -- \t// checkcastPP of $dst" %} 10195 size(0); 10196 ins_encode( /*empty*/ ); 10197 ins_pipe(pipe_class_default); 10198 %} 10199 10200 //----------Convert instructions----------------------------------------------- 10201 10202 // Convert to boolean. 10203 10204 // int_to_bool(src) : { 1 if src != 0 10205 // { 0 else 10206 // 10207 // strategy: 10208 // 1) Count leading zeros of 32 bit-value src, 10209 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10210 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10211 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10212 10213 // convI2Bool 10214 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10215 match(Set dst (Conv2B src)); 10216 predicate(UseCountLeadingZerosInstructionsPPC64); 10217 ins_cost(DEFAULT_COST); 10218 10219 expand %{ 10220 immI shiftAmount %{ 0x5 %} 10221 uimmI16 mask %{ 0x1 %} 10222 iRegIdst tmp1; 10223 iRegIdst tmp2; 10224 countLeadingZerosI(tmp1, src); 10225 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10226 xorI_reg_uimm16(dst, tmp2, mask); 10227 %} 10228 %} 10229 10230 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10231 match(Set dst (Conv2B src)); 10232 effect(TEMP crx); 10233 predicate(!UseCountLeadingZerosInstructionsPPC64); 10234 ins_cost(DEFAULT_COST); 10235 10236 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10237 "LI $dst, #0\n\t" 10238 "BEQ $crx, done\n\t" 10239 "LI $dst, #1\n" 10240 "done:" %} 10241 size(16); 10242 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10243 ins_pipe(pipe_class_compare); 10244 %} 10245 10246 // ConvI2B + XorI 10247 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10248 match(Set dst (XorI (Conv2B src) mask)); 10249 predicate(UseCountLeadingZerosInstructionsPPC64); 10250 ins_cost(DEFAULT_COST); 10251 10252 expand %{ 10253 immI shiftAmount %{ 0x5 %} 10254 iRegIdst tmp1; 10255 countLeadingZerosI(tmp1, src); 10256 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10257 %} 10258 %} 10259 10260 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10261 match(Set dst (XorI (Conv2B src) mask)); 10262 effect(TEMP crx); 10263 predicate(!UseCountLeadingZerosInstructionsPPC64); 10264 ins_cost(DEFAULT_COST); 10265 10266 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10267 "LI $dst, #1\n\t" 10268 "BEQ $crx, done\n\t" 10269 "LI $dst, #0\n" 10270 "done:" %} 10271 size(16); 10272 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10273 ins_pipe(pipe_class_compare); 10274 %} 10275 10276 // AndI 0b0..010..0 + ConvI2B 10277 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10278 match(Set dst (Conv2B (AndI src mask))); 10279 predicate(UseRotateAndMaskInstructionsPPC64); 10280 ins_cost(DEFAULT_COST); 10281 10282 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10283 size(4); 10284 ins_encode %{ 10285 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10286 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10287 %} 10288 ins_pipe(pipe_class_default); 10289 %} 10290 10291 // Convert pointer to boolean. 10292 // 10293 // ptr_to_bool(src) : { 1 if src != 0 10294 // { 0 else 10295 // 10296 // strategy: 10297 // 1) Count leading zeros of 64 bit-value src, 10298 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10299 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10300 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10301 10302 // ConvP2B 10303 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10304 match(Set dst (Conv2B src)); 10305 predicate(UseCountLeadingZerosInstructionsPPC64); 10306 ins_cost(DEFAULT_COST); 10307 10308 expand %{ 10309 immI shiftAmount %{ 0x6 %} 10310 uimmI16 mask %{ 0x1 %} 10311 iRegIdst tmp1; 10312 iRegIdst tmp2; 10313 countLeadingZerosP(tmp1, src); 10314 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10315 xorI_reg_uimm16(dst, tmp2, mask); 10316 %} 10317 %} 10318 10319 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10320 match(Set dst (Conv2B src)); 10321 effect(TEMP crx); 10322 predicate(!UseCountLeadingZerosInstructionsPPC64); 10323 ins_cost(DEFAULT_COST); 10324 10325 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10326 "LI $dst, #0\n\t" 10327 "BEQ $crx, done\n\t" 10328 "LI $dst, #1\n" 10329 "done:" %} 10330 size(16); 10331 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10332 ins_pipe(pipe_class_compare); 10333 %} 10334 10335 // ConvP2B + XorI 10336 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10337 match(Set dst (XorI (Conv2B src) mask)); 10338 predicate(UseCountLeadingZerosInstructionsPPC64); 10339 ins_cost(DEFAULT_COST); 10340 10341 expand %{ 10342 immI shiftAmount %{ 0x6 %} 10343 iRegIdst tmp1; 10344 countLeadingZerosP(tmp1, src); 10345 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10346 %} 10347 %} 10348 10349 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10350 match(Set dst (XorI (Conv2B src) mask)); 10351 effect(TEMP crx); 10352 predicate(!UseCountLeadingZerosInstructionsPPC64); 10353 ins_cost(DEFAULT_COST); 10354 10355 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10356 "LI $dst, #1\n\t" 10357 "BEQ $crx, done\n\t" 10358 "LI $dst, #0\n" 10359 "done:" %} 10360 size(16); 10361 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10362 ins_pipe(pipe_class_compare); 10363 %} 10364 10365 // if src1 < src2, return -1 else return 0 10366 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10367 match(Set dst (CmpLTMask src1 src2)); 10368 ins_cost(DEFAULT_COST*4); 10369 10370 expand %{ 10371 iRegLdst src1s; 10372 iRegLdst src2s; 10373 iRegLdst diff; 10374 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10375 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10376 subL_reg_reg(diff, src1s, src2s); 10377 // Need to consider >=33 bit result, therefore we need signmaskL. 10378 signmask64I_regL(dst, diff); 10379 %} 10380 %} 10381 10382 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 10383 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 10384 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 10385 size(4); 10386 ins_encode %{ 10387 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 10388 __ srawi($dst$$Register, $src1$$Register, 0x1f); 10389 %} 10390 ins_pipe(pipe_class_default); 10391 %} 10392 10393 //----------Arithmetic Conversion Instructions--------------------------------- 10394 10395 // Convert to Byte -- nop 10396 // Convert to Short -- nop 10397 10398 // Convert to Int 10399 10400 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 10401 match(Set dst (RShiftI (LShiftI src amount) amount)); 10402 format %{ "EXTSB $dst, $src \t// byte->int" %} 10403 size(4); 10404 ins_encode %{ 10405 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 10406 __ extsb($dst$$Register, $src$$Register); 10407 %} 10408 ins_pipe(pipe_class_default); 10409 %} 10410 10411 // LShiftI 16 + RShiftI 16 converts short to int. 10412 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 10413 match(Set dst (RShiftI (LShiftI src amount) amount)); 10414 format %{ "EXTSH $dst, $src \t// short->int" %} 10415 size(4); 10416 ins_encode %{ 10417 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 10418 __ extsh($dst$$Register, $src$$Register); 10419 %} 10420 ins_pipe(pipe_class_default); 10421 %} 10422 10423 // ConvL2I + ConvI2L: Sign extend int in long register. 10424 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 10425 match(Set dst (ConvI2L (ConvL2I src))); 10426 10427 format %{ "EXTSW $dst, $src \t// long->long" %} 10428 size(4); 10429 ins_encode %{ 10430 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10431 __ extsw($dst$$Register, $src$$Register); 10432 %} 10433 ins_pipe(pipe_class_default); 10434 %} 10435 10436 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 10437 match(Set dst (ConvL2I src)); 10438 format %{ "MR $dst, $src \t// long->int" %} 10439 // variable size, 0 or 4 10440 ins_encode %{ 10441 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10442 __ mr_if_needed($dst$$Register, $src$$Register); 10443 %} 10444 ins_pipe(pipe_class_default); 10445 %} 10446 10447 instruct convD2IRaw_regD(regD dst, regD src) %{ 10448 // no match-rule, false predicate 10449 effect(DEF dst, USE src); 10450 predicate(false); 10451 10452 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 10453 size(4); 10454 ins_encode %{ 10455 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 10456 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10457 %} 10458 ins_pipe(pipe_class_default); 10459 %} 10460 10461 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 10462 // no match-rule, false predicate 10463 effect(DEF dst, USE crx, USE src); 10464 predicate(false); 10465 10466 ins_variable_size_depending_on_alignment(true); 10467 10468 format %{ "cmovI $crx, $dst, $src" %} 10469 // Worst case is branch + move + stop, no stop without scheduler. 10470 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 10471 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10472 ins_pipe(pipe_class_default); 10473 %} 10474 10475 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10476 // no match-rule, false predicate 10477 effect(DEF dst, USE crx, USE mem); 10478 predicate(false); 10479 10480 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 10481 postalloc_expand %{ 10482 // 10483 // replaces 10484 // 10485 // region dst crx mem 10486 // \ | | / 10487 // dst=cmovI_bso_stackSlotL_conLvalue0 10488 // 10489 // with 10490 // 10491 // region dst 10492 // \ / 10493 // dst=loadConI16(0) 10494 // | 10495 // ^ region dst crx mem 10496 // | \ | | / 10497 // dst=cmovI_bso_stackSlotL 10498 // 10499 10500 // Create new nodes. 10501 MachNode *m1 = new loadConI16Node(); 10502 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 10503 10504 // inputs for new nodes 10505 m1->add_req(n_region); 10506 m2->add_req(n_region, n_crx, n_mem); 10507 10508 // precedences for new nodes 10509 m2->add_prec(m1); 10510 10511 // operands for new nodes 10512 m1->_opnds[0] = op_dst; 10513 m1->_opnds[1] = new immI16Oper(0); 10514 10515 m2->_opnds[0] = op_dst; 10516 m2->_opnds[1] = op_crx; 10517 m2->_opnds[2] = op_mem; 10518 10519 // registers for new nodes 10520 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10521 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10522 10523 // Insert new nodes. 10524 nodes->push(m1); 10525 nodes->push(m2); 10526 %} 10527 %} 10528 10529 // Double to Int conversion, NaN is mapped to 0. 10530 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 10531 match(Set dst (ConvD2I src)); 10532 ins_cost(DEFAULT_COST); 10533 10534 expand %{ 10535 regD tmpD; 10536 stackSlotL tmpS; 10537 flagsReg crx; 10538 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10539 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10540 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10541 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10542 %} 10543 %} 10544 10545 instruct convF2IRaw_regF(regF dst, regF src) %{ 10546 // no match-rule, false predicate 10547 effect(DEF dst, USE src); 10548 predicate(false); 10549 10550 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 10551 size(4); 10552 ins_encode %{ 10553 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10554 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10555 %} 10556 ins_pipe(pipe_class_default); 10557 %} 10558 10559 // Float to Int conversion, NaN is mapped to 0. 10560 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 10561 match(Set dst (ConvF2I src)); 10562 ins_cost(DEFAULT_COST); 10563 10564 expand %{ 10565 regF tmpF; 10566 stackSlotL tmpS; 10567 flagsReg crx; 10568 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10569 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10570 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10571 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10572 %} 10573 %} 10574 10575 // Convert to Long 10576 10577 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 10578 match(Set dst (ConvI2L src)); 10579 format %{ "EXTSW $dst, $src \t// int->long" %} 10580 size(4); 10581 ins_encode %{ 10582 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10583 __ extsw($dst$$Register, $src$$Register); 10584 %} 10585 ins_pipe(pipe_class_default); 10586 %} 10587 10588 // Zero-extend: convert unsigned int to long (convUI2L). 10589 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 10590 match(Set dst (AndL (ConvI2L src) mask)); 10591 ins_cost(DEFAULT_COST); 10592 10593 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10594 size(4); 10595 ins_encode %{ 10596 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10597 __ clrldi($dst$$Register, $src$$Register, 32); 10598 %} 10599 ins_pipe(pipe_class_default); 10600 %} 10601 10602 // Zero-extend: convert unsigned int to long in long register. 10603 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 10604 match(Set dst (AndL src mask)); 10605 ins_cost(DEFAULT_COST); 10606 10607 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10608 size(4); 10609 ins_encode %{ 10610 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10611 __ clrldi($dst$$Register, $src$$Register, 32); 10612 %} 10613 ins_pipe(pipe_class_default); 10614 %} 10615 10616 instruct convF2LRaw_regF(regF dst, regF src) %{ 10617 // no match-rule, false predicate 10618 effect(DEF dst, USE src); 10619 predicate(false); 10620 10621 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 10622 size(4); 10623 ins_encode %{ 10624 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10625 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10626 %} 10627 ins_pipe(pipe_class_default); 10628 %} 10629 10630 instruct cmovL_bso_stackSlotL(iRegLdst 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 %{ "cmovL $crx, $dst, $src" %} 10638 // Worst case is branch + move + stop, no stop without scheduler. 10639 size(false /* TODO: PPC PORT 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 cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst 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 %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 10650 postalloc_expand %{ 10651 // 10652 // replaces 10653 // 10654 // region dst crx mem 10655 // \ | | / 10656 // dst=cmovL_bso_stackSlotL_conLvalue0 10657 // 10658 // with 10659 // 10660 // region dst 10661 // \ / 10662 // dst=loadConL16(0) 10663 // | 10664 // ^ region dst crx mem 10665 // | \ | | / 10666 // dst=cmovL_bso_stackSlotL 10667 // 10668 10669 // Create new nodes. 10670 MachNode *m1 = new loadConL16Node(); 10671 MachNode *m2 = new cmovL_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 m2->add_prec(m1); 10677 10678 // operands for new nodes 10679 m1->_opnds[0] = op_dst; 10680 m1->_opnds[1] = new immL16Oper(0); 10681 m2->_opnds[0] = op_dst; 10682 m2->_opnds[1] = op_crx; 10683 m2->_opnds[2] = op_mem; 10684 10685 // registers for new nodes 10686 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10687 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10688 10689 // Insert new nodes. 10690 nodes->push(m1); 10691 nodes->push(m2); 10692 %} 10693 %} 10694 10695 // Float to Long conversion, NaN is mapped to 0. 10696 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 10697 match(Set dst (ConvF2L src)); 10698 ins_cost(DEFAULT_COST); 10699 10700 expand %{ 10701 regF tmpF; 10702 stackSlotL tmpS; 10703 flagsReg crx; 10704 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10705 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 10706 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10707 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10708 %} 10709 %} 10710 10711 instruct convD2LRaw_regD(regD dst, regD src) %{ 10712 // no match-rule, false predicate 10713 effect(DEF dst, USE src); 10714 predicate(false); 10715 10716 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 10717 size(4); 10718 ins_encode %{ 10719 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10720 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10721 %} 10722 ins_pipe(pipe_class_default); 10723 %} 10724 10725 // Double to Long conversion, NaN is mapped to 0. 10726 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 10727 match(Set dst (ConvD2L src)); 10728 ins_cost(DEFAULT_COST); 10729 10730 expand %{ 10731 regD tmpD; 10732 stackSlotL tmpS; 10733 flagsReg crx; 10734 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10735 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 10736 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10737 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10738 %} 10739 %} 10740 10741 // Convert to Float 10742 10743 // Placed here as needed in expand. 10744 instruct convL2DRaw_regD(regD dst, regD src) %{ 10745 // no match-rule, false predicate 10746 effect(DEF dst, USE src); 10747 predicate(false); 10748 10749 format %{ "FCFID $dst, $src \t// convL2D" %} 10750 size(4); 10751 ins_encode %{ 10752 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10753 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 10754 %} 10755 ins_pipe(pipe_class_default); 10756 %} 10757 10758 // Placed here as needed in expand. 10759 instruct convD2F_reg(regF dst, regD src) %{ 10760 match(Set dst (ConvD2F src)); 10761 format %{ "FRSP $dst, $src \t// convD2F" %} 10762 size(4); 10763 ins_encode %{ 10764 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 10765 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 10766 %} 10767 ins_pipe(pipe_class_default); 10768 %} 10769 10770 // Integer to Float conversion. 10771 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 10772 match(Set dst (ConvI2F src)); 10773 predicate(!VM_Version::has_fcfids()); 10774 ins_cost(DEFAULT_COST); 10775 10776 expand %{ 10777 iRegLdst tmpL; 10778 stackSlotL tmpS; 10779 regD tmpD; 10780 regD tmpD2; 10781 convI2L_reg(tmpL, src); // Sign-extension int to long. 10782 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10783 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10784 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 10785 convD2F_reg(dst, tmpD2); // Convert double to float. 10786 %} 10787 %} 10788 10789 instruct convL2FRaw_regF(regF dst, regD src) %{ 10790 // no match-rule, false predicate 10791 effect(DEF dst, USE src); 10792 predicate(false); 10793 10794 format %{ "FCFIDS $dst, $src \t// convL2F" %} 10795 size(4); 10796 ins_encode %{ 10797 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10798 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 10799 %} 10800 ins_pipe(pipe_class_default); 10801 %} 10802 10803 // Integer to Float conversion. Special version for Power7. 10804 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 10805 match(Set dst (ConvI2F src)); 10806 predicate(VM_Version::has_fcfids()); 10807 ins_cost(DEFAULT_COST); 10808 10809 expand %{ 10810 iRegLdst tmpL; 10811 stackSlotL tmpS; 10812 regD tmpD; 10813 convI2L_reg(tmpL, src); // Sign-extension int to long. 10814 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10815 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10816 convL2FRaw_regF(dst, tmpD); // Convert to float. 10817 %} 10818 %} 10819 10820 // L2F to avoid runtime call. 10821 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 10822 match(Set dst (ConvL2F src)); 10823 predicate(VM_Version::has_fcfids()); 10824 ins_cost(DEFAULT_COST); 10825 10826 expand %{ 10827 stackSlotL tmpS; 10828 regD tmpD; 10829 regL_to_stkL(tmpS, src); // Store long to stack. 10830 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10831 convL2FRaw_regF(dst, tmpD); // Convert to float. 10832 %} 10833 %} 10834 10835 // Moved up as used in expand. 10836 //instruct convD2F_reg(regF dst, regD src) %{%} 10837 10838 // Convert to Double 10839 10840 // Integer to Double conversion. 10841 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 10842 match(Set dst (ConvI2D src)); 10843 ins_cost(DEFAULT_COST); 10844 10845 expand %{ 10846 iRegLdst tmpL; 10847 stackSlotL tmpS; 10848 regD tmpD; 10849 convI2L_reg(tmpL, src); // Sign-extension int to long. 10850 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10851 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10852 convL2DRaw_regD(dst, tmpD); // Convert to double. 10853 %} 10854 %} 10855 10856 // Long to Double conversion 10857 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 10858 match(Set dst (ConvL2D src)); 10859 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 10860 10861 expand %{ 10862 regD tmpD; 10863 moveL2D_stack_reg(tmpD, src); 10864 convL2DRaw_regD(dst, tmpD); 10865 %} 10866 %} 10867 10868 instruct convF2D_reg(regD dst, regF src) %{ 10869 match(Set dst (ConvF2D src)); 10870 format %{ "FMR $dst, $src \t// float->double" %} 10871 // variable size, 0 or 4 10872 ins_encode %{ 10873 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 10874 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 10875 %} 10876 ins_pipe(pipe_class_default); 10877 %} 10878 10879 //----------Control Flow Instructions------------------------------------------ 10880 // Compare Instructions 10881 10882 // Compare Integers 10883 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 10884 match(Set crx (CmpI src1 src2)); 10885 size(4); 10886 format %{ "CMPW $crx, $src1, $src2" %} 10887 ins_encode %{ 10888 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 10889 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 10890 %} 10891 ins_pipe(pipe_class_compare); 10892 %} 10893 10894 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 10895 match(Set crx (CmpI src1 src2)); 10896 format %{ "CMPWI $crx, $src1, $src2" %} 10897 size(4); 10898 ins_encode %{ 10899 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 10900 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 10901 %} 10902 ins_pipe(pipe_class_compare); 10903 %} 10904 10905 // (src1 & src2) == 0? 10906 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 10907 match(Set cr0 (CmpI (AndI src1 src2) zero)); 10908 // r0 is killed 10909 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 10910 size(4); 10911 ins_encode %{ 10912 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10913 __ andi_(R0, $src1$$Register, $src2$$constant); 10914 %} 10915 ins_pipe(pipe_class_compare); 10916 %} 10917 10918 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 10919 match(Set crx (CmpL src1 src2)); 10920 format %{ "CMPD $crx, $src1, $src2" %} 10921 size(4); 10922 ins_encode %{ 10923 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 10924 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 10925 %} 10926 ins_pipe(pipe_class_compare); 10927 %} 10928 10929 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 10930 match(Set crx (CmpL src1 src2)); 10931 format %{ "CMPDI $crx, $src1, $src2" %} 10932 size(4); 10933 ins_encode %{ 10934 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 10935 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 10936 %} 10937 ins_pipe(pipe_class_compare); 10938 %} 10939 10940 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 10941 match(Set cr0 (CmpL (AndL src1 src2) zero)); 10942 // r0 is killed 10943 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 10944 size(4); 10945 ins_encode %{ 10946 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 10947 __ and_(R0, $src1$$Register, $src2$$Register); 10948 %} 10949 ins_pipe(pipe_class_compare); 10950 %} 10951 10952 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 10953 match(Set cr0 (CmpL (AndL src1 src2) zero)); 10954 // r0 is killed 10955 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 10956 size(4); 10957 ins_encode %{ 10958 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10959 __ andi_(R0, $src1$$Register, $src2$$constant); 10960 %} 10961 ins_pipe(pipe_class_compare); 10962 %} 10963 10964 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 10965 // no match-rule, false predicate 10966 effect(DEF dst, USE crx); 10967 predicate(false); 10968 10969 ins_variable_size_depending_on_alignment(true); 10970 10971 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 10972 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 10973 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16); 10974 ins_encode %{ 10975 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 10976 Label done; 10977 // li(Rdst, 0); // equal -> 0 10978 __ beq($crx$$CondRegister, done); 10979 __ li($dst$$Register, 1); // greater -> +1 10980 __ bgt($crx$$CondRegister, done); 10981 __ li($dst$$Register, -1); // unordered or less -> -1 10982 // TODO: PPC port__ endgroup_if_needed(_size == 20); 10983 __ bind(done); 10984 %} 10985 ins_pipe(pipe_class_compare); 10986 %} 10987 10988 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 10989 // no match-rule, false predicate 10990 effect(DEF dst, USE crx); 10991 predicate(false); 10992 10993 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 10994 postalloc_expand %{ 10995 // 10996 // replaces 10997 // 10998 // region crx 10999 // \ | 11000 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11001 // 11002 // with 11003 // 11004 // region 11005 // \ 11006 // dst=loadConI16(0) 11007 // | 11008 // ^ region crx 11009 // | \ | 11010 // dst=cmovI_conIvalueMinus1_conIvalue1 11011 // 11012 11013 // Create new nodes. 11014 MachNode *m1 = new loadConI16Node(); 11015 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11016 11017 // inputs for new nodes 11018 m1->add_req(n_region); 11019 m2->add_req(n_region, n_crx); 11020 m2->add_prec(m1); 11021 11022 // operands for new nodes 11023 m1->_opnds[0] = op_dst; 11024 m1->_opnds[1] = new immI16Oper(0); 11025 m2->_opnds[0] = op_dst; 11026 m2->_opnds[1] = op_crx; 11027 11028 // registers for new nodes 11029 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11030 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11031 11032 // Insert new nodes. 11033 nodes->push(m1); 11034 nodes->push(m2); 11035 %} 11036 %} 11037 11038 // Manifest a CmpL3 result in an integer register. Very painful. 11039 // This is the test to avoid. 11040 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11041 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11042 match(Set dst (CmpL3 src1 src2)); 11043 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11044 11045 expand %{ 11046 flagsReg tmp1; 11047 cmpL_reg_reg(tmp1, src1, src2); 11048 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11049 %} 11050 %} 11051 11052 // Implicit range checks. 11053 // A range check in the ideal world has one of the following shapes: 11054 // - (If le (CmpU length index)), (IfTrue throw exception) 11055 // - (If lt (CmpU index length)), (IfFalse throw exception) 11056 // 11057 // Match range check 'If le (CmpU length index)'. 11058 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11059 match(If cmp (CmpU src_length index)); 11060 effect(USE labl); 11061 predicate(TrapBasedRangeChecks && 11062 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11063 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11064 (Matcher::branches_to_uncommon_trap(_leaf))); 11065 11066 ins_is_TrapBasedCheckNode(true); 11067 11068 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11069 size(4); 11070 ins_encode %{ 11071 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11072 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11073 __ trap_range_check_le($src_length$$Register, $index$$constant); 11074 } else { 11075 // Both successors are uncommon traps, probability is 0. 11076 // Node got flipped during fixup flow. 11077 assert($cmp$$cmpcode == 0x9, "must be greater"); 11078 __ trap_range_check_g($src_length$$Register, $index$$constant); 11079 } 11080 %} 11081 ins_pipe(pipe_class_trap); 11082 %} 11083 11084 // Match range check 'If lt (CmpU index length)'. 11085 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11086 match(If cmp (CmpU src_index src_length)); 11087 effect(USE labl); 11088 predicate(TrapBasedRangeChecks && 11089 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11090 _leaf->as_If()->_prob >= PROB_ALWAYS && 11091 (Matcher::branches_to_uncommon_trap(_leaf))); 11092 11093 ins_is_TrapBasedCheckNode(true); 11094 11095 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 11096 size(4); 11097 ins_encode %{ 11098 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 11099 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11100 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 11101 } else { 11102 // Both successors are uncommon traps, probability is 0. 11103 // Node got flipped during fixup flow. 11104 assert($cmp$$cmpcode == 0x8, "must be less"); 11105 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 11106 } 11107 %} 11108 ins_pipe(pipe_class_trap); 11109 %} 11110 11111 // Match range check 'If lt (CmpU index length)'. 11112 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 11113 match(If cmp (CmpU src_index length)); 11114 effect(USE labl); 11115 predicate(TrapBasedRangeChecks && 11116 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11117 _leaf->as_If()->_prob >= PROB_ALWAYS && 11118 (Matcher::branches_to_uncommon_trap(_leaf))); 11119 11120 ins_is_TrapBasedCheckNode(true); 11121 11122 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 11123 size(4); 11124 ins_encode %{ 11125 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11126 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11127 __ trap_range_check_ge($src_index$$Register, $length$$constant); 11128 } else { 11129 // Both successors are uncommon traps, probability is 0. 11130 // Node got flipped during fixup flow. 11131 assert($cmp$$cmpcode == 0x8, "must be less"); 11132 __ trap_range_check_l($src_index$$Register, $length$$constant); 11133 } 11134 %} 11135 ins_pipe(pipe_class_trap); 11136 %} 11137 11138 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11139 match(Set crx (CmpU src1 src2)); 11140 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 11141 size(4); 11142 ins_encode %{ 11143 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11144 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11145 %} 11146 ins_pipe(pipe_class_compare); 11147 %} 11148 11149 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 11150 match(Set crx (CmpU src1 src2)); 11151 size(4); 11152 format %{ "CMPLWI $crx, $src1, $src2" %} 11153 ins_encode %{ 11154 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11155 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11156 %} 11157 ins_pipe(pipe_class_compare); 11158 %} 11159 11160 // Implicit zero checks (more implicit null checks). 11161 // No constant pool entries required. 11162 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 11163 match(If cmp (CmpN value zero)); 11164 effect(USE labl); 11165 predicate(TrapBasedNullChecks && 11166 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11167 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11168 Matcher::branches_to_uncommon_trap(_leaf)); 11169 ins_cost(1); 11170 11171 ins_is_TrapBasedCheckNode(true); 11172 11173 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 11174 size(4); 11175 ins_encode %{ 11176 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11177 if ($cmp$$cmpcode == 0xA) { 11178 __ trap_null_check($value$$Register); 11179 } else { 11180 // Both successors are uncommon traps, probability is 0. 11181 // Node got flipped during fixup flow. 11182 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11183 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11184 } 11185 %} 11186 ins_pipe(pipe_class_trap); 11187 %} 11188 11189 // Compare narrow oops. 11190 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 11191 match(Set crx (CmpN src1 src2)); 11192 11193 size(4); 11194 ins_cost(2); 11195 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 11196 ins_encode %{ 11197 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11198 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11199 %} 11200 ins_pipe(pipe_class_compare); 11201 %} 11202 11203 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 11204 match(Set crx (CmpN src1 src2)); 11205 // Make this more expensive than zeroCheckN_iReg_imm0. 11206 ins_cost(2); 11207 11208 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 11209 size(4); 11210 ins_encode %{ 11211 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11212 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11213 %} 11214 ins_pipe(pipe_class_compare); 11215 %} 11216 11217 // Implicit zero checks (more implicit null checks). 11218 // No constant pool entries required. 11219 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 11220 match(If cmp (CmpP value zero)); 11221 effect(USE labl); 11222 predicate(TrapBasedNullChecks && 11223 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11224 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11225 Matcher::branches_to_uncommon_trap(_leaf)); 11226 ins_cost(1); // Should not be cheaper than zeroCheckN. 11227 11228 ins_is_TrapBasedCheckNode(true); 11229 11230 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 11231 size(4); 11232 ins_encode %{ 11233 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11234 if ($cmp$$cmpcode == 0xA) { 11235 __ trap_null_check($value$$Register); 11236 } else { 11237 // Both successors are uncommon traps, probability is 0. 11238 // Node got flipped during fixup flow. 11239 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11240 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11241 } 11242 %} 11243 ins_pipe(pipe_class_trap); 11244 %} 11245 11246 // Compare Pointers 11247 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 11248 match(Set crx (CmpP src1 src2)); 11249 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 11250 size(4); 11251 ins_encode %{ 11252 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11253 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11254 %} 11255 ins_pipe(pipe_class_compare); 11256 %} 11257 11258 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 11259 match(Set crx (CmpP src1 src2)); 11260 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 11261 size(4); 11262 ins_encode %{ 11263 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11264 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 11265 %} 11266 ins_pipe(pipe_class_compare); 11267 %} 11268 11269 // Used in postalloc expand. 11270 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 11271 // This match rule prevents reordering of node before a safepoint. 11272 // This only makes sense if this instructions is used exclusively 11273 // for the expansion of EncodeP! 11274 match(Set crx (CmpP src1 src2)); 11275 predicate(false); 11276 11277 format %{ "CMPDI $crx, $src1, $src2" %} 11278 size(4); 11279 ins_encode %{ 11280 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11281 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11282 %} 11283 ins_pipe(pipe_class_compare); 11284 %} 11285 11286 //----------Float Compares---------------------------------------------------- 11287 11288 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 11289 // Needs matchrule, see cmpDUnordered. 11290 match(Set crx (CmpF src1 src2)); 11291 // no match-rule, false predicate 11292 predicate(false); 11293 11294 format %{ "cmpFUrd $crx, $src1, $src2" %} 11295 size(4); 11296 ins_encode %{ 11297 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11298 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11299 %} 11300 ins_pipe(pipe_class_default); 11301 %} 11302 11303 instruct cmov_bns_less(flagsReg crx) %{ 11304 // no match-rule, false predicate 11305 effect(DEF crx); 11306 predicate(false); 11307 11308 ins_variable_size_depending_on_alignment(true); 11309 11310 format %{ "cmov $crx" %} 11311 // Worst case is branch + move + stop, no stop without scheduler. 11312 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12); 11313 ins_encode %{ 11314 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 11315 Label done; 11316 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 11317 __ li(R0, 0); 11318 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 11319 // TODO PPC port __ endgroup_if_needed(_size == 16); 11320 __ bind(done); 11321 %} 11322 ins_pipe(pipe_class_default); 11323 %} 11324 11325 // Compare floating, generate condition code. 11326 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 11327 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 11328 // 11329 // The following code sequence occurs a lot in mpegaudio: 11330 // 11331 // block BXX: 11332 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 11333 // cmpFUrd CCR6, F11, F9 11334 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 11335 // cmov CCR6 11336 // 8: instruct branchConSched: 11337 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 11338 match(Set crx (CmpF src1 src2)); 11339 ins_cost(DEFAULT_COST+BRANCH_COST); 11340 11341 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 11342 postalloc_expand %{ 11343 // 11344 // replaces 11345 // 11346 // region src1 src2 11347 // \ | | 11348 // crx=cmpF_reg_reg 11349 // 11350 // with 11351 // 11352 // region src1 src2 11353 // \ | | 11354 // crx=cmpFUnordered_reg_reg 11355 // | 11356 // ^ region 11357 // | \ 11358 // crx=cmov_bns_less 11359 // 11360 11361 // Create new nodes. 11362 MachNode *m1 = new cmpFUnordered_reg_regNode(); 11363 MachNode *m2 = new cmov_bns_lessNode(); 11364 11365 // inputs for new nodes 11366 m1->add_req(n_region, n_src1, n_src2); 11367 m2->add_req(n_region); 11368 m2->add_prec(m1); 11369 11370 // operands for new nodes 11371 m1->_opnds[0] = op_crx; 11372 m1->_opnds[1] = op_src1; 11373 m1->_opnds[2] = op_src2; 11374 m2->_opnds[0] = op_crx; 11375 11376 // registers for new nodes 11377 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11378 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11379 11380 // Insert new nodes. 11381 nodes->push(m1); 11382 nodes->push(m2); 11383 %} 11384 %} 11385 11386 // Compare float, generate -1,0,1 11387 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 11388 match(Set dst (CmpF3 src1 src2)); 11389 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11390 11391 expand %{ 11392 flagsReg tmp1; 11393 cmpFUnordered_reg_reg(tmp1, src1, src2); 11394 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11395 %} 11396 %} 11397 11398 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 11399 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 11400 // node right before the conditional move using it. 11401 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 11402 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 11403 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 11404 // conditional move was supposed to be spilled. 11405 match(Set crx (CmpD src1 src2)); 11406 // False predicate, shall not be matched. 11407 predicate(false); 11408 11409 format %{ "cmpFUrd $crx, $src1, $src2" %} 11410 size(4); 11411 ins_encode %{ 11412 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11413 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11414 %} 11415 ins_pipe(pipe_class_default); 11416 %} 11417 11418 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 11419 match(Set crx (CmpD src1 src2)); 11420 ins_cost(DEFAULT_COST+BRANCH_COST); 11421 11422 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 11423 postalloc_expand %{ 11424 // 11425 // replaces 11426 // 11427 // region src1 src2 11428 // \ | | 11429 // crx=cmpD_reg_reg 11430 // 11431 // with 11432 // 11433 // region src1 src2 11434 // \ | | 11435 // crx=cmpDUnordered_reg_reg 11436 // | 11437 // ^ region 11438 // | \ 11439 // crx=cmov_bns_less 11440 // 11441 11442 // create new nodes 11443 MachNode *m1 = new cmpDUnordered_reg_regNode(); 11444 MachNode *m2 = new cmov_bns_lessNode(); 11445 11446 // inputs for new nodes 11447 m1->add_req(n_region, n_src1, n_src2); 11448 m2->add_req(n_region); 11449 m2->add_prec(m1); 11450 11451 // operands for new nodes 11452 m1->_opnds[0] = op_crx; 11453 m1->_opnds[1] = op_src1; 11454 m1->_opnds[2] = op_src2; 11455 m2->_opnds[0] = op_crx; 11456 11457 // registers for new nodes 11458 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11459 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11460 11461 // Insert new nodes. 11462 nodes->push(m1); 11463 nodes->push(m2); 11464 %} 11465 %} 11466 11467 // Compare double, generate -1,0,1 11468 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 11469 match(Set dst (CmpD3 src1 src2)); 11470 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11471 11472 expand %{ 11473 flagsReg tmp1; 11474 cmpDUnordered_reg_reg(tmp1, src1, src2); 11475 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11476 %} 11477 %} 11478 11479 //----------Branches--------------------------------------------------------- 11480 // Jump 11481 11482 // Direct Branch. 11483 instruct branch(label labl) %{ 11484 match(Goto); 11485 effect(USE labl); 11486 ins_cost(BRANCH_COST); 11487 11488 format %{ "B $labl" %} 11489 size(4); 11490 ins_encode %{ 11491 // TODO: PPC port $archOpcode(ppc64Opcode_b); 11492 Label d; // dummy 11493 __ bind(d); 11494 Label* p = $labl$$label; 11495 // `p' is `NULL' when this encoding class is used only to 11496 // determine the size of the encoded instruction. 11497 Label& l = (NULL == p)? d : *(p); 11498 __ b(l); 11499 %} 11500 ins_pipe(pipe_class_default); 11501 %} 11502 11503 // Conditional Near Branch 11504 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11505 // Same match rule as `branchConFar'. 11506 match(If cmp crx); 11507 effect(USE lbl); 11508 ins_cost(BRANCH_COST); 11509 11510 // If set to 1 this indicates that the current instruction is a 11511 // short variant of a long branch. This avoids using this 11512 // instruction in first-pass matching. It will then only be used in 11513 // the `Shorten_branches' pass. 11514 ins_short_branch(1); 11515 11516 format %{ "B$cmp $crx, $lbl" %} 11517 size(4); 11518 ins_encode( enc_bc(crx, cmp, lbl) ); 11519 ins_pipe(pipe_class_default); 11520 %} 11521 11522 // This is for cases when the ppc64 `bc' instruction does not 11523 // reach far enough. So we emit a far branch here, which is more 11524 // expensive. 11525 // 11526 // Conditional Far Branch 11527 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11528 // Same match rule as `branchCon'. 11529 match(If cmp crx); 11530 effect(USE crx, USE lbl); 11531 predicate(!false /* TODO: PPC port HB_Schedule*/); 11532 // Higher cost than `branchCon'. 11533 ins_cost(5*BRANCH_COST); 11534 11535 // This is not a short variant of a branch, but the long variant. 11536 ins_short_branch(0); 11537 11538 format %{ "B_FAR$cmp $crx, $lbl" %} 11539 size(8); 11540 ins_encode( enc_bc_far(crx, cmp, lbl) ); 11541 ins_pipe(pipe_class_default); 11542 %} 11543 11544 // Conditional Branch used with Power6 scheduler (can be far or short). 11545 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11546 // Same match rule as `branchCon'. 11547 match(If cmp crx); 11548 effect(USE crx, USE lbl); 11549 predicate(false /* TODO: PPC port HB_Schedule*/); 11550 // Higher cost than `branchCon'. 11551 ins_cost(5*BRANCH_COST); 11552 11553 // Actually size doesn't depend on alignment but on shortening. 11554 ins_variable_size_depending_on_alignment(true); 11555 // long variant. 11556 ins_short_branch(0); 11557 11558 format %{ "B_FAR$cmp $crx, $lbl" %} 11559 size(8); // worst case 11560 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 11561 ins_pipe(pipe_class_default); 11562 %} 11563 11564 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11565 match(CountedLoopEnd cmp crx); 11566 effect(USE labl); 11567 ins_cost(BRANCH_COST); 11568 11569 // short variant. 11570 ins_short_branch(1); 11571 11572 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 11573 size(4); 11574 ins_encode( enc_bc(crx, cmp, labl) ); 11575 ins_pipe(pipe_class_default); 11576 %} 11577 11578 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11579 match(CountedLoopEnd cmp crx); 11580 effect(USE labl); 11581 predicate(!false /* TODO: PPC port HB_Schedule */); 11582 ins_cost(BRANCH_COST); 11583 11584 // Long variant. 11585 ins_short_branch(0); 11586 11587 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11588 size(8); 11589 ins_encode( enc_bc_far(crx, cmp, labl) ); 11590 ins_pipe(pipe_class_default); 11591 %} 11592 11593 // Conditional Branch used with Power6 scheduler (can be far or short). 11594 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11595 match(CountedLoopEnd cmp crx); 11596 effect(USE labl); 11597 predicate(false /* TODO: PPC port HB_Schedule */); 11598 // Higher cost than `branchCon'. 11599 ins_cost(5*BRANCH_COST); 11600 11601 // Actually size doesn't depend on alignment but on shortening. 11602 ins_variable_size_depending_on_alignment(true); 11603 // Long variant. 11604 ins_short_branch(0); 11605 11606 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11607 size(8); // worst case 11608 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 11609 ins_pipe(pipe_class_default); 11610 %} 11611 11612 // ============================================================================ 11613 // Java runtime operations, intrinsics and other complex operations. 11614 11615 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 11616 // array for an instance of the superklass. Set a hidden internal cache on a 11617 // hit (cache is checked with exposed code in gen_subtype_check()). Return 11618 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 11619 // 11620 // GL TODO: Improve this. 11621 // - result should not be a TEMP 11622 // - Add match rule as on sparc avoiding additional Cmp. 11623 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 11624 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 11625 match(Set result (PartialSubtypeCheck subklass superklass)); 11626 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 11627 ins_cost(DEFAULT_COST*10); 11628 11629 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 11630 ins_encode %{ 11631 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11632 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 11633 $tmp_klass$$Register, NULL, $result$$Register); 11634 %} 11635 ins_pipe(pipe_class_default); 11636 %} 11637 11638 // inlined locking and unlocking 11639 11640 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 11641 match(Set crx (FastLock oop box)); 11642 effect(TEMP tmp1, TEMP tmp2); 11643 predicate(!Compile::current()->use_rtm()); 11644 11645 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 11646 ins_encode %{ 11647 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11648 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11649 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 11650 UseBiasedLocking && !UseOptoBiasInlining); 11651 // If locking was successfull, crx should indicate 'EQ'. 11652 // The compiler generates a branch to the runtime call to 11653 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11654 %} 11655 ins_pipe(pipe_class_compare); 11656 %} 11657 11658 // Separate version for TM. Use bound register for box to enable USE_KILL. 11659 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11660 match(Set crx (FastLock oop box)); 11661 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 11662 predicate(Compile::current()->use_rtm()); 11663 11664 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 11665 ins_encode %{ 11666 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11667 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11668 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11669 /*Biased Locking*/ false, 11670 _rtm_counters, _stack_rtm_counters, 11671 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 11672 /*TM*/ true, ra_->C->profile_rtm()); 11673 // If locking was successfull, crx should indicate 'EQ'. 11674 // The compiler generates a branch to the runtime call to 11675 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11676 %} 11677 ins_pipe(pipe_class_compare); 11678 %} 11679 11680 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11681 match(Set crx (FastUnlock oop box)); 11682 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11683 predicate(!Compile::current()->use_rtm()); 11684 11685 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 11686 ins_encode %{ 11687 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11688 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11689 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11690 UseBiasedLocking && !UseOptoBiasInlining, 11691 false); 11692 // If unlocking was successfull, crx should indicate 'EQ'. 11693 // The compiler generates a branch to the runtime call to 11694 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11695 %} 11696 ins_pipe(pipe_class_compare); 11697 %} 11698 11699 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11700 match(Set crx (FastUnlock oop box)); 11701 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11702 predicate(Compile::current()->use_rtm()); 11703 11704 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 11705 ins_encode %{ 11706 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11707 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11708 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11709 /*Biased Locking*/ false, /*TM*/ true); 11710 // If unlocking was successfull, crx should indicate 'EQ'. 11711 // The compiler generates a branch to the runtime call to 11712 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11713 %} 11714 ins_pipe(pipe_class_compare); 11715 %} 11716 11717 // Align address. 11718 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 11719 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 11720 11721 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 11722 size(4); 11723 ins_encode %{ 11724 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 11725 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 11726 %} 11727 ins_pipe(pipe_class_default); 11728 %} 11729 11730 // Array size computation. 11731 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 11732 match(Set dst (SubL (CastP2X end) (CastP2X start))); 11733 11734 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 11735 size(4); 11736 ins_encode %{ 11737 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 11738 __ subf($dst$$Register, $start$$Register, $end$$Register); 11739 %} 11740 ins_pipe(pipe_class_default); 11741 %} 11742 11743 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 11744 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 11745 match(Set dummy (ClearArray cnt base)); 11746 effect(USE_KILL base, KILL ctr); 11747 ins_cost(2 * MEMORY_REF_COST); 11748 11749 format %{ "ClearArray $cnt, $base" %} 11750 ins_encode %{ 11751 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11752 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 11753 %} 11754 ins_pipe(pipe_class_default); 11755 %} 11756 11757 // Clear-array with constant large array length. 11758 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 11759 match(Set dummy (ClearArray cnt base)); 11760 effect(USE_KILL base, TEMP tmp, KILL ctr); 11761 ins_cost(3 * MEMORY_REF_COST); 11762 11763 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 11764 ins_encode %{ 11765 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11766 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 11767 %} 11768 ins_pipe(pipe_class_default); 11769 %} 11770 11771 // Clear-array with dynamic array length. 11772 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 11773 match(Set dummy (ClearArray cnt base)); 11774 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 11775 ins_cost(4 * MEMORY_REF_COST); 11776 11777 format %{ "ClearArray $cnt, $base" %} 11778 ins_encode %{ 11779 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11780 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 11781 %} 11782 ins_pipe(pipe_class_default); 11783 %} 11784 11785 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11786 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11787 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11788 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11789 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11790 ins_cost(300); 11791 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11792 ins_encode %{ 11793 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11794 __ string_compare($str1$$Register, $str2$$Register, 11795 $cnt1$$Register, $cnt2$$Register, 11796 $tmp$$Register, 11797 $result$$Register, StrIntrinsicNode::LL); 11798 %} 11799 ins_pipe(pipe_class_default); 11800 %} 11801 11802 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11803 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11804 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11805 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11806 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11807 ins_cost(300); 11808 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11809 ins_encode %{ 11810 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11811 __ string_compare($str1$$Register, $str2$$Register, 11812 $cnt1$$Register, $cnt2$$Register, 11813 $tmp$$Register, 11814 $result$$Register, StrIntrinsicNode::UU); 11815 %} 11816 ins_pipe(pipe_class_default); 11817 %} 11818 11819 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11820 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11821 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11822 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11823 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11824 ins_cost(300); 11825 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11826 ins_encode %{ 11827 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11828 __ string_compare($str1$$Register, $str2$$Register, 11829 $cnt1$$Register, $cnt2$$Register, 11830 $tmp$$Register, 11831 $result$$Register, StrIntrinsicNode::LU); 11832 %} 11833 ins_pipe(pipe_class_default); 11834 %} 11835 11836 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11837 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11838 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11839 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11840 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11841 ins_cost(300); 11842 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11843 ins_encode %{ 11844 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11845 __ string_compare($str2$$Register, $str1$$Register, 11846 $cnt2$$Register, $cnt1$$Register, 11847 $tmp$$Register, 11848 $result$$Register, StrIntrinsicNode::UL); 11849 %} 11850 ins_pipe(pipe_class_default); 11851 %} 11852 11853 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 11854 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11855 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 11856 match(Set result (StrEquals (Binary str1 str2) cnt)); 11857 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 11858 ins_cost(300); 11859 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 11860 ins_encode %{ 11861 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11862 __ array_equals(false, $str1$$Register, $str2$$Register, 11863 $cnt$$Register, $tmp$$Register, 11864 $result$$Register, true /* byte */); 11865 %} 11866 ins_pipe(pipe_class_default); 11867 %} 11868 11869 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 11870 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11871 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 11872 match(Set result (StrEquals (Binary str1 str2) cnt)); 11873 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 11874 ins_cost(300); 11875 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 11876 ins_encode %{ 11877 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11878 __ array_equals(false, $str1$$Register, $str2$$Register, 11879 $cnt$$Register, $tmp$$Register, 11880 $result$$Register, false /* byte */); 11881 %} 11882 ins_pipe(pipe_class_default); 11883 %} 11884 11885 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 11886 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 11887 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11888 match(Set result (AryEq ary1 ary2)); 11889 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 11890 ins_cost(300); 11891 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 11892 ins_encode %{ 11893 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11894 __ array_equals(true, $ary1$$Register, $ary2$$Register, 11895 $tmp1$$Register, $tmp2$$Register, 11896 $result$$Register, true /* byte */); 11897 %} 11898 ins_pipe(pipe_class_default); 11899 %} 11900 11901 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 11902 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 11903 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11904 match(Set result (AryEq ary1 ary2)); 11905 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 11906 ins_cost(300); 11907 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 11908 ins_encode %{ 11909 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11910 __ array_equals(true, $ary1$$Register, $ary2$$Register, 11911 $tmp1$$Register, $tmp2$$Register, 11912 $result$$Register, false /* byte */); 11913 %} 11914 ins_pipe(pipe_class_default); 11915 %} 11916 11917 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11918 immP needleImm, immL offsetImm, immI_1 needlecntImm, 11919 iRegIdst tmp1, iRegIdst tmp2, 11920 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11921 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 11922 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11923 // Required for EA: check if it is still a type_array. 11924 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 11925 ins_cost(150); 11926 11927 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 11928 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 11929 11930 ins_encode %{ 11931 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11932 immPOper *needleOper = (immPOper *)$needleImm; 11933 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 11934 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 11935 jchar chr; 11936 #ifdef VM_LITTLE_ENDIAN 11937 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 11938 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 11939 #else 11940 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 11941 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 11942 #endif 11943 __ string_indexof_char($result$$Register, 11944 $haystack$$Register, $haycnt$$Register, 11945 R0, chr, 11946 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 11947 %} 11948 ins_pipe(pipe_class_compare); 11949 %} 11950 11951 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11952 immP needleImm, immL offsetImm, immI_1 needlecntImm, 11953 iRegIdst tmp1, iRegIdst tmp2, 11954 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11955 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 11956 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11957 // Required for EA: check if it is still a type_array. 11958 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 11959 ins_cost(150); 11960 11961 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 11962 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 11963 11964 ins_encode %{ 11965 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11966 immPOper *needleOper = (immPOper *)$needleImm; 11967 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 11968 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 11969 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 11970 __ string_indexof_char($result$$Register, 11971 $haystack$$Register, $haycnt$$Register, 11972 R0, chr, 11973 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 11974 %} 11975 ins_pipe(pipe_class_compare); 11976 %} 11977 11978 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11979 immP needleImm, immL offsetImm, immI_1 needlecntImm, 11980 iRegIdst tmp1, iRegIdst tmp2, 11981 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11982 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 11983 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11984 // Required for EA: check if it is still a type_array. 11985 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 11986 ins_cost(150); 11987 11988 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 11989 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 11990 11991 ins_encode %{ 11992 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11993 immPOper *needleOper = (immPOper *)$needleImm; 11994 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 11995 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 11996 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 11997 __ string_indexof_char($result$$Register, 11998 $haystack$$Register, $haycnt$$Register, 11999 R0, chr, 12000 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12001 %} 12002 ins_pipe(pipe_class_compare); 12003 %} 12004 12005 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12006 rscratch2RegP needle, immI_1 needlecntImm, 12007 iRegIdst tmp1, iRegIdst tmp2, 12008 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12009 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12010 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12011 // Required for EA: check if it is still a type_array. 12012 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12013 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12014 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12015 ins_cost(180); 12016 12017 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12018 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12019 ins_encode %{ 12020 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12021 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12022 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12023 guarantee(needle_values, "sanity"); 12024 jchar chr; 12025 #ifdef VM_LITTLE_ENDIAN 12026 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12027 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12028 #else 12029 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12030 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12031 #endif 12032 __ string_indexof_char($result$$Register, 12033 $haystack$$Register, $haycnt$$Register, 12034 R0, chr, 12035 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12036 %} 12037 ins_pipe(pipe_class_compare); 12038 %} 12039 12040 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12041 rscratch2RegP needle, immI_1 needlecntImm, 12042 iRegIdst tmp1, iRegIdst tmp2, 12043 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12044 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12045 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12046 // Required for EA: check if it is still a type_array. 12047 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12048 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12049 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12050 ins_cost(180); 12051 12052 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12053 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12054 ins_encode %{ 12055 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12056 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12057 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12058 guarantee(needle_values, "sanity"); 12059 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12060 __ string_indexof_char($result$$Register, 12061 $haystack$$Register, $haycnt$$Register, 12062 R0, chr, 12063 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12064 %} 12065 ins_pipe(pipe_class_compare); 12066 %} 12067 12068 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12069 rscratch2RegP needle, immI_1 needlecntImm, 12070 iRegIdst tmp1, iRegIdst tmp2, 12071 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12072 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12073 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12074 // Required for EA: check if it is still a type_array. 12075 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12076 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12077 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12078 ins_cost(180); 12079 12080 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12081 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12082 ins_encode %{ 12083 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12084 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12085 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12086 guarantee(needle_values, "sanity"); 12087 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12088 __ string_indexof_char($result$$Register, 12089 $haystack$$Register, $haycnt$$Register, 12090 R0, chr, 12091 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12092 %} 12093 ins_pipe(pipe_class_compare); 12094 %} 12095 12096 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12097 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12098 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12099 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12100 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12101 ins_cost(180); 12102 12103 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 12104 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12105 ins_encode %{ 12106 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12107 __ string_indexof_char($result$$Register, 12108 $haystack$$Register, $haycnt$$Register, 12109 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12110 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12111 %} 12112 ins_pipe(pipe_class_compare); 12113 %} 12114 12115 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12116 iRegPsrc needle, uimmI15 needlecntImm, 12117 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12118 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12119 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12120 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12121 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12122 // Required for EA: check if it is still a type_array. 12123 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12124 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12125 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12126 ins_cost(250); 12127 12128 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12129 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12130 ins_encode %{ 12131 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12132 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12133 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12134 12135 __ string_indexof($result$$Register, 12136 $haystack$$Register, $haycnt$$Register, 12137 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12138 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12139 %} 12140 ins_pipe(pipe_class_compare); 12141 %} 12142 12143 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12144 iRegPsrc needle, uimmI15 needlecntImm, 12145 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12146 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12147 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12148 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12149 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12150 // Required for EA: check if it is still a type_array. 12151 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12152 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12153 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12154 ins_cost(250); 12155 12156 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12157 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12158 ins_encode %{ 12159 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12160 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12161 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12162 12163 __ string_indexof($result$$Register, 12164 $haystack$$Register, $haycnt$$Register, 12165 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12166 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12167 %} 12168 ins_pipe(pipe_class_compare); 12169 %} 12170 12171 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12172 iRegPsrc needle, uimmI15 needlecntImm, 12173 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12174 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12175 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12176 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12177 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12178 // Required for EA: check if it is still a type_array. 12179 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12180 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12181 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12182 ins_cost(250); 12183 12184 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12185 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12186 ins_encode %{ 12187 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12188 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12189 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12190 12191 __ string_indexof($result$$Register, 12192 $haystack$$Register, $haycnt$$Register, 12193 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12194 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12195 %} 12196 ins_pipe(pipe_class_compare); 12197 %} 12198 12199 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12200 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12201 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12202 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12203 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12204 TEMP_DEF result, 12205 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12206 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12207 ins_cost(300); 12208 12209 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12210 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12211 ins_encode %{ 12212 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12213 __ string_indexof($result$$Register, 12214 $haystack$$Register, $haycnt$$Register, 12215 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12216 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12217 %} 12218 ins_pipe(pipe_class_compare); 12219 %} 12220 12221 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12222 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12223 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12224 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12225 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12226 TEMP_DEF result, 12227 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12228 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12229 ins_cost(300); 12230 12231 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12232 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12233 ins_encode %{ 12234 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12235 __ string_indexof($result$$Register, 12236 $haystack$$Register, $haycnt$$Register, 12237 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12238 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12239 %} 12240 ins_pipe(pipe_class_compare); 12241 %} 12242 12243 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12244 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12245 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12246 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12247 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12248 TEMP_DEF result, 12249 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12250 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12251 ins_cost(300); 12252 12253 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12254 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12255 ins_encode %{ 12256 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12257 __ string_indexof($result$$Register, 12258 $haystack$$Register, $haycnt$$Register, 12259 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12260 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12261 %} 12262 ins_pipe(pipe_class_compare); 12263 %} 12264 12265 // char[] to byte[] compression 12266 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12267 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12268 match(Set result (StrCompressedCopy src (Binary dst len))); 12269 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12270 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12271 ins_cost(300); 12272 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12273 ins_encode %{ 12274 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12275 Label Lskip, Ldone; 12276 __ li($result$$Register, 0); 12277 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12278 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 12279 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12280 __ beq(CCR0, Lskip); 12281 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 12282 __ bind(Lskip); 12283 __ mr($result$$Register, $len$$Register); 12284 __ bind(Ldone); 12285 %} 12286 ins_pipe(pipe_class_default); 12287 %} 12288 12289 // byte[] to char[] inflation 12290 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 12291 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12292 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12293 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12294 ins_cost(300); 12295 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12296 ins_encode %{ 12297 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12298 Label Ldone; 12299 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12300 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 12301 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12302 __ beq(CCR0, Ldone); 12303 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 12304 __ bind(Ldone); 12305 %} 12306 ins_pipe(pipe_class_default); 12307 %} 12308 12309 // StringCoding.java intrinsics 12310 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 12311 regCTR ctr, flagsRegCR0 cr0) 12312 %{ 12313 match(Set result (HasNegatives ary1 len)); 12314 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 12315 ins_cost(300); 12316 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 12317 ins_encode %{ 12318 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12319 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 12320 $tmp1$$Register, $tmp2$$Register); 12321 %} 12322 ins_pipe(pipe_class_default); 12323 %} 12324 12325 // encode char[] to byte[] in ISO_8859_1 12326 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12327 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12328 match(Set result (EncodeISOArray src (Binary dst len))); 12329 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12330 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12331 ins_cost(300); 12332 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12333 ins_encode %{ 12334 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12335 Label Lslow, Lfailure1, Lfailure2, Ldone; 12336 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12337 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 12338 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12339 __ beq(CCR0, Ldone); 12340 __ bind(Lslow); 12341 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 12342 __ li($result$$Register, 0); 12343 __ b(Ldone); 12344 12345 __ bind(Lfailure1); 12346 __ mr($result$$Register, $len$$Register); 12347 __ mfctr($tmp1$$Register); 12348 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 12349 __ beq(CCR0, Ldone); 12350 __ b(Lslow); 12351 12352 __ bind(Lfailure2); 12353 __ mfctr($result$$Register); // Remaining characters. 12354 12355 __ bind(Ldone); 12356 __ subf($result$$Register, $result$$Register, $len$$Register); 12357 %} 12358 ins_pipe(pipe_class_default); 12359 %} 12360 12361 12362 //---------- Min/Max Instructions --------------------------------------------- 12363 12364 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12365 match(Set dst (MinI src1 src2)); 12366 ins_cost(DEFAULT_COST*6); 12367 12368 expand %{ 12369 iRegLdst src1s; 12370 iRegLdst src2s; 12371 iRegLdst diff; 12372 iRegLdst sm; 12373 iRegLdst doz; // difference or zero 12374 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12375 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12376 subL_reg_reg(diff, src2s, src1s); 12377 // Need to consider >=33 bit result, therefore we need signmaskL. 12378 signmask64L_regL(sm, diff); 12379 andL_reg_reg(doz, diff, sm); // <=0 12380 addI_regL_regL(dst, doz, src1s); 12381 %} 12382 %} 12383 12384 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12385 match(Set dst (MinI src1 src2)); 12386 effect(KILL cr0); 12387 predicate(VM_Version::has_isel()); 12388 ins_cost(DEFAULT_COST*2); 12389 12390 ins_encode %{ 12391 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12392 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12393 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 12394 %} 12395 ins_pipe(pipe_class_default); 12396 %} 12397 12398 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12399 match(Set dst (MaxI src1 src2)); 12400 ins_cost(DEFAULT_COST*6); 12401 12402 expand %{ 12403 iRegLdst src1s; 12404 iRegLdst src2s; 12405 iRegLdst diff; 12406 iRegLdst sm; 12407 iRegLdst doz; // difference or zero 12408 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12409 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12410 subL_reg_reg(diff, src2s, src1s); 12411 // Need to consider >=33 bit result, therefore we need signmaskL. 12412 signmask64L_regL(sm, diff); 12413 andcL_reg_reg(doz, diff, sm); // >=0 12414 addI_regL_regL(dst, doz, src1s); 12415 %} 12416 %} 12417 12418 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12419 match(Set dst (MaxI src1 src2)); 12420 effect(KILL cr0); 12421 predicate(VM_Version::has_isel()); 12422 ins_cost(DEFAULT_COST*2); 12423 12424 ins_encode %{ 12425 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12426 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12427 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 12428 %} 12429 ins_pipe(pipe_class_default); 12430 %} 12431 12432 //---------- Population Count Instructions ------------------------------------ 12433 12434 // Popcnt for Power7. 12435 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 12436 match(Set dst (PopCountI src)); 12437 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12438 ins_cost(DEFAULT_COST); 12439 12440 format %{ "POPCNTW $dst, $src" %} 12441 size(4); 12442 ins_encode %{ 12443 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12444 __ popcntw($dst$$Register, $src$$Register); 12445 %} 12446 ins_pipe(pipe_class_default); 12447 %} 12448 12449 // Popcnt for Power7. 12450 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 12451 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12452 match(Set dst (PopCountL src)); 12453 ins_cost(DEFAULT_COST); 12454 12455 format %{ "POPCNTD $dst, $src" %} 12456 size(4); 12457 ins_encode %{ 12458 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12459 __ popcntd($dst$$Register, $src$$Register); 12460 %} 12461 ins_pipe(pipe_class_default); 12462 %} 12463 12464 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 12465 match(Set dst (CountLeadingZerosI src)); 12466 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12467 ins_cost(DEFAULT_COST); 12468 12469 format %{ "CNTLZW $dst, $src" %} 12470 size(4); 12471 ins_encode %{ 12472 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 12473 __ cntlzw($dst$$Register, $src$$Register); 12474 %} 12475 ins_pipe(pipe_class_default); 12476 %} 12477 12478 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 12479 match(Set dst (CountLeadingZerosL src)); 12480 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12481 ins_cost(DEFAULT_COST); 12482 12483 format %{ "CNTLZD $dst, $src" %} 12484 size(4); 12485 ins_encode %{ 12486 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12487 __ cntlzd($dst$$Register, $src$$Register); 12488 %} 12489 ins_pipe(pipe_class_default); 12490 %} 12491 12492 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 12493 // no match-rule, false predicate 12494 effect(DEF dst, USE src); 12495 predicate(false); 12496 12497 format %{ "CNTLZD $dst, $src" %} 12498 size(4); 12499 ins_encode %{ 12500 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12501 __ cntlzd($dst$$Register, $src$$Register); 12502 %} 12503 ins_pipe(pipe_class_default); 12504 %} 12505 12506 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 12507 match(Set dst (CountTrailingZerosI src)); 12508 predicate(UseCountLeadingZerosInstructionsPPC64); 12509 ins_cost(DEFAULT_COST); 12510 12511 expand %{ 12512 immI16 imm1 %{ (int)-1 %} 12513 immI16 imm2 %{ (int)32 %} 12514 immI_minus1 m1 %{ -1 %} 12515 iRegIdst tmpI1; 12516 iRegIdst tmpI2; 12517 iRegIdst tmpI3; 12518 addI_reg_imm16(tmpI1, src, imm1); 12519 andcI_reg_reg(tmpI2, src, m1, tmpI1); 12520 countLeadingZerosI(tmpI3, tmpI2); 12521 subI_imm16_reg(dst, imm2, tmpI3); 12522 %} 12523 %} 12524 12525 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 12526 match(Set dst (CountTrailingZerosL src)); 12527 predicate(UseCountLeadingZerosInstructionsPPC64); 12528 ins_cost(DEFAULT_COST); 12529 12530 expand %{ 12531 immL16 imm1 %{ (long)-1 %} 12532 immI16 imm2 %{ (int)64 %} 12533 iRegLdst tmpL1; 12534 iRegLdst tmpL2; 12535 iRegIdst tmpL3; 12536 addL_reg_imm16(tmpL1, src, imm1); 12537 andcL_reg_reg(tmpL2, tmpL1, src); 12538 countLeadingZerosL(tmpL3, tmpL2); 12539 subI_imm16_reg(dst, imm2, tmpL3); 12540 %} 12541 %} 12542 12543 // Expand nodes for byte_reverse_int. 12544 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12545 effect(DEF dst, USE src, USE pos, USE shift); 12546 predicate(false); 12547 12548 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12549 size(4); 12550 ins_encode %{ 12551 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12552 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12553 %} 12554 ins_pipe(pipe_class_default); 12555 %} 12556 12557 // As insrwi_a, but with USE_DEF. 12558 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12559 effect(USE_DEF dst, USE src, USE pos, USE shift); 12560 predicate(false); 12561 12562 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12563 size(4); 12564 ins_encode %{ 12565 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12566 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12567 %} 12568 ins_pipe(pipe_class_default); 12569 %} 12570 12571 // Just slightly faster than java implementation. 12572 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 12573 match(Set dst (ReverseBytesI src)); 12574 predicate(UseCountLeadingZerosInstructionsPPC64); 12575 ins_cost(DEFAULT_COST); 12576 12577 expand %{ 12578 immI16 imm24 %{ (int) 24 %} 12579 immI16 imm16 %{ (int) 16 %} 12580 immI16 imm8 %{ (int) 8 %} 12581 immI16 imm4 %{ (int) 4 %} 12582 immI16 imm0 %{ (int) 0 %} 12583 iRegLdst tmpI1; 12584 iRegLdst tmpI2; 12585 iRegLdst tmpI3; 12586 12587 urShiftI_reg_imm(tmpI1, src, imm24); 12588 insrwi_a(dst, tmpI1, imm24, imm8); 12589 urShiftI_reg_imm(tmpI2, src, imm16); 12590 insrwi(dst, tmpI2, imm8, imm16); 12591 urShiftI_reg_imm(tmpI3, src, imm8); 12592 insrwi(dst, tmpI3, imm8, imm8); 12593 insrwi(dst, src, imm0, imm8); 12594 %} 12595 %} 12596 12597 //---------- Replicate Vector Instructions ------------------------------------ 12598 12599 // Insrdi does replicate if src == dst. 12600 instruct repl32(iRegLdst dst) %{ 12601 predicate(false); 12602 effect(USE_DEF dst); 12603 12604 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 12605 size(4); 12606 ins_encode %{ 12607 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12608 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 12609 %} 12610 ins_pipe(pipe_class_default); 12611 %} 12612 12613 // Insrdi does replicate if src == dst. 12614 instruct repl48(iRegLdst dst) %{ 12615 predicate(false); 12616 effect(USE_DEF dst); 12617 12618 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 12619 size(4); 12620 ins_encode %{ 12621 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12622 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 12623 %} 12624 ins_pipe(pipe_class_default); 12625 %} 12626 12627 // Insrdi does replicate if src == dst. 12628 instruct repl56(iRegLdst dst) %{ 12629 predicate(false); 12630 effect(USE_DEF dst); 12631 12632 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 12633 size(4); 12634 ins_encode %{ 12635 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12636 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 12637 %} 12638 ins_pipe(pipe_class_default); 12639 %} 12640 12641 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12642 match(Set dst (ReplicateB src)); 12643 predicate(n->as_Vector()->length() == 8); 12644 expand %{ 12645 moveReg(dst, src); 12646 repl56(dst); 12647 repl48(dst); 12648 repl32(dst); 12649 %} 12650 %} 12651 12652 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 12653 match(Set dst (ReplicateB zero)); 12654 predicate(n->as_Vector()->length() == 8); 12655 format %{ "LI $dst, #0 \t// replicate8B" %} 12656 size(4); 12657 ins_encode %{ 12658 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12659 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12660 %} 12661 ins_pipe(pipe_class_default); 12662 %} 12663 12664 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12665 match(Set dst (ReplicateB src)); 12666 predicate(n->as_Vector()->length() == 8); 12667 format %{ "LI $dst, #-1 \t// replicate8B" %} 12668 size(4); 12669 ins_encode %{ 12670 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12671 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12672 %} 12673 ins_pipe(pipe_class_default); 12674 %} 12675 12676 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12677 match(Set dst (ReplicateS src)); 12678 predicate(n->as_Vector()->length() == 4); 12679 expand %{ 12680 moveReg(dst, src); 12681 repl48(dst); 12682 repl32(dst); 12683 %} 12684 %} 12685 12686 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 12687 match(Set dst (ReplicateS zero)); 12688 predicate(n->as_Vector()->length() == 4); 12689 format %{ "LI $dst, #0 \t// replicate4C" %} 12690 size(4); 12691 ins_encode %{ 12692 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12693 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12694 %} 12695 ins_pipe(pipe_class_default); 12696 %} 12697 12698 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12699 match(Set dst (ReplicateS src)); 12700 predicate(n->as_Vector()->length() == 4); 12701 format %{ "LI $dst, -1 \t// replicate4C" %} 12702 size(4); 12703 ins_encode %{ 12704 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12705 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12706 %} 12707 ins_pipe(pipe_class_default); 12708 %} 12709 12710 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12711 match(Set dst (ReplicateI src)); 12712 predicate(n->as_Vector()->length() == 2); 12713 ins_cost(2 * DEFAULT_COST); 12714 expand %{ 12715 moveReg(dst, src); 12716 repl32(dst); 12717 %} 12718 %} 12719 12720 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 12721 match(Set dst (ReplicateI zero)); 12722 predicate(n->as_Vector()->length() == 2); 12723 format %{ "LI $dst, #0 \t// replicate4C" %} 12724 size(4); 12725 ins_encode %{ 12726 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12727 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12728 %} 12729 ins_pipe(pipe_class_default); 12730 %} 12731 12732 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12733 match(Set dst (ReplicateI src)); 12734 predicate(n->as_Vector()->length() == 2); 12735 format %{ "LI $dst, -1 \t// replicate4C" %} 12736 size(4); 12737 ins_encode %{ 12738 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12739 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12740 %} 12741 ins_pipe(pipe_class_default); 12742 %} 12743 12744 // Move float to int register via stack, replicate. 12745 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 12746 match(Set dst (ReplicateF src)); 12747 predicate(n->as_Vector()->length() == 2); 12748 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 12749 expand %{ 12750 stackSlotL tmpS; 12751 iRegIdst tmpI; 12752 moveF2I_reg_stack(tmpS, src); // Move float to stack. 12753 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 12754 moveReg(dst, tmpI); // Move int to long reg. 12755 repl32(dst); // Replicate bitpattern. 12756 %} 12757 %} 12758 12759 // Replicate scalar constant to packed float values in Double register 12760 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 12761 match(Set dst (ReplicateF src)); 12762 predicate(n->as_Vector()->length() == 2); 12763 ins_cost(5 * DEFAULT_COST); 12764 12765 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 12766 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 12767 %} 12768 12769 // Replicate scalar zero constant to packed float values in Double register 12770 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 12771 match(Set dst (ReplicateF zero)); 12772 predicate(n->as_Vector()->length() == 2); 12773 12774 format %{ "LI $dst, #0 \t// replicate2F" %} 12775 ins_encode %{ 12776 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12777 __ li($dst$$Register, 0x0); 12778 %} 12779 ins_pipe(pipe_class_default); 12780 %} 12781 12782 12783 //----------Overflow Math Instructions----------------------------------------- 12784 12785 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 12786 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 12787 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 12788 12789 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12790 match(Set cr0 (OverflowAddL op1 op2)); 12791 12792 format %{ "add_ $op1, $op2\t# overflow check long" %} 12793 ins_encode %{ 12794 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12795 __ li(R0, 0); 12796 __ mtxer(R0); // clear XER.SO 12797 __ addo_(R0, $op1$$Register, $op2$$Register); 12798 %} 12799 ins_pipe(pipe_class_default); 12800 %} 12801 12802 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12803 match(Set cr0 (OverflowSubL op1 op2)); 12804 12805 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 12806 ins_encode %{ 12807 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12808 __ li(R0, 0); 12809 __ mtxer(R0); // clear XER.SO 12810 __ subfo_(R0, $op2$$Register, $op1$$Register); 12811 %} 12812 ins_pipe(pipe_class_default); 12813 %} 12814 12815 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 12816 match(Set cr0 (OverflowSubL zero op2)); 12817 12818 format %{ "nego_ R0, $op2\t# overflow check long" %} 12819 ins_encode %{ 12820 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12821 __ li(R0, 0); 12822 __ mtxer(R0); // clear XER.SO 12823 __ nego_(R0, $op2$$Register); 12824 %} 12825 ins_pipe(pipe_class_default); 12826 %} 12827 12828 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12829 match(Set cr0 (OverflowMulL op1 op2)); 12830 12831 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 12832 ins_encode %{ 12833 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12834 __ li(R0, 0); 12835 __ mtxer(R0); // clear XER.SO 12836 __ mulldo_(R0, $op1$$Register, $op2$$Register); 12837 %} 12838 ins_pipe(pipe_class_default); 12839 %} 12840 12841 12842 // ============================================================================ 12843 // Safepoint Instruction 12844 12845 instruct safePoint_poll(iRegPdst poll) %{ 12846 match(SafePoint poll); 12847 predicate(LoadPollAddressFromThread); 12848 12849 // It caused problems to add the effect that r0 is killed, but this 12850 // effect no longer needs to be mentioned, since r0 is not contained 12851 // in a reg_class. 12852 12853 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 12854 size(4); 12855 ins_encode( enc_poll(0x0, poll) ); 12856 ins_pipe(pipe_class_default); 12857 %} 12858 12859 // Safepoint without per-thread support. Load address of page to poll 12860 // as constant. 12861 // Rscratch2RegP is R12. 12862 // LoadConPollAddr node is added in pd_post_matching_hook(). It must be 12863 // a seperate node so that the oop map is at the right location. 12864 instruct safePoint_poll_conPollAddr(rscratch2RegP poll) %{ 12865 match(SafePoint poll); 12866 predicate(!LoadPollAddressFromThread); 12867 12868 // It caused problems to add the effect that r0 is killed, but this 12869 // effect no longer needs to be mentioned, since r0 is not contained 12870 // in a reg_class. 12871 12872 format %{ "LD R0, #0, R12 \t// Safepoint poll for GC" %} 12873 ins_encode( enc_poll(0x0, poll) ); 12874 ins_pipe(pipe_class_default); 12875 %} 12876 12877 // ============================================================================ 12878 // Call Instructions 12879 12880 // Call Java Static Instruction 12881 12882 // Schedulable version of call static node. 12883 instruct CallStaticJavaDirect(method meth) %{ 12884 match(CallStaticJava); 12885 effect(USE meth); 12886 ins_cost(CALL_COST); 12887 12888 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 12889 12890 format %{ "CALL,static $meth \t// ==> " %} 12891 size(4); 12892 ins_encode( enc_java_static_call(meth) ); 12893 ins_pipe(pipe_class_call); 12894 %} 12895 12896 // Call Java Dynamic Instruction 12897 12898 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 12899 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 12900 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 12901 // The call destination must still be placed in the constant pool. 12902 instruct CallDynamicJavaDirectSched(method meth) %{ 12903 match(CallDynamicJava); // To get all the data fields we need ... 12904 effect(USE meth); 12905 predicate(false); // ... but never match. 12906 12907 ins_field_load_ic_hi_node(loadConL_hiNode*); 12908 ins_field_load_ic_node(loadConLNode*); 12909 ins_num_consts(1 /* 1 patchable constant: call destination */); 12910 12911 format %{ "BL \t// dynamic $meth ==> " %} 12912 size(4); 12913 ins_encode( enc_java_dynamic_call_sched(meth) ); 12914 ins_pipe(pipe_class_call); 12915 %} 12916 12917 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 12918 // We use postalloc expanded calls if we use inline caches 12919 // and do not update method data. 12920 // 12921 // This instruction has two constants: inline cache (IC) and call destination. 12922 // Loading the inline cache will be postalloc expanded, thus leaving a call with 12923 // one constant. 12924 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 12925 match(CallDynamicJava); 12926 effect(USE meth); 12927 predicate(UseInlineCaches); 12928 ins_cost(CALL_COST); 12929 12930 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 12931 12932 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 12933 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 12934 %} 12935 12936 // Compound version of call dynamic java 12937 // We use postalloc expanded calls if we use inline caches 12938 // and do not update method data. 12939 instruct CallDynamicJavaDirect(method meth) %{ 12940 match(CallDynamicJava); 12941 effect(USE meth); 12942 predicate(!UseInlineCaches); 12943 ins_cost(CALL_COST); 12944 12945 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 12946 ins_num_consts(4); 12947 12948 format %{ "CALL,dynamic $meth \t// ==> " %} 12949 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 12950 ins_pipe(pipe_class_call); 12951 %} 12952 12953 // Call Runtime Instruction 12954 12955 instruct CallRuntimeDirect(method meth) %{ 12956 match(CallRuntime); 12957 effect(USE meth); 12958 ins_cost(CALL_COST); 12959 12960 // Enc_java_to_runtime_call needs up to 3 constants: call target, 12961 // env for callee, C-toc. 12962 ins_num_consts(3); 12963 12964 format %{ "CALL,runtime" %} 12965 ins_encode( enc_java_to_runtime_call(meth) ); 12966 ins_pipe(pipe_class_call); 12967 %} 12968 12969 // Call Leaf 12970 12971 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 12972 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 12973 effect(DEF dst, USE src); 12974 12975 ins_num_consts(1); 12976 12977 format %{ "MTCTR $src" %} 12978 size(4); 12979 ins_encode( enc_leaf_call_mtctr(src) ); 12980 ins_pipe(pipe_class_default); 12981 %} 12982 12983 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 12984 instruct CallLeafDirect(method meth) %{ 12985 match(CallLeaf); // To get the data all the data fields we need ... 12986 effect(USE meth); 12987 predicate(false); // but never match. 12988 12989 format %{ "BCTRL \t// leaf call $meth ==> " %} 12990 size(4); 12991 ins_encode %{ 12992 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 12993 __ bctrl(); 12994 %} 12995 ins_pipe(pipe_class_call); 12996 %} 12997 12998 // postalloc expand of CallLeafDirect. 12999 // Load adress to call from TOC, then bl to it. 13000 instruct CallLeafDirect_Ex(method meth) %{ 13001 match(CallLeaf); 13002 effect(USE meth); 13003 ins_cost(CALL_COST); 13004 13005 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 13006 // env for callee, C-toc. 13007 ins_num_consts(3); 13008 13009 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 13010 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 13011 %} 13012 13013 // Call runtime without safepoint - same as CallLeaf. 13014 // postalloc expand of CallLeafNoFPDirect. 13015 // Load adress to call from TOC, then bl to it. 13016 instruct CallLeafNoFPDirect_Ex(method meth) %{ 13017 match(CallLeafNoFP); 13018 effect(USE meth); 13019 ins_cost(CALL_COST); 13020 13021 // Enc_java_to_runtime_call needs up to 3 constants: call target, 13022 // env for callee, C-toc. 13023 ins_num_consts(3); 13024 13025 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 13026 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 13027 %} 13028 13029 // Tail Call; Jump from runtime stub to Java code. 13030 // Also known as an 'interprocedural jump'. 13031 // Target of jump will eventually return to caller. 13032 // TailJump below removes the return address. 13033 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 13034 match(TailCall jump_target method_oop); 13035 ins_cost(CALL_COST); 13036 13037 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 13038 "BCTR \t// tail call" %} 13039 size(8); 13040 ins_encode %{ 13041 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13042 __ mtctr($jump_target$$Register); 13043 __ bctr(); 13044 %} 13045 ins_pipe(pipe_class_call); 13046 %} 13047 13048 // Return Instruction 13049 instruct Ret() %{ 13050 match(Return); 13051 format %{ "BLR \t// branch to link register" %} 13052 size(4); 13053 ins_encode %{ 13054 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 13055 // LR is restored in MachEpilogNode. Just do the RET here. 13056 __ blr(); 13057 %} 13058 ins_pipe(pipe_class_default); 13059 %} 13060 13061 // Tail Jump; remove the return address; jump to target. 13062 // TailCall above leaves the return address around. 13063 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 13064 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 13065 // "restore" before this instruction (in Epilogue), we need to materialize it 13066 // in %i0. 13067 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 13068 match(TailJump jump_target ex_oop); 13069 ins_cost(CALL_COST); 13070 13071 format %{ "LD R4_ARG2 = LR\n\t" 13072 "MTCTR $jump_target\n\t" 13073 "BCTR \t// TailJump, exception oop: $ex_oop" %} 13074 size(12); 13075 ins_encode %{ 13076 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13077 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 13078 __ mtctr($jump_target$$Register); 13079 __ bctr(); 13080 %} 13081 ins_pipe(pipe_class_call); 13082 %} 13083 13084 // Create exception oop: created by stack-crawling runtime code. 13085 // Created exception is now available to this handler, and is setup 13086 // just prior to jumping to this handler. No code emitted. 13087 instruct CreateException(rarg1RegP ex_oop) %{ 13088 match(Set ex_oop (CreateEx)); 13089 ins_cost(0); 13090 13091 format %{ " -- \t// exception oop; no code emitted" %} 13092 size(0); 13093 ins_encode( /*empty*/ ); 13094 ins_pipe(pipe_class_default); 13095 %} 13096 13097 // Rethrow exception: The exception oop will come in the first 13098 // argument position. Then JUMP (not call) to the rethrow stub code. 13099 instruct RethrowException() %{ 13100 match(Rethrow); 13101 ins_cost(CALL_COST); 13102 13103 format %{ "Jmp rethrow_stub" %} 13104 ins_encode %{ 13105 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13106 cbuf.set_insts_mark(); 13107 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 13108 %} 13109 ins_pipe(pipe_class_call); 13110 %} 13111 13112 // Die now. 13113 instruct ShouldNotReachHere() %{ 13114 match(Halt); 13115 ins_cost(CALL_COST); 13116 13117 format %{ "ShouldNotReachHere" %} 13118 size(4); 13119 ins_encode %{ 13120 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 13121 __ trap_should_not_reach_here(); 13122 %} 13123 ins_pipe(pipe_class_default); 13124 %} 13125 13126 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 13127 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 13128 // Get a DEF on threadRegP, no costs, no encoding, use 13129 // 'ins_should_rematerialize(true)' to avoid spilling. 13130 instruct tlsLoadP(threadRegP dst) %{ 13131 match(Set dst (ThreadLocal)); 13132 ins_cost(0); 13133 13134 ins_should_rematerialize(true); 13135 13136 format %{ " -- \t// $dst=Thread::current(), empty" %} 13137 size(0); 13138 ins_encode( /*empty*/ ); 13139 ins_pipe(pipe_class_empty); 13140 %} 13141 13142 //---Some PPC specific nodes--------------------------------------------------- 13143 13144 // Stop a group. 13145 instruct endGroup() %{ 13146 ins_cost(0); 13147 13148 ins_is_nop(true); 13149 13150 format %{ "End Bundle (ori r1, r1, 0)" %} 13151 size(4); 13152 ins_encode %{ 13153 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 13154 __ endgroup(); 13155 %} 13156 ins_pipe(pipe_class_default); 13157 %} 13158 13159 // Nop instructions 13160 13161 instruct fxNop() %{ 13162 ins_cost(0); 13163 13164 ins_is_nop(true); 13165 13166 format %{ "fxNop" %} 13167 size(4); 13168 ins_encode %{ 13169 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13170 __ nop(); 13171 %} 13172 ins_pipe(pipe_class_default); 13173 %} 13174 13175 instruct fpNop0() %{ 13176 ins_cost(0); 13177 13178 ins_is_nop(true); 13179 13180 format %{ "fpNop0" %} 13181 size(4); 13182 ins_encode %{ 13183 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13184 __ fpnop0(); 13185 %} 13186 ins_pipe(pipe_class_default); 13187 %} 13188 13189 instruct fpNop1() %{ 13190 ins_cost(0); 13191 13192 ins_is_nop(true); 13193 13194 format %{ "fpNop1" %} 13195 size(4); 13196 ins_encode %{ 13197 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13198 __ fpnop1(); 13199 %} 13200 ins_pipe(pipe_class_default); 13201 %} 13202 13203 instruct brNop0() %{ 13204 ins_cost(0); 13205 size(4); 13206 format %{ "brNop0" %} 13207 ins_encode %{ 13208 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13209 __ brnop0(); 13210 %} 13211 ins_is_nop(true); 13212 ins_pipe(pipe_class_default); 13213 %} 13214 13215 instruct brNop1() %{ 13216 ins_cost(0); 13217 13218 ins_is_nop(true); 13219 13220 format %{ "brNop1" %} 13221 size(4); 13222 ins_encode %{ 13223 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13224 __ brnop1(); 13225 %} 13226 ins_pipe(pipe_class_default); 13227 %} 13228 13229 instruct brNop2() %{ 13230 ins_cost(0); 13231 13232 ins_is_nop(true); 13233 13234 format %{ "brNop2" %} 13235 size(4); 13236 ins_encode %{ 13237 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13238 __ brnop2(); 13239 %} 13240 ins_pipe(pipe_class_default); 13241 %} 13242 13243 //----------PEEPHOLE RULES----------------------------------------------------- 13244 // These must follow all instruction definitions as they use the names 13245 // defined in the instructions definitions. 13246 // 13247 // peepmatch ( root_instr_name [preceeding_instruction]* ); 13248 // 13249 // peepconstraint %{ 13250 // (instruction_number.operand_name relational_op instruction_number.operand_name 13251 // [, ...] ); 13252 // // instruction numbers are zero-based using left to right order in peepmatch 13253 // 13254 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 13255 // // provide an instruction_number.operand_name for each operand that appears 13256 // // in the replacement instruction's match rule 13257 // 13258 // ---------VM FLAGS--------------------------------------------------------- 13259 // 13260 // All peephole optimizations can be turned off using -XX:-OptoPeephole 13261 // 13262 // Each peephole rule is given an identifying number starting with zero and 13263 // increasing by one in the order seen by the parser. An individual peephole 13264 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 13265 // on the command-line. 13266 // 13267 // ---------CURRENT LIMITATIONS---------------------------------------------- 13268 // 13269 // Only match adjacent instructions in same basic block 13270 // Only equality constraints 13271 // Only constraints between operands, not (0.dest_reg == EAX_enc) 13272 // Only one replacement instruction 13273 // 13274 // ---------EXAMPLE---------------------------------------------------------- 13275 // 13276 // // pertinent parts of existing instructions in architecture description 13277 // instruct movI(eRegI dst, eRegI src) %{ 13278 // match(Set dst (CopyI src)); 13279 // %} 13280 // 13281 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 13282 // match(Set dst (AddI dst src)); 13283 // effect(KILL cr); 13284 // %} 13285 // 13286 // // Change (inc mov) to lea 13287 // peephole %{ 13288 // // increment preceeded by register-register move 13289 // peepmatch ( incI_eReg movI ); 13290 // // require that the destination register of the increment 13291 // // match the destination register of the move 13292 // peepconstraint ( 0.dst == 1.dst ); 13293 // // construct a replacement instruction that sets 13294 // // the destination to ( move's source register + one ) 13295 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13296 // %} 13297 // 13298 // Implementation no longer uses movX instructions since 13299 // machine-independent system no longer uses CopyX nodes. 13300 // 13301 // peephole %{ 13302 // peepmatch ( incI_eReg movI ); 13303 // peepconstraint ( 0.dst == 1.dst ); 13304 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13305 // %} 13306 // 13307 // peephole %{ 13308 // peepmatch ( decI_eReg movI ); 13309 // peepconstraint ( 0.dst == 1.dst ); 13310 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13311 // %} 13312 // 13313 // peephole %{ 13314 // peepmatch ( addI_eReg_imm movI ); 13315 // peepconstraint ( 0.dst == 1.dst ); 13316 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13317 // %} 13318 // 13319 // peephole %{ 13320 // peepmatch ( addP_eReg_imm movP ); 13321 // peepconstraint ( 0.dst == 1.dst ); 13322 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 13323 // %} 13324 13325 // // Change load of spilled value to only a spill 13326 // instruct storeI(memory mem, eRegI src) %{ 13327 // match(Set mem (StoreI mem src)); 13328 // %} 13329 // 13330 // instruct loadI(eRegI dst, memory mem) %{ 13331 // match(Set dst (LoadI mem)); 13332 // %} 13333 // 13334 peephole %{ 13335 peepmatch ( loadI storeI ); 13336 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13337 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 13338 %} 13339 13340 peephole %{ 13341 peepmatch ( loadL storeL ); 13342 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13343 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 13344 %} 13345 13346 peephole %{ 13347 peepmatch ( loadP storeP ); 13348 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 13349 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 13350 %} 13351 13352 //----------SMARTSPILL RULES--------------------------------------------------- 13353 // These must follow all instruction definitions as they use the names 13354 // defined in the instructions definitions.