1 // 2 // Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2016 SAP SE. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // 27 // PPC64 Architecture Description File 28 // 29 30 //----------REGISTER DEFINITION BLOCK------------------------------------------ 31 // This information is used by the matcher and the register allocator to 32 // describe individual registers and classes of registers within the target 33 // architecture. 34 register %{ 35 //----------Architecture Description Register Definitions---------------------- 36 // General Registers 37 // "reg_def" name (register save type, C convention save type, 38 // ideal register type, encoding); 39 // 40 // Register Save Types: 41 // 42 // NS = No-Save: The register allocator assumes that these registers 43 // can be used without saving upon entry to the method, & 44 // that they do not need to be saved at call sites. 45 // 46 // SOC = Save-On-Call: The register allocator assumes that these registers 47 // can be used without saving upon entry to the method, 48 // but that they must be saved at call sites. 49 // These are called "volatiles" on ppc. 50 // 51 // SOE = Save-On-Entry: The register allocator assumes that these registers 52 // must be saved before using them upon entry to the 53 // method, but they do not need to be saved at call 54 // sites. 55 // These are called "nonvolatiles" on ppc. 56 // 57 // AS = Always-Save: The register allocator assumes that these registers 58 // must be saved before using them upon entry to the 59 // method, & that they must be saved at call sites. 60 // 61 // Ideal Register Type is used to determine how to save & restore a 62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 64 // 65 // The encoding number is the actual bit-pattern placed into the opcodes. 66 // 67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI 68 // Supplement Version 1.7 as of 2003-10-29. 69 // 70 // For each 64-bit register we must define two registers: the register 71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half', 72 // e.g. R3_H, which is needed by the allocator, but is not used 73 // for stores, loads, etc. 74 75 // ---------------------------- 76 // Integer/Long Registers 77 // ---------------------------- 78 79 // PPC64 has 32 64-bit integer registers. 80 81 // types: v = volatile, nv = non-volatile, s = system 82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs 83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() ); 84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP 85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() ); 86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC 87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() ); 88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret 89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() ); 90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2 91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() ); 92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3 93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() ); 94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4 95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() ); 96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5 97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() ); 98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6 99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() ); 100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7 101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() ); 102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8 103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next()); 104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch 105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next()); 106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch 107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next()); 108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id 109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next()); 110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv 111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next()); 112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv 113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next()); 114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv 115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next()); 116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv 117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next()); 118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv 119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next()); 120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv 121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next()); 122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv 123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next()); 124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv 125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next()); 126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv 127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next()); 128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv 129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next()); 130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv 131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next()); 132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv 133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next()); 134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv 135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next()); 136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv 137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next()); 138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv 139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next()); 140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv 141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next()); 142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv 143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next()); 144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv 145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next()); 146 147 148 // ---------------------------- 149 // Float/Double Registers 150 // ---------------------------- 151 152 // Double Registers 153 // The rules of ADL require that double registers be defined in pairs. 154 // Each pair must be two 32-bit values, but not necessarily a pair of 155 // single float registers. In each pair, ADLC-assigned register numbers 156 // must be adjacent, with the lower number even. Finally, when the 157 // CPU stores such a register pair to memory, the word associated with 158 // the lower ADLC-assigned number must be stored to the lower address. 159 160 // PPC64 has 32 64-bit floating-point registers. Each can store a single 161 // or double precision floating-point value. 162 163 // types: v = volatile, nv = non-volatile, s = system 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch 165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret 167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2 169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3 171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4 173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5 175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6 177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7 179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8 181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9 183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10 185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next()); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11 187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next()); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12 189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next()); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13 191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next()); 192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv 193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next()); 194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv 195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next()); 196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv 197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next()); 198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv 199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next()); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv 201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next()); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv 203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next()); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv 205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next()); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv 207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next()); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv 209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next()); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv 211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next()); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv 213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next()); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv 215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next()); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv 217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next()); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv 219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next()); 220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv 221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next()); 222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv 223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next()); 224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv 225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next()); 226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv 227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next()); 228 229 // ---------------------------- 230 // Special Registers 231 // ---------------------------- 232 233 // Condition Codes Flag Registers 234 235 // PPC64 has 8 condition code "registers" which are all contained 236 // in the CR register. 237 238 // types: v = volatile, nv = non-volatile, s = system 239 reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v 240 reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v 241 reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv 242 reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv 243 reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv 244 reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v 245 reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v 246 reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg()); // v 247 248 // Special registers of PPC64 249 250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v 251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v 252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v 253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v 254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v 255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v 256 257 258 // ---------------------------- 259 // Specify priority of register selection within phases of register 260 // allocation. Highest priority is first. A useful heuristic is to 261 // give registers a low priority when they are required by machine 262 // instructions, like EAX and EDX on I486, and choose no-save registers 263 // before save-on-call, & save-on-call before save-on-entry. Registers 264 // which participate in fixed calling sequences should come last. 265 // Registers which are used as pairs must fall on an even boundary. 266 267 // It's worth about 1% on SPEC geomean to get this right. 268 269 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 270 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 271 // R3_num. Therefore, R3_num may not be (and in reality is not) 272 // the same as R3->encoding()! Furthermore, we cannot make any 273 // assumptions on ordering, e.g. R3_num may be less than R2_num. 274 // Additionally, the function 275 // static enum RC rc_class(OptoReg::Name reg ) 276 // maps a given <register>_num value to its chunk type (except for flags) 277 // and its current implementation relies on chunk0 and chunk1 having a 278 // size of 64 each. 279 280 // If you change this allocation class, please have a look at the 281 // default values for the parameters RoundRobinIntegerRegIntervalStart 282 // and RoundRobinFloatRegIntervalStart 283 284 alloc_class chunk0 ( 285 // Chunk0 contains *all* 64 integer registers halves. 286 287 // "non-volatile" registers 288 R14, R14_H, 289 R15, R15_H, 290 R17, R17_H, 291 R18, R18_H, 292 R19, R19_H, 293 R20, R20_H, 294 R21, R21_H, 295 R22, R22_H, 296 R23, R23_H, 297 R24, R24_H, 298 R25, R25_H, 299 R26, R26_H, 300 R27, R27_H, 301 R28, R28_H, 302 R29, R29_H, 303 R30, R30_H, 304 R31, R31_H, 305 306 // scratch/special registers 307 R11, R11_H, 308 R12, R12_H, 309 310 // argument registers 311 R10, R10_H, 312 R9, R9_H, 313 R8, R8_H, 314 R7, R7_H, 315 R6, R6_H, 316 R5, R5_H, 317 R4, R4_H, 318 R3, R3_H, 319 320 // special registers, not available for allocation 321 R16, R16_H, // R16_thread 322 R13, R13_H, // system thread id 323 R2, R2_H, // may be used for TOC 324 R1, R1_H, // SP 325 R0, R0_H // R0 (scratch) 326 ); 327 328 // If you change this allocation class, please have a look at the 329 // default values for the parameters RoundRobinIntegerRegIntervalStart 330 // and RoundRobinFloatRegIntervalStart 331 332 alloc_class chunk1 ( 333 // Chunk1 contains *all* 64 floating-point registers halves. 334 335 // scratch register 336 F0, F0_H, 337 338 // argument registers 339 F13, F13_H, 340 F12, F12_H, 341 F11, F11_H, 342 F10, F10_H, 343 F9, F9_H, 344 F8, F8_H, 345 F7, F7_H, 346 F6, F6_H, 347 F5, F5_H, 348 F4, F4_H, 349 F3, F3_H, 350 F2, F2_H, 351 F1, F1_H, 352 353 // non-volatile registers 354 F14, F14_H, 355 F15, F15_H, 356 F16, F16_H, 357 F17, F17_H, 358 F18, F18_H, 359 F19, F19_H, 360 F20, F20_H, 361 F21, F21_H, 362 F22, F22_H, 363 F23, F23_H, 364 F24, F24_H, 365 F25, F25_H, 366 F26, F26_H, 367 F27, F27_H, 368 F28, F28_H, 369 F29, F29_H, 370 F30, F30_H, 371 F31, F31_H 372 ); 373 374 alloc_class chunk2 ( 375 // Chunk2 contains *all* 8 condition code registers. 376 377 CCR0, 378 CCR1, 379 CCR2, 380 CCR3, 381 CCR4, 382 CCR5, 383 CCR6, 384 CCR7 385 ); 386 387 alloc_class chunk3 ( 388 // special registers 389 // These registers are not allocated, but used for nodes generated by postalloc expand. 390 SR_XER, 391 SR_LR, 392 SR_CTR, 393 SR_VRSAVE, 394 SR_SPEFSCR, 395 SR_PPR 396 ); 397 398 //-------Architecture Description Register Classes----------------------- 399 400 // Several register classes are automatically defined based upon 401 // information in this architecture description. 402 403 // 1) reg_class inline_cache_reg ( as defined in frame section ) 404 // 2) reg_class compiler_method_oop_reg ( as defined in frame section ) 405 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 406 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 407 // 408 409 // ---------------------------- 410 // 32 Bit Register Classes 411 // ---------------------------- 412 413 // We specify registers twice, once as read/write, and once read-only. 414 // We use the read-only registers for source operands. With this, we 415 // can include preset read only registers in this class, as a hard-coded 416 // '0'-register. (We used to simulate this on ppc.) 417 418 // 32 bit registers that can be read and written i.e. these registers 419 // can be dest (or src) of normal instructions. 420 reg_class bits32_reg_rw( 421 /*R0*/ // R0 422 /*R1*/ // SP 423 R2, // TOC 424 R3, 425 R4, 426 R5, 427 R6, 428 R7, 429 R8, 430 R9, 431 R10, 432 R11, 433 R12, 434 /*R13*/ // system thread id 435 R14, 436 R15, 437 /*R16*/ // R16_thread 438 R17, 439 R18, 440 R19, 441 R20, 442 R21, 443 R22, 444 R23, 445 R24, 446 R25, 447 R26, 448 R27, 449 R28, 450 /*R29,*/ // global TOC 451 R30, 452 R31 453 ); 454 455 // 32 bit registers that can only be read i.e. these registers can 456 // only be src of all instructions. 457 reg_class bits32_reg_ro( 458 /*R0*/ // R0 459 /*R1*/ // SP 460 R2 // TOC 461 R3, 462 R4, 463 R5, 464 R6, 465 R7, 466 R8, 467 R9, 468 R10, 469 R11, 470 R12, 471 /*R13*/ // system thread id 472 R14, 473 R15, 474 /*R16*/ // R16_thread 475 R17, 476 R18, 477 R19, 478 R20, 479 R21, 480 R22, 481 R23, 482 R24, 483 R25, 484 R26, 485 R27, 486 R28, 487 /*R29,*/ 488 R30, 489 R31 490 ); 491 492 reg_class rscratch1_bits32_reg(R11); 493 reg_class rscratch2_bits32_reg(R12); 494 reg_class rarg1_bits32_reg(R3); 495 reg_class rarg2_bits32_reg(R4); 496 reg_class rarg3_bits32_reg(R5); 497 reg_class rarg4_bits32_reg(R6); 498 499 // ---------------------------- 500 // 64 Bit Register Classes 501 // ---------------------------- 502 // 64-bit build means 64-bit pointers means hi/lo pairs 503 504 reg_class rscratch1_bits64_reg(R11_H, R11); 505 reg_class rscratch2_bits64_reg(R12_H, R12); 506 reg_class rarg1_bits64_reg(R3_H, R3); 507 reg_class rarg2_bits64_reg(R4_H, R4); 508 reg_class rarg3_bits64_reg(R5_H, R5); 509 reg_class rarg4_bits64_reg(R6_H, R6); 510 // Thread register, 'written' by tlsLoadP, see there. 511 reg_class thread_bits64_reg(R16_H, R16); 512 513 reg_class r19_bits64_reg(R19_H, R19); 514 515 // 64 bit registers that can be read and written i.e. these registers 516 // can be dest (or src) of normal instructions. 517 reg_class bits64_reg_rw( 518 /*R0_H, R0*/ // R0 519 /*R1_H, R1*/ // SP 520 R2_H, R2, // TOC 521 R3_H, R3, 522 R4_H, R4, 523 R5_H, R5, 524 R6_H, R6, 525 R7_H, R7, 526 R8_H, R8, 527 R9_H, R9, 528 R10_H, R10, 529 R11_H, R11, 530 R12_H, R12, 531 /*R13_H, R13*/ // system thread id 532 R14_H, R14, 533 R15_H, R15, 534 /*R16_H, R16*/ // R16_thread 535 R17_H, R17, 536 R18_H, R18, 537 R19_H, R19, 538 R20_H, R20, 539 R21_H, R21, 540 R22_H, R22, 541 R23_H, R23, 542 R24_H, R24, 543 R25_H, R25, 544 R26_H, R26, 545 R27_H, R27, 546 R28_H, R28, 547 /*R29_H, R29,*/ 548 R30_H, R30, 549 R31_H, R31 550 ); 551 552 // 64 bit registers used excluding r2, r11 and r12 553 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses 554 // r2, r11 and r12 internally. 555 reg_class bits64_reg_leaf_call( 556 /*R0_H, R0*/ // R0 557 /*R1_H, R1*/ // SP 558 /*R2_H, R2*/ // TOC 559 R3_H, R3, 560 R4_H, R4, 561 R5_H, R5, 562 R6_H, R6, 563 R7_H, R7, 564 R8_H, R8, 565 R9_H, R9, 566 R10_H, R10, 567 /*R11_H, R11*/ 568 /*R12_H, R12*/ 569 /*R13_H, R13*/ // system thread id 570 R14_H, R14, 571 R15_H, R15, 572 /*R16_H, R16*/ // R16_thread 573 R17_H, R17, 574 R18_H, R18, 575 R19_H, R19, 576 R20_H, R20, 577 R21_H, R21, 578 R22_H, R22, 579 R23_H, R23, 580 R24_H, R24, 581 R25_H, R25, 582 R26_H, R26, 583 R27_H, R27, 584 R28_H, R28, 585 /*R29_H, R29,*/ 586 R30_H, R30, 587 R31_H, R31 588 ); 589 590 // Used to hold the TOC to avoid collisions with expanded DynamicCall 591 // which uses r19 as inline cache internally and expanded LeafCall which uses 592 // r2, r11 and r12 internally. 593 reg_class bits64_constant_table_base( 594 /*R0_H, R0*/ // R0 595 /*R1_H, R1*/ // SP 596 /*R2_H, R2*/ // TOC 597 R3_H, R3, 598 R4_H, R4, 599 R5_H, R5, 600 R6_H, R6, 601 R7_H, R7, 602 R8_H, R8, 603 R9_H, R9, 604 R10_H, R10, 605 /*R11_H, R11*/ 606 /*R12_H, R12*/ 607 /*R13_H, R13*/ // system thread id 608 R14_H, R14, 609 R15_H, R15, 610 /*R16_H, R16*/ // R16_thread 611 R17_H, R17, 612 R18_H, R18, 613 /*R19_H, R19*/ 614 R20_H, R20, 615 R21_H, R21, 616 R22_H, R22, 617 R23_H, R23, 618 R24_H, R24, 619 R25_H, R25, 620 R26_H, R26, 621 R27_H, R27, 622 R28_H, R28, 623 /*R29_H, R29,*/ 624 R30_H, R30, 625 R31_H, R31 626 ); 627 628 // 64 bit registers that can only be read i.e. these registers can 629 // only be src of all instructions. 630 reg_class bits64_reg_ro( 631 /*R0_H, R0*/ // R0 632 R1_H, R1, 633 R2_H, R2, // TOC 634 R3_H, R3, 635 R4_H, R4, 636 R5_H, R5, 637 R6_H, R6, 638 R7_H, R7, 639 R8_H, R8, 640 R9_H, R9, 641 R10_H, R10, 642 R11_H, R11, 643 R12_H, R12, 644 /*R13_H, R13*/ // system thread id 645 R14_H, R14, 646 R15_H, R15, 647 R16_H, R16, // R16_thread 648 R17_H, R17, 649 R18_H, R18, 650 R19_H, R19, 651 R20_H, R20, 652 R21_H, R21, 653 R22_H, R22, 654 R23_H, R23, 655 R24_H, R24, 656 R25_H, R25, 657 R26_H, R26, 658 R27_H, R27, 659 R28_H, R28, 660 /*R29_H, R29,*/ // TODO: let allocator handle TOC!! 661 R30_H, R30, 662 R31_H, R31 663 ); 664 665 666 // ---------------------------- 667 // Special Class for Condition Code Flags Register 668 669 reg_class int_flags( 670 /*CCR0*/ // scratch 671 /*CCR1*/ // scratch 672 /*CCR2*/ // nv! 673 /*CCR3*/ // nv! 674 /*CCR4*/ // nv! 675 CCR5, 676 CCR6, 677 CCR7 678 ); 679 680 reg_class int_flags_ro( 681 CCR0, 682 CCR1, 683 CCR2, 684 CCR3, 685 CCR4, 686 CCR5, 687 CCR6, 688 CCR7 689 ); 690 691 reg_class int_flags_CR0(CCR0); 692 reg_class int_flags_CR1(CCR1); 693 reg_class int_flags_CR6(CCR6); 694 reg_class ctr_reg(SR_CTR); 695 696 // ---------------------------- 697 // Float Register Classes 698 // ---------------------------- 699 700 reg_class flt_reg( 701 F0, 702 F1, 703 F2, 704 F3, 705 F4, 706 F5, 707 F6, 708 F7, 709 F8, 710 F9, 711 F10, 712 F11, 713 F12, 714 F13, 715 F14, // nv! 716 F15, // nv! 717 F16, // nv! 718 F17, // nv! 719 F18, // nv! 720 F19, // nv! 721 F20, // nv! 722 F21, // nv! 723 F22, // nv! 724 F23, // nv! 725 F24, // nv! 726 F25, // nv! 727 F26, // nv! 728 F27, // nv! 729 F28, // nv! 730 F29, // nv! 731 F30, // nv! 732 F31 // nv! 733 ); 734 735 // Double precision float registers have virtual `high halves' that 736 // are needed by the allocator. 737 reg_class dbl_reg( 738 F0, F0_H, 739 F1, F1_H, 740 F2, F2_H, 741 F3, F3_H, 742 F4, F4_H, 743 F5, F5_H, 744 F6, F6_H, 745 F7, F7_H, 746 F8, F8_H, 747 F9, F9_H, 748 F10, F10_H, 749 F11, F11_H, 750 F12, F12_H, 751 F13, F13_H, 752 F14, F14_H, // nv! 753 F15, F15_H, // nv! 754 F16, F16_H, // nv! 755 F17, F17_H, // nv! 756 F18, F18_H, // nv! 757 F19, F19_H, // nv! 758 F20, F20_H, // nv! 759 F21, F21_H, // nv! 760 F22, F22_H, // nv! 761 F23, F23_H, // nv! 762 F24, F24_H, // nv! 763 F25, F25_H, // nv! 764 F26, F26_H, // nv! 765 F27, F27_H, // nv! 766 F28, F28_H, // nv! 767 F29, F29_H, // nv! 768 F30, F30_H, // nv! 769 F31, F31_H // nv! 770 ); 771 772 %} 773 774 //----------DEFINITION BLOCK--------------------------------------------------- 775 // Define name --> value mappings to inform the ADLC of an integer valued name 776 // Current support includes integer values in the range [0, 0x7FFFFFFF] 777 // Format: 778 // int_def <name> ( <int_value>, <expression>); 779 // Generated Code in ad_<arch>.hpp 780 // #define <name> (<expression>) 781 // // value == <int_value> 782 // Generated code in ad_<arch>.cpp adlc_verification() 783 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 784 // 785 definitions %{ 786 // The default cost (of an ALU instruction). 787 int_def DEFAULT_COST_LOW ( 30, 30); 788 int_def DEFAULT_COST ( 100, 100); 789 int_def HUGE_COST (1000000, 1000000); 790 791 // Memory refs 792 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 793 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 794 795 // Branches are even more expensive. 796 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 797 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 798 %} 799 800 801 //----------SOURCE BLOCK------------------------------------------------------- 802 // This is a block of C++ code which provides values, functions, and 803 // definitions necessary in the rest of the architecture description. 804 source_hpp %{ 805 // Header information of the source block. 806 // Method declarations/definitions which are used outside 807 // the ad-scope can conveniently be defined here. 808 // 809 // To keep related declarations/definitions/uses close together, 810 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 811 812 // Returns true if Node n is followed by a MemBar node that 813 // will do an acquire. If so, this node must not do the acquire 814 // operation. 815 bool followed_by_acquire(const Node *n); 816 %} 817 818 source %{ 819 820 // Should the Matcher clone shifts on addressing modes, expecting them 821 // to be subsumed into complex addressing expressions or compute them 822 // into registers? 823 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 824 return clone_base_plus_offset_address(m, mstack, address_visited); 825 } 826 827 void Compile::reshape_address(AddPNode* addp) { 828 } 829 830 // Optimize load-acquire. 831 // 832 // Check if acquire is unnecessary due to following operation that does 833 // acquire anyways. 834 // Walk the pattern: 835 // 836 // n: Load.acq 837 // | 838 // MemBarAcquire 839 // | | 840 // Proj(ctrl) Proj(mem) 841 // | | 842 // MemBarRelease/Volatile 843 // 844 bool followed_by_acquire(const Node *load) { 845 assert(load->is_Load(), "So far implemented only for loads."); 846 847 // Find MemBarAcquire. 848 const Node *mba = NULL; 849 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 850 const Node *out = load->fast_out(i); 851 if (out->Opcode() == Op_MemBarAcquire) { 852 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 853 mba = out; 854 break; 855 } 856 } 857 if (!mba) return false; 858 859 // Find following MemBar node. 860 // 861 // The following node must be reachable by control AND memory 862 // edge to assure no other operations are in between the two nodes. 863 // 864 // So first get the Proj node, mem_proj, to use it to iterate forward. 865 Node *mem_proj = NULL; 866 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 867 mem_proj = mba->fast_out(i); // Throw out-of-bounds if proj not found 868 assert(mem_proj->is_Proj(), "only projections here"); 869 ProjNode *proj = mem_proj->as_Proj(); 870 if (proj->_con == TypeFunc::Memory && 871 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 872 break; 873 } 874 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 875 876 // Search MemBar behind Proj. If there are other memory operations 877 // behind the Proj we lost. 878 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 879 Node *x = mem_proj->fast_out(j); 880 // Proj might have an edge to a store or load node which precedes the membar. 881 if (x->is_Mem()) return false; 882 883 // On PPC64 release and volatile are implemented by an instruction 884 // that also has acquire semantics. I.e. there is no need for an 885 // acquire before these. 886 int xop = x->Opcode(); 887 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 888 // Make sure we're not missing Call/Phi/MergeMem by checking 889 // control edges. The control edge must directly lead back 890 // to the MemBarAcquire 891 Node *ctrl_proj = x->in(0); 892 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 893 return true; 894 } 895 } 896 } 897 898 return false; 899 } 900 901 #define __ _masm. 902 903 // Tertiary op of a LoadP or StoreP encoding. 904 #define REGP_OP true 905 906 // **************************************************************************** 907 908 // REQUIRED FUNCTIONALITY 909 910 // !!!!! Special hack to get all type of calls to specify the byte offset 911 // from the start of the call to the point where the return address 912 // will point. 913 914 // PPC port: Removed use of lazy constant construct. 915 916 int MachCallStaticJavaNode::ret_addr_offset() { 917 // It's only a single branch-and-link instruction. 918 return 4; 919 } 920 921 int MachCallDynamicJavaNode::ret_addr_offset() { 922 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 923 // postalloc expanded calls if we use inline caches and do not update method data. 924 if (UseInlineCaches) 925 return 4; 926 927 int vtable_index = this->_vtable_index; 928 if (vtable_index < 0) { 929 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 930 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 931 return 12; 932 } else { 933 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 934 return 24; 935 } 936 } 937 938 int MachCallRuntimeNode::ret_addr_offset() { 939 #if defined(ABI_ELFv2) 940 return 28; 941 #else 942 return 40; 943 #endif 944 } 945 946 //============================================================================= 947 948 // condition code conversions 949 950 static int cc_to_boint(int cc) { 951 return Assembler::bcondCRbiIs0 | (cc & 8); 952 } 953 954 static int cc_to_inverse_boint(int cc) { 955 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 956 } 957 958 static int cc_to_biint(int cc, int flags_reg) { 959 return (flags_reg << 2) | (cc & 3); 960 } 961 962 //============================================================================= 963 964 // Compute padding required for nodes which need alignment. The padding 965 // is the number of bytes (not instructions) which will be inserted before 966 // the instruction. The padding must match the size of a NOP instruction. 967 968 int inlineCallClearArrayNode::compute_padding(int current_offset) const { 969 int desired_padding = (2*4-current_offset)&31; // see MacroAssembler::clear_memory_doubleword 970 return (desired_padding <= 3*4) ? desired_padding : 0; 971 } 972 973 //============================================================================= 974 975 // Indicate if the safepoint node needs the polling page as an input. 976 bool SafePointNode::needs_polling_address_input() { 977 // The address is loaded from thread by a seperate node. 978 return true; 979 } 980 981 //============================================================================= 982 983 // Emit an interrupt that is caught by the debugger (for debugging compiler). 984 void emit_break(CodeBuffer &cbuf) { 985 MacroAssembler _masm(&cbuf); 986 __ illtrap(); 987 } 988 989 #ifndef PRODUCT 990 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 991 st->print("BREAKPOINT"); 992 } 993 #endif 994 995 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 996 emit_break(cbuf); 997 } 998 999 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1000 return MachNode::size(ra_); 1001 } 1002 1003 //============================================================================= 1004 1005 void emit_nop(CodeBuffer &cbuf) { 1006 MacroAssembler _masm(&cbuf); 1007 __ nop(); 1008 } 1009 1010 static inline void emit_long(CodeBuffer &cbuf, int value) { 1011 *((int*)(cbuf.insts_end())) = value; 1012 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1013 } 1014 1015 //============================================================================= 1016 1017 %} // interrupt source 1018 1019 source_hpp %{ // Header information of the source block. 1020 1021 //-------------------------------------------------------------- 1022 //---< Used for optimization in Compile::Shorten_branches >--- 1023 //-------------------------------------------------------------- 1024 1025 class CallStubImpl { 1026 1027 public: 1028 1029 // Emit call stub, compiled java to interpreter. 1030 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1031 1032 // Size of call trampoline stub. 1033 // This doesn't need to be accurate to the byte, but it 1034 // must be larger than or equal to the real size of the stub. 1035 static uint size_call_trampoline() { 1036 return MacroAssembler::trampoline_stub_size; 1037 } 1038 1039 // number of relocations needed by a call trampoline stub 1040 static uint reloc_call_trampoline() { 1041 return 5; 1042 } 1043 1044 }; 1045 1046 %} // end source_hpp 1047 1048 source %{ 1049 1050 // Emit a trampoline stub for a call to a target which is too far away. 1051 // 1052 // code sequences: 1053 // 1054 // call-site: 1055 // branch-and-link to <destination> or <trampoline stub> 1056 // 1057 // Related trampoline stub for this call-site in the stub section: 1058 // load the call target from the constant pool 1059 // branch via CTR (LR/link still points to the call-site above) 1060 1061 void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1062 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1063 if (stub == NULL) { 1064 ciEnv::current()->record_out_of_memory_failure(); 1065 } 1066 } 1067 1068 //============================================================================= 1069 1070 // Emit an inline branch-and-link call and a related trampoline stub. 1071 // 1072 // code sequences: 1073 // 1074 // call-site: 1075 // branch-and-link to <destination> or <trampoline stub> 1076 // 1077 // Related trampoline stub for this call-site in the stub section: 1078 // load the call target from the constant pool 1079 // branch via CTR (LR/link still points to the call-site above) 1080 // 1081 1082 typedef struct { 1083 int insts_call_instruction_offset; 1084 int ret_addr_offset; 1085 } EmitCallOffsets; 1086 1087 // Emit a branch-and-link instruction that branches to a trampoline. 1088 // - Remember the offset of the branch-and-link instruction. 1089 // - Add a relocation at the branch-and-link instruction. 1090 // - Emit a branch-and-link. 1091 // - Remember the return pc offset. 1092 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1093 EmitCallOffsets offsets = { -1, -1 }; 1094 const int start_offset = __ offset(); 1095 offsets.insts_call_instruction_offset = __ offset(); 1096 1097 // No entry point given, use the current pc. 1098 if (entry_point == NULL) entry_point = __ pc(); 1099 1100 // Put the entry point as a constant into the constant pool. 1101 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1102 if (entry_point_toc_addr == NULL) { 1103 ciEnv::current()->record_out_of_memory_failure(); 1104 return offsets; 1105 } 1106 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1107 1108 // Emit the trampoline stub which will be related to the branch-and-link below. 1109 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1110 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1111 __ relocate(rtype); 1112 1113 // Note: At this point we do not have the address of the trampoline 1114 // stub, and the entry point might be too far away for bl, so __ pc() 1115 // serves as dummy and the bl will be patched later. 1116 __ bl((address) __ pc()); 1117 1118 offsets.ret_addr_offset = __ offset() - start_offset; 1119 1120 return offsets; 1121 } 1122 1123 //============================================================================= 1124 1125 // Factory for creating loadConL* nodes for large/small constant pool. 1126 1127 static inline jlong replicate_immF(float con) { 1128 // Replicate float con 2 times and pack into vector. 1129 int val = *((int*)&con); 1130 jlong lval = val; 1131 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1132 return lval; 1133 } 1134 1135 //============================================================================= 1136 1137 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1138 int Compile::ConstantTable::calculate_table_base_offset() const { 1139 return 0; // absolute addressing, no offset 1140 } 1141 1142 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1143 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1144 iRegPdstOper *op_dst = new iRegPdstOper(); 1145 MachNode *m1 = new loadToc_hiNode(); 1146 MachNode *m2 = new loadToc_loNode(); 1147 1148 m1->add_req(NULL); 1149 m2->add_req(NULL, m1); 1150 m1->_opnds[0] = op_dst; 1151 m2->_opnds[0] = op_dst; 1152 m2->_opnds[1] = op_dst; 1153 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1154 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1155 nodes->push(m1); 1156 nodes->push(m2); 1157 } 1158 1159 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1160 // Is postalloc expanded. 1161 ShouldNotReachHere(); 1162 } 1163 1164 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1165 return 0; 1166 } 1167 1168 #ifndef PRODUCT 1169 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1170 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1171 } 1172 #endif 1173 1174 //============================================================================= 1175 1176 #ifndef PRODUCT 1177 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1178 Compile* C = ra_->C; 1179 const long framesize = C->frame_slots() << LogBytesPerInt; 1180 1181 st->print("PROLOG\n\t"); 1182 if (C->need_stack_bang(framesize)) { 1183 st->print("stack_overflow_check\n\t"); 1184 } 1185 1186 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1187 st->print("save return pc\n\t"); 1188 st->print("push frame %ld\n\t", -framesize); 1189 } 1190 } 1191 #endif 1192 1193 // Macro used instead of the common __ to emulate the pipes of PPC. 1194 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1195 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1196 // still no scheduling of this code is possible, the micro scheduler is aware of the 1197 // code and can update its internal data. The following mechanism is used to achieve this: 1198 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1199 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1200 #if 0 // TODO: PPC port 1201 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1202 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1203 _masm. 1204 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1205 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1206 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1207 C->hb_scheduling()->_pdScheduling->advance_offset 1208 #else 1209 #define ___(op) if (UsePower6SchedulerPPC64) \ 1210 Unimplemented(); \ 1211 _masm. 1212 #define ___stop if (UsePower6SchedulerPPC64) \ 1213 Unimplemented() 1214 #define ___advance if (UsePower6SchedulerPPC64) \ 1215 Unimplemented() 1216 #endif 1217 1218 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1219 Compile* C = ra_->C; 1220 MacroAssembler _masm(&cbuf); 1221 1222 const long framesize = C->frame_size_in_bytes(); 1223 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1224 1225 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1226 1227 const Register return_pc = R20; // Must match return_addr() in frame section. 1228 const Register callers_sp = R21; 1229 const Register push_frame_temp = R22; 1230 const Register toc_temp = R23; 1231 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1232 1233 if (method_is_frameless) { 1234 // Add nop at beginning of all frameless methods to prevent any 1235 // oop instructions from getting overwritten by make_not_entrant 1236 // (patching attempt would fail). 1237 ___(nop) nop(); 1238 } else { 1239 // Get return pc. 1240 ___(mflr) mflr(return_pc); 1241 } 1242 1243 // Calls to C2R adapters often do not accept exceptional returns. 1244 // We require that their callers must bang for them. But be 1245 // careful, because some VM calls (such as call site linkage) can 1246 // use several kilobytes of stack. But the stack safety zone should 1247 // account for that. See bugs 4446381, 4468289, 4497237. 1248 1249 int bangsize = C->bang_size_in_bytes(); 1250 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1251 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1252 // Unfortunately we cannot use the function provided in 1253 // assembler.cpp as we have to emulate the pipes. So I had to 1254 // insert the code of generate_stack_overflow_check(), see 1255 // assembler.cpp for some illuminative comments. 1256 const int page_size = os::vm_page_size(); 1257 int bang_end = JavaThread::stack_shadow_zone_size(); 1258 1259 // This is how far the previous frame's stack banging extended. 1260 const int bang_end_safe = bang_end; 1261 1262 if (bangsize > page_size) { 1263 bang_end += bangsize; 1264 } 1265 1266 int bang_offset = bang_end_safe; 1267 1268 while (bang_offset <= bang_end) { 1269 // Need at least one stack bang at end of shadow zone. 1270 1271 // Again I had to copy code, this time from assembler_ppc.cpp, 1272 // bang_stack_with_offset - see there for comments. 1273 1274 // Stack grows down, caller passes positive offset. 1275 assert(bang_offset > 0, "must bang with positive offset"); 1276 1277 long stdoffset = -bang_offset; 1278 1279 if (Assembler::is_simm(stdoffset, 16)) { 1280 // Signed 16 bit offset, a simple std is ok. 1281 if (UseLoadInstructionsForStackBangingPPC64) { 1282 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1283 } else { 1284 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1285 } 1286 } else if (Assembler::is_simm(stdoffset, 31)) { 1287 // Use largeoffset calculations for addis & ld/std. 1288 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1289 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1290 1291 Register tmp = R11; 1292 ___(addis) addis(tmp, R1_SP, hi); 1293 if (UseLoadInstructionsForStackBangingPPC64) { 1294 ___(ld) ld(R0, lo, tmp); 1295 } else { 1296 ___(std) std(R0, lo, tmp); 1297 } 1298 } else { 1299 ShouldNotReachHere(); 1300 } 1301 1302 bang_offset += page_size; 1303 } 1304 // R11 trashed 1305 } // C->need_stack_bang(framesize) && UseStackBanging 1306 1307 unsigned int bytes = (unsigned int)framesize; 1308 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1309 ciMethod *currMethod = C->method(); 1310 1311 // Optimized version for most common case. 1312 if (UsePower6SchedulerPPC64 && 1313 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1314 !(false /* ConstantsALot TODO: PPC port*/)) { 1315 ___(or) mr(callers_sp, R1_SP); 1316 ___(std) std(return_pc, _abi(lr), R1_SP); 1317 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1318 return; 1319 } 1320 1321 if (!method_is_frameless) { 1322 // Get callers sp. 1323 ___(or) mr(callers_sp, R1_SP); 1324 1325 // Push method's frame, modifies SP. 1326 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1327 // The ABI is already accounted for in 'framesize' via the 1328 // 'out_preserve' area. 1329 Register tmp = push_frame_temp; 1330 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1331 if (Assembler::is_simm(-offset, 16)) { 1332 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1333 } else { 1334 long x = -offset; 1335 // Had to insert load_const(tmp, -offset). 1336 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1337 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1338 ___(rldicr) sldi(tmp, tmp, 32); 1339 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1340 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1341 1342 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1343 } 1344 } 1345 #if 0 // TODO: PPC port 1346 // For testing large constant pools, emit a lot of constants to constant pool. 1347 // "Randomize" const_size. 1348 if (ConstantsALot) { 1349 const int num_consts = const_size(); 1350 for (int i = 0; i < num_consts; i++) { 1351 __ long_constant(0xB0B5B00BBABE); 1352 } 1353 } 1354 #endif 1355 if (!method_is_frameless) { 1356 // Save return pc. 1357 ___(std) std(return_pc, _abi(lr), callers_sp); 1358 } 1359 1360 C->set_frame_complete(cbuf.insts_size()); 1361 } 1362 #undef ___ 1363 #undef ___stop 1364 #undef ___advance 1365 1366 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1367 // Variable size. determine dynamically. 1368 return MachNode::size(ra_); 1369 } 1370 1371 int MachPrologNode::reloc() const { 1372 // Return number of relocatable values contained in this instruction. 1373 return 1; // 1 reloc entry for load_const(toc). 1374 } 1375 1376 //============================================================================= 1377 1378 #ifndef PRODUCT 1379 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1380 Compile* C = ra_->C; 1381 1382 st->print("EPILOG\n\t"); 1383 st->print("restore return pc\n\t"); 1384 st->print("pop frame\n\t"); 1385 1386 if (do_polling() && C->is_method_compilation()) { 1387 st->print("touch polling page\n\t"); 1388 } 1389 } 1390 #endif 1391 1392 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1393 Compile* C = ra_->C; 1394 MacroAssembler _masm(&cbuf); 1395 1396 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1397 assert(framesize >= 0, "negative frame-size?"); 1398 1399 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1400 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1401 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1402 const Register polling_page = R12; 1403 1404 if (!method_is_frameless) { 1405 // Restore return pc relative to callers' sp. 1406 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1407 } 1408 1409 if (method_needs_polling) { 1410 if (LoadPollAddressFromThread) { 1411 // TODO: PPC port __ ld(polling_page, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1412 Unimplemented(); 1413 } else { 1414 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); // TODO: PPC port: get_standard_polling_page() 1415 } 1416 } 1417 1418 if (!method_is_frameless) { 1419 // Move return pc to LR. 1420 __ mtlr(return_pc); 1421 // Pop frame (fixed frame-size). 1422 __ addi(R1_SP, R1_SP, (int)framesize); 1423 } 1424 1425 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1426 __ reserved_stack_check(return_pc); 1427 } 1428 1429 if (method_needs_polling) { 1430 // We need to mark the code position where the load from the safepoint 1431 // polling page was emitted as relocInfo::poll_return_type here. 1432 __ relocate(relocInfo::poll_return_type); 1433 __ load_from_polling_page(polling_page); 1434 } 1435 } 1436 1437 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1438 // Variable size. Determine dynamically. 1439 return MachNode::size(ra_); 1440 } 1441 1442 int MachEpilogNode::reloc() const { 1443 // Return number of relocatable values contained in this instruction. 1444 return 1; // 1 for load_from_polling_page. 1445 } 1446 1447 const Pipeline * MachEpilogNode::pipeline() const { 1448 return MachNode::pipeline_class(); 1449 } 1450 1451 // This method seems to be obsolete. It is declared in machnode.hpp 1452 // and defined in all *.ad files, but it is never called. Should we 1453 // get rid of it? 1454 int MachEpilogNode::safepoint_offset() const { 1455 assert(do_polling(), "no return for this epilog node"); 1456 return 0; 1457 } 1458 1459 #if 0 // TODO: PPC port 1460 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1461 MacroAssembler _masm(&cbuf); 1462 if (LoadPollAddressFromThread) { 1463 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1464 } else { 1465 _masm.nop(); 1466 } 1467 } 1468 1469 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1470 if (LoadPollAddressFromThread) { 1471 return 4; 1472 } else { 1473 return 4; 1474 } 1475 } 1476 1477 #ifndef PRODUCT 1478 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1479 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1480 } 1481 #endif 1482 1483 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1484 return RSCRATCH1_BITS64_REG_mask(); 1485 } 1486 #endif // PPC port 1487 1488 // ============================================================================= 1489 1490 // Figure out which register class each belongs in: rc_int, rc_float or 1491 // rc_stack. 1492 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1493 1494 static enum RC rc_class(OptoReg::Name reg) { 1495 // Return the register class for the given register. The given register 1496 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1497 // enumeration in adGlobals_ppc.hpp. 1498 1499 if (reg == OptoReg::Bad) return rc_bad; 1500 1501 // We have 64 integer register halves, starting at index 0. 1502 if (reg < 64) return rc_int; 1503 1504 // We have 64 floating-point register halves, starting at index 64. 1505 if (reg < 64+64) return rc_float; 1506 1507 // Between float regs & stack are the flags regs. 1508 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1509 1510 return rc_stack; 1511 } 1512 1513 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1514 bool do_print, Compile* C, outputStream *st) { 1515 1516 assert(opcode == Assembler::LD_OPCODE || 1517 opcode == Assembler::STD_OPCODE || 1518 opcode == Assembler::LWZ_OPCODE || 1519 opcode == Assembler::STW_OPCODE || 1520 opcode == Assembler::LFD_OPCODE || 1521 opcode == Assembler::STFD_OPCODE || 1522 opcode == Assembler::LFS_OPCODE || 1523 opcode == Assembler::STFS_OPCODE, 1524 "opcode not supported"); 1525 1526 if (cbuf) { 1527 int d = 1528 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1529 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1530 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1531 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1532 } 1533 #ifndef PRODUCT 1534 else if (do_print) { 1535 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1536 op_str, 1537 Matcher::regName[reg], 1538 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1539 } 1540 #endif 1541 return 4; // size 1542 } 1543 1544 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1545 Compile* C = ra_->C; 1546 1547 // Get registers to move. 1548 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1549 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1550 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1551 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1552 1553 enum RC src_hi_rc = rc_class(src_hi); 1554 enum RC src_lo_rc = rc_class(src_lo); 1555 enum RC dst_hi_rc = rc_class(dst_hi); 1556 enum RC dst_lo_rc = rc_class(dst_lo); 1557 1558 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1559 if (src_hi != OptoReg::Bad) 1560 assert((src_lo&1)==0 && src_lo+1==src_hi && 1561 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1562 "expected aligned-adjacent pairs"); 1563 // Generate spill code! 1564 int size = 0; 1565 1566 if (src_lo == dst_lo && src_hi == dst_hi) 1567 return size; // Self copy, no move. 1568 1569 // -------------------------------------- 1570 // Memory->Memory Spill. Use R0 to hold the value. 1571 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1572 int src_offset = ra_->reg2offset(src_lo); 1573 int dst_offset = ra_->reg2offset(dst_lo); 1574 if (src_hi != OptoReg::Bad) { 1575 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1576 "expected same type of move for high parts"); 1577 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1578 if (!cbuf && !do_size) st->print("\n\t"); 1579 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1580 } else { 1581 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1582 if (!cbuf && !do_size) st->print("\n\t"); 1583 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1584 } 1585 return size; 1586 } 1587 1588 // -------------------------------------- 1589 // Check for float->int copy; requires a trip through memory. 1590 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1591 Unimplemented(); 1592 } 1593 1594 // -------------------------------------- 1595 // Check for integer reg-reg copy. 1596 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1597 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1598 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1599 size = (Rsrc != Rdst) ? 4 : 0; 1600 1601 if (cbuf) { 1602 MacroAssembler _masm(cbuf); 1603 if (size) { 1604 __ mr(Rdst, Rsrc); 1605 } 1606 } 1607 #ifndef PRODUCT 1608 else if (!do_size) { 1609 if (size) { 1610 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1611 } else { 1612 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1613 } 1614 } 1615 #endif 1616 return size; 1617 } 1618 1619 // Check for integer store. 1620 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1621 int dst_offset = ra_->reg2offset(dst_lo); 1622 if (src_hi != OptoReg::Bad) { 1623 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1624 "expected same type of move for high parts"); 1625 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1626 } else { 1627 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1628 } 1629 return size; 1630 } 1631 1632 // Check for integer load. 1633 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1634 int src_offset = ra_->reg2offset(src_lo); 1635 if (src_hi != OptoReg::Bad) { 1636 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1637 "expected same type of move for high parts"); 1638 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1639 } else { 1640 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1641 } 1642 return size; 1643 } 1644 1645 // Check for float reg-reg copy. 1646 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1647 if (cbuf) { 1648 MacroAssembler _masm(cbuf); 1649 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1650 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1651 __ fmr(Rdst, Rsrc); 1652 } 1653 #ifndef PRODUCT 1654 else if (!do_size) { 1655 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1656 } 1657 #endif 1658 return 4; 1659 } 1660 1661 // Check for float store. 1662 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1663 int dst_offset = ra_->reg2offset(dst_lo); 1664 if (src_hi != OptoReg::Bad) { 1665 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1666 "expected same type of move for high parts"); 1667 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1668 } else { 1669 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1670 } 1671 return size; 1672 } 1673 1674 // Check for float load. 1675 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1676 int src_offset = ra_->reg2offset(src_lo); 1677 if (src_hi != OptoReg::Bad) { 1678 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1679 "expected same type of move for high parts"); 1680 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1681 } else { 1682 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1683 } 1684 return size; 1685 } 1686 1687 // -------------------------------------------------------------------- 1688 // Check for hi bits still needing moving. Only happens for misaligned 1689 // arguments to native calls. 1690 if (src_hi == dst_hi) 1691 return size; // Self copy; no move. 1692 1693 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1694 ShouldNotReachHere(); // Unimplemented 1695 return 0; 1696 } 1697 1698 #ifndef PRODUCT 1699 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1700 if (!ra_) 1701 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1702 else 1703 implementation(NULL, ra_, false, st); 1704 } 1705 #endif 1706 1707 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1708 implementation(&cbuf, ra_, false, NULL); 1709 } 1710 1711 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1712 return implementation(NULL, ra_, true, NULL); 1713 } 1714 1715 #if 0 // TODO: PPC port 1716 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1717 #ifndef PRODUCT 1718 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1719 #endif 1720 assert(ra_->node_regs_max_index() != 0, ""); 1721 1722 // Get registers to move. 1723 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1724 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1725 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1726 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1727 1728 enum RC src_lo_rc = rc_class(src_lo); 1729 enum RC dst_lo_rc = rc_class(dst_lo); 1730 1731 if (src_lo == dst_lo && src_hi == dst_hi) 1732 return ppc64Opcode_none; // Self copy, no move. 1733 1734 // -------------------------------------- 1735 // Memory->Memory Spill. Use R0 to hold the value. 1736 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1737 return ppc64Opcode_compound; 1738 } 1739 1740 // -------------------------------------- 1741 // Check for float->int copy; requires a trip through memory. 1742 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1743 Unimplemented(); 1744 } 1745 1746 // -------------------------------------- 1747 // Check for integer reg-reg copy. 1748 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1749 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1750 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1751 if (Rsrc == Rdst) { 1752 return ppc64Opcode_none; 1753 } else { 1754 return ppc64Opcode_or; 1755 } 1756 } 1757 1758 // Check for integer store. 1759 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1760 if (src_hi != OptoReg::Bad) { 1761 return ppc64Opcode_std; 1762 } else { 1763 return ppc64Opcode_stw; 1764 } 1765 } 1766 1767 // Check for integer load. 1768 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1769 if (src_hi != OptoReg::Bad) { 1770 return ppc64Opcode_ld; 1771 } else { 1772 return ppc64Opcode_lwz; 1773 } 1774 } 1775 1776 // Check for float reg-reg copy. 1777 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1778 return ppc64Opcode_fmr; 1779 } 1780 1781 // Check for float store. 1782 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1783 if (src_hi != OptoReg::Bad) { 1784 return ppc64Opcode_stfd; 1785 } else { 1786 return ppc64Opcode_stfs; 1787 } 1788 } 1789 1790 // Check for float load. 1791 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1792 if (src_hi != OptoReg::Bad) { 1793 return ppc64Opcode_lfd; 1794 } else { 1795 return ppc64Opcode_lfs; 1796 } 1797 } 1798 1799 // -------------------------------------------------------------------- 1800 // Check for hi bits still needing moving. Only happens for misaligned 1801 // arguments to native calls. 1802 if (src_hi == dst_hi) { 1803 return ppc64Opcode_none; // Self copy; no move. 1804 } 1805 1806 ShouldNotReachHere(); 1807 return ppc64Opcode_undefined; 1808 } 1809 #endif // PPC port 1810 1811 #ifndef PRODUCT 1812 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1813 st->print("NOP \t// %d nops to pad for loops.", _count); 1814 } 1815 #endif 1816 1817 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 1818 MacroAssembler _masm(&cbuf); 1819 // _count contains the number of nops needed for padding. 1820 for (int i = 0; i < _count; i++) { 1821 __ nop(); 1822 } 1823 } 1824 1825 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 1826 return _count * 4; 1827 } 1828 1829 #ifndef PRODUCT 1830 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1831 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1832 char reg_str[128]; 1833 ra_->dump_register(this, reg_str); 1834 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 1835 } 1836 #endif 1837 1838 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1839 MacroAssembler _masm(&cbuf); 1840 1841 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1842 int reg = ra_->get_encode(this); 1843 1844 if (Assembler::is_simm(offset, 16)) { 1845 __ addi(as_Register(reg), R1, offset); 1846 } else { 1847 ShouldNotReachHere(); 1848 } 1849 } 1850 1851 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1852 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1853 return 4; 1854 } 1855 1856 #ifndef PRODUCT 1857 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1858 st->print_cr("---- MachUEPNode ----"); 1859 st->print_cr("..."); 1860 } 1861 #endif 1862 1863 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1864 // This is the unverified entry point. 1865 MacroAssembler _masm(&cbuf); 1866 1867 // Inline_cache contains a klass. 1868 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 1869 Register receiver_klass = R12_scratch2; // tmp 1870 1871 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 1872 assert(R11_scratch1 == R11, "need prologue scratch register"); 1873 1874 // Check for NULL argument if we don't have implicit null checks. 1875 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 1876 if (TrapBasedNullChecks) { 1877 __ trap_null_check(R3_ARG1); 1878 } else { 1879 Label valid; 1880 __ cmpdi(CCR0, R3_ARG1, 0); 1881 __ bne_predict_taken(CCR0, valid); 1882 // We have a null argument, branch to ic_miss_stub. 1883 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 1884 relocInfo::runtime_call_type); 1885 __ bind(valid); 1886 } 1887 } 1888 // Assume argument is not NULL, load klass from receiver. 1889 __ load_klass(receiver_klass, R3_ARG1); 1890 1891 if (TrapBasedICMissChecks) { 1892 __ trap_ic_miss_check(receiver_klass, ic_klass); 1893 } else { 1894 Label valid; 1895 __ cmpd(CCR0, receiver_klass, ic_klass); 1896 __ beq_predict_taken(CCR0, valid); 1897 // We have an unexpected klass, branch to ic_miss_stub. 1898 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 1899 relocInfo::runtime_call_type); 1900 __ bind(valid); 1901 } 1902 1903 // Argument is valid and klass is as expected, continue. 1904 } 1905 1906 #if 0 // TODO: PPC port 1907 // Optimize UEP code on z (save a load_const() call in main path). 1908 int MachUEPNode::ep_offset() { 1909 return 0; 1910 } 1911 #endif 1912 1913 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 1914 // Variable size. Determine dynamically. 1915 return MachNode::size(ra_); 1916 } 1917 1918 //============================================================================= 1919 1920 %} // interrupt source 1921 1922 source_hpp %{ // Header information of the source block. 1923 1924 class HandlerImpl { 1925 1926 public: 1927 1928 static int emit_exception_handler(CodeBuffer &cbuf); 1929 static int emit_deopt_handler(CodeBuffer& cbuf); 1930 1931 static uint size_exception_handler() { 1932 // The exception_handler is a b64_patchable. 1933 return MacroAssembler::b64_patchable_size; 1934 } 1935 1936 static uint size_deopt_handler() { 1937 // The deopt_handler is a bl64_patchable. 1938 return MacroAssembler::bl64_patchable_size; 1939 } 1940 1941 }; 1942 1943 %} // end source_hpp 1944 1945 source %{ 1946 1947 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 1948 MacroAssembler _masm(&cbuf); 1949 1950 address base = __ start_a_stub(size_exception_handler()); 1951 if (base == NULL) return 0; // CodeBuffer::expand failed 1952 1953 int offset = __ offset(); 1954 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 1955 relocInfo::runtime_call_type); 1956 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 1957 __ end_a_stub(); 1958 1959 return offset; 1960 } 1961 1962 // The deopt_handler is like the exception handler, but it calls to 1963 // the deoptimization blob instead of jumping to the exception blob. 1964 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 1965 MacroAssembler _masm(&cbuf); 1966 1967 address base = __ start_a_stub(size_deopt_handler()); 1968 if (base == NULL) return 0; // CodeBuffer::expand failed 1969 1970 int offset = __ offset(); 1971 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 1972 relocInfo::runtime_call_type); 1973 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 1974 __ end_a_stub(); 1975 1976 return offset; 1977 } 1978 1979 //============================================================================= 1980 1981 // Use a frame slots bias for frameless methods if accessing the stack. 1982 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 1983 if (as_Register(reg_enc) == R1_SP) { 1984 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 1985 } 1986 return 0; 1987 } 1988 1989 const bool Matcher::match_rule_supported(int opcode) { 1990 if (!has_match_rule(opcode)) 1991 return false; 1992 1993 switch (opcode) { 1994 case Op_SqrtD: 1995 return VM_Version::has_fsqrt(); 1996 case Op_CountLeadingZerosI: 1997 case Op_CountLeadingZerosL: 1998 case Op_CountTrailingZerosI: 1999 case Op_CountTrailingZerosL: 2000 if (!UseCountLeadingZerosInstructionsPPC64) 2001 return false; 2002 break; 2003 2004 case Op_PopCountI: 2005 case Op_PopCountL: 2006 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2007 2008 case Op_StrComp: 2009 return SpecialStringCompareTo; 2010 case Op_StrEquals: 2011 return SpecialStringEquals; 2012 case Op_StrIndexOf: 2013 return SpecialStringIndexOf; 2014 case Op_StrIndexOfChar: 2015 return SpecialStringIndexOf; 2016 } 2017 2018 return true; // Per default match rules are supported. 2019 } 2020 2021 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2022 2023 // TODO 2024 // identify extra cases that we might want to provide match rules for 2025 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2026 bool ret_value = match_rule_supported(opcode); 2027 // Add rules here. 2028 2029 return ret_value; // Per default match rules are supported. 2030 } 2031 2032 const bool Matcher::has_predicated_vectors(void) { 2033 return false; 2034 } 2035 2036 const int Matcher::float_pressure(int default_pressure_threshold) { 2037 return default_pressure_threshold; 2038 } 2039 2040 int Matcher::regnum_to_fpu_offset(int regnum) { 2041 // No user for this method? 2042 Unimplemented(); 2043 return 999; 2044 } 2045 2046 const bool Matcher::convL2FSupported(void) { 2047 // fcfids can do the conversion (>= Power7). 2048 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2049 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2050 } 2051 2052 // Vector width in bytes. 2053 const int Matcher::vector_width_in_bytes(BasicType bt) { 2054 assert(MaxVectorSize == 8, ""); 2055 return 8; 2056 } 2057 2058 // Vector ideal reg. 2059 const int Matcher::vector_ideal_reg(int size) { 2060 assert(MaxVectorSize == 8 && size == 8, ""); 2061 return Op_RegL; 2062 } 2063 2064 const int Matcher::vector_shift_count_ideal_reg(int size) { 2065 fatal("vector shift is not supported"); 2066 return Node::NotAMachineReg; 2067 } 2068 2069 // Limits on vector size (number of elements) loaded into vector. 2070 const int Matcher::max_vector_size(const BasicType bt) { 2071 assert(is_java_primitive(bt), "only primitive type vectors"); 2072 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2073 } 2074 2075 const int Matcher::min_vector_size(const BasicType bt) { 2076 return max_vector_size(bt); // Same as max. 2077 } 2078 2079 // PPC doesn't support misaligned vectors store/load. 2080 const bool Matcher::misaligned_vectors_ok() { 2081 return false; 2082 } 2083 2084 // PPC AES support not yet implemented 2085 const bool Matcher::pass_original_key_for_aes() { 2086 return false; 2087 } 2088 2089 // RETURNS: whether this branch offset is short enough that a short 2090 // branch can be used. 2091 // 2092 // If the platform does not provide any short branch variants, then 2093 // this method should return `false' for offset 0. 2094 // 2095 // `Compile::Fill_buffer' will decide on basis of this information 2096 // whether to do the pass `Compile::Shorten_branches' at all. 2097 // 2098 // And `Compile::Shorten_branches' will decide on basis of this 2099 // information whether to replace particular branch sites by short 2100 // ones. 2101 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2102 // Is the offset within the range of a ppc64 pc relative branch? 2103 bool b; 2104 2105 const int safety_zone = 3 * BytesPerInstWord; 2106 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2107 29 - 16 + 1 + 2); 2108 return b; 2109 } 2110 2111 const bool Matcher::isSimpleConstant64(jlong value) { 2112 // Probably always true, even if a temp register is required. 2113 return true; 2114 } 2115 /* TODO: PPC port 2116 // Make a new machine dependent decode node (with its operands). 2117 MachTypeNode *Matcher::make_decode_node() { 2118 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2119 "This method is only implemented for unscaled cOops mode so far"); 2120 MachTypeNode *decode = new decodeN_unscaledNode(); 2121 decode->set_opnd_array(0, new iRegPdstOper()); 2122 decode->set_opnd_array(1, new iRegNsrcOper()); 2123 return decode; 2124 } 2125 */ 2126 2127 // false => size gets scaled to BytesPerLong, ok. 2128 const bool Matcher::init_array_count_is_in_bytes = false; 2129 2130 // Use conditional move (CMOVL) on Power7. 2131 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2132 2133 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2134 // fsel doesn't accept a condition register as input, so this would be slightly different. 2135 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2136 2137 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2138 const bool Matcher::require_postalloc_expand = true; 2139 2140 // Do we need to mask the count passed to shift instructions or does 2141 // the cpu only look at the lower 5/6 bits anyway? 2142 // PowerPC requires masked shift counts. 2143 const bool Matcher::need_masked_shift_count = true; 2144 2145 // This affects two different things: 2146 // - how Decode nodes are matched 2147 // - how ImplicitNullCheck opportunities are recognized 2148 // If true, the matcher will try to remove all Decodes and match them 2149 // (as operands) into nodes. NullChecks are not prepared to deal with 2150 // Decodes by final_graph_reshaping(). 2151 // If false, final_graph_reshaping() forces the decode behind the Cmp 2152 // for a NullCheck. The matcher matches the Decode node into a register. 2153 // Implicit_null_check optimization moves the Decode along with the 2154 // memory operation back up before the NullCheck. 2155 bool Matcher::narrow_oop_use_complex_address() { 2156 // TODO: PPC port if (MatchDecodeNodes) return true; 2157 return false; 2158 } 2159 2160 bool Matcher::narrow_klass_use_complex_address() { 2161 NOT_LP64(ShouldNotCallThis()); 2162 assert(UseCompressedClassPointers, "only for compressed klass code"); 2163 // TODO: PPC port if (MatchDecodeNodes) return true; 2164 return false; 2165 } 2166 2167 bool Matcher::const_oop_prefer_decode() { 2168 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2169 return Universe::narrow_oop_base() == NULL; 2170 } 2171 2172 bool Matcher::const_klass_prefer_decode() { 2173 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2174 return Universe::narrow_klass_base() == NULL; 2175 } 2176 2177 // Is it better to copy float constants, or load them directly from memory? 2178 // Intel can load a float constant from a direct address, requiring no 2179 // extra registers. Most RISCs will have to materialize an address into a 2180 // register first, so they would do better to copy the constant from stack. 2181 const bool Matcher::rematerialize_float_constants = false; 2182 2183 // If CPU can load and store mis-aligned doubles directly then no fixup is 2184 // needed. Else we split the double into 2 integer pieces and move it 2185 // piece-by-piece. Only happens when passing doubles into C code as the 2186 // Java calling convention forces doubles to be aligned. 2187 const bool Matcher::misaligned_doubles_ok = true; 2188 2189 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2190 Unimplemented(); 2191 } 2192 2193 // Advertise here if the CPU requires explicit rounding operations 2194 // to implement the UseStrictFP mode. 2195 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2196 2197 // Do floats take an entire double register or just half? 2198 // 2199 // A float occupies a ppc64 double register. For the allocator, a 2200 // ppc64 double register appears as a pair of float registers. 2201 bool Matcher::float_in_double() { return true; } 2202 2203 // Do ints take an entire long register or just half? 2204 // The relevant question is how the int is callee-saved: 2205 // the whole long is written but de-opt'ing will have to extract 2206 // the relevant 32 bits. 2207 const bool Matcher::int_in_long = true; 2208 2209 // Constants for c2c and c calling conventions. 2210 2211 const MachRegisterNumbers iarg_reg[8] = { 2212 R3_num, R4_num, R5_num, R6_num, 2213 R7_num, R8_num, R9_num, R10_num 2214 }; 2215 2216 const MachRegisterNumbers farg_reg[13] = { 2217 F1_num, F2_num, F3_num, F4_num, 2218 F5_num, F6_num, F7_num, F8_num, 2219 F9_num, F10_num, F11_num, F12_num, 2220 F13_num 2221 }; 2222 2223 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2224 2225 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2226 2227 // Return whether or not this register is ever used as an argument. This 2228 // function is used on startup to build the trampoline stubs in generateOptoStub. 2229 // Registers not mentioned will be killed by the VM call in the trampoline, and 2230 // arguments in those registers not be available to the callee. 2231 bool Matcher::can_be_java_arg(int reg) { 2232 // We return true for all registers contained in iarg_reg[] and 2233 // farg_reg[] and their virtual halves. 2234 // We must include the virtual halves in order to get STDs and LDs 2235 // instead of STWs and LWs in the trampoline stubs. 2236 2237 if ( reg == R3_num || reg == R3_H_num 2238 || reg == R4_num || reg == R4_H_num 2239 || reg == R5_num || reg == R5_H_num 2240 || reg == R6_num || reg == R6_H_num 2241 || reg == R7_num || reg == R7_H_num 2242 || reg == R8_num || reg == R8_H_num 2243 || reg == R9_num || reg == R9_H_num 2244 || reg == R10_num || reg == R10_H_num) 2245 return true; 2246 2247 if ( reg == F1_num || reg == F1_H_num 2248 || reg == F2_num || reg == F2_H_num 2249 || reg == F3_num || reg == F3_H_num 2250 || reg == F4_num || reg == F4_H_num 2251 || reg == F5_num || reg == F5_H_num 2252 || reg == F6_num || reg == F6_H_num 2253 || reg == F7_num || reg == F7_H_num 2254 || reg == F8_num || reg == F8_H_num 2255 || reg == F9_num || reg == F9_H_num 2256 || reg == F10_num || reg == F10_H_num 2257 || reg == F11_num || reg == F11_H_num 2258 || reg == F12_num || reg == F12_H_num 2259 || reg == F13_num || reg == F13_H_num) 2260 return true; 2261 2262 return false; 2263 } 2264 2265 bool Matcher::is_spillable_arg(int reg) { 2266 return can_be_java_arg(reg); 2267 } 2268 2269 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2270 return false; 2271 } 2272 2273 // Register for DIVI projection of divmodI. 2274 RegMask Matcher::divI_proj_mask() { 2275 ShouldNotReachHere(); 2276 return RegMask(); 2277 } 2278 2279 // Register for MODI projection of divmodI. 2280 RegMask Matcher::modI_proj_mask() { 2281 ShouldNotReachHere(); 2282 return RegMask(); 2283 } 2284 2285 // Register for DIVL projection of divmodL. 2286 RegMask Matcher::divL_proj_mask() { 2287 ShouldNotReachHere(); 2288 return RegMask(); 2289 } 2290 2291 // Register for MODL projection of divmodL. 2292 RegMask Matcher::modL_proj_mask() { 2293 ShouldNotReachHere(); 2294 return RegMask(); 2295 } 2296 2297 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2298 return RegMask(); 2299 } 2300 2301 const bool Matcher::convi2l_type_required = true; 2302 2303 %} 2304 2305 //----------ENCODING BLOCK----------------------------------------------------- 2306 // This block specifies the encoding classes used by the compiler to output 2307 // byte streams. Encoding classes are parameterized macros used by 2308 // Machine Instruction Nodes in order to generate the bit encoding of the 2309 // instruction. Operands specify their base encoding interface with the 2310 // interface keyword. There are currently supported four interfaces, 2311 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2312 // operand to generate a function which returns its register number when 2313 // queried. CONST_INTER causes an operand to generate a function which 2314 // returns the value of the constant when queried. MEMORY_INTER causes an 2315 // operand to generate four functions which return the Base Register, the 2316 // Index Register, the Scale Value, and the Offset Value of the operand when 2317 // queried. COND_INTER causes an operand to generate six functions which 2318 // return the encoding code (ie - encoding bits for the instruction) 2319 // associated with each basic boolean condition for a conditional instruction. 2320 // 2321 // Instructions specify two basic values for encoding. Again, a function 2322 // is available to check if the constant displacement is an oop. They use the 2323 // ins_encode keyword to specify their encoding classes (which must be 2324 // a sequence of enc_class names, and their parameters, specified in 2325 // the encoding block), and they use the 2326 // opcode keyword to specify, in order, their primary, secondary, and 2327 // tertiary opcode. Only the opcode sections which a particular instruction 2328 // needs for encoding need to be specified. 2329 encode %{ 2330 enc_class enc_unimplemented %{ 2331 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2332 MacroAssembler _masm(&cbuf); 2333 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2334 %} 2335 2336 enc_class enc_untested %{ 2337 #ifdef ASSERT 2338 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2339 MacroAssembler _masm(&cbuf); 2340 __ untested("Untested mach node encoding in AD file."); 2341 #else 2342 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2343 #endif 2344 %} 2345 2346 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2347 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2348 MacroAssembler _masm(&cbuf); 2349 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2350 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2351 %} 2352 2353 // Load acquire. 2354 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2355 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2356 MacroAssembler _masm(&cbuf); 2357 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2358 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2359 __ twi_0($dst$$Register); 2360 __ isync(); 2361 %} 2362 2363 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2364 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2365 2366 MacroAssembler _masm(&cbuf); 2367 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2368 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2369 %} 2370 2371 // Load acquire. 2372 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2373 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2374 2375 MacroAssembler _masm(&cbuf); 2376 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2377 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2378 __ twi_0($dst$$Register); 2379 __ isync(); 2380 %} 2381 2382 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2383 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2384 2385 MacroAssembler _masm(&cbuf); 2386 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2387 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2388 %} 2389 2390 // Load acquire. 2391 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2392 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2393 2394 MacroAssembler _masm(&cbuf); 2395 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2396 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2397 __ twi_0($dst$$Register); 2398 __ isync(); 2399 %} 2400 2401 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2402 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2403 MacroAssembler _masm(&cbuf); 2404 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2405 // Operand 'ds' requires 4-alignment. 2406 assert((Idisp & 0x3) == 0, "unaligned offset"); 2407 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2408 %} 2409 2410 // Load acquire. 2411 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2412 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2413 MacroAssembler _masm(&cbuf); 2414 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2415 // Operand 'ds' requires 4-alignment. 2416 assert((Idisp & 0x3) == 0, "unaligned offset"); 2417 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2418 __ twi_0($dst$$Register); 2419 __ isync(); 2420 %} 2421 2422 enc_class enc_lfd(RegF dst, memory mem) %{ 2423 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2424 MacroAssembler _masm(&cbuf); 2425 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2426 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2427 %} 2428 2429 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2430 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2431 2432 MacroAssembler _masm(&cbuf); 2433 int toc_offset = 0; 2434 2435 address const_toc_addr; 2436 // Create a non-oop constant, no relocation needed. 2437 // If it is an IC, it has a virtual_call_Relocation. 2438 const_toc_addr = __ long_constant((jlong)$src$$constant); 2439 if (const_toc_addr == NULL) { 2440 ciEnv::current()->record_out_of_memory_failure(); 2441 return; 2442 } 2443 2444 // Get the constant's TOC offset. 2445 toc_offset = __ offset_to_method_toc(const_toc_addr); 2446 2447 // Keep the current instruction offset in mind. 2448 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2449 2450 __ ld($dst$$Register, toc_offset, $toc$$Register); 2451 %} 2452 2453 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2454 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2455 2456 MacroAssembler _masm(&cbuf); 2457 2458 if (!ra_->C->in_scratch_emit_size()) { 2459 address const_toc_addr; 2460 // Create a non-oop constant, no relocation needed. 2461 // If it is an IC, it has a virtual_call_Relocation. 2462 const_toc_addr = __ long_constant((jlong)$src$$constant); 2463 if (const_toc_addr == NULL) { 2464 ciEnv::current()->record_out_of_memory_failure(); 2465 return; 2466 } 2467 2468 // Get the constant's TOC offset. 2469 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2470 // Store the toc offset of the constant. 2471 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2472 2473 // Also keep the current instruction offset in mind. 2474 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2475 } 2476 2477 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2478 %} 2479 2480 %} // encode 2481 2482 source %{ 2483 2484 typedef struct { 2485 loadConL_hiNode *_large_hi; 2486 loadConL_loNode *_large_lo; 2487 loadConLNode *_small; 2488 MachNode *_last; 2489 } loadConLNodesTuple; 2490 2491 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2492 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2493 loadConLNodesTuple nodes; 2494 2495 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2496 if (large_constant_pool) { 2497 // Create new nodes. 2498 loadConL_hiNode *m1 = new loadConL_hiNode(); 2499 loadConL_loNode *m2 = new loadConL_loNode(); 2500 2501 // inputs for new nodes 2502 m1->add_req(NULL, toc); 2503 m2->add_req(NULL, m1); 2504 2505 // operands for new nodes 2506 m1->_opnds[0] = new iRegLdstOper(); // dst 2507 m1->_opnds[1] = immSrc; // src 2508 m1->_opnds[2] = new iRegPdstOper(); // toc 2509 m2->_opnds[0] = new iRegLdstOper(); // dst 2510 m2->_opnds[1] = immSrc; // src 2511 m2->_opnds[2] = new iRegLdstOper(); // base 2512 2513 // Initialize ins_attrib TOC fields. 2514 m1->_const_toc_offset = -1; 2515 m2->_const_toc_offset_hi_node = m1; 2516 2517 // Initialize ins_attrib instruction offset. 2518 m1->_cbuf_insts_offset = -1; 2519 2520 // register allocation for new nodes 2521 ra_->set_pair(m1->_idx, reg_second, reg_first); 2522 ra_->set_pair(m2->_idx, reg_second, reg_first); 2523 2524 // Create result. 2525 nodes._large_hi = m1; 2526 nodes._large_lo = m2; 2527 nodes._small = NULL; 2528 nodes._last = nodes._large_lo; 2529 assert(m2->bottom_type()->isa_long(), "must be long"); 2530 } else { 2531 loadConLNode *m2 = new loadConLNode(); 2532 2533 // inputs for new nodes 2534 m2->add_req(NULL, toc); 2535 2536 // operands for new nodes 2537 m2->_opnds[0] = new iRegLdstOper(); // dst 2538 m2->_opnds[1] = immSrc; // src 2539 m2->_opnds[2] = new iRegPdstOper(); // toc 2540 2541 // Initialize ins_attrib instruction offset. 2542 m2->_cbuf_insts_offset = -1; 2543 2544 // register allocation for new nodes 2545 ra_->set_pair(m2->_idx, reg_second, reg_first); 2546 2547 // Create result. 2548 nodes._large_hi = NULL; 2549 nodes._large_lo = NULL; 2550 nodes._small = m2; 2551 nodes._last = nodes._small; 2552 assert(m2->bottom_type()->isa_long(), "must be long"); 2553 } 2554 2555 return nodes; 2556 } 2557 2558 %} // source 2559 2560 encode %{ 2561 // Postalloc expand emitter for loading a long constant from the method's TOC. 2562 // Enc_class needed as consttanttablebase is not supported by postalloc 2563 // expand. 2564 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2565 // Create new nodes. 2566 loadConLNodesTuple loadConLNodes = 2567 loadConLNodesTuple_create(ra_, n_toc, op_src, 2568 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2569 2570 // Push new nodes. 2571 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2572 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2573 2574 // some asserts 2575 assert(nodes->length() >= 1, "must have created at least 1 node"); 2576 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2577 %} 2578 2579 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2580 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2581 2582 MacroAssembler _masm(&cbuf); 2583 int toc_offset = 0; 2584 2585 intptr_t val = $src$$constant; 2586 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2587 address const_toc_addr; 2588 if (constant_reloc == relocInfo::oop_type) { 2589 // Create an oop constant and a corresponding relocation. 2590 AddressLiteral a = __ allocate_oop_address((jobject)val); 2591 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2592 __ relocate(a.rspec()); 2593 } else if (constant_reloc == relocInfo::metadata_type) { 2594 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2595 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2596 __ relocate(a.rspec()); 2597 } else { 2598 // Create a non-oop constant, no relocation needed. 2599 const_toc_addr = __ long_constant((jlong)$src$$constant); 2600 } 2601 2602 if (const_toc_addr == NULL) { 2603 ciEnv::current()->record_out_of_memory_failure(); 2604 return; 2605 } 2606 // Get the constant's TOC offset. 2607 toc_offset = __ offset_to_method_toc(const_toc_addr); 2608 2609 __ ld($dst$$Register, toc_offset, $toc$$Register); 2610 %} 2611 2612 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2613 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2614 2615 MacroAssembler _masm(&cbuf); 2616 if (!ra_->C->in_scratch_emit_size()) { 2617 intptr_t val = $src$$constant; 2618 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2619 address const_toc_addr; 2620 if (constant_reloc == relocInfo::oop_type) { 2621 // Create an oop constant and a corresponding relocation. 2622 AddressLiteral a = __ allocate_oop_address((jobject)val); 2623 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2624 __ relocate(a.rspec()); 2625 } else if (constant_reloc == relocInfo::metadata_type) { 2626 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2627 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2628 __ relocate(a.rspec()); 2629 } else { // non-oop pointers, e.g. card mark base, heap top 2630 // Create a non-oop constant, no relocation needed. 2631 const_toc_addr = __ long_constant((jlong)$src$$constant); 2632 } 2633 2634 if (const_toc_addr == NULL) { 2635 ciEnv::current()->record_out_of_memory_failure(); 2636 return; 2637 } 2638 // Get the constant's TOC offset. 2639 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2640 // Store the toc offset of the constant. 2641 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 2642 } 2643 2644 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2645 %} 2646 2647 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 2648 // Enc_class needed as consttanttablebase is not supported by postalloc 2649 // expand. 2650 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 2651 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2652 if (large_constant_pool) { 2653 // Create new nodes. 2654 loadConP_hiNode *m1 = new loadConP_hiNode(); 2655 loadConP_loNode *m2 = new loadConP_loNode(); 2656 2657 // inputs for new nodes 2658 m1->add_req(NULL, n_toc); 2659 m2->add_req(NULL, m1); 2660 2661 // operands for new nodes 2662 m1->_opnds[0] = new iRegPdstOper(); // dst 2663 m1->_opnds[1] = op_src; // src 2664 m1->_opnds[2] = new iRegPdstOper(); // toc 2665 m2->_opnds[0] = new iRegPdstOper(); // dst 2666 m2->_opnds[1] = op_src; // src 2667 m2->_opnds[2] = new iRegLdstOper(); // base 2668 2669 // Initialize ins_attrib TOC fields. 2670 m1->_const_toc_offset = -1; 2671 m2->_const_toc_offset_hi_node = m1; 2672 2673 // Register allocation for new nodes. 2674 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2675 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2676 2677 nodes->push(m1); 2678 nodes->push(m2); 2679 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2680 } else { 2681 loadConPNode *m2 = new loadConPNode(); 2682 2683 // inputs for new nodes 2684 m2->add_req(NULL, n_toc); 2685 2686 // operands for new nodes 2687 m2->_opnds[0] = new iRegPdstOper(); // dst 2688 m2->_opnds[1] = op_src; // src 2689 m2->_opnds[2] = new iRegPdstOper(); // toc 2690 2691 // Register allocation for new nodes. 2692 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2693 2694 nodes->push(m2); 2695 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2696 } 2697 %} 2698 2699 // Enc_class needed as consttanttablebase is not supported by postalloc 2700 // expand. 2701 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 2702 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2703 2704 MachNode *m2; 2705 if (large_constant_pool) { 2706 m2 = new loadConFCompNode(); 2707 } else { 2708 m2 = new loadConFNode(); 2709 } 2710 // inputs for new nodes 2711 m2->add_req(NULL, n_toc); 2712 2713 // operands for new nodes 2714 m2->_opnds[0] = op_dst; 2715 m2->_opnds[1] = op_src; 2716 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2717 2718 // register allocation for new nodes 2719 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2720 nodes->push(m2); 2721 %} 2722 2723 // Enc_class needed as consttanttablebase is not supported by postalloc 2724 // expand. 2725 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 2726 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2727 2728 MachNode *m2; 2729 if (large_constant_pool) { 2730 m2 = new loadConDCompNode(); 2731 } else { 2732 m2 = new loadConDNode(); 2733 } 2734 // inputs for new nodes 2735 m2->add_req(NULL, n_toc); 2736 2737 // operands for new nodes 2738 m2->_opnds[0] = op_dst; 2739 m2->_opnds[1] = op_src; 2740 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2741 2742 // register allocation for new nodes 2743 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2744 nodes->push(m2); 2745 %} 2746 2747 enc_class enc_stw(iRegIsrc src, memory mem) %{ 2748 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 2749 MacroAssembler _masm(&cbuf); 2750 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2751 __ stw($src$$Register, Idisp, $mem$$base$$Register); 2752 %} 2753 2754 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 2755 // TODO: PPC port $archOpcode(ppc64Opcode_std); 2756 MacroAssembler _masm(&cbuf); 2757 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2758 // Operand 'ds' requires 4-alignment. 2759 assert((Idisp & 0x3) == 0, "unaligned offset"); 2760 __ std($src$$Register, Idisp, $mem$$base$$Register); 2761 %} 2762 2763 enc_class enc_stfs(RegF src, memory mem) %{ 2764 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 2765 MacroAssembler _masm(&cbuf); 2766 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2767 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 2768 %} 2769 2770 enc_class enc_stfd(RegF src, memory mem) %{ 2771 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 2772 MacroAssembler _masm(&cbuf); 2773 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2774 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 2775 %} 2776 2777 // Use release_store for card-marking to ensure that previous 2778 // oop-stores are visible before the card-mark change. 2779 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 2780 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2781 // FIXME: Implement this as a cmove and use a fixed condition code 2782 // register which is written on every transition to compiled code, 2783 // e.g. in call-stub and when returning from runtime stubs. 2784 // 2785 // Proposed code sequence for the cmove implementation: 2786 // 2787 // Label skip_release; 2788 // __ beq(CCRfixed, skip_release); 2789 // __ release(); 2790 // __ bind(skip_release); 2791 // __ stb(card mark); 2792 2793 MacroAssembler _masm(&cbuf); 2794 Label skip_storestore; 2795 2796 #if 0 // TODO: PPC port 2797 // Check CMSCollectorCardTableModRefBSExt::_requires_release and do the 2798 // StoreStore barrier conditionally. 2799 __ lwz(R0, 0, $releaseFieldAddr$$Register); 2800 __ cmpwi($crx$$CondRegister, R0, 0); 2801 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 2802 #endif 2803 __ li(R0, 0); 2804 __ membar(Assembler::StoreStore); 2805 #if 0 // TODO: PPC port 2806 __ bind(skip_storestore); 2807 #endif 2808 2809 // Do the store. 2810 if ($mem$$index == 0) { 2811 __ stb(R0, $mem$$disp, $mem$$base$$Register); 2812 } else { 2813 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 2814 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 2815 } 2816 %} 2817 2818 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 2819 2820 if (VM_Version::has_isel()) { 2821 // use isel instruction with Power 7 2822 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2823 encodeP_subNode *n_sub_base = new encodeP_subNode(); 2824 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2825 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 2826 2827 n_compare->add_req(n_region, n_src); 2828 n_compare->_opnds[0] = op_crx; 2829 n_compare->_opnds[1] = op_src; 2830 n_compare->_opnds[2] = new immL16Oper(0); 2831 2832 n_sub_base->add_req(n_region, n_src); 2833 n_sub_base->_opnds[0] = op_dst; 2834 n_sub_base->_opnds[1] = op_src; 2835 n_sub_base->_bottom_type = _bottom_type; 2836 2837 n_shift->add_req(n_region, n_sub_base); 2838 n_shift->_opnds[0] = op_dst; 2839 n_shift->_opnds[1] = op_dst; 2840 n_shift->_bottom_type = _bottom_type; 2841 2842 n_cond_set->add_req(n_region, n_compare, n_shift); 2843 n_cond_set->_opnds[0] = op_dst; 2844 n_cond_set->_opnds[1] = op_crx; 2845 n_cond_set->_opnds[2] = op_dst; 2846 n_cond_set->_bottom_type = _bottom_type; 2847 2848 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2849 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2850 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2851 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2852 2853 nodes->push(n_compare); 2854 nodes->push(n_sub_base); 2855 nodes->push(n_shift); 2856 nodes->push(n_cond_set); 2857 2858 } else { 2859 // before Power 7 2860 moveRegNode *n_move = new moveRegNode(); 2861 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2862 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2863 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 2864 2865 n_move->add_req(n_region, n_src); 2866 n_move->_opnds[0] = op_dst; 2867 n_move->_opnds[1] = op_src; 2868 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 2869 2870 n_compare->add_req(n_region, n_src); 2871 n_compare->add_prec(n_move); 2872 2873 n_compare->_opnds[0] = op_crx; 2874 n_compare->_opnds[1] = op_src; 2875 n_compare->_opnds[2] = new immL16Oper(0); 2876 2877 n_sub_base->add_req(n_region, n_compare, n_src); 2878 n_sub_base->_opnds[0] = op_dst; 2879 n_sub_base->_opnds[1] = op_crx; 2880 n_sub_base->_opnds[2] = op_src; 2881 n_sub_base->_bottom_type = _bottom_type; 2882 2883 n_shift->add_req(n_region, n_sub_base); 2884 n_shift->_opnds[0] = op_dst; 2885 n_shift->_opnds[1] = op_dst; 2886 n_shift->_bottom_type = _bottom_type; 2887 2888 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2889 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2890 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2891 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2892 2893 nodes->push(n_move); 2894 nodes->push(n_compare); 2895 nodes->push(n_sub_base); 2896 nodes->push(n_shift); 2897 } 2898 2899 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 2900 %} 2901 2902 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 2903 2904 encodeP_subNode *n1 = new encodeP_subNode(); 2905 n1->add_req(n_region, n_src); 2906 n1->_opnds[0] = op_dst; 2907 n1->_opnds[1] = op_src; 2908 n1->_bottom_type = _bottom_type; 2909 2910 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 2911 n2->add_req(n_region, n1); 2912 n2->_opnds[0] = op_dst; 2913 n2->_opnds[1] = op_dst; 2914 n2->_bottom_type = _bottom_type; 2915 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2916 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2917 2918 nodes->push(n1); 2919 nodes->push(n2); 2920 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 2921 %} 2922 2923 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 2924 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 2925 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 2926 2927 n_compare->add_req(n_region, n_src); 2928 n_compare->_opnds[0] = op_crx; 2929 n_compare->_opnds[1] = op_src; 2930 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 2931 2932 n_shift->add_req(n_region, n_src); 2933 n_shift->_opnds[0] = op_dst; 2934 n_shift->_opnds[1] = op_src; 2935 n_shift->_bottom_type = _bottom_type; 2936 2937 if (VM_Version::has_isel()) { 2938 // use isel instruction with Power 7 2939 2940 decodeN_addNode *n_add_base = new decodeN_addNode(); 2941 n_add_base->add_req(n_region, n_shift); 2942 n_add_base->_opnds[0] = op_dst; 2943 n_add_base->_opnds[1] = op_dst; 2944 n_add_base->_bottom_type = _bottom_type; 2945 2946 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 2947 n_cond_set->add_req(n_region, n_compare, n_add_base); 2948 n_cond_set->_opnds[0] = op_dst; 2949 n_cond_set->_opnds[1] = op_crx; 2950 n_cond_set->_opnds[2] = op_dst; 2951 n_cond_set->_bottom_type = _bottom_type; 2952 2953 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 2954 ra_->set_oop(n_cond_set, true); 2955 2956 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2957 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2958 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2959 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2960 2961 nodes->push(n_compare); 2962 nodes->push(n_shift); 2963 nodes->push(n_add_base); 2964 nodes->push(n_cond_set); 2965 2966 } else { 2967 // before Power 7 2968 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 2969 2970 n_add_base->add_req(n_region, n_compare, n_shift); 2971 n_add_base->_opnds[0] = op_dst; 2972 n_add_base->_opnds[1] = op_crx; 2973 n_add_base->_opnds[2] = op_dst; 2974 n_add_base->_bottom_type = _bottom_type; 2975 2976 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 2977 ra_->set_oop(n_add_base, true); 2978 2979 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2980 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2981 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2982 2983 nodes->push(n_compare); 2984 nodes->push(n_shift); 2985 nodes->push(n_add_base); 2986 } 2987 %} 2988 2989 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 2990 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 2991 n1->add_req(n_region, n_src); 2992 n1->_opnds[0] = op_dst; 2993 n1->_opnds[1] = op_src; 2994 n1->_bottom_type = _bottom_type; 2995 2996 decodeN_addNode *n2 = new decodeN_addNode(); 2997 n2->add_req(n_region, n1); 2998 n2->_opnds[0] = op_dst; 2999 n2->_opnds[1] = op_dst; 3000 n2->_bottom_type = _bottom_type; 3001 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3002 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3003 3004 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3005 ra_->set_oop(n2, true); 3006 3007 nodes->push(n1); 3008 nodes->push(n2); 3009 %} 3010 3011 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3012 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3013 3014 MacroAssembler _masm(&cbuf); 3015 int cc = $cmp$$cmpcode; 3016 int flags_reg = $crx$$reg; 3017 Label done; 3018 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3019 // Branch if not (cmp crx). 3020 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3021 __ mr($dst$$Register, $src$$Register); 3022 // TODO PPC port __ endgroup_if_needed(_size == 12); 3023 __ bind(done); 3024 %} 3025 3026 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3027 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3028 3029 MacroAssembler _masm(&cbuf); 3030 Label done; 3031 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3032 // Branch if not (cmp crx). 3033 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3034 __ li($dst$$Register, $src$$constant); 3035 // TODO PPC port __ endgroup_if_needed(_size == 12); 3036 __ bind(done); 3037 %} 3038 3039 // This enc_class is needed so that scheduler gets proper 3040 // input mapping for latency computation. 3041 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3042 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3043 MacroAssembler _masm(&cbuf); 3044 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3045 %} 3046 3047 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3048 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3049 3050 MacroAssembler _masm(&cbuf); 3051 3052 Label done; 3053 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3054 __ li($dst$$Register, $zero$$constant); 3055 __ beq($crx$$CondRegister, done); 3056 __ li($dst$$Register, $notzero$$constant); 3057 __ bind(done); 3058 %} 3059 3060 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3061 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3062 3063 MacroAssembler _masm(&cbuf); 3064 3065 Label done; 3066 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3067 __ li($dst$$Register, $zero$$constant); 3068 __ beq($crx$$CondRegister, done); 3069 __ li($dst$$Register, $notzero$$constant); 3070 __ bind(done); 3071 %} 3072 3073 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3074 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3075 3076 MacroAssembler _masm(&cbuf); 3077 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3078 Label done; 3079 __ bso($crx$$CondRegister, done); 3080 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3081 // TODO PPC port __ endgroup_if_needed(_size == 12); 3082 __ bind(done); 3083 %} 3084 3085 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3086 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3087 3088 MacroAssembler _masm(&cbuf); 3089 Label d; // dummy 3090 __ bind(d); 3091 Label* p = ($lbl$$label); 3092 // `p' is `NULL' when this encoding class is used only to 3093 // determine the size of the encoded instruction. 3094 Label& l = (NULL == p)? d : *(p); 3095 int cc = $cmp$$cmpcode; 3096 int flags_reg = $crx$$reg; 3097 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3098 int bhint = Assembler::bhintNoHint; 3099 3100 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3101 if (_prob <= PROB_NEVER) { 3102 bhint = Assembler::bhintIsNotTaken; 3103 } else if (_prob >= PROB_ALWAYS) { 3104 bhint = Assembler::bhintIsTaken; 3105 } 3106 } 3107 3108 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3109 cc_to_biint(cc, flags_reg), 3110 l); 3111 %} 3112 3113 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3114 // The scheduler doesn't know about branch shortening, so we set the opcode 3115 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3116 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3117 3118 MacroAssembler _masm(&cbuf); 3119 Label d; // dummy 3120 __ bind(d); 3121 Label* p = ($lbl$$label); 3122 // `p' is `NULL' when this encoding class is used only to 3123 // determine the size of the encoded instruction. 3124 Label& l = (NULL == p)? d : *(p); 3125 int cc = $cmp$$cmpcode; 3126 int flags_reg = $crx$$reg; 3127 int bhint = Assembler::bhintNoHint; 3128 3129 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3130 if (_prob <= PROB_NEVER) { 3131 bhint = Assembler::bhintIsNotTaken; 3132 } else if (_prob >= PROB_ALWAYS) { 3133 bhint = Assembler::bhintIsTaken; 3134 } 3135 } 3136 3137 // Tell the conditional far branch to optimize itself when being relocated. 3138 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3139 cc_to_biint(cc, flags_reg), 3140 l, 3141 MacroAssembler::bc_far_optimize_on_relocate); 3142 %} 3143 3144 // Branch used with Power6 scheduling (can be shortened without changing the node). 3145 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3146 // The scheduler doesn't know about branch shortening, so we set the opcode 3147 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3148 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3149 3150 MacroAssembler _masm(&cbuf); 3151 Label d; // dummy 3152 __ bind(d); 3153 Label* p = ($lbl$$label); 3154 // `p' is `NULL' when this encoding class is used only to 3155 // determine the size of the encoded instruction. 3156 Label& l = (NULL == p)? d : *(p); 3157 int cc = $cmp$$cmpcode; 3158 int flags_reg = $crx$$reg; 3159 int bhint = Assembler::bhintNoHint; 3160 3161 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3162 if (_prob <= PROB_NEVER) { 3163 bhint = Assembler::bhintIsNotTaken; 3164 } else if (_prob >= PROB_ALWAYS) { 3165 bhint = Assembler::bhintIsTaken; 3166 } 3167 } 3168 3169 #if 0 // TODO: PPC port 3170 if (_size == 8) { 3171 // Tell the conditional far branch to optimize itself when being relocated. 3172 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3173 cc_to_biint(cc, flags_reg), 3174 l, 3175 MacroAssembler::bc_far_optimize_on_relocate); 3176 } else { 3177 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3178 cc_to_biint(cc, flags_reg), 3179 l); 3180 } 3181 #endif 3182 Unimplemented(); 3183 %} 3184 3185 // Postalloc expand emitter for loading a replicatef float constant from 3186 // the method's TOC. 3187 // Enc_class needed as consttanttablebase is not supported by postalloc 3188 // expand. 3189 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3190 // Create new nodes. 3191 3192 // Make an operand with the bit pattern to load as float. 3193 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3194 3195 loadConLNodesTuple loadConLNodes = 3196 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3197 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3198 3199 // Push new nodes. 3200 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3201 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3202 3203 assert(nodes->length() >= 1, "must have created at least 1 node"); 3204 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3205 %} 3206 3207 // This enc_class is needed so that scheduler gets proper 3208 // input mapping for latency computation. 3209 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3210 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3211 // Fake operand dst needed for PPC scheduler. 3212 assert($dst$$constant == 0x0, "dst must be 0x0"); 3213 3214 MacroAssembler _masm(&cbuf); 3215 // Mark the code position where the load from the safepoint 3216 // polling page was emitted as relocInfo::poll_type. 3217 __ relocate(relocInfo::poll_type); 3218 __ load_from_polling_page($poll$$Register); 3219 %} 3220 3221 // A Java static call or a runtime call. 3222 // 3223 // Branch-and-link relative to a trampoline. 3224 // The trampoline loads the target address and does a long branch to there. 3225 // In case we call java, the trampoline branches to a interpreter_stub 3226 // which loads the inline cache and the real call target from the constant pool. 3227 // 3228 // This basically looks like this: 3229 // 3230 // >>>> consts -+ -+ 3231 // | |- offset1 3232 // [call target1] | <-+ 3233 // [IC cache] |- offset2 3234 // [call target2] <--+ 3235 // 3236 // <<<< consts 3237 // >>>> insts 3238 // 3239 // bl offset16 -+ -+ ??? // How many bits available? 3240 // | | 3241 // <<<< insts | | 3242 // >>>> stubs | | 3243 // | |- trampoline_stub_Reloc 3244 // trampoline stub: | <-+ 3245 // r2 = toc | 3246 // r2 = [r2 + offset1] | // Load call target1 from const section 3247 // mtctr r2 | 3248 // bctr |- static_stub_Reloc 3249 // comp_to_interp_stub: <---+ 3250 // r1 = toc 3251 // ICreg = [r1 + IC_offset] // Load IC from const section 3252 // r1 = [r1 + offset2] // Load call target2 from const section 3253 // mtctr r1 3254 // bctr 3255 // 3256 // <<<< stubs 3257 // 3258 // The call instruction in the code either 3259 // - Branches directly to a compiled method if the offset is encodable in instruction. 3260 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3261 // - Branches to the compiled_to_interp stub if the target is interpreted. 3262 // 3263 // Further there are three relocations from the loads to the constants in 3264 // the constant section. 3265 // 3266 // Usage of r1 and r2 in the stubs allows to distinguish them. 3267 enc_class enc_java_static_call(method meth) %{ 3268 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3269 3270 MacroAssembler _masm(&cbuf); 3271 address entry_point = (address)$meth$$method; 3272 3273 if (!_method) { 3274 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3275 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3276 } else { 3277 // Remember the offset not the address. 3278 const int start_offset = __ offset(); 3279 3280 // The trampoline stub. 3281 // No entry point given, use the current pc. 3282 // Make sure branch fits into 3283 if (entry_point == 0) entry_point = __ pc(); 3284 3285 // Put the entry point as a constant into the constant pool. 3286 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3287 if (entry_point_toc_addr == NULL) { 3288 ciEnv::current()->record_out_of_memory_failure(); 3289 return; 3290 } 3291 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3292 3293 // Emit the trampoline stub which will be related to the branch-and-link below. 3294 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3295 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3296 int method_index = resolved_method_index(cbuf); 3297 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3298 : static_call_Relocation::spec(method_index)); 3299 3300 // The real call. 3301 // Note: At this point we do not have the address of the trampoline 3302 // stub, and the entry point might be too far away for bl, so __ pc() 3303 // serves as dummy and the bl will be patched later. 3304 cbuf.set_insts_mark(); 3305 __ bl(__ pc()); // Emits a relocation. 3306 3307 // The stub for call to interpreter. 3308 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3309 if (stub == NULL) { 3310 ciEnv::current()->record_failure("CodeCache is full"); 3311 return; 3312 } 3313 } 3314 %} 3315 3316 // Second node of expanded dynamic call - the call. 3317 enc_class enc_java_dynamic_call_sched(method meth) %{ 3318 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3319 3320 MacroAssembler _masm(&cbuf); 3321 3322 if (!ra_->C->in_scratch_emit_size()) { 3323 // Create a call trampoline stub for the given method. 3324 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3325 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3326 if (entry_point_const == NULL) { 3327 ciEnv::current()->record_out_of_memory_failure(); 3328 return; 3329 } 3330 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3331 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3332 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3333 3334 // Build relocation at call site with ic position as data. 3335 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3336 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3337 "must have one, but can't have both"); 3338 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3339 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3340 "must contain instruction offset"); 3341 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3342 ? _load_ic_hi_node->_cbuf_insts_offset 3343 : _load_ic_node->_cbuf_insts_offset; 3344 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3345 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3346 "should be load from TOC"); 3347 int method_index = resolved_method_index(cbuf); 3348 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3349 } 3350 3351 // At this point I do not have the address of the trampoline stub, 3352 // and the entry point might be too far away for bl. Pc() serves 3353 // as dummy and bl will be patched later. 3354 __ bl((address) __ pc()); 3355 %} 3356 3357 // postalloc expand emitter for virtual calls. 3358 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3359 3360 // Create the nodes for loading the IC from the TOC. 3361 loadConLNodesTuple loadConLNodes_IC = 3362 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3363 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3364 3365 // Create the call node. 3366 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3367 call->_method_handle_invoke = _method_handle_invoke; 3368 call->_vtable_index = _vtable_index; 3369 call->_method = _method; 3370 call->_bci = _bci; 3371 call->_optimized_virtual = _optimized_virtual; 3372 call->_tf = _tf; 3373 call->_entry_point = _entry_point; 3374 call->_cnt = _cnt; 3375 call->_argsize = _argsize; 3376 call->_oop_map = _oop_map; 3377 call->_jvms = _jvms; 3378 call->_jvmadj = _jvmadj; 3379 call->_in_rms = _in_rms; 3380 call->_nesting = _nesting; 3381 call->_override_symbolic_info = _override_symbolic_info; 3382 3383 // New call needs all inputs of old call. 3384 // Req... 3385 for (uint i = 0; i < req(); ++i) { 3386 // The expanded node does not need toc any more. 3387 // Add the inline cache constant here instead. This expresses the 3388 // register of the inline cache must be live at the call. 3389 // Else we would have to adapt JVMState by -1. 3390 if (i == mach_constant_base_node_input()) { 3391 call->add_req(loadConLNodes_IC._last); 3392 } else { 3393 call->add_req(in(i)); 3394 } 3395 } 3396 // ...as well as prec 3397 for (uint i = req(); i < len(); ++i) { 3398 call->add_prec(in(i)); 3399 } 3400 3401 // Remember nodes loading the inline cache into r19. 3402 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3403 call->_load_ic_node = loadConLNodes_IC._small; 3404 3405 // Operands for new nodes. 3406 call->_opnds[0] = _opnds[0]; 3407 call->_opnds[1] = _opnds[1]; 3408 3409 // Only the inline cache is associated with a register. 3410 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3411 3412 // Push new nodes. 3413 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3414 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3415 nodes->push(call); 3416 %} 3417 3418 // Compound version of call dynamic 3419 // Toc is only passed so that it can be used in ins_encode statement. 3420 // In the code we have to use $constanttablebase. 3421 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3422 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3423 MacroAssembler _masm(&cbuf); 3424 int start_offset = __ offset(); 3425 3426 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3427 #if 0 3428 int vtable_index = this->_vtable_index; 3429 if (_vtable_index < 0) { 3430 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3431 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3432 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3433 3434 // Virtual call relocation will point to ic load. 3435 address virtual_call_meta_addr = __ pc(); 3436 // Load a clear inline cache. 3437 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3438 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3439 if (!success) { 3440 ciEnv::current()->record_out_of_memory_failure(); 3441 return; 3442 } 3443 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3444 // to determine who we intended to call. 3445 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3446 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3447 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3448 "Fix constant in ret_addr_offset()"); 3449 } else { 3450 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3451 // Go thru the vtable. Get receiver klass. Receiver already 3452 // checked for non-null. If we'll go thru a C2I adapter, the 3453 // interpreter expects method in R19_method. 3454 3455 __ load_klass(R11_scratch1, R3); 3456 3457 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3458 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3459 __ li(R19_method, v_off); 3460 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3461 // NOTE: for vtable dispatches, the vtable entry will never be 3462 // null. However it may very well end up in handle_wrong_method 3463 // if the method is abstract for the particular class. 3464 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3465 // Call target. Either compiled code or C2I adapter. 3466 __ mtctr(R11_scratch1); 3467 __ bctrl(); 3468 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3469 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3470 } 3471 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3472 "Fix constant in ret_addr_offset()"); 3473 } 3474 #endif 3475 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3476 %} 3477 3478 // a runtime call 3479 enc_class enc_java_to_runtime_call (method meth) %{ 3480 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3481 3482 MacroAssembler _masm(&cbuf); 3483 const address start_pc = __ pc(); 3484 3485 #if defined(ABI_ELFv2) 3486 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3487 __ call_c(entry, relocInfo::runtime_call_type); 3488 #else 3489 // The function we're going to call. 3490 FunctionDescriptor fdtemp; 3491 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3492 3493 Register Rtoc = R12_scratch2; 3494 // Calculate the method's TOC. 3495 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3496 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3497 // pool entries; call_c_using_toc will optimize the call. 3498 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3499 if (!success) { 3500 ciEnv::current()->record_out_of_memory_failure(); 3501 return; 3502 } 3503 #endif 3504 3505 // Check the ret_addr_offset. 3506 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3507 "Fix constant in ret_addr_offset()"); 3508 %} 3509 3510 // Move to ctr for leaf call. 3511 // This enc_class is needed so that scheduler gets proper 3512 // input mapping for latency computation. 3513 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3514 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3515 MacroAssembler _masm(&cbuf); 3516 __ mtctr($src$$Register); 3517 %} 3518 3519 // Postalloc expand emitter for runtime leaf calls. 3520 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3521 loadConLNodesTuple loadConLNodes_Entry; 3522 #if defined(ABI_ELFv2) 3523 jlong entry_address = (jlong) this->entry_point(); 3524 assert(entry_address, "need address here"); 3525 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3526 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3527 #else 3528 // Get the struct that describes the function we are about to call. 3529 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3530 assert(fd, "need fd here"); 3531 jlong entry_address = (jlong) fd->entry(); 3532 // new nodes 3533 loadConLNodesTuple loadConLNodes_Env; 3534 loadConLNodesTuple loadConLNodes_Toc; 3535 3536 // Create nodes and operands for loading the entry point. 3537 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3538 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3539 3540 3541 // Create nodes and operands for loading the env pointer. 3542 if (fd->env() != NULL) { 3543 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3544 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3545 } else { 3546 loadConLNodes_Env._large_hi = NULL; 3547 loadConLNodes_Env._large_lo = NULL; 3548 loadConLNodes_Env._small = NULL; 3549 loadConLNodes_Env._last = new loadConL16Node(); 3550 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3551 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3552 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3553 } 3554 3555 // Create nodes and operands for loading the Toc point. 3556 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3557 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3558 #endif // ABI_ELFv2 3559 // mtctr node 3560 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3561 3562 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3563 mtctr->add_req(0, loadConLNodes_Entry._last); 3564 3565 mtctr->_opnds[0] = new iRegLdstOper(); 3566 mtctr->_opnds[1] = new iRegLdstOper(); 3567 3568 // call node 3569 MachCallLeafNode *call = new CallLeafDirectNode(); 3570 3571 call->_opnds[0] = _opnds[0]; 3572 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3573 3574 // Make the new call node look like the old one. 3575 call->_name = _name; 3576 call->_tf = _tf; 3577 call->_entry_point = _entry_point; 3578 call->_cnt = _cnt; 3579 call->_argsize = _argsize; 3580 call->_oop_map = _oop_map; 3581 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3582 call->_jvms = NULL; 3583 call->_jvmadj = _jvmadj; 3584 call->_in_rms = _in_rms; 3585 call->_nesting = _nesting; 3586 3587 3588 // New call needs all inputs of old call. 3589 // Req... 3590 for (uint i = 0; i < req(); ++i) { 3591 if (i != mach_constant_base_node_input()) { 3592 call->add_req(in(i)); 3593 } 3594 } 3595 3596 // These must be reqired edges, as the registers are live up to 3597 // the call. Else the constants are handled as kills. 3598 call->add_req(mtctr); 3599 #if !defined(ABI_ELFv2) 3600 call->add_req(loadConLNodes_Env._last); 3601 call->add_req(loadConLNodes_Toc._last); 3602 #endif 3603 3604 // ...as well as prec 3605 for (uint i = req(); i < len(); ++i) { 3606 call->add_prec(in(i)); 3607 } 3608 3609 // registers 3610 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 3611 3612 // Insert the new nodes. 3613 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 3614 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 3615 #if !defined(ABI_ELFv2) 3616 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 3617 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 3618 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 3619 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 3620 #endif 3621 nodes->push(mtctr); 3622 nodes->push(call); 3623 %} 3624 %} 3625 3626 //----------FRAME-------------------------------------------------------------- 3627 // Definition of frame structure and management information. 3628 3629 frame %{ 3630 // What direction does stack grow in (assumed to be same for native & Java). 3631 stack_direction(TOWARDS_LOW); 3632 3633 // These two registers define part of the calling convention between 3634 // compiled code and the interpreter. 3635 3636 // Inline Cache Register or method for I2C. 3637 inline_cache_reg(R19); // R19_method 3638 3639 // Method Oop Register when calling interpreter. 3640 interpreter_method_oop_reg(R19); // R19_method 3641 3642 // Optional: name the operand used by cisc-spilling to access 3643 // [stack_pointer + offset]. 3644 cisc_spilling_operand_name(indOffset); 3645 3646 // Number of stack slots consumed by a Monitor enter. 3647 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 3648 3649 // Compiled code's Frame Pointer. 3650 frame_pointer(R1); // R1_SP 3651 3652 // Interpreter stores its frame pointer in a register which is 3653 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 3654 // interpreted java to compiled java. 3655 // 3656 // R14_state holds pointer to caller's cInterpreter. 3657 interpreter_frame_pointer(R14); // R14_state 3658 3659 stack_alignment(frame::alignment_in_bytes); 3660 3661 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 3662 3663 // Number of outgoing stack slots killed above the 3664 // out_preserve_stack_slots for calls to C. Supports the var-args 3665 // backing area for register parms. 3666 // 3667 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 3668 3669 // The after-PROLOG location of the return address. Location of 3670 // return address specifies a type (REG or STACK) and a number 3671 // representing the register number (i.e. - use a register name) or 3672 // stack slot. 3673 // 3674 // A: Link register is stored in stack slot ... 3675 // M: ... but it's in the caller's frame according to PPC-64 ABI. 3676 // J: Therefore, we make sure that the link register is also in R11_scratch1 3677 // at the end of the prolog. 3678 // B: We use R20, now. 3679 //return_addr(REG R20); 3680 3681 // G: After reading the comments made by all the luminaries on their 3682 // failure to tell the compiler where the return address really is, 3683 // I hardly dare to try myself. However, I'm convinced it's in slot 3684 // 4 what apparently works and saves us some spills. 3685 return_addr(STACK 4); 3686 3687 // This is the body of the function 3688 // 3689 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 3690 // uint length, // length of array 3691 // bool is_outgoing) 3692 // 3693 // The `sig' array is to be updated. sig[j] represents the location 3694 // of the j-th argument, either a register or a stack slot. 3695 3696 // Comment taken from i486.ad: 3697 // Body of function which returns an integer array locating 3698 // arguments either in registers or in stack slots. Passed an array 3699 // of ideal registers called "sig" and a "length" count. Stack-slot 3700 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3701 // arguments for a CALLEE. Incoming stack arguments are 3702 // automatically biased by the preserve_stack_slots field above. 3703 calling_convention %{ 3704 // No difference between ingoing/outgoing. Just pass false. 3705 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3706 %} 3707 3708 // Comment taken from i486.ad: 3709 // Body of function which returns an integer array locating 3710 // arguments either in registers or in stack slots. Passed an array 3711 // of ideal registers called "sig" and a "length" count. Stack-slot 3712 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3713 // arguments for a CALLEE. Incoming stack arguments are 3714 // automatically biased by the preserve_stack_slots field above. 3715 c_calling_convention %{ 3716 // This is obviously always outgoing. 3717 // C argument in register AND stack slot. 3718 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 3719 %} 3720 3721 // Location of native (C/C++) and interpreter return values. This 3722 // is specified to be the same as Java. In the 32-bit VM, long 3723 // values are actually returned from native calls in O0:O1 and 3724 // returned to the interpreter in I0:I1. The copying to and from 3725 // the register pairs is done by the appropriate call and epilog 3726 // opcodes. This simplifies the register allocator. 3727 c_return_value %{ 3728 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3729 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 3730 "only return normal values"); 3731 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3732 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3733 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3734 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3735 %} 3736 3737 // Location of compiled Java return values. Same as C 3738 return_value %{ 3739 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3740 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 3741 "only return normal values"); 3742 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3743 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3744 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3745 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3746 %} 3747 %} 3748 3749 3750 //----------ATTRIBUTES--------------------------------------------------------- 3751 3752 //----------Operand Attributes------------------------------------------------- 3753 op_attrib op_cost(1); // Required cost attribute. 3754 3755 //----------Instruction Attributes--------------------------------------------- 3756 3757 // Cost attribute. required. 3758 ins_attrib ins_cost(DEFAULT_COST); 3759 3760 // Is this instruction a non-matching short branch variant of some 3761 // long branch? Not required. 3762 ins_attrib ins_short_branch(0); 3763 3764 ins_attrib ins_is_TrapBasedCheckNode(true); 3765 3766 // Number of constants. 3767 // This instruction uses the given number of constants 3768 // (optional attribute). 3769 // This is needed to determine in time whether the constant pool will 3770 // exceed 4000 entries. Before postalloc_expand the overall number of constants 3771 // is determined. It's also used to compute the constant pool size 3772 // in Output(). 3773 ins_attrib ins_num_consts(0); 3774 3775 // Required alignment attribute (must be a power of 2) specifies the 3776 // alignment that some part of the instruction (not necessarily the 3777 // start) requires. If > 1, a compute_padding() function must be 3778 // provided for the instruction. 3779 ins_attrib ins_alignment(1); 3780 3781 // Enforce/prohibit rematerializations. 3782 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 3783 // then rematerialization of that instruction is prohibited and the 3784 // instruction's value will be spilled if necessary. 3785 // Causes that MachNode::rematerialize() returns false. 3786 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 3787 // then rematerialization should be enforced and a copy of the instruction 3788 // should be inserted if possible; rematerialization is not guaranteed. 3789 // Note: this may result in rematerializations in front of every use. 3790 // Causes that MachNode::rematerialize() can return true. 3791 // (optional attribute) 3792 ins_attrib ins_cannot_rematerialize(false); 3793 ins_attrib ins_should_rematerialize(false); 3794 3795 // Instruction has variable size depending on alignment. 3796 ins_attrib ins_variable_size_depending_on_alignment(false); 3797 3798 // Instruction is a nop. 3799 ins_attrib ins_is_nop(false); 3800 3801 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 3802 ins_attrib ins_use_mach_if_fast_lock_node(false); 3803 3804 // Field for the toc offset of a constant. 3805 // 3806 // This is needed if the toc offset is not encodable as an immediate in 3807 // the PPC load instruction. If so, the upper (hi) bits of the offset are 3808 // added to the toc, and from this a load with immediate is performed. 3809 // With postalloc expand, we get two nodes that require the same offset 3810 // but which don't know about each other. The offset is only known 3811 // when the constant is added to the constant pool during emitting. 3812 // It is generated in the 'hi'-node adding the upper bits, and saved 3813 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 3814 // the offset from there when it gets encoded. 3815 ins_attrib ins_field_const_toc_offset(0); 3816 ins_attrib ins_field_const_toc_offset_hi_node(0); 3817 3818 // A field that can hold the instructions offset in the code buffer. 3819 // Set in the nodes emitter. 3820 ins_attrib ins_field_cbuf_insts_offset(-1); 3821 3822 // Fields for referencing a call's load-IC-node. 3823 // If the toc offset can not be encoded as an immediate in a load, we 3824 // use two nodes. 3825 ins_attrib ins_field_load_ic_hi_node(0); 3826 ins_attrib ins_field_load_ic_node(0); 3827 3828 //----------OPERANDS----------------------------------------------------------- 3829 // Operand definitions must precede instruction definitions for correct 3830 // parsing in the ADLC because operands constitute user defined types 3831 // which are used in instruction definitions. 3832 // 3833 // Formats are generated automatically for constants and base registers. 3834 3835 //----------Simple Operands---------------------------------------------------- 3836 // Immediate Operands 3837 3838 // Integer Immediate: 32-bit 3839 operand immI() %{ 3840 match(ConI); 3841 op_cost(40); 3842 format %{ %} 3843 interface(CONST_INTER); 3844 %} 3845 3846 operand immI8() %{ 3847 predicate(Assembler::is_simm(n->get_int(), 8)); 3848 op_cost(0); 3849 match(ConI); 3850 format %{ %} 3851 interface(CONST_INTER); 3852 %} 3853 3854 // Integer Immediate: 16-bit 3855 operand immI16() %{ 3856 predicate(Assembler::is_simm(n->get_int(), 16)); 3857 op_cost(0); 3858 match(ConI); 3859 format %{ %} 3860 interface(CONST_INTER); 3861 %} 3862 3863 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 3864 operand immIhi16() %{ 3865 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 3866 match(ConI); 3867 op_cost(0); 3868 format %{ %} 3869 interface(CONST_INTER); 3870 %} 3871 3872 operand immInegpow2() %{ 3873 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 3874 match(ConI); 3875 op_cost(0); 3876 format %{ %} 3877 interface(CONST_INTER); 3878 %} 3879 3880 operand immIpow2minus1() %{ 3881 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 3882 match(ConI); 3883 op_cost(0); 3884 format %{ %} 3885 interface(CONST_INTER); 3886 %} 3887 3888 operand immIpowerOf2() %{ 3889 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 3890 match(ConI); 3891 op_cost(0); 3892 format %{ %} 3893 interface(CONST_INTER); 3894 %} 3895 3896 // Unsigned Integer Immediate: the values 0-31 3897 operand uimmI5() %{ 3898 predicate(Assembler::is_uimm(n->get_int(), 5)); 3899 match(ConI); 3900 op_cost(0); 3901 format %{ %} 3902 interface(CONST_INTER); 3903 %} 3904 3905 // Unsigned Integer Immediate: 6-bit 3906 operand uimmI6() %{ 3907 predicate(Assembler::is_uimm(n->get_int(), 6)); 3908 match(ConI); 3909 op_cost(0); 3910 format %{ %} 3911 interface(CONST_INTER); 3912 %} 3913 3914 // Unsigned Integer Immediate: 6-bit int, greater than 32 3915 operand uimmI6_ge32() %{ 3916 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 3917 match(ConI); 3918 op_cost(0); 3919 format %{ %} 3920 interface(CONST_INTER); 3921 %} 3922 3923 // Unsigned Integer Immediate: 15-bit 3924 operand uimmI15() %{ 3925 predicate(Assembler::is_uimm(n->get_int(), 15)); 3926 match(ConI); 3927 op_cost(0); 3928 format %{ %} 3929 interface(CONST_INTER); 3930 %} 3931 3932 // Unsigned Integer Immediate: 16-bit 3933 operand uimmI16() %{ 3934 predicate(Assembler::is_uimm(n->get_int(), 16)); 3935 match(ConI); 3936 op_cost(0); 3937 format %{ %} 3938 interface(CONST_INTER); 3939 %} 3940 3941 // constant 'int 0'. 3942 operand immI_0() %{ 3943 predicate(n->get_int() == 0); 3944 match(ConI); 3945 op_cost(0); 3946 format %{ %} 3947 interface(CONST_INTER); 3948 %} 3949 3950 // constant 'int 1'. 3951 operand immI_1() %{ 3952 predicate(n->get_int() == 1); 3953 match(ConI); 3954 op_cost(0); 3955 format %{ %} 3956 interface(CONST_INTER); 3957 %} 3958 3959 // constant 'int -1'. 3960 operand immI_minus1() %{ 3961 predicate(n->get_int() == -1); 3962 match(ConI); 3963 op_cost(0); 3964 format %{ %} 3965 interface(CONST_INTER); 3966 %} 3967 3968 // int value 16. 3969 operand immI_16() %{ 3970 predicate(n->get_int() == 16); 3971 match(ConI); 3972 op_cost(0); 3973 format %{ %} 3974 interface(CONST_INTER); 3975 %} 3976 3977 // int value 24. 3978 operand immI_24() %{ 3979 predicate(n->get_int() == 24); 3980 match(ConI); 3981 op_cost(0); 3982 format %{ %} 3983 interface(CONST_INTER); 3984 %} 3985 3986 // Compressed oops constants 3987 // Pointer Immediate 3988 operand immN() %{ 3989 match(ConN); 3990 3991 op_cost(10); 3992 format %{ %} 3993 interface(CONST_INTER); 3994 %} 3995 3996 // NULL Pointer Immediate 3997 operand immN_0() %{ 3998 predicate(n->get_narrowcon() == 0); 3999 match(ConN); 4000 4001 op_cost(0); 4002 format %{ %} 4003 interface(CONST_INTER); 4004 %} 4005 4006 // Compressed klass constants 4007 operand immNKlass() %{ 4008 match(ConNKlass); 4009 4010 op_cost(0); 4011 format %{ %} 4012 interface(CONST_INTER); 4013 %} 4014 4015 // This operand can be used to avoid matching of an instruct 4016 // with chain rule. 4017 operand immNKlass_NM() %{ 4018 match(ConNKlass); 4019 predicate(false); 4020 op_cost(0); 4021 format %{ %} 4022 interface(CONST_INTER); 4023 %} 4024 4025 // Pointer Immediate: 64-bit 4026 operand immP() %{ 4027 match(ConP); 4028 op_cost(0); 4029 format %{ %} 4030 interface(CONST_INTER); 4031 %} 4032 4033 // Operand to avoid match of loadConP. 4034 // This operand can be used to avoid matching of an instruct 4035 // with chain rule. 4036 operand immP_NM() %{ 4037 match(ConP); 4038 predicate(false); 4039 op_cost(0); 4040 format %{ %} 4041 interface(CONST_INTER); 4042 %} 4043 4044 // costant 'pointer 0'. 4045 operand immP_0() %{ 4046 predicate(n->get_ptr() == 0); 4047 match(ConP); 4048 op_cost(0); 4049 format %{ %} 4050 interface(CONST_INTER); 4051 %} 4052 4053 // pointer 0x0 or 0x1 4054 operand immP_0or1() %{ 4055 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4056 match(ConP); 4057 op_cost(0); 4058 format %{ %} 4059 interface(CONST_INTER); 4060 %} 4061 4062 operand immL() %{ 4063 match(ConL); 4064 op_cost(40); 4065 format %{ %} 4066 interface(CONST_INTER); 4067 %} 4068 4069 // Long Immediate: 16-bit 4070 operand immL16() %{ 4071 predicate(Assembler::is_simm(n->get_long(), 16)); 4072 match(ConL); 4073 op_cost(0); 4074 format %{ %} 4075 interface(CONST_INTER); 4076 %} 4077 4078 // Long Immediate: 16-bit, 4-aligned 4079 operand immL16Alg4() %{ 4080 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4081 match(ConL); 4082 op_cost(0); 4083 format %{ %} 4084 interface(CONST_INTER); 4085 %} 4086 4087 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4088 operand immL32hi16() %{ 4089 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4090 match(ConL); 4091 op_cost(0); 4092 format %{ %} 4093 interface(CONST_INTER); 4094 %} 4095 4096 // Long Immediate: 32-bit 4097 operand immL32() %{ 4098 predicate(Assembler::is_simm(n->get_long(), 32)); 4099 match(ConL); 4100 op_cost(0); 4101 format %{ %} 4102 interface(CONST_INTER); 4103 %} 4104 4105 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4106 operand immLhighest16() %{ 4107 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4108 match(ConL); 4109 op_cost(0); 4110 format %{ %} 4111 interface(CONST_INTER); 4112 %} 4113 4114 operand immLnegpow2() %{ 4115 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4116 match(ConL); 4117 op_cost(0); 4118 format %{ %} 4119 interface(CONST_INTER); 4120 %} 4121 4122 operand immLpow2minus1() %{ 4123 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4124 (n->get_long() != (jlong)0xffffffffffffffffL)); 4125 match(ConL); 4126 op_cost(0); 4127 format %{ %} 4128 interface(CONST_INTER); 4129 %} 4130 4131 // constant 'long 0'. 4132 operand immL_0() %{ 4133 predicate(n->get_long() == 0L); 4134 match(ConL); 4135 op_cost(0); 4136 format %{ %} 4137 interface(CONST_INTER); 4138 %} 4139 4140 // constat ' long -1'. 4141 operand immL_minus1() %{ 4142 predicate(n->get_long() == -1L); 4143 match(ConL); 4144 op_cost(0); 4145 format %{ %} 4146 interface(CONST_INTER); 4147 %} 4148 4149 // Long Immediate: low 32-bit mask 4150 operand immL_32bits() %{ 4151 predicate(n->get_long() == 0xFFFFFFFFL); 4152 match(ConL); 4153 op_cost(0); 4154 format %{ %} 4155 interface(CONST_INTER); 4156 %} 4157 4158 // Unsigned Long Immediate: 16-bit 4159 operand uimmL16() %{ 4160 predicate(Assembler::is_uimm(n->get_long(), 16)); 4161 match(ConL); 4162 op_cost(0); 4163 format %{ %} 4164 interface(CONST_INTER); 4165 %} 4166 4167 // Float Immediate 4168 operand immF() %{ 4169 match(ConF); 4170 op_cost(40); 4171 format %{ %} 4172 interface(CONST_INTER); 4173 %} 4174 4175 // Float Immediate: +0.0f. 4176 operand immF_0() %{ 4177 predicate(jint_cast(n->getf()) == 0); 4178 match(ConF); 4179 4180 op_cost(0); 4181 format %{ %} 4182 interface(CONST_INTER); 4183 %} 4184 4185 // Double Immediate 4186 operand immD() %{ 4187 match(ConD); 4188 op_cost(40); 4189 format %{ %} 4190 interface(CONST_INTER); 4191 %} 4192 4193 // Integer Register Operands 4194 // Integer Destination Register 4195 // See definition of reg_class bits32_reg_rw. 4196 operand iRegIdst() %{ 4197 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4198 match(RegI); 4199 match(rscratch1RegI); 4200 match(rscratch2RegI); 4201 match(rarg1RegI); 4202 match(rarg2RegI); 4203 match(rarg3RegI); 4204 match(rarg4RegI); 4205 format %{ %} 4206 interface(REG_INTER); 4207 %} 4208 4209 // Integer Source Register 4210 // See definition of reg_class bits32_reg_ro. 4211 operand iRegIsrc() %{ 4212 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4213 match(RegI); 4214 match(rscratch1RegI); 4215 match(rscratch2RegI); 4216 match(rarg1RegI); 4217 match(rarg2RegI); 4218 match(rarg3RegI); 4219 match(rarg4RegI); 4220 format %{ %} 4221 interface(REG_INTER); 4222 %} 4223 4224 operand rscratch1RegI() %{ 4225 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4226 match(iRegIdst); 4227 format %{ %} 4228 interface(REG_INTER); 4229 %} 4230 4231 operand rscratch2RegI() %{ 4232 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4233 match(iRegIdst); 4234 format %{ %} 4235 interface(REG_INTER); 4236 %} 4237 4238 operand rarg1RegI() %{ 4239 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4240 match(iRegIdst); 4241 format %{ %} 4242 interface(REG_INTER); 4243 %} 4244 4245 operand rarg2RegI() %{ 4246 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4247 match(iRegIdst); 4248 format %{ %} 4249 interface(REG_INTER); 4250 %} 4251 4252 operand rarg3RegI() %{ 4253 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4254 match(iRegIdst); 4255 format %{ %} 4256 interface(REG_INTER); 4257 %} 4258 4259 operand rarg4RegI() %{ 4260 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4261 match(iRegIdst); 4262 format %{ %} 4263 interface(REG_INTER); 4264 %} 4265 4266 operand rarg1RegL() %{ 4267 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4268 match(iRegLdst); 4269 format %{ %} 4270 interface(REG_INTER); 4271 %} 4272 4273 operand rarg2RegL() %{ 4274 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4275 match(iRegLdst); 4276 format %{ %} 4277 interface(REG_INTER); 4278 %} 4279 4280 operand rarg3RegL() %{ 4281 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4282 match(iRegLdst); 4283 format %{ %} 4284 interface(REG_INTER); 4285 %} 4286 4287 operand rarg4RegL() %{ 4288 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4289 match(iRegLdst); 4290 format %{ %} 4291 interface(REG_INTER); 4292 %} 4293 4294 // Pointer Destination Register 4295 // See definition of reg_class bits64_reg_rw. 4296 operand iRegPdst() %{ 4297 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4298 match(RegP); 4299 match(rscratch1RegP); 4300 match(rscratch2RegP); 4301 match(rarg1RegP); 4302 match(rarg2RegP); 4303 match(rarg3RegP); 4304 match(rarg4RegP); 4305 format %{ %} 4306 interface(REG_INTER); 4307 %} 4308 4309 // Pointer Destination Register 4310 // Operand not using r11 and r12 (killed in epilog). 4311 operand iRegPdstNoScratch() %{ 4312 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4313 match(RegP); 4314 match(rarg1RegP); 4315 match(rarg2RegP); 4316 match(rarg3RegP); 4317 match(rarg4RegP); 4318 format %{ %} 4319 interface(REG_INTER); 4320 %} 4321 4322 // Pointer Source Register 4323 // See definition of reg_class bits64_reg_ro. 4324 operand iRegPsrc() %{ 4325 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4326 match(RegP); 4327 match(iRegPdst); 4328 match(rscratch1RegP); 4329 match(rscratch2RegP); 4330 match(rarg1RegP); 4331 match(rarg2RegP); 4332 match(rarg3RegP); 4333 match(rarg4RegP); 4334 match(threadRegP); 4335 format %{ %} 4336 interface(REG_INTER); 4337 %} 4338 4339 // Thread operand. 4340 operand threadRegP() %{ 4341 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4342 match(iRegPdst); 4343 format %{ "R16" %} 4344 interface(REG_INTER); 4345 %} 4346 4347 operand rscratch1RegP() %{ 4348 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4349 match(iRegPdst); 4350 format %{ "R11" %} 4351 interface(REG_INTER); 4352 %} 4353 4354 operand rscratch2RegP() %{ 4355 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4356 match(iRegPdst); 4357 format %{ %} 4358 interface(REG_INTER); 4359 %} 4360 4361 operand rarg1RegP() %{ 4362 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4363 match(iRegPdst); 4364 format %{ %} 4365 interface(REG_INTER); 4366 %} 4367 4368 operand rarg2RegP() %{ 4369 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4370 match(iRegPdst); 4371 format %{ %} 4372 interface(REG_INTER); 4373 %} 4374 4375 operand rarg3RegP() %{ 4376 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4377 match(iRegPdst); 4378 format %{ %} 4379 interface(REG_INTER); 4380 %} 4381 4382 operand rarg4RegP() %{ 4383 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4384 match(iRegPdst); 4385 format %{ %} 4386 interface(REG_INTER); 4387 %} 4388 4389 operand iRegNsrc() %{ 4390 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4391 match(RegN); 4392 match(iRegNdst); 4393 4394 format %{ %} 4395 interface(REG_INTER); 4396 %} 4397 4398 operand iRegNdst() %{ 4399 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4400 match(RegN); 4401 4402 format %{ %} 4403 interface(REG_INTER); 4404 %} 4405 4406 // Long Destination Register 4407 // See definition of reg_class bits64_reg_rw. 4408 operand iRegLdst() %{ 4409 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4410 match(RegL); 4411 match(rscratch1RegL); 4412 match(rscratch2RegL); 4413 format %{ %} 4414 interface(REG_INTER); 4415 %} 4416 4417 // Long Source Register 4418 // See definition of reg_class bits64_reg_ro. 4419 operand iRegLsrc() %{ 4420 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4421 match(RegL); 4422 match(iRegLdst); 4423 match(rscratch1RegL); 4424 match(rscratch2RegL); 4425 format %{ %} 4426 interface(REG_INTER); 4427 %} 4428 4429 // Special operand for ConvL2I. 4430 operand iRegL2Isrc(iRegLsrc reg) %{ 4431 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4432 match(ConvL2I reg); 4433 format %{ "ConvL2I($reg)" %} 4434 interface(REG_INTER) 4435 %} 4436 4437 operand rscratch1RegL() %{ 4438 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4439 match(RegL); 4440 format %{ %} 4441 interface(REG_INTER); 4442 %} 4443 4444 operand rscratch2RegL() %{ 4445 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4446 match(RegL); 4447 format %{ %} 4448 interface(REG_INTER); 4449 %} 4450 4451 // Condition Code Flag Registers 4452 operand flagsReg() %{ 4453 constraint(ALLOC_IN_RC(int_flags)); 4454 match(RegFlags); 4455 format %{ %} 4456 interface(REG_INTER); 4457 %} 4458 4459 operand flagsRegSrc() %{ 4460 constraint(ALLOC_IN_RC(int_flags_ro)); 4461 match(RegFlags); 4462 match(flagsReg); 4463 match(flagsRegCR0); 4464 format %{ %} 4465 interface(REG_INTER); 4466 %} 4467 4468 // Condition Code Flag Register CR0 4469 operand flagsRegCR0() %{ 4470 constraint(ALLOC_IN_RC(int_flags_CR0)); 4471 match(RegFlags); 4472 format %{ "CR0" %} 4473 interface(REG_INTER); 4474 %} 4475 4476 operand flagsRegCR1() %{ 4477 constraint(ALLOC_IN_RC(int_flags_CR1)); 4478 match(RegFlags); 4479 format %{ "CR1" %} 4480 interface(REG_INTER); 4481 %} 4482 4483 operand flagsRegCR6() %{ 4484 constraint(ALLOC_IN_RC(int_flags_CR6)); 4485 match(RegFlags); 4486 format %{ "CR6" %} 4487 interface(REG_INTER); 4488 %} 4489 4490 operand regCTR() %{ 4491 constraint(ALLOC_IN_RC(ctr_reg)); 4492 // RegFlags should work. Introducing a RegSpecial type would cause a 4493 // lot of changes. 4494 match(RegFlags); 4495 format %{"SR_CTR" %} 4496 interface(REG_INTER); 4497 %} 4498 4499 operand regD() %{ 4500 constraint(ALLOC_IN_RC(dbl_reg)); 4501 match(RegD); 4502 format %{ %} 4503 interface(REG_INTER); 4504 %} 4505 4506 operand regF() %{ 4507 constraint(ALLOC_IN_RC(flt_reg)); 4508 match(RegF); 4509 format %{ %} 4510 interface(REG_INTER); 4511 %} 4512 4513 // Special Registers 4514 4515 // Method Register 4516 operand inline_cache_regP(iRegPdst reg) %{ 4517 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4518 match(reg); 4519 format %{ %} 4520 interface(REG_INTER); 4521 %} 4522 4523 operand compiler_method_oop_regP(iRegPdst reg) %{ 4524 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4525 match(reg); 4526 format %{ %} 4527 interface(REG_INTER); 4528 %} 4529 4530 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4531 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4532 match(reg); 4533 format %{ %} 4534 interface(REG_INTER); 4535 %} 4536 4537 // Operands to remove register moves in unscaled mode. 4538 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4539 operand iRegP2N(iRegPsrc reg) %{ 4540 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4541 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4542 match(EncodeP reg); 4543 format %{ "$reg" %} 4544 interface(REG_INTER) 4545 %} 4546 4547 operand iRegN2P(iRegNsrc reg) %{ 4548 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4549 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4550 match(DecodeN reg); 4551 format %{ "$reg" %} 4552 interface(REG_INTER) 4553 %} 4554 4555 operand iRegN2P_klass(iRegNsrc reg) %{ 4556 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4557 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4558 match(DecodeNKlass reg); 4559 format %{ "$reg" %} 4560 interface(REG_INTER) 4561 %} 4562 4563 //----------Complex Operands--------------------------------------------------- 4564 // Indirect Memory Reference 4565 operand indirect(iRegPsrc reg) %{ 4566 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4567 match(reg); 4568 op_cost(100); 4569 format %{ "[$reg]" %} 4570 interface(MEMORY_INTER) %{ 4571 base($reg); 4572 index(0x0); 4573 scale(0x0); 4574 disp(0x0); 4575 %} 4576 %} 4577 4578 // Indirect with Offset 4579 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 4580 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4581 match(AddP reg offset); 4582 op_cost(100); 4583 format %{ "[$reg + $offset]" %} 4584 interface(MEMORY_INTER) %{ 4585 base($reg); 4586 index(0x0); 4587 scale(0x0); 4588 disp($offset); 4589 %} 4590 %} 4591 4592 // Indirect with 4-aligned Offset 4593 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 4594 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4595 match(AddP reg offset); 4596 op_cost(100); 4597 format %{ "[$reg + $offset]" %} 4598 interface(MEMORY_INTER) %{ 4599 base($reg); 4600 index(0x0); 4601 scale(0x0); 4602 disp($offset); 4603 %} 4604 %} 4605 4606 //----------Complex Operands for Compressed OOPs------------------------------- 4607 // Compressed OOPs with narrow_oop_shift == 0. 4608 4609 // Indirect Memory Reference, compressed OOP 4610 operand indirectNarrow(iRegNsrc reg) %{ 4611 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4612 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4613 match(DecodeN reg); 4614 op_cost(100); 4615 format %{ "[$reg]" %} 4616 interface(MEMORY_INTER) %{ 4617 base($reg); 4618 index(0x0); 4619 scale(0x0); 4620 disp(0x0); 4621 %} 4622 %} 4623 4624 operand indirectNarrow_klass(iRegNsrc reg) %{ 4625 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4626 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4627 match(DecodeNKlass reg); 4628 op_cost(100); 4629 format %{ "[$reg]" %} 4630 interface(MEMORY_INTER) %{ 4631 base($reg); 4632 index(0x0); 4633 scale(0x0); 4634 disp(0x0); 4635 %} 4636 %} 4637 4638 // Indirect with Offset, compressed OOP 4639 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 4640 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4641 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4642 match(AddP (DecodeN reg) offset); 4643 op_cost(100); 4644 format %{ "[$reg + $offset]" %} 4645 interface(MEMORY_INTER) %{ 4646 base($reg); 4647 index(0x0); 4648 scale(0x0); 4649 disp($offset); 4650 %} 4651 %} 4652 4653 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 4654 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4655 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4656 match(AddP (DecodeNKlass reg) offset); 4657 op_cost(100); 4658 format %{ "[$reg + $offset]" %} 4659 interface(MEMORY_INTER) %{ 4660 base($reg); 4661 index(0x0); 4662 scale(0x0); 4663 disp($offset); 4664 %} 4665 %} 4666 4667 // Indirect with 4-aligned Offset, compressed OOP 4668 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 4669 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4670 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4671 match(AddP (DecodeN reg) offset); 4672 op_cost(100); 4673 format %{ "[$reg + $offset]" %} 4674 interface(MEMORY_INTER) %{ 4675 base($reg); 4676 index(0x0); 4677 scale(0x0); 4678 disp($offset); 4679 %} 4680 %} 4681 4682 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 4683 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4684 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4685 match(AddP (DecodeNKlass reg) offset); 4686 op_cost(100); 4687 format %{ "[$reg + $offset]" %} 4688 interface(MEMORY_INTER) %{ 4689 base($reg); 4690 index(0x0); 4691 scale(0x0); 4692 disp($offset); 4693 %} 4694 %} 4695 4696 //----------Special Memory Operands-------------------------------------------- 4697 // Stack Slot Operand 4698 // 4699 // This operand is used for loading and storing temporary values on 4700 // the stack where a match requires a value to flow through memory. 4701 operand stackSlotI(sRegI reg) %{ 4702 constraint(ALLOC_IN_RC(stack_slots)); 4703 op_cost(100); 4704 //match(RegI); 4705 format %{ "[sp+$reg]" %} 4706 interface(MEMORY_INTER) %{ 4707 base(0x1); // R1_SP 4708 index(0x0); 4709 scale(0x0); 4710 disp($reg); // Stack Offset 4711 %} 4712 %} 4713 4714 operand stackSlotL(sRegL reg) %{ 4715 constraint(ALLOC_IN_RC(stack_slots)); 4716 op_cost(100); 4717 //match(RegL); 4718 format %{ "[sp+$reg]" %} 4719 interface(MEMORY_INTER) %{ 4720 base(0x1); // R1_SP 4721 index(0x0); 4722 scale(0x0); 4723 disp($reg); // Stack Offset 4724 %} 4725 %} 4726 4727 operand stackSlotP(sRegP reg) %{ 4728 constraint(ALLOC_IN_RC(stack_slots)); 4729 op_cost(100); 4730 //match(RegP); 4731 format %{ "[sp+$reg]" %} 4732 interface(MEMORY_INTER) %{ 4733 base(0x1); // R1_SP 4734 index(0x0); 4735 scale(0x0); 4736 disp($reg); // Stack Offset 4737 %} 4738 %} 4739 4740 operand stackSlotF(sRegF reg) %{ 4741 constraint(ALLOC_IN_RC(stack_slots)); 4742 op_cost(100); 4743 //match(RegF); 4744 format %{ "[sp+$reg]" %} 4745 interface(MEMORY_INTER) %{ 4746 base(0x1); // R1_SP 4747 index(0x0); 4748 scale(0x0); 4749 disp($reg); // Stack Offset 4750 %} 4751 %} 4752 4753 operand stackSlotD(sRegD reg) %{ 4754 constraint(ALLOC_IN_RC(stack_slots)); 4755 op_cost(100); 4756 //match(RegD); 4757 format %{ "[sp+$reg]" %} 4758 interface(MEMORY_INTER) %{ 4759 base(0x1); // R1_SP 4760 index(0x0); 4761 scale(0x0); 4762 disp($reg); // Stack Offset 4763 %} 4764 %} 4765 4766 // Operands for expressing Control Flow 4767 // NOTE: Label is a predefined operand which should not be redefined in 4768 // the AD file. It is generically handled within the ADLC. 4769 4770 //----------Conditional Branch Operands---------------------------------------- 4771 // Comparison Op 4772 // 4773 // This is the operation of the comparison, and is limited to the 4774 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 4775 // (!=). 4776 // 4777 // Other attributes of the comparison, such as unsignedness, are specified 4778 // by the comparison instruction that sets a condition code flags register. 4779 // That result is represented by a flags operand whose subtype is appropriate 4780 // to the unsignedness (etc.) of the comparison. 4781 // 4782 // Later, the instruction which matches both the Comparison Op (a Bool) and 4783 // the flags (produced by the Cmp) specifies the coding of the comparison op 4784 // by matching a specific subtype of Bool operand below. 4785 4786 // When used for floating point comparisons: unordered same as less. 4787 operand cmpOp() %{ 4788 match(Bool); 4789 format %{ "" %} 4790 interface(COND_INTER) %{ 4791 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 4792 // BO & BI 4793 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 4794 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 4795 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 4796 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 4797 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 4798 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 4799 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 4800 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 4801 %} 4802 %} 4803 4804 //----------OPERAND CLASSES---------------------------------------------------- 4805 // Operand Classes are groups of operands that are used to simplify 4806 // instruction definitions by not requiring the AD writer to specify 4807 // seperate instructions for every form of operand when the 4808 // instruction accepts multiple operand types with the same basic 4809 // encoding and format. The classic case of this is memory operands. 4810 // Indirect is not included since its use is limited to Compare & Swap. 4811 4812 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 4813 // Memory operand where offsets are 4-aligned. Required for ld, std. 4814 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 4815 opclass indirectMemory(indirect, indirectNarrow); 4816 4817 // Special opclass for I and ConvL2I. 4818 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 4819 4820 // Operand classes to match encode and decode. iRegN_P2N is only used 4821 // for storeN. I have never seen an encode node elsewhere. 4822 opclass iRegN_P2N(iRegNsrc, iRegP2N); 4823 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 4824 4825 //----------PIPELINE----------------------------------------------------------- 4826 4827 pipeline %{ 4828 4829 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 4830 // J. Res. & Dev., No. 1, Jan. 2002. 4831 4832 //----------ATTRIBUTES--------------------------------------------------------- 4833 attributes %{ 4834 4835 // Power4 instructions are of fixed length. 4836 fixed_size_instructions; 4837 4838 // TODO: if `bundle' means number of instructions fetched 4839 // per cycle, this is 8. If `bundle' means Power4 `group', that is 4840 // max instructions issued per cycle, this is 5. 4841 max_instructions_per_bundle = 8; 4842 4843 // A Power4 instruction is 4 bytes long. 4844 instruction_unit_size = 4; 4845 4846 // The Power4 processor fetches 64 bytes... 4847 instruction_fetch_unit_size = 64; 4848 4849 // ...in one line 4850 instruction_fetch_units = 1 4851 4852 // Unused, list one so that array generated by adlc is not empty. 4853 // Aix compiler chokes if _nop_count = 0. 4854 nops(fxNop); 4855 %} 4856 4857 //----------RESOURCES---------------------------------------------------------- 4858 // Resources are the functional units available to the machine 4859 resources( 4860 PPC_BR, // branch unit 4861 PPC_CR, // condition unit 4862 PPC_FX1, // integer arithmetic unit 1 4863 PPC_FX2, // integer arithmetic unit 2 4864 PPC_LDST1, // load/store unit 1 4865 PPC_LDST2, // load/store unit 2 4866 PPC_FP1, // float arithmetic unit 1 4867 PPC_FP2, // float arithmetic unit 2 4868 PPC_LDST = PPC_LDST1 | PPC_LDST2, 4869 PPC_FX = PPC_FX1 | PPC_FX2, 4870 PPC_FP = PPC_FP1 | PPC_FP2 4871 ); 4872 4873 //----------PIPELINE DESCRIPTION----------------------------------------------- 4874 // Pipeline Description specifies the stages in the machine's pipeline 4875 pipe_desc( 4876 // Power4 longest pipeline path 4877 PPC_IF, // instruction fetch 4878 PPC_IC, 4879 //PPC_BP, // branch prediction 4880 PPC_D0, // decode 4881 PPC_D1, // decode 4882 PPC_D2, // decode 4883 PPC_D3, // decode 4884 PPC_Xfer1, 4885 PPC_GD, // group definition 4886 PPC_MP, // map 4887 PPC_ISS, // issue 4888 PPC_RF, // resource fetch 4889 PPC_EX1, // execute (all units) 4890 PPC_EX2, // execute (FP, LDST) 4891 PPC_EX3, // execute (FP, LDST) 4892 PPC_EX4, // execute (FP) 4893 PPC_EX5, // execute (FP) 4894 PPC_EX6, // execute (FP) 4895 PPC_WB, // write back 4896 PPC_Xfer2, 4897 PPC_CP 4898 ); 4899 4900 //----------PIPELINE CLASSES--------------------------------------------------- 4901 // Pipeline Classes describe the stages in which input and output are 4902 // referenced by the hardware pipeline. 4903 4904 // Simple pipeline classes. 4905 4906 // Default pipeline class. 4907 pipe_class pipe_class_default() %{ 4908 single_instruction; 4909 fixed_latency(2); 4910 %} 4911 4912 // Pipeline class for empty instructions. 4913 pipe_class pipe_class_empty() %{ 4914 single_instruction; 4915 fixed_latency(0); 4916 %} 4917 4918 // Pipeline class for compares. 4919 pipe_class pipe_class_compare() %{ 4920 single_instruction; 4921 fixed_latency(16); 4922 %} 4923 4924 // Pipeline class for traps. 4925 pipe_class pipe_class_trap() %{ 4926 single_instruction; 4927 fixed_latency(100); 4928 %} 4929 4930 // Pipeline class for memory operations. 4931 pipe_class pipe_class_memory() %{ 4932 single_instruction; 4933 fixed_latency(16); 4934 %} 4935 4936 // Pipeline class for call. 4937 pipe_class pipe_class_call() %{ 4938 single_instruction; 4939 fixed_latency(100); 4940 %} 4941 4942 // Define the class for the Nop node. 4943 define %{ 4944 MachNop = pipe_class_default; 4945 %} 4946 4947 %} 4948 4949 //----------INSTRUCTIONS------------------------------------------------------- 4950 4951 // Naming of instructions: 4952 // opA_operB / opA_operB_operC: 4953 // Operation 'op' with one or two source operands 'oper'. Result 4954 // type is A, source operand types are B and C. 4955 // Iff A == B == C, B and C are left out. 4956 // 4957 // The instructions are ordered according to the following scheme: 4958 // - loads 4959 // - load constants 4960 // - prefetch 4961 // - store 4962 // - encode/decode 4963 // - membar 4964 // - conditional moves 4965 // - compare & swap 4966 // - arithmetic and logic operations 4967 // * int: Add, Sub, Mul, Div, Mod 4968 // * int: lShift, arShift, urShift, rot 4969 // * float: Add, Sub, Mul, Div 4970 // * and, or, xor ... 4971 // - register moves: float <-> int, reg <-> stack, repl 4972 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 4973 // - conv (low level type cast requiring bit changes (sign extend etc) 4974 // - compares, range & zero checks. 4975 // - branches 4976 // - complex operations, intrinsics, min, max, replicate 4977 // - lock 4978 // - Calls 4979 // 4980 // If there are similar instructions with different types they are sorted: 4981 // int before float 4982 // small before big 4983 // signed before unsigned 4984 // e.g., loadS before loadUS before loadI before loadF. 4985 4986 4987 //----------Load/Store Instructions-------------------------------------------- 4988 4989 //----------Load Instructions-------------------------------------------------- 4990 4991 // Converts byte to int. 4992 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 4993 // reuses the 'amount' operand, but adlc expects that operand specification 4994 // and operands in match rule are equivalent. 4995 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 4996 effect(DEF dst, USE src); 4997 format %{ "EXTSB $dst, $src \t// byte->int" %} 4998 size(4); 4999 ins_encode %{ 5000 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5001 __ extsb($dst$$Register, $src$$Register); 5002 %} 5003 ins_pipe(pipe_class_default); 5004 %} 5005 5006 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5007 // match-rule, false predicate 5008 match(Set dst (LoadB mem)); 5009 predicate(false); 5010 5011 format %{ "LBZ $dst, $mem" %} 5012 size(4); 5013 ins_encode( enc_lbz(dst, mem) ); 5014 ins_pipe(pipe_class_memory); 5015 %} 5016 5017 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5018 // match-rule, false predicate 5019 match(Set dst (LoadB mem)); 5020 predicate(false); 5021 5022 format %{ "LBZ $dst, $mem\n\t" 5023 "TWI $dst\n\t" 5024 "ISYNC" %} 5025 size(12); 5026 ins_encode( enc_lbz_ac(dst, mem) ); 5027 ins_pipe(pipe_class_memory); 5028 %} 5029 5030 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5031 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5032 match(Set dst (LoadB mem)); 5033 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5034 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5035 expand %{ 5036 iRegIdst tmp; 5037 loadUB_indirect(tmp, mem); 5038 convB2I_reg_2(dst, tmp); 5039 %} 5040 %} 5041 5042 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5043 match(Set dst (LoadB mem)); 5044 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5045 expand %{ 5046 iRegIdst tmp; 5047 loadUB_indirect_ac(tmp, mem); 5048 convB2I_reg_2(dst, tmp); 5049 %} 5050 %} 5051 5052 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5053 // match-rule, false predicate 5054 match(Set dst (LoadB mem)); 5055 predicate(false); 5056 5057 format %{ "LBZ $dst, $mem" %} 5058 size(4); 5059 ins_encode( enc_lbz(dst, mem) ); 5060 ins_pipe(pipe_class_memory); 5061 %} 5062 5063 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5064 // match-rule, false predicate 5065 match(Set dst (LoadB mem)); 5066 predicate(false); 5067 5068 format %{ "LBZ $dst, $mem\n\t" 5069 "TWI $dst\n\t" 5070 "ISYNC" %} 5071 size(12); 5072 ins_encode( enc_lbz_ac(dst, mem) ); 5073 ins_pipe(pipe_class_memory); 5074 %} 5075 5076 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5077 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5078 match(Set dst (LoadB mem)); 5079 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5080 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5081 5082 expand %{ 5083 iRegIdst tmp; 5084 loadUB_indOffset16(tmp, mem); 5085 convB2I_reg_2(dst, tmp); 5086 %} 5087 %} 5088 5089 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5090 match(Set dst (LoadB mem)); 5091 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5092 5093 expand %{ 5094 iRegIdst tmp; 5095 loadUB_indOffset16_ac(tmp, mem); 5096 convB2I_reg_2(dst, tmp); 5097 %} 5098 %} 5099 5100 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5101 instruct loadUB(iRegIdst dst, memory mem) %{ 5102 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5103 match(Set dst (LoadUB mem)); 5104 ins_cost(MEMORY_REF_COST); 5105 5106 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5107 size(4); 5108 ins_encode( enc_lbz(dst, mem) ); 5109 ins_pipe(pipe_class_memory); 5110 %} 5111 5112 // Load Unsigned Byte (8bit UNsigned) acquire. 5113 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5114 match(Set dst (LoadUB mem)); 5115 ins_cost(3*MEMORY_REF_COST); 5116 5117 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5118 "TWI $dst\n\t" 5119 "ISYNC" %} 5120 size(12); 5121 ins_encode( enc_lbz_ac(dst, mem) ); 5122 ins_pipe(pipe_class_memory); 5123 %} 5124 5125 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5126 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5127 match(Set dst (ConvI2L (LoadUB mem))); 5128 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5129 ins_cost(MEMORY_REF_COST); 5130 5131 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5132 size(4); 5133 ins_encode( enc_lbz(dst, mem) ); 5134 ins_pipe(pipe_class_memory); 5135 %} 5136 5137 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5138 match(Set dst (ConvI2L (LoadUB mem))); 5139 ins_cost(3*MEMORY_REF_COST); 5140 5141 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5142 "TWI $dst\n\t" 5143 "ISYNC" %} 5144 size(12); 5145 ins_encode( enc_lbz_ac(dst, mem) ); 5146 ins_pipe(pipe_class_memory); 5147 %} 5148 5149 // Load Short (16bit signed) 5150 instruct loadS(iRegIdst dst, memory mem) %{ 5151 match(Set dst (LoadS mem)); 5152 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5153 ins_cost(MEMORY_REF_COST); 5154 5155 format %{ "LHA $dst, $mem" %} 5156 size(4); 5157 ins_encode %{ 5158 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5159 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5160 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5161 %} 5162 ins_pipe(pipe_class_memory); 5163 %} 5164 5165 // Load Short (16bit signed) acquire. 5166 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5167 match(Set dst (LoadS mem)); 5168 ins_cost(3*MEMORY_REF_COST); 5169 5170 format %{ "LHA $dst, $mem\t acquire\n\t" 5171 "TWI $dst\n\t" 5172 "ISYNC" %} 5173 size(12); 5174 ins_encode %{ 5175 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5176 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5177 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5178 __ twi_0($dst$$Register); 5179 __ isync(); 5180 %} 5181 ins_pipe(pipe_class_memory); 5182 %} 5183 5184 // Load Char (16bit unsigned) 5185 instruct loadUS(iRegIdst dst, memory mem) %{ 5186 match(Set dst (LoadUS mem)); 5187 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5188 ins_cost(MEMORY_REF_COST); 5189 5190 format %{ "LHZ $dst, $mem" %} 5191 size(4); 5192 ins_encode( enc_lhz(dst, mem) ); 5193 ins_pipe(pipe_class_memory); 5194 %} 5195 5196 // Load Char (16bit unsigned) acquire. 5197 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5198 match(Set dst (LoadUS mem)); 5199 ins_cost(3*MEMORY_REF_COST); 5200 5201 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5202 "TWI $dst\n\t" 5203 "ISYNC" %} 5204 size(12); 5205 ins_encode( enc_lhz_ac(dst, mem) ); 5206 ins_pipe(pipe_class_memory); 5207 %} 5208 5209 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5210 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5211 match(Set dst (ConvI2L (LoadUS mem))); 5212 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5213 ins_cost(MEMORY_REF_COST); 5214 5215 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5216 size(4); 5217 ins_encode( enc_lhz(dst, mem) ); 5218 ins_pipe(pipe_class_memory); 5219 %} 5220 5221 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5222 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5223 match(Set dst (ConvI2L (LoadUS mem))); 5224 ins_cost(3*MEMORY_REF_COST); 5225 5226 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5227 "TWI $dst\n\t" 5228 "ISYNC" %} 5229 size(12); 5230 ins_encode( enc_lhz_ac(dst, mem) ); 5231 ins_pipe(pipe_class_memory); 5232 %} 5233 5234 // Load Integer. 5235 instruct loadI(iRegIdst dst, memory mem) %{ 5236 match(Set dst (LoadI mem)); 5237 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5238 ins_cost(MEMORY_REF_COST); 5239 5240 format %{ "LWZ $dst, $mem" %} 5241 size(4); 5242 ins_encode( enc_lwz(dst, mem) ); 5243 ins_pipe(pipe_class_memory); 5244 %} 5245 5246 // Load Integer acquire. 5247 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5248 match(Set dst (LoadI mem)); 5249 ins_cost(3*MEMORY_REF_COST); 5250 5251 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5252 "TWI $dst\n\t" 5253 "ISYNC" %} 5254 size(12); 5255 ins_encode( enc_lwz_ac(dst, mem) ); 5256 ins_pipe(pipe_class_memory); 5257 %} 5258 5259 // Match loading integer and casting it to unsigned int in 5260 // long register. 5261 // LoadI + ConvI2L + AndL 0xffffffff. 5262 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5263 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5264 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5265 ins_cost(MEMORY_REF_COST); 5266 5267 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5268 size(4); 5269 ins_encode( enc_lwz(dst, mem) ); 5270 ins_pipe(pipe_class_memory); 5271 %} 5272 5273 // Match loading integer and casting it to long. 5274 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5275 match(Set dst (ConvI2L (LoadI mem))); 5276 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5277 ins_cost(MEMORY_REF_COST); 5278 5279 format %{ "LWA $dst, $mem \t// loadI2L" %} 5280 size(4); 5281 ins_encode %{ 5282 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5283 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5284 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5285 %} 5286 ins_pipe(pipe_class_memory); 5287 %} 5288 5289 // Match loading integer and casting it to long - acquire. 5290 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5291 match(Set dst (ConvI2L (LoadI mem))); 5292 ins_cost(3*MEMORY_REF_COST); 5293 5294 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5295 "TWI $dst\n\t" 5296 "ISYNC" %} 5297 size(12); 5298 ins_encode %{ 5299 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5300 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5301 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5302 __ twi_0($dst$$Register); 5303 __ isync(); 5304 %} 5305 ins_pipe(pipe_class_memory); 5306 %} 5307 5308 // Load Long - aligned 5309 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5310 match(Set dst (LoadL mem)); 5311 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5312 ins_cost(MEMORY_REF_COST); 5313 5314 format %{ "LD $dst, $mem \t// long" %} 5315 size(4); 5316 ins_encode( enc_ld(dst, mem) ); 5317 ins_pipe(pipe_class_memory); 5318 %} 5319 5320 // Load Long - aligned acquire. 5321 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5322 match(Set dst (LoadL mem)); 5323 ins_cost(3*MEMORY_REF_COST); 5324 5325 format %{ "LD $dst, $mem \t// long acquire\n\t" 5326 "TWI $dst\n\t" 5327 "ISYNC" %} 5328 size(12); 5329 ins_encode( enc_ld_ac(dst, mem) ); 5330 ins_pipe(pipe_class_memory); 5331 %} 5332 5333 // Load Long - UNaligned 5334 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5335 match(Set dst (LoadL_unaligned mem)); 5336 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5337 ins_cost(MEMORY_REF_COST); 5338 5339 format %{ "LD $dst, $mem \t// unaligned long" %} 5340 size(4); 5341 ins_encode( enc_ld(dst, mem) ); 5342 ins_pipe(pipe_class_memory); 5343 %} 5344 5345 // Load nodes for superwords 5346 5347 // Load Aligned Packed Byte 5348 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5349 predicate(n->as_LoadVector()->memory_size() == 8); 5350 match(Set dst (LoadVector mem)); 5351 ins_cost(MEMORY_REF_COST); 5352 5353 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5354 size(4); 5355 ins_encode( enc_ld(dst, mem) ); 5356 ins_pipe(pipe_class_memory); 5357 %} 5358 5359 // Load Range, range = array length (=jint) 5360 instruct loadRange(iRegIdst dst, memory mem) %{ 5361 match(Set dst (LoadRange mem)); 5362 ins_cost(MEMORY_REF_COST); 5363 5364 format %{ "LWZ $dst, $mem \t// range" %} 5365 size(4); 5366 ins_encode( enc_lwz(dst, mem) ); 5367 ins_pipe(pipe_class_memory); 5368 %} 5369 5370 // Load Compressed Pointer 5371 instruct loadN(iRegNdst dst, memory mem) %{ 5372 match(Set dst (LoadN mem)); 5373 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5374 ins_cost(MEMORY_REF_COST); 5375 5376 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5377 size(4); 5378 ins_encode( enc_lwz(dst, mem) ); 5379 ins_pipe(pipe_class_memory); 5380 %} 5381 5382 // Load Compressed Pointer acquire. 5383 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5384 match(Set dst (LoadN mem)); 5385 ins_cost(3*MEMORY_REF_COST); 5386 5387 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5388 "TWI $dst\n\t" 5389 "ISYNC" %} 5390 size(12); 5391 ins_encode( enc_lwz_ac(dst, mem) ); 5392 ins_pipe(pipe_class_memory); 5393 %} 5394 5395 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5396 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5397 match(Set dst (DecodeN (LoadN mem))); 5398 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5399 ins_cost(MEMORY_REF_COST); 5400 5401 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5402 size(4); 5403 ins_encode( enc_lwz(dst, mem) ); 5404 ins_pipe(pipe_class_memory); 5405 %} 5406 5407 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5408 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5409 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5410 _kids[0]->_leaf->as_Load()->is_unordered()); 5411 ins_cost(MEMORY_REF_COST); 5412 5413 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5414 size(4); 5415 ins_encode( enc_lwz(dst, mem) ); 5416 ins_pipe(pipe_class_memory); 5417 %} 5418 5419 // Load Pointer 5420 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5421 match(Set dst (LoadP mem)); 5422 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5423 ins_cost(MEMORY_REF_COST); 5424 5425 format %{ "LD $dst, $mem \t// ptr" %} 5426 size(4); 5427 ins_encode( enc_ld(dst, mem) ); 5428 ins_pipe(pipe_class_memory); 5429 %} 5430 5431 // Load Pointer acquire. 5432 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5433 match(Set dst (LoadP mem)); 5434 ins_cost(3*MEMORY_REF_COST); 5435 5436 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5437 "TWI $dst\n\t" 5438 "ISYNC" %} 5439 size(12); 5440 ins_encode( enc_ld_ac(dst, mem) ); 5441 ins_pipe(pipe_class_memory); 5442 %} 5443 5444 // LoadP + CastP2L 5445 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5446 match(Set dst (CastP2X (LoadP mem))); 5447 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5448 ins_cost(MEMORY_REF_COST); 5449 5450 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5451 size(4); 5452 ins_encode( enc_ld(dst, mem) ); 5453 ins_pipe(pipe_class_memory); 5454 %} 5455 5456 // Load compressed klass pointer. 5457 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5458 match(Set dst (LoadNKlass mem)); 5459 ins_cost(MEMORY_REF_COST); 5460 5461 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5462 size(4); 5463 ins_encode( enc_lwz(dst, mem) ); 5464 ins_pipe(pipe_class_memory); 5465 %} 5466 5467 // Load Klass Pointer 5468 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5469 match(Set dst (LoadKlass mem)); 5470 ins_cost(MEMORY_REF_COST); 5471 5472 format %{ "LD $dst, $mem \t// klass ptr" %} 5473 size(4); 5474 ins_encode( enc_ld(dst, mem) ); 5475 ins_pipe(pipe_class_memory); 5476 %} 5477 5478 // Load Float 5479 instruct loadF(regF dst, memory mem) %{ 5480 match(Set dst (LoadF mem)); 5481 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5482 ins_cost(MEMORY_REF_COST); 5483 5484 format %{ "LFS $dst, $mem" %} 5485 size(4); 5486 ins_encode %{ 5487 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5488 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5489 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5490 %} 5491 ins_pipe(pipe_class_memory); 5492 %} 5493 5494 // Load Float acquire. 5495 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5496 match(Set dst (LoadF mem)); 5497 effect(TEMP cr0); 5498 ins_cost(3*MEMORY_REF_COST); 5499 5500 format %{ "LFS $dst, $mem \t// acquire\n\t" 5501 "FCMPU cr0, $dst, $dst\n\t" 5502 "BNE cr0, next\n" 5503 "next:\n\t" 5504 "ISYNC" %} 5505 size(16); 5506 ins_encode %{ 5507 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5508 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5509 Label next; 5510 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5511 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5512 __ bne(CCR0, next); 5513 __ bind(next); 5514 __ isync(); 5515 %} 5516 ins_pipe(pipe_class_memory); 5517 %} 5518 5519 // Load Double - aligned 5520 instruct loadD(regD dst, memory mem) %{ 5521 match(Set dst (LoadD mem)); 5522 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5523 ins_cost(MEMORY_REF_COST); 5524 5525 format %{ "LFD $dst, $mem" %} 5526 size(4); 5527 ins_encode( enc_lfd(dst, mem) ); 5528 ins_pipe(pipe_class_memory); 5529 %} 5530 5531 // Load Double - aligned acquire. 5532 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5533 match(Set dst (LoadD mem)); 5534 effect(TEMP cr0); 5535 ins_cost(3*MEMORY_REF_COST); 5536 5537 format %{ "LFD $dst, $mem \t// acquire\n\t" 5538 "FCMPU cr0, $dst, $dst\n\t" 5539 "BNE cr0, next\n" 5540 "next:\n\t" 5541 "ISYNC" %} 5542 size(16); 5543 ins_encode %{ 5544 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5545 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5546 Label next; 5547 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5548 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5549 __ bne(CCR0, next); 5550 __ bind(next); 5551 __ isync(); 5552 %} 5553 ins_pipe(pipe_class_memory); 5554 %} 5555 5556 // Load Double - UNaligned 5557 instruct loadD_unaligned(regD dst, memory mem) %{ 5558 match(Set dst (LoadD_unaligned mem)); 5559 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5560 ins_cost(MEMORY_REF_COST); 5561 5562 format %{ "LFD $dst, $mem" %} 5563 size(4); 5564 ins_encode( enc_lfd(dst, mem) ); 5565 ins_pipe(pipe_class_memory); 5566 %} 5567 5568 //----------Constants-------------------------------------------------------- 5569 5570 // Load MachConstantTableBase: add hi offset to global toc. 5571 // TODO: Handle hidden register r29 in bundler! 5572 instruct loadToc_hi(iRegLdst dst) %{ 5573 effect(DEF dst); 5574 ins_cost(DEFAULT_COST); 5575 5576 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 5577 size(4); 5578 ins_encode %{ 5579 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5580 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 5581 %} 5582 ins_pipe(pipe_class_default); 5583 %} 5584 5585 // Load MachConstantTableBase: add lo offset to global toc. 5586 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 5587 effect(DEF dst, USE src); 5588 ins_cost(DEFAULT_COST); 5589 5590 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 5591 size(4); 5592 ins_encode %{ 5593 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5594 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 5595 %} 5596 ins_pipe(pipe_class_default); 5597 %} 5598 5599 // Load 16-bit integer constant 0xssss???? 5600 instruct loadConI16(iRegIdst dst, immI16 src) %{ 5601 match(Set dst src); 5602 5603 format %{ "LI $dst, $src" %} 5604 size(4); 5605 ins_encode %{ 5606 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5607 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 5608 %} 5609 ins_pipe(pipe_class_default); 5610 %} 5611 5612 // Load integer constant 0x????0000 5613 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 5614 match(Set dst src); 5615 ins_cost(DEFAULT_COST); 5616 5617 format %{ "LIS $dst, $src.hi" %} 5618 size(4); 5619 ins_encode %{ 5620 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5621 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 5622 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5623 %} 5624 ins_pipe(pipe_class_default); 5625 %} 5626 5627 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 5628 // and sign extended), this adds the low 16 bits. 5629 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 5630 // no match-rule, false predicate 5631 effect(DEF dst, USE src1, USE src2); 5632 predicate(false); 5633 5634 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 5635 size(4); 5636 ins_encode %{ 5637 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5638 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5639 %} 5640 ins_pipe(pipe_class_default); 5641 %} 5642 5643 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 5644 match(Set dst src); 5645 ins_cost(DEFAULT_COST*2); 5646 5647 expand %{ 5648 // Would like to use $src$$constant. 5649 immI16 srcLo %{ _opnds[1]->constant() %} 5650 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5651 immIhi16 srcHi %{ _opnds[1]->constant() %} 5652 iRegIdst tmpI; 5653 loadConIhi16(tmpI, srcHi); 5654 loadConI32_lo16(dst, tmpI, srcLo); 5655 %} 5656 %} 5657 5658 // No constant pool entries required. 5659 instruct loadConL16(iRegLdst dst, immL16 src) %{ 5660 match(Set dst src); 5661 5662 format %{ "LI $dst, $src \t// long" %} 5663 size(4); 5664 ins_encode %{ 5665 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5666 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 5667 %} 5668 ins_pipe(pipe_class_default); 5669 %} 5670 5671 // Load long constant 0xssssssss????0000 5672 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 5673 match(Set dst src); 5674 ins_cost(DEFAULT_COST); 5675 5676 format %{ "LIS $dst, $src.hi \t// long" %} 5677 size(4); 5678 ins_encode %{ 5679 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5680 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5681 %} 5682 ins_pipe(pipe_class_default); 5683 %} 5684 5685 // To load a 32 bit constant: merge lower 16 bits into already loaded 5686 // high 16 bits. 5687 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 5688 // no match-rule, false predicate 5689 effect(DEF dst, USE src1, USE src2); 5690 predicate(false); 5691 5692 format %{ "ORI $dst, $src1, $src2.lo" %} 5693 size(4); 5694 ins_encode %{ 5695 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5696 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5697 %} 5698 ins_pipe(pipe_class_default); 5699 %} 5700 5701 // Load 32-bit long constant 5702 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 5703 match(Set dst src); 5704 ins_cost(DEFAULT_COST*2); 5705 5706 expand %{ 5707 // Would like to use $src$$constant. 5708 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 5709 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5710 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 5711 iRegLdst tmpL; 5712 loadConL32hi16(tmpL, srcHi); 5713 loadConL32_lo16(dst, tmpL, srcLo); 5714 %} 5715 %} 5716 5717 // Load long constant 0x????000000000000. 5718 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 5719 match(Set dst src); 5720 ins_cost(DEFAULT_COST); 5721 5722 expand %{ 5723 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 5724 immI shift32 %{ 32 %} 5725 iRegLdst tmpL; 5726 loadConL32hi16(tmpL, srcHi); 5727 lshiftL_regL_immI(dst, tmpL, shift32); 5728 %} 5729 %} 5730 5731 // Expand node for constant pool load: small offset. 5732 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 5733 effect(DEF dst, USE src, USE toc); 5734 ins_cost(MEMORY_REF_COST); 5735 5736 ins_num_consts(1); 5737 // Needed so that CallDynamicJavaDirect can compute the address of this 5738 // instruction for relocation. 5739 ins_field_cbuf_insts_offset(int); 5740 5741 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 5742 size(4); 5743 ins_encode( enc_load_long_constL(dst, src, toc) ); 5744 ins_pipe(pipe_class_memory); 5745 %} 5746 5747 // Expand node for constant pool load: large offset. 5748 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 5749 effect(DEF dst, USE src, USE toc); 5750 predicate(false); 5751 5752 ins_num_consts(1); 5753 ins_field_const_toc_offset(int); 5754 // Needed so that CallDynamicJavaDirect can compute the address of this 5755 // instruction for relocation. 5756 ins_field_cbuf_insts_offset(int); 5757 5758 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 5759 size(4); 5760 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 5761 ins_pipe(pipe_class_default); 5762 %} 5763 5764 // Expand node for constant pool load: large offset. 5765 // No constant pool entries required. 5766 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 5767 effect(DEF dst, USE src, USE base); 5768 predicate(false); 5769 5770 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 5771 5772 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 5773 size(4); 5774 ins_encode %{ 5775 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 5776 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 5777 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 5778 %} 5779 ins_pipe(pipe_class_memory); 5780 %} 5781 5782 // Load long constant from constant table. Expand in case of 5783 // offset > 16 bit is needed. 5784 // Adlc adds toc node MachConstantTableBase. 5785 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 5786 match(Set dst src); 5787 ins_cost(MEMORY_REF_COST); 5788 5789 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 5790 // We can not inline the enc_class for the expand as that does not support constanttablebase. 5791 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 5792 %} 5793 5794 // Load NULL as compressed oop. 5795 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 5796 match(Set dst src); 5797 ins_cost(DEFAULT_COST); 5798 5799 format %{ "LI $dst, $src \t// compressed ptr" %} 5800 size(4); 5801 ins_encode %{ 5802 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5803 __ li($dst$$Register, 0); 5804 %} 5805 ins_pipe(pipe_class_default); 5806 %} 5807 5808 // Load hi part of compressed oop constant. 5809 instruct loadConN_hi(iRegNdst dst, immN src) %{ 5810 effect(DEF dst, USE src); 5811 ins_cost(DEFAULT_COST); 5812 5813 format %{ "LIS $dst, $src \t// narrow oop hi" %} 5814 size(4); 5815 ins_encode %{ 5816 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5817 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 5818 %} 5819 ins_pipe(pipe_class_default); 5820 %} 5821 5822 // Add lo part of compressed oop constant to already loaded hi part. 5823 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 5824 effect(DEF dst, USE src1, USE src2); 5825 ins_cost(DEFAULT_COST); 5826 5827 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 5828 size(4); 5829 ins_encode %{ 5830 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5831 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5832 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 5833 RelocationHolder rspec = oop_Relocation::spec(oop_index); 5834 __ relocate(rspec, 1); 5835 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 5836 %} 5837 ins_pipe(pipe_class_default); 5838 %} 5839 5840 // Needed to postalloc expand loadConN: ConN is loaded as ConI 5841 // leaving the upper 32 bits with sign-extension bits. 5842 // This clears these bits: dst = src & 0xFFFFFFFF. 5843 // TODO: Eventually call this maskN_regN_FFFFFFFF. 5844 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 5845 effect(DEF dst, USE src); 5846 predicate(false); 5847 5848 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 5849 size(4); 5850 ins_encode %{ 5851 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5852 __ clrldi($dst$$Register, $src$$Register, 0x20); 5853 %} 5854 ins_pipe(pipe_class_default); 5855 %} 5856 5857 // Optimize DecodeN for disjoint base. 5858 // Load base of compressed oops into a register 5859 instruct loadBase(iRegLdst dst) %{ 5860 effect(DEF dst); 5861 5862 format %{ "LoadConst $dst, heapbase" %} 5863 ins_encode %{ 5864 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5865 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 5866 %} 5867 ins_pipe(pipe_class_default); 5868 %} 5869 5870 // Loading ConN must be postalloc expanded so that edges between 5871 // the nodes are safe. They may not interfere with a safepoint. 5872 // GL TODO: This needs three instructions: better put this into the constant pool. 5873 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 5874 match(Set dst src); 5875 ins_cost(DEFAULT_COST*2); 5876 5877 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5878 postalloc_expand %{ 5879 MachNode *m1 = new loadConN_hiNode(); 5880 MachNode *m2 = new loadConN_loNode(); 5881 MachNode *m3 = new clearMs32bNode(); 5882 m1->add_req(NULL); 5883 m2->add_req(NULL, m1); 5884 m3->add_req(NULL, m2); 5885 m1->_opnds[0] = op_dst; 5886 m1->_opnds[1] = op_src; 5887 m2->_opnds[0] = op_dst; 5888 m2->_opnds[1] = op_dst; 5889 m2->_opnds[2] = op_src; 5890 m3->_opnds[0] = op_dst; 5891 m3->_opnds[1] = op_dst; 5892 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5893 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5894 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5895 nodes->push(m1); 5896 nodes->push(m2); 5897 nodes->push(m3); 5898 %} 5899 %} 5900 5901 // We have seen a safepoint between the hi and lo parts, and this node was handled 5902 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 5903 // not a narrow oop. 5904 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 5905 match(Set dst src); 5906 effect(DEF dst, USE src); 5907 ins_cost(DEFAULT_COST); 5908 5909 format %{ "LIS $dst, $src \t// narrow klass hi" %} 5910 size(4); 5911 ins_encode %{ 5912 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5913 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 5914 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 5915 %} 5916 ins_pipe(pipe_class_default); 5917 %} 5918 5919 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 5920 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5921 match(Set dst src1); 5922 effect(TEMP src2); 5923 ins_cost(DEFAULT_COST); 5924 5925 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 5926 size(4); 5927 ins_encode %{ 5928 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5929 __ clrldi($dst$$Register, $src2$$Register, 0x20); 5930 %} 5931 ins_pipe(pipe_class_default); 5932 %} 5933 5934 // This needs a match rule so that build_oop_map knows this is 5935 // not a narrow oop. 5936 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5937 match(Set dst src1); 5938 effect(TEMP src2); 5939 ins_cost(DEFAULT_COST); 5940 5941 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 5942 size(4); 5943 ins_encode %{ 5944 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5945 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 5946 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5947 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 5948 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 5949 5950 __ relocate(rspec, 1); 5951 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 5952 %} 5953 ins_pipe(pipe_class_default); 5954 %} 5955 5956 // Loading ConNKlass must be postalloc expanded so that edges between 5957 // the nodes are safe. They may not interfere with a safepoint. 5958 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 5959 match(Set dst src); 5960 ins_cost(DEFAULT_COST*2); 5961 5962 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5963 postalloc_expand %{ 5964 // Load high bits into register. Sign extended. 5965 MachNode *m1 = new loadConNKlass_hiNode(); 5966 m1->add_req(NULL); 5967 m1->_opnds[0] = op_dst; 5968 m1->_opnds[1] = op_src; 5969 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5970 nodes->push(m1); 5971 5972 MachNode *m2 = m1; 5973 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 5974 // Value might be 1-extended. Mask out these bits. 5975 m2 = new loadConNKlass_maskNode(); 5976 m2->add_req(NULL, m1); 5977 m2->_opnds[0] = op_dst; 5978 m2->_opnds[1] = op_src; 5979 m2->_opnds[2] = op_dst; 5980 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5981 nodes->push(m2); 5982 } 5983 5984 MachNode *m3 = new loadConNKlass_loNode(); 5985 m3->add_req(NULL, m2); 5986 m3->_opnds[0] = op_dst; 5987 m3->_opnds[1] = op_src; 5988 m3->_opnds[2] = op_dst; 5989 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5990 nodes->push(m3); 5991 %} 5992 %} 5993 5994 // 0x1 is used in object initialization (initial object header). 5995 // No constant pool entries required. 5996 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 5997 match(Set dst src); 5998 5999 format %{ "LI $dst, $src \t// ptr" %} 6000 size(4); 6001 ins_encode %{ 6002 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6003 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6004 %} 6005 ins_pipe(pipe_class_default); 6006 %} 6007 6008 // Expand node for constant pool load: small offset. 6009 // The match rule is needed to generate the correct bottom_type(), 6010 // however this node should never match. The use of predicate is not 6011 // possible since ADLC forbids predicates for chain rules. The higher 6012 // costs do not prevent matching in this case. For that reason the 6013 // operand immP_NM with predicate(false) is used. 6014 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6015 match(Set dst src); 6016 effect(TEMP toc); 6017 6018 ins_num_consts(1); 6019 6020 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6021 size(4); 6022 ins_encode( enc_load_long_constP(dst, src, toc) ); 6023 ins_pipe(pipe_class_memory); 6024 %} 6025 6026 // Expand node for constant pool load: large offset. 6027 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6028 effect(DEF dst, USE src, USE toc); 6029 predicate(false); 6030 6031 ins_num_consts(1); 6032 ins_field_const_toc_offset(int); 6033 6034 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6035 size(4); 6036 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6037 ins_pipe(pipe_class_default); 6038 %} 6039 6040 // Expand node for constant pool load: large offset. 6041 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6042 match(Set dst src); 6043 effect(TEMP base); 6044 6045 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6046 6047 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6048 size(4); 6049 ins_encode %{ 6050 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6051 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6052 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6053 %} 6054 ins_pipe(pipe_class_memory); 6055 %} 6056 6057 // Load pointer constant from constant table. Expand in case an 6058 // offset > 16 bit is needed. 6059 // Adlc adds toc node MachConstantTableBase. 6060 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6061 match(Set dst src); 6062 ins_cost(MEMORY_REF_COST); 6063 6064 // This rule does not use "expand" because then 6065 // the result type is not known to be an Oop. An ADLC 6066 // enhancement will be needed to make that work - not worth it! 6067 6068 // If this instruction rematerializes, it prolongs the live range 6069 // of the toc node, causing illegal graphs. 6070 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6071 ins_cannot_rematerialize(true); 6072 6073 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6074 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6075 %} 6076 6077 // Expand node for constant pool load: small offset. 6078 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6079 effect(DEF dst, USE src, USE toc); 6080 ins_cost(MEMORY_REF_COST); 6081 6082 ins_num_consts(1); 6083 6084 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6085 size(4); 6086 ins_encode %{ 6087 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6088 address float_address = __ float_constant($src$$constant); 6089 if (float_address == NULL) { 6090 ciEnv::current()->record_out_of_memory_failure(); 6091 return; 6092 } 6093 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6094 %} 6095 ins_pipe(pipe_class_memory); 6096 %} 6097 6098 // Expand node for constant pool load: large offset. 6099 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6100 effect(DEF dst, USE src, USE toc); 6101 ins_cost(MEMORY_REF_COST); 6102 6103 ins_num_consts(1); 6104 6105 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6106 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6107 "ADDIS $toc, $toc, -offset_hi"%} 6108 size(12); 6109 ins_encode %{ 6110 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6111 FloatRegister Rdst = $dst$$FloatRegister; 6112 Register Rtoc = $toc$$Register; 6113 address float_address = __ float_constant($src$$constant); 6114 if (float_address == NULL) { 6115 ciEnv::current()->record_out_of_memory_failure(); 6116 return; 6117 } 6118 int offset = __ offset_to_method_toc(float_address); 6119 int hi = (offset + (1<<15))>>16; 6120 int lo = offset - hi * (1<<16); 6121 6122 __ addis(Rtoc, Rtoc, hi); 6123 __ lfs(Rdst, lo, Rtoc); 6124 __ addis(Rtoc, Rtoc, -hi); 6125 %} 6126 ins_pipe(pipe_class_memory); 6127 %} 6128 6129 // Adlc adds toc node MachConstantTableBase. 6130 instruct loadConF_Ex(regF dst, immF src) %{ 6131 match(Set dst src); 6132 ins_cost(MEMORY_REF_COST); 6133 6134 // See loadConP. 6135 ins_cannot_rematerialize(true); 6136 6137 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6138 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6139 %} 6140 6141 // Expand node for constant pool load: small offset. 6142 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6143 effect(DEF dst, USE src, USE toc); 6144 ins_cost(MEMORY_REF_COST); 6145 6146 ins_num_consts(1); 6147 6148 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6149 size(4); 6150 ins_encode %{ 6151 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6152 address float_address = __ double_constant($src$$constant); 6153 if (float_address == NULL) { 6154 ciEnv::current()->record_out_of_memory_failure(); 6155 return; 6156 } 6157 int offset = __ offset_to_method_toc(float_address); 6158 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6159 %} 6160 ins_pipe(pipe_class_memory); 6161 %} 6162 6163 // Expand node for constant pool load: large offset. 6164 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6165 effect(DEF dst, USE src, USE toc); 6166 ins_cost(MEMORY_REF_COST); 6167 6168 ins_num_consts(1); 6169 6170 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6171 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6172 "ADDIS $toc, $toc, -offset_hi" %} 6173 size(12); 6174 ins_encode %{ 6175 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6176 FloatRegister Rdst = $dst$$FloatRegister; 6177 Register Rtoc = $toc$$Register; 6178 address float_address = __ double_constant($src$$constant); 6179 if (float_address == NULL) { 6180 ciEnv::current()->record_out_of_memory_failure(); 6181 return; 6182 } 6183 int offset = __ offset_to_method_toc(float_address); 6184 int hi = (offset + (1<<15))>>16; 6185 int lo = offset - hi * (1<<16); 6186 6187 __ addis(Rtoc, Rtoc, hi); 6188 __ lfd(Rdst, lo, Rtoc); 6189 __ addis(Rtoc, Rtoc, -hi); 6190 %} 6191 ins_pipe(pipe_class_memory); 6192 %} 6193 6194 // Adlc adds toc node MachConstantTableBase. 6195 instruct loadConD_Ex(regD dst, immD src) %{ 6196 match(Set dst src); 6197 ins_cost(MEMORY_REF_COST); 6198 6199 // See loadConP. 6200 ins_cannot_rematerialize(true); 6201 6202 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6203 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6204 %} 6205 6206 // Prefetch instructions. 6207 // Must be safe to execute with invalid address (cannot fault). 6208 6209 // Special prefetch versions which use the dcbz instruction. 6210 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6211 match(PrefetchAllocation (AddP mem src)); 6212 predicate(AllocatePrefetchStyle == 3); 6213 ins_cost(MEMORY_REF_COST); 6214 6215 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6216 size(4); 6217 ins_encode %{ 6218 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6219 __ dcbz($src$$Register, $mem$$base$$Register); 6220 %} 6221 ins_pipe(pipe_class_memory); 6222 %} 6223 6224 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6225 match(PrefetchAllocation mem); 6226 predicate(AllocatePrefetchStyle == 3); 6227 ins_cost(MEMORY_REF_COST); 6228 6229 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6230 size(4); 6231 ins_encode %{ 6232 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6233 __ dcbz($mem$$base$$Register); 6234 %} 6235 ins_pipe(pipe_class_memory); 6236 %} 6237 6238 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6239 match(PrefetchAllocation (AddP mem src)); 6240 predicate(AllocatePrefetchStyle != 3); 6241 ins_cost(MEMORY_REF_COST); 6242 6243 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6244 size(4); 6245 ins_encode %{ 6246 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6247 __ dcbtst($src$$Register, $mem$$base$$Register); 6248 %} 6249 ins_pipe(pipe_class_memory); 6250 %} 6251 6252 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6253 match(PrefetchAllocation mem); 6254 predicate(AllocatePrefetchStyle != 3); 6255 ins_cost(MEMORY_REF_COST); 6256 6257 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6258 size(4); 6259 ins_encode %{ 6260 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6261 __ dcbtst($mem$$base$$Register); 6262 %} 6263 ins_pipe(pipe_class_memory); 6264 %} 6265 6266 //----------Store Instructions------------------------------------------------- 6267 6268 // Store Byte 6269 instruct storeB(memory mem, iRegIsrc src) %{ 6270 match(Set mem (StoreB mem src)); 6271 ins_cost(MEMORY_REF_COST); 6272 6273 format %{ "STB $src, $mem \t// byte" %} 6274 size(4); 6275 ins_encode %{ 6276 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6277 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6278 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6279 %} 6280 ins_pipe(pipe_class_memory); 6281 %} 6282 6283 // Store Char/Short 6284 instruct storeC(memory mem, iRegIsrc src) %{ 6285 match(Set mem (StoreC mem src)); 6286 ins_cost(MEMORY_REF_COST); 6287 6288 format %{ "STH $src, $mem \t// short" %} 6289 size(4); 6290 ins_encode %{ 6291 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6292 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6293 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6294 %} 6295 ins_pipe(pipe_class_memory); 6296 %} 6297 6298 // Store Integer 6299 instruct storeI(memory mem, iRegIsrc src) %{ 6300 match(Set mem (StoreI mem src)); 6301 ins_cost(MEMORY_REF_COST); 6302 6303 format %{ "STW $src, $mem" %} 6304 size(4); 6305 ins_encode( enc_stw(src, mem) ); 6306 ins_pipe(pipe_class_memory); 6307 %} 6308 6309 // ConvL2I + StoreI. 6310 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6311 match(Set mem (StoreI mem (ConvL2I src))); 6312 ins_cost(MEMORY_REF_COST); 6313 6314 format %{ "STW l2i($src), $mem" %} 6315 size(4); 6316 ins_encode( enc_stw(src, mem) ); 6317 ins_pipe(pipe_class_memory); 6318 %} 6319 6320 // Store Long 6321 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6322 match(Set mem (StoreL mem src)); 6323 ins_cost(MEMORY_REF_COST); 6324 6325 format %{ "STD $src, $mem \t// long" %} 6326 size(4); 6327 ins_encode( enc_std(src, mem) ); 6328 ins_pipe(pipe_class_memory); 6329 %} 6330 6331 // Store super word nodes. 6332 6333 // Store Aligned Packed Byte long register to memory 6334 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6335 predicate(n->as_StoreVector()->memory_size() == 8); 6336 match(Set mem (StoreVector mem src)); 6337 ins_cost(MEMORY_REF_COST); 6338 6339 format %{ "STD $mem, $src \t// packed8B" %} 6340 size(4); 6341 ins_encode( enc_std(src, mem) ); 6342 ins_pipe(pipe_class_memory); 6343 %} 6344 6345 // Store Compressed Oop 6346 instruct storeN(memory dst, iRegN_P2N src) %{ 6347 match(Set dst (StoreN dst src)); 6348 ins_cost(MEMORY_REF_COST); 6349 6350 format %{ "STW $src, $dst \t// compressed oop" %} 6351 size(4); 6352 ins_encode( enc_stw(src, dst) ); 6353 ins_pipe(pipe_class_memory); 6354 %} 6355 6356 // Store Compressed KLass 6357 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6358 match(Set dst (StoreNKlass dst src)); 6359 ins_cost(MEMORY_REF_COST); 6360 6361 format %{ "STW $src, $dst \t// compressed klass" %} 6362 size(4); 6363 ins_encode( enc_stw(src, dst) ); 6364 ins_pipe(pipe_class_memory); 6365 %} 6366 6367 // Store Pointer 6368 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6369 match(Set dst (StoreP dst src)); 6370 ins_cost(MEMORY_REF_COST); 6371 6372 format %{ "STD $src, $dst \t// ptr" %} 6373 size(4); 6374 ins_encode( enc_std(src, dst) ); 6375 ins_pipe(pipe_class_memory); 6376 %} 6377 6378 // Store Float 6379 instruct storeF(memory mem, regF src) %{ 6380 match(Set mem (StoreF mem src)); 6381 ins_cost(MEMORY_REF_COST); 6382 6383 format %{ "STFS $src, $mem" %} 6384 size(4); 6385 ins_encode( enc_stfs(src, mem) ); 6386 ins_pipe(pipe_class_memory); 6387 %} 6388 6389 // Store Double 6390 instruct storeD(memory mem, regD src) %{ 6391 match(Set mem (StoreD mem src)); 6392 ins_cost(MEMORY_REF_COST); 6393 6394 format %{ "STFD $src, $mem" %} 6395 size(4); 6396 ins_encode( enc_stfd(src, mem) ); 6397 ins_pipe(pipe_class_memory); 6398 %} 6399 6400 //----------Store Instructions With Zeros-------------------------------------- 6401 6402 // Card-mark for CMS garbage collection. 6403 // This cardmark does an optimization so that it must not always 6404 // do a releasing store. For this, it gets the address of 6405 // CMSCollectorCardTableModRefBSExt::_requires_release as input. 6406 // (Using releaseFieldAddr in the match rule is a hack.) 6407 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6408 match(Set mem (StoreCM mem releaseFieldAddr)); 6409 effect(TEMP crx); 6410 predicate(false); 6411 ins_cost(MEMORY_REF_COST); 6412 6413 // See loadConP. 6414 ins_cannot_rematerialize(true); 6415 6416 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6417 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6418 ins_pipe(pipe_class_memory); 6419 %} 6420 6421 // Card-mark for CMS garbage collection. 6422 // This cardmark does an optimization so that it must not always 6423 // do a releasing store. For this, it needs the constant address of 6424 // CMSCollectorCardTableModRefBSExt::_requires_release. 6425 // This constant address is split off here by expand so we can use 6426 // adlc / matcher functionality to load it from the constant section. 6427 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6428 match(Set mem (StoreCM mem zero)); 6429 predicate(UseConcMarkSweepGC); 6430 6431 expand %{ 6432 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableModRefBSExt::requires_release_address() */ %} 6433 iRegLdst releaseFieldAddress; 6434 flagsReg crx; 6435 loadConL_Ex(releaseFieldAddress, baseImm); 6436 storeCM_CMS(mem, releaseFieldAddress, crx); 6437 %} 6438 %} 6439 6440 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6441 match(Set mem (StoreCM mem zero)); 6442 predicate(UseG1GC); 6443 ins_cost(MEMORY_REF_COST); 6444 6445 ins_cannot_rematerialize(true); 6446 6447 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6448 size(8); 6449 ins_encode %{ 6450 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6451 __ li(R0, 0); 6452 //__ release(); // G1: oops are allowed to get visible after dirty marking 6453 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6454 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6455 %} 6456 ins_pipe(pipe_class_memory); 6457 %} 6458 6459 // Convert oop pointer into compressed form. 6460 6461 // Nodes for postalloc expand. 6462 6463 // Shift node for expand. 6464 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6465 // The match rule is needed to make it a 'MachTypeNode'! 6466 match(Set dst (EncodeP src)); 6467 predicate(false); 6468 6469 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6470 size(4); 6471 ins_encode %{ 6472 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6473 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6474 %} 6475 ins_pipe(pipe_class_default); 6476 %} 6477 6478 // Add node for expand. 6479 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6480 // The match rule is needed to make it a 'MachTypeNode'! 6481 match(Set dst (EncodeP src)); 6482 predicate(false); 6483 6484 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6485 ins_encode %{ 6486 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6487 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6488 %} 6489 ins_pipe(pipe_class_default); 6490 %} 6491 6492 // Conditional sub base. 6493 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6494 // The match rule is needed to make it a 'MachTypeNode'! 6495 match(Set dst (EncodeP (Binary crx src1))); 6496 predicate(false); 6497 6498 format %{ "BEQ $crx, done\n\t" 6499 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6500 "done:" %} 6501 ins_encode %{ 6502 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6503 Label done; 6504 __ beq($crx$$CondRegister, done); 6505 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6506 __ bind(done); 6507 %} 6508 ins_pipe(pipe_class_default); 6509 %} 6510 6511 // Power 7 can use isel instruction 6512 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6513 // The match rule is needed to make it a 'MachTypeNode'! 6514 match(Set dst (EncodeP (Binary crx src1))); 6515 predicate(false); 6516 6517 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6518 size(4); 6519 ins_encode %{ 6520 // This is a Power7 instruction for which no machine description exists. 6521 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6522 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6523 %} 6524 ins_pipe(pipe_class_default); 6525 %} 6526 6527 // Disjoint narrow oop base. 6528 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6529 match(Set dst (EncodeP src)); 6530 predicate(Universe::narrow_oop_base_disjoint()); 6531 6532 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6533 size(4); 6534 ins_encode %{ 6535 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6536 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 6537 %} 6538 ins_pipe(pipe_class_default); 6539 %} 6540 6541 // shift != 0, base != 0 6542 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6543 match(Set dst (EncodeP src)); 6544 effect(TEMP crx); 6545 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6546 Universe::narrow_oop_shift() != 0 && 6547 Universe::narrow_oop_base_overlaps()); 6548 6549 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 6550 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 6551 %} 6552 6553 // shift != 0, base != 0 6554 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 6555 match(Set dst (EncodeP src)); 6556 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 6557 Universe::narrow_oop_shift() != 0 && 6558 Universe::narrow_oop_base_overlaps()); 6559 6560 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 6561 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 6562 %} 6563 6564 // shift != 0, base == 0 6565 // TODO: This is the same as encodeP_shift. Merge! 6566 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 6567 match(Set dst (EncodeP src)); 6568 predicate(Universe::narrow_oop_shift() != 0 && 6569 Universe::narrow_oop_base() ==0); 6570 6571 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 6572 size(4); 6573 ins_encode %{ 6574 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6575 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6576 %} 6577 ins_pipe(pipe_class_default); 6578 %} 6579 6580 // Compressed OOPs with narrow_oop_shift == 0. 6581 // shift == 0, base == 0 6582 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 6583 match(Set dst (EncodeP src)); 6584 predicate(Universe::narrow_oop_shift() == 0); 6585 6586 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 6587 // variable size, 0 or 4. 6588 ins_encode %{ 6589 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6590 __ mr_if_needed($dst$$Register, $src$$Register); 6591 %} 6592 ins_pipe(pipe_class_default); 6593 %} 6594 6595 // Decode nodes. 6596 6597 // Shift node for expand. 6598 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 6599 // The match rule is needed to make it a 'MachTypeNode'! 6600 match(Set dst (DecodeN src)); 6601 predicate(false); 6602 6603 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 6604 size(4); 6605 ins_encode %{ 6606 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6607 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6608 %} 6609 ins_pipe(pipe_class_default); 6610 %} 6611 6612 // Add node for expand. 6613 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 6614 // The match rule is needed to make it a 'MachTypeNode'! 6615 match(Set dst (DecodeN src)); 6616 predicate(false); 6617 6618 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 6619 ins_encode %{ 6620 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6621 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6622 %} 6623 ins_pipe(pipe_class_default); 6624 %} 6625 6626 // conditianal add base for expand 6627 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 6628 // The match rule is needed to make it a 'MachTypeNode'! 6629 // NOTICE that the rule is nonsense - we just have to make sure that: 6630 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6631 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6632 match(Set dst (DecodeN (Binary crx src))); 6633 predicate(false); 6634 6635 format %{ "BEQ $crx, done\n\t" 6636 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 6637 "done:" %} 6638 ins_encode %{ 6639 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6640 Label done; 6641 __ beq($crx$$CondRegister, done); 6642 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6643 __ bind(done); 6644 %} 6645 ins_pipe(pipe_class_default); 6646 %} 6647 6648 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6649 // The match rule is needed to make it a 'MachTypeNode'! 6650 // NOTICE that the rule is nonsense - we just have to make sure that: 6651 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6652 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6653 match(Set dst (DecodeN (Binary crx src1))); 6654 predicate(false); 6655 6656 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 6657 size(4); 6658 ins_encode %{ 6659 // This is a Power7 instruction for which no machine description exists. 6660 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6661 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6662 %} 6663 ins_pipe(pipe_class_default); 6664 %} 6665 6666 // shift != 0, base != 0 6667 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6668 match(Set dst (DecodeN src)); 6669 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6670 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6671 Universe::narrow_oop_shift() != 0 && 6672 Universe::narrow_oop_base() != 0); 6673 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 6674 effect(TEMP crx); 6675 6676 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 6677 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 6678 %} 6679 6680 // shift != 0, base == 0 6681 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 6682 match(Set dst (DecodeN src)); 6683 predicate(Universe::narrow_oop_shift() != 0 && 6684 Universe::narrow_oop_base() == 0); 6685 6686 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 6687 size(4); 6688 ins_encode %{ 6689 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6690 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6691 %} 6692 ins_pipe(pipe_class_default); 6693 %} 6694 6695 // Optimize DecodeN for disjoint base. 6696 // Shift narrow oop and or it into register that already contains the heap base. 6697 // Base == dst must hold, and is assured by construction in postaloc_expand. 6698 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 6699 match(Set dst (DecodeN src)); 6700 effect(TEMP base); 6701 predicate(false); 6702 6703 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 6704 size(4); 6705 ins_encode %{ 6706 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 6707 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 6708 %} 6709 ins_pipe(pipe_class_default); 6710 %} 6711 6712 // Optimize DecodeN for disjoint base. 6713 // This node requires only one cycle on the critical path. 6714 // We must postalloc_expand as we can not express use_def effects where 6715 // the used register is L and the def'ed register P. 6716 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 6717 match(Set dst (DecodeN src)); 6718 effect(TEMP_DEF dst); 6719 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6720 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6721 Universe::narrow_oop_base_disjoint()); 6722 ins_cost(DEFAULT_COST); 6723 6724 format %{ "MOV $dst, heapbase \t\n" 6725 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 6726 postalloc_expand %{ 6727 loadBaseNode *n1 = new loadBaseNode(); 6728 n1->add_req(NULL); 6729 n1->_opnds[0] = op_dst; 6730 6731 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6732 n2->add_req(n_region, n_src, n1); 6733 n2->_opnds[0] = op_dst; 6734 n2->_opnds[1] = op_src; 6735 n2->_opnds[2] = op_dst; 6736 n2->_bottom_type = _bottom_type; 6737 6738 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6739 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6740 6741 nodes->push(n1); 6742 nodes->push(n2); 6743 %} 6744 %} 6745 6746 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6747 match(Set dst (DecodeN src)); 6748 effect(TEMP_DEF dst, TEMP crx); 6749 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6750 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6751 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 6752 ins_cost(3 * DEFAULT_COST); 6753 6754 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 6755 postalloc_expand %{ 6756 loadBaseNode *n1 = new loadBaseNode(); 6757 n1->add_req(NULL); 6758 n1->_opnds[0] = op_dst; 6759 6760 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 6761 n_compare->add_req(n_region, n_src); 6762 n_compare->_opnds[0] = op_crx; 6763 n_compare->_opnds[1] = op_src; 6764 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 6765 6766 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6767 n2->add_req(n_region, n_src, n1); 6768 n2->_opnds[0] = op_dst; 6769 n2->_opnds[1] = op_src; 6770 n2->_opnds[2] = op_dst; 6771 n2->_bottom_type = _bottom_type; 6772 6773 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 6774 n_cond_set->add_req(n_region, n_compare, n2); 6775 n_cond_set->_opnds[0] = op_dst; 6776 n_cond_set->_opnds[1] = op_crx; 6777 n_cond_set->_opnds[2] = op_dst; 6778 n_cond_set->_bottom_type = _bottom_type; 6779 6780 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 6781 ra_->set_oop(n_cond_set, true); 6782 6783 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6784 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 6785 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6786 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6787 6788 nodes->push(n1); 6789 nodes->push(n_compare); 6790 nodes->push(n2); 6791 nodes->push(n_cond_set); 6792 %} 6793 %} 6794 6795 // src != 0, shift != 0, base != 0 6796 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 6797 match(Set dst (DecodeN src)); 6798 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6799 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6800 Universe::narrow_oop_shift() != 0 && 6801 Universe::narrow_oop_base() != 0); 6802 ins_cost(2 * DEFAULT_COST); 6803 6804 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 6805 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 6806 %} 6807 6808 // Compressed OOPs with narrow_oop_shift == 0. 6809 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 6810 match(Set dst (DecodeN src)); 6811 predicate(Universe::narrow_oop_shift() == 0); 6812 ins_cost(DEFAULT_COST); 6813 6814 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 6815 // variable size, 0 or 4. 6816 ins_encode %{ 6817 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6818 __ mr_if_needed($dst$$Register, $src$$Register); 6819 %} 6820 ins_pipe(pipe_class_default); 6821 %} 6822 6823 // Convert compressed oop into int for vectors alignment masking. 6824 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 6825 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6826 predicate(Universe::narrow_oop_shift() == 0); 6827 ins_cost(DEFAULT_COST); 6828 6829 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 6830 // variable size, 0 or 4. 6831 ins_encode %{ 6832 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6833 __ mr_if_needed($dst$$Register, $src$$Register); 6834 %} 6835 ins_pipe(pipe_class_default); 6836 %} 6837 6838 // Convert klass pointer into compressed form. 6839 6840 // Nodes for postalloc expand. 6841 6842 // Shift node for expand. 6843 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 6844 // The match rule is needed to make it a 'MachTypeNode'! 6845 match(Set dst (EncodePKlass src)); 6846 predicate(false); 6847 6848 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6849 size(4); 6850 ins_encode %{ 6851 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6852 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6853 %} 6854 ins_pipe(pipe_class_default); 6855 %} 6856 6857 // Add node for expand. 6858 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6859 // The match rule is needed to make it a 'MachTypeNode'! 6860 match(Set dst (EncodePKlass (Binary base src))); 6861 predicate(false); 6862 6863 format %{ "SUB $dst, $base, $src \t// encode" %} 6864 size(4); 6865 ins_encode %{ 6866 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 6867 __ subf($dst$$Register, $base$$Register, $src$$Register); 6868 %} 6869 ins_pipe(pipe_class_default); 6870 %} 6871 6872 // Disjoint narrow oop base. 6873 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6874 match(Set dst (EncodePKlass src)); 6875 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 6876 6877 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6878 size(4); 6879 ins_encode %{ 6880 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6881 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 6882 %} 6883 ins_pipe(pipe_class_default); 6884 %} 6885 6886 // shift != 0, base != 0 6887 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 6888 match(Set dst (EncodePKlass (Binary base src))); 6889 predicate(false); 6890 6891 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6892 postalloc_expand %{ 6893 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 6894 n1->add_req(n_region, n_base, n_src); 6895 n1->_opnds[0] = op_dst; 6896 n1->_opnds[1] = op_base; 6897 n1->_opnds[2] = op_src; 6898 n1->_bottom_type = _bottom_type; 6899 6900 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 6901 n2->add_req(n_region, n1); 6902 n2->_opnds[0] = op_dst; 6903 n2->_opnds[1] = op_dst; 6904 n2->_bottom_type = _bottom_type; 6905 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6906 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6907 6908 nodes->push(n1); 6909 nodes->push(n2); 6910 %} 6911 %} 6912 6913 // shift != 0, base != 0 6914 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 6915 match(Set dst (EncodePKlass src)); 6916 //predicate(Universe::narrow_klass_shift() != 0 && 6917 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 6918 6919 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6920 ins_cost(DEFAULT_COST*2); // Don't count constant. 6921 expand %{ 6922 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 6923 iRegLdst base; 6924 loadConL_Ex(base, baseImm); 6925 encodePKlass_not_null_Ex(dst, base, src); 6926 %} 6927 %} 6928 6929 // Decode nodes. 6930 6931 // Shift node for expand. 6932 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 6933 // The match rule is needed to make it a 'MachTypeNode'! 6934 match(Set dst (DecodeNKlass src)); 6935 predicate(false); 6936 6937 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 6938 size(4); 6939 ins_encode %{ 6940 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6941 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6942 %} 6943 ins_pipe(pipe_class_default); 6944 %} 6945 6946 // Add node for expand. 6947 6948 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6949 // The match rule is needed to make it a 'MachTypeNode'! 6950 match(Set dst (DecodeNKlass (Binary base src))); 6951 predicate(false); 6952 6953 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 6954 size(4); 6955 ins_encode %{ 6956 // TODO: PPC port $archOpcode(ppc64Opcode_add); 6957 __ add($dst$$Register, $base$$Register, $src$$Register); 6958 %} 6959 ins_pipe(pipe_class_default); 6960 %} 6961 6962 // src != 0, shift != 0, base != 0 6963 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 6964 match(Set dst (DecodeNKlass (Binary base src))); 6965 //effect(kill src); // We need a register for the immediate result after shifting. 6966 predicate(false); 6967 6968 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 6969 postalloc_expand %{ 6970 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 6971 n1->add_req(n_region, n_base, n_src); 6972 n1->_opnds[0] = op_dst; 6973 n1->_opnds[1] = op_base; 6974 n1->_opnds[2] = op_src; 6975 n1->_bottom_type = _bottom_type; 6976 6977 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 6978 n2->add_req(n_region, n1); 6979 n2->_opnds[0] = op_dst; 6980 n2->_opnds[1] = op_dst; 6981 n2->_bottom_type = _bottom_type; 6982 6983 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6984 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6985 6986 nodes->push(n1); 6987 nodes->push(n2); 6988 %} 6989 %} 6990 6991 // src != 0, shift != 0, base != 0 6992 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 6993 match(Set dst (DecodeNKlass src)); 6994 // predicate(Universe::narrow_klass_shift() != 0 && 6995 // Universe::narrow_klass_base() != 0); 6996 6997 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 6998 6999 ins_cost(DEFAULT_COST*2); // Don't count constant. 7000 expand %{ 7001 // We add first, then we shift. Like this, we can get along with one register less. 7002 // But we have to load the base pre-shifted. 7003 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7004 iRegLdst base; 7005 loadConL_Ex(base, baseImm); 7006 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7007 %} 7008 %} 7009 7010 //----------MemBar Instructions----------------------------------------------- 7011 // Memory barrier flavors 7012 7013 instruct membar_acquire() %{ 7014 match(LoadFence); 7015 ins_cost(4*MEMORY_REF_COST); 7016 7017 format %{ "MEMBAR-acquire" %} 7018 size(4); 7019 ins_encode %{ 7020 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7021 __ acquire(); 7022 %} 7023 ins_pipe(pipe_class_default); 7024 %} 7025 7026 instruct unnecessary_membar_acquire() %{ 7027 match(MemBarAcquire); 7028 ins_cost(0); 7029 7030 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7031 size(0); 7032 ins_encode( /*empty*/ ); 7033 ins_pipe(pipe_class_default); 7034 %} 7035 7036 instruct membar_acquire_lock() %{ 7037 match(MemBarAcquireLock); 7038 ins_cost(0); 7039 7040 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7041 size(0); 7042 ins_encode( /*empty*/ ); 7043 ins_pipe(pipe_class_default); 7044 %} 7045 7046 instruct membar_release() %{ 7047 match(MemBarRelease); 7048 match(StoreFence); 7049 ins_cost(4*MEMORY_REF_COST); 7050 7051 format %{ "MEMBAR-release" %} 7052 size(4); 7053 ins_encode %{ 7054 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7055 __ release(); 7056 %} 7057 ins_pipe(pipe_class_default); 7058 %} 7059 7060 instruct membar_storestore() %{ 7061 match(MemBarStoreStore); 7062 ins_cost(4*MEMORY_REF_COST); 7063 7064 format %{ "MEMBAR-store-store" %} 7065 size(4); 7066 ins_encode %{ 7067 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7068 __ membar(Assembler::StoreStore); 7069 %} 7070 ins_pipe(pipe_class_default); 7071 %} 7072 7073 instruct membar_release_lock() %{ 7074 match(MemBarReleaseLock); 7075 ins_cost(0); 7076 7077 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7078 size(0); 7079 ins_encode( /*empty*/ ); 7080 ins_pipe(pipe_class_default); 7081 %} 7082 7083 instruct membar_volatile() %{ 7084 match(MemBarVolatile); 7085 ins_cost(4*MEMORY_REF_COST); 7086 7087 format %{ "MEMBAR-volatile" %} 7088 size(4); 7089 ins_encode %{ 7090 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7091 __ fence(); 7092 %} 7093 ins_pipe(pipe_class_default); 7094 %} 7095 7096 // This optimization is wrong on PPC. The following pattern is not supported: 7097 // MemBarVolatile 7098 // ^ ^ 7099 // | | 7100 // CtrlProj MemProj 7101 // ^ ^ 7102 // | | 7103 // | Load 7104 // | 7105 // MemBarVolatile 7106 // 7107 // The first MemBarVolatile could get optimized out! According to 7108 // Vladimir, this pattern can not occur on Oracle platforms. 7109 // However, it does occur on PPC64 (because of membars in 7110 // inline_unsafe_load_store). 7111 // 7112 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7113 // Don't forget to look at the implementation of post_store_load_barrier again, 7114 // we did other fixes in that method. 7115 //instruct unnecessary_membar_volatile() %{ 7116 // match(MemBarVolatile); 7117 // predicate(Matcher::post_store_load_barrier(n)); 7118 // ins_cost(0); 7119 // 7120 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7121 // size(0); 7122 // ins_encode( /*empty*/ ); 7123 // ins_pipe(pipe_class_default); 7124 //%} 7125 7126 instruct membar_CPUOrder() %{ 7127 match(MemBarCPUOrder); 7128 ins_cost(0); 7129 7130 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7131 size(0); 7132 ins_encode( /*empty*/ ); 7133 ins_pipe(pipe_class_default); 7134 %} 7135 7136 //----------Conditional Move--------------------------------------------------- 7137 7138 // Cmove using isel. 7139 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7140 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7141 predicate(VM_Version::has_isel()); 7142 ins_cost(DEFAULT_COST); 7143 7144 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7145 size(4); 7146 ins_encode %{ 7147 // This is a Power7 instruction for which no machine description 7148 // exists. Anyways, the scheduler should be off on Power7. 7149 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7150 int cc = $cmp$$cmpcode; 7151 __ isel($dst$$Register, $crx$$CondRegister, 7152 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7153 %} 7154 ins_pipe(pipe_class_default); 7155 %} 7156 7157 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7158 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7159 predicate(!VM_Version::has_isel()); 7160 ins_cost(DEFAULT_COST+BRANCH_COST); 7161 7162 ins_variable_size_depending_on_alignment(true); 7163 7164 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7165 // Worst case is branch + move + stop, no stop without scheduler 7166 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7167 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7168 ins_pipe(pipe_class_default); 7169 %} 7170 7171 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7172 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7173 ins_cost(DEFAULT_COST+BRANCH_COST); 7174 7175 ins_variable_size_depending_on_alignment(true); 7176 7177 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7178 // Worst case is branch + move + stop, no stop without scheduler 7179 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7180 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7181 ins_pipe(pipe_class_default); 7182 %} 7183 7184 // Cmove using isel. 7185 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7186 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7187 predicate(VM_Version::has_isel()); 7188 ins_cost(DEFAULT_COST); 7189 7190 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7191 size(4); 7192 ins_encode %{ 7193 // This is a Power7 instruction for which no machine description 7194 // exists. Anyways, the scheduler should be off on Power7. 7195 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7196 int cc = $cmp$$cmpcode; 7197 __ isel($dst$$Register, $crx$$CondRegister, 7198 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7199 %} 7200 ins_pipe(pipe_class_default); 7201 %} 7202 7203 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7204 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7205 predicate(!VM_Version::has_isel()); 7206 ins_cost(DEFAULT_COST+BRANCH_COST); 7207 7208 ins_variable_size_depending_on_alignment(true); 7209 7210 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7211 // Worst case is branch + move + stop, no stop without scheduler. 7212 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7213 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7214 ins_pipe(pipe_class_default); 7215 %} 7216 7217 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7218 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7219 ins_cost(DEFAULT_COST+BRANCH_COST); 7220 7221 ins_variable_size_depending_on_alignment(true); 7222 7223 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7224 // Worst case is branch + move + stop, no stop without scheduler. 7225 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7226 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7227 ins_pipe(pipe_class_default); 7228 %} 7229 7230 // Cmove using isel. 7231 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7232 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7233 predicate(VM_Version::has_isel()); 7234 ins_cost(DEFAULT_COST); 7235 7236 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7237 size(4); 7238 ins_encode %{ 7239 // This is a Power7 instruction for which no machine description 7240 // exists. Anyways, the scheduler should be off on Power7. 7241 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7242 int cc = $cmp$$cmpcode; 7243 __ isel($dst$$Register, $crx$$CondRegister, 7244 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7245 %} 7246 ins_pipe(pipe_class_default); 7247 %} 7248 7249 // Conditional move for RegN. Only cmov(reg, reg). 7250 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7251 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7252 predicate(!VM_Version::has_isel()); 7253 ins_cost(DEFAULT_COST+BRANCH_COST); 7254 7255 ins_variable_size_depending_on_alignment(true); 7256 7257 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7258 // Worst case is branch + move + stop, no stop without scheduler. 7259 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7260 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7261 ins_pipe(pipe_class_default); 7262 %} 7263 7264 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7265 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7266 ins_cost(DEFAULT_COST+BRANCH_COST); 7267 7268 ins_variable_size_depending_on_alignment(true); 7269 7270 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7271 // Worst case is branch + move + stop, no stop without scheduler. 7272 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7273 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7274 ins_pipe(pipe_class_default); 7275 %} 7276 7277 // Cmove using isel. 7278 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7279 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7280 predicate(VM_Version::has_isel()); 7281 ins_cost(DEFAULT_COST); 7282 7283 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7284 size(4); 7285 ins_encode %{ 7286 // This is a Power7 instruction for which no machine description 7287 // exists. Anyways, the scheduler should be off on Power7. 7288 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7289 int cc = $cmp$$cmpcode; 7290 __ isel($dst$$Register, $crx$$CondRegister, 7291 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7292 %} 7293 ins_pipe(pipe_class_default); 7294 %} 7295 7296 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7297 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7298 predicate(!VM_Version::has_isel()); 7299 ins_cost(DEFAULT_COST+BRANCH_COST); 7300 7301 ins_variable_size_depending_on_alignment(true); 7302 7303 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7304 // Worst case is branch + move + stop, no stop without scheduler. 7305 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7306 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7307 ins_pipe(pipe_class_default); 7308 %} 7309 7310 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7311 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7312 ins_cost(DEFAULT_COST+BRANCH_COST); 7313 7314 ins_variable_size_depending_on_alignment(true); 7315 7316 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7317 // Worst case is branch + move + stop, no stop without scheduler. 7318 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7319 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7320 ins_pipe(pipe_class_default); 7321 %} 7322 7323 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7324 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7325 ins_cost(DEFAULT_COST+BRANCH_COST); 7326 7327 ins_variable_size_depending_on_alignment(true); 7328 7329 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7330 // Worst case is branch + move + stop, no stop without scheduler. 7331 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7332 ins_encode %{ 7333 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7334 Label done; 7335 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7336 // Branch if not (cmp crx). 7337 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7338 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7339 // TODO PPC port __ endgroup_if_needed(_size == 12); 7340 __ bind(done); 7341 %} 7342 ins_pipe(pipe_class_default); 7343 %} 7344 7345 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7346 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7347 ins_cost(DEFAULT_COST+BRANCH_COST); 7348 7349 ins_variable_size_depending_on_alignment(true); 7350 7351 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7352 // Worst case is branch + move + stop, no stop without scheduler. 7353 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7354 ins_encode %{ 7355 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7356 Label done; 7357 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7358 // Branch if not (cmp crx). 7359 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7360 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7361 // TODO PPC port __ endgroup_if_needed(_size == 12); 7362 __ bind(done); 7363 %} 7364 ins_pipe(pipe_class_default); 7365 %} 7366 7367 //----------Conditional_store-------------------------------------------------- 7368 // Conditional-store of the updated heap-top. 7369 // Used during allocation of the shared heap. 7370 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7371 7372 // As compareAndSwapL, but return flag register instead of boolean value in 7373 // int register. 7374 // Used by sun/misc/AtomicLongCSImpl.java. 7375 // Mem_ptr must be a memory operand, else this node does not get 7376 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7377 // can be rematerialized which leads to errors. 7378 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7379 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7380 effect(TEMP cr0); 7381 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7382 ins_encode %{ 7383 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7384 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7385 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7386 noreg, NULL, true); 7387 %} 7388 ins_pipe(pipe_class_default); 7389 %} 7390 7391 // As compareAndSwapP, but return flag register instead of boolean value in 7392 // int register. 7393 // This instruction is matched if UseTLAB is off. 7394 // Mem_ptr must be a memory operand, else this node does not get 7395 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7396 // can be rematerialized which leads to errors. 7397 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7398 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7399 ins_cost(2*MEMORY_REF_COST); 7400 7401 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7402 ins_encode %{ 7403 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7404 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7405 %} 7406 ins_pipe(pipe_class_memory); 7407 %} 7408 7409 // Implement LoadPLocked. Must be ordered against changes of the memory location 7410 // by storePConditional. 7411 // Don't know whether this is ever used. 7412 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7413 match(Set dst (LoadPLocked mem)); 7414 ins_cost(2*MEMORY_REF_COST); 7415 7416 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7417 size(4); 7418 ins_encode %{ 7419 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7420 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7421 %} 7422 ins_pipe(pipe_class_memory); 7423 %} 7424 7425 //----------Compare-And-Swap--------------------------------------------------- 7426 7427 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7428 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7429 // matched. 7430 7431 // Strong versions: 7432 7433 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7434 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7435 predicate(VM_Version::has_lqarx()); 7436 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7437 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7438 ins_encode %{ 7439 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7440 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7441 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7442 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7443 $res$$Register, true); 7444 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7445 __ isync(); 7446 } else { 7447 __ sync(); 7448 } 7449 %} 7450 ins_pipe(pipe_class_default); 7451 %} 7452 7453 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7454 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7455 predicate(!VM_Version::has_lqarx()); 7456 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7457 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7458 ins_encode %{ 7459 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7460 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7461 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7462 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7463 $res$$Register, true); 7464 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7465 __ isync(); 7466 } else { 7467 __ sync(); 7468 } 7469 %} 7470 ins_pipe(pipe_class_default); 7471 %} 7472 7473 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7474 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7475 predicate(VM_Version::has_lqarx()); 7476 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7477 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7478 ins_encode %{ 7479 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7480 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7481 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7482 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7483 $res$$Register, true); 7484 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7485 __ isync(); 7486 } else { 7487 __ sync(); 7488 } 7489 %} 7490 ins_pipe(pipe_class_default); 7491 %} 7492 7493 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7494 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7495 predicate(!VM_Version::has_lqarx()); 7496 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7497 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7498 ins_encode %{ 7499 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7500 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7501 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7502 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7503 $res$$Register, true); 7504 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7505 __ isync(); 7506 } else { 7507 __ sync(); 7508 } 7509 %} 7510 ins_pipe(pipe_class_default); 7511 %} 7512 7513 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7514 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7515 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7516 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7517 ins_encode %{ 7518 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7519 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7520 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7521 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7522 $res$$Register, true); 7523 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7524 __ isync(); 7525 } else { 7526 __ sync(); 7527 } 7528 %} 7529 ins_pipe(pipe_class_default); 7530 %} 7531 7532 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7533 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7534 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7535 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7536 ins_encode %{ 7537 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7538 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7539 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7540 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7541 $res$$Register, true); 7542 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7543 __ isync(); 7544 } else { 7545 __ sync(); 7546 } 7547 %} 7548 ins_pipe(pipe_class_default); 7549 %} 7550 7551 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7552 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 7553 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7554 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7555 ins_encode %{ 7556 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7557 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7558 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7559 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7560 $res$$Register, NULL, true); 7561 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7562 __ isync(); 7563 } else { 7564 __ sync(); 7565 } 7566 %} 7567 ins_pipe(pipe_class_default); 7568 %} 7569 7570 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7571 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 7572 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7573 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7574 ins_encode %{ 7575 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7576 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7577 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7578 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7579 $res$$Register, NULL, true); 7580 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7581 __ isync(); 7582 } else { 7583 __ sync(); 7584 } 7585 %} 7586 ins_pipe(pipe_class_default); 7587 %} 7588 7589 // Weak versions: 7590 7591 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7592 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7593 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7594 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7595 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7596 ins_encode %{ 7597 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7598 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7599 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7600 MacroAssembler::MemBarNone, 7601 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7602 %} 7603 ins_pipe(pipe_class_default); 7604 %} 7605 7606 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7607 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7608 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7609 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7610 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7611 ins_encode %{ 7612 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7613 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7614 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7615 MacroAssembler::MemBarNone, 7616 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7617 %} 7618 ins_pipe(pipe_class_default); 7619 %} 7620 7621 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7622 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7623 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7624 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7625 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7626 ins_encode %{ 7627 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7628 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7629 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7630 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7631 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7632 %} 7633 ins_pipe(pipe_class_default); 7634 %} 7635 7636 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7637 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7638 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7639 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7640 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7641 ins_encode %{ 7642 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7643 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7644 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7645 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7646 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7647 %} 7648 ins_pipe(pipe_class_default); 7649 %} 7650 7651 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7652 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7653 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7654 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7655 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7656 ins_encode %{ 7657 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7658 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7659 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7660 MacroAssembler::MemBarNone, 7661 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7662 %} 7663 ins_pipe(pipe_class_default); 7664 %} 7665 7666 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7667 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7668 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7669 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7670 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7671 ins_encode %{ 7672 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7673 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7674 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7675 MacroAssembler::MemBarNone, 7676 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7677 %} 7678 ins_pipe(pipe_class_default); 7679 %} 7680 7681 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7682 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7683 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7684 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7685 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7686 ins_encode %{ 7687 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7688 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7689 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7690 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7691 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7692 %} 7693 ins_pipe(pipe_class_default); 7694 %} 7695 7696 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7697 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7698 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7699 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7700 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7701 ins_encode %{ 7702 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7703 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7704 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7705 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7706 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7707 %} 7708 ins_pipe(pipe_class_default); 7709 %} 7710 7711 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7712 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7713 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7714 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7715 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7716 ins_encode %{ 7717 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7718 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7719 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7720 MacroAssembler::MemBarNone, 7721 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7722 %} 7723 ins_pipe(pipe_class_default); 7724 %} 7725 7726 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7727 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7728 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7729 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7730 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7731 ins_encode %{ 7732 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7733 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7734 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7735 // value is never passed to caller. 7736 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7737 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7738 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7739 %} 7740 ins_pipe(pipe_class_default); 7741 %} 7742 7743 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7744 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7745 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7746 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7747 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7748 ins_encode %{ 7749 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7750 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7751 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7752 MacroAssembler::MemBarNone, 7753 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7754 %} 7755 ins_pipe(pipe_class_default); 7756 %} 7757 7758 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7759 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7760 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7761 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7762 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7763 ins_encode %{ 7764 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7765 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7766 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7767 // value is never passed to caller. 7768 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7769 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7770 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7771 %} 7772 ins_pipe(pipe_class_default); 7773 %} 7774 7775 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7776 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7777 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7778 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7779 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7780 ins_encode %{ 7781 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7782 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7783 // value is never passed to caller. 7784 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7785 MacroAssembler::MemBarNone, 7786 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7787 %} 7788 ins_pipe(pipe_class_default); 7789 %} 7790 7791 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7792 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7793 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7794 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7795 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 7796 ins_encode %{ 7797 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7798 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7799 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7800 // value is never passed to caller. 7801 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7802 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7803 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7804 %} 7805 ins_pipe(pipe_class_default); 7806 %} 7807 7808 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7809 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7810 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7811 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7812 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7813 ins_encode %{ 7814 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7815 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7816 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7817 MacroAssembler::MemBarNone, 7818 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7819 %} 7820 ins_pipe(pipe_class_default); 7821 %} 7822 7823 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7824 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7825 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7826 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7827 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7828 ins_encode %{ 7829 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7830 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7831 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7832 // value is never passed to caller. 7833 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7834 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7835 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7836 %} 7837 ins_pipe(pipe_class_default); 7838 %} 7839 7840 // CompareAndExchange 7841 7842 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7843 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7844 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7845 effect(TEMP_DEF res, TEMP cr0); 7846 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7847 ins_encode %{ 7848 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7849 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7850 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7851 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7852 noreg, true); 7853 %} 7854 ins_pipe(pipe_class_default); 7855 %} 7856 7857 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7858 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7859 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7860 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7861 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7862 ins_encode %{ 7863 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7864 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7865 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7866 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7867 noreg, true); 7868 %} 7869 ins_pipe(pipe_class_default); 7870 %} 7871 7872 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7873 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7874 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7875 effect(TEMP_DEF res, TEMP cr0); 7876 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7877 ins_encode %{ 7878 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7879 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7880 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7881 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7882 noreg, true); 7883 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7884 __ isync(); 7885 } else { 7886 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7887 __ sync(); 7888 } 7889 %} 7890 ins_pipe(pipe_class_default); 7891 %} 7892 7893 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7894 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7895 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7896 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7897 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7898 ins_encode %{ 7899 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7900 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7901 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7902 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7903 noreg, true); 7904 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7905 __ isync(); 7906 } else { 7907 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7908 __ sync(); 7909 } 7910 %} 7911 ins_pipe(pipe_class_default); 7912 %} 7913 7914 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7915 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7916 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7917 effect(TEMP_DEF res, TEMP cr0); 7918 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7919 ins_encode %{ 7920 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7921 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7922 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7923 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7924 noreg, true); 7925 %} 7926 ins_pipe(pipe_class_default); 7927 %} 7928 7929 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7930 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7931 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7932 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7933 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7934 ins_encode %{ 7935 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7936 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7937 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7938 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7939 noreg, true); 7940 %} 7941 ins_pipe(pipe_class_default); 7942 %} 7943 7944 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7945 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7946 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7947 effect(TEMP_DEF res, TEMP cr0); 7948 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7949 ins_encode %{ 7950 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7951 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7952 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7953 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7954 noreg, true); 7955 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7956 __ isync(); 7957 } else { 7958 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7959 __ sync(); 7960 } 7961 %} 7962 ins_pipe(pipe_class_default); 7963 %} 7964 7965 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7966 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7967 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7968 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7969 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7970 ins_encode %{ 7971 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7972 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7973 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7974 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7975 noreg, true); 7976 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7977 __ isync(); 7978 } else { 7979 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7980 __ sync(); 7981 } 7982 %} 7983 ins_pipe(pipe_class_default); 7984 %} 7985 7986 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7987 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 7988 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7989 effect(TEMP_DEF res, TEMP cr0); 7990 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 7991 ins_encode %{ 7992 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7993 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7994 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7995 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7996 noreg, true); 7997 %} 7998 ins_pipe(pipe_class_default); 7999 %} 8000 8001 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8002 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8003 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8004 effect(TEMP_DEF res, TEMP cr0); 8005 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8006 ins_encode %{ 8007 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8008 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8009 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8010 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8011 noreg, true); 8012 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8013 __ isync(); 8014 } else { 8015 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8016 __ sync(); 8017 } 8018 %} 8019 ins_pipe(pipe_class_default); 8020 %} 8021 8022 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8023 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8024 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8025 effect(TEMP_DEF res, TEMP cr0); 8026 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8027 ins_encode %{ 8028 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8029 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8030 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8031 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8032 noreg, true); 8033 %} 8034 ins_pipe(pipe_class_default); 8035 %} 8036 8037 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8038 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8039 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8040 effect(TEMP_DEF res, TEMP cr0); 8041 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8042 ins_encode %{ 8043 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8044 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8045 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8046 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8047 noreg, true); 8048 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8049 __ isync(); 8050 } else { 8051 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8052 __ sync(); 8053 } 8054 %} 8055 ins_pipe(pipe_class_default); 8056 %} 8057 8058 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8059 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8060 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8061 effect(TEMP_DEF res, TEMP cr0); 8062 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8063 ins_encode %{ 8064 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8065 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8066 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8067 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8068 noreg, NULL, true); 8069 %} 8070 ins_pipe(pipe_class_default); 8071 %} 8072 8073 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8074 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8075 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8076 effect(TEMP_DEF res, TEMP cr0); 8077 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8078 ins_encode %{ 8079 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8080 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8081 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8082 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8083 noreg, NULL, true); 8084 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8085 __ isync(); 8086 } else { 8087 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8088 __ sync(); 8089 } 8090 %} 8091 ins_pipe(pipe_class_default); 8092 %} 8093 8094 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8095 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8096 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8097 effect(TEMP_DEF res, TEMP cr0); 8098 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8099 ins_encode %{ 8100 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8101 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8102 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8103 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8104 noreg, NULL, true); 8105 %} 8106 ins_pipe(pipe_class_default); 8107 %} 8108 8109 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8110 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8111 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8112 effect(TEMP_DEF res, TEMP cr0); 8113 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8114 ins_encode %{ 8115 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8116 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8117 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8118 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8119 noreg, NULL, true); 8120 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8121 __ isync(); 8122 } else { 8123 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8124 __ sync(); 8125 } 8126 %} 8127 ins_pipe(pipe_class_default); 8128 %} 8129 8130 // Special RMW 8131 8132 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8133 match(Set res (GetAndAddB mem_ptr src)); 8134 predicate(VM_Version::has_lqarx()); 8135 effect(TEMP_DEF res, TEMP cr0); 8136 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8137 ins_encode %{ 8138 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8139 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8140 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8141 __ isync(); 8142 } else { 8143 __ sync(); 8144 } 8145 %} 8146 ins_pipe(pipe_class_default); 8147 %} 8148 8149 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8150 match(Set res (GetAndAddB mem_ptr src)); 8151 predicate(!VM_Version::has_lqarx()); 8152 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8153 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8154 ins_encode %{ 8155 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8156 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8157 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8158 __ isync(); 8159 } else { 8160 __ sync(); 8161 } 8162 %} 8163 ins_pipe(pipe_class_default); 8164 %} 8165 8166 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8167 match(Set res (GetAndAddS mem_ptr src)); 8168 predicate(VM_Version::has_lqarx()); 8169 effect(TEMP_DEF res, TEMP cr0); 8170 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8171 ins_encode %{ 8172 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8173 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8174 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8175 __ isync(); 8176 } else { 8177 __ sync(); 8178 } 8179 %} 8180 ins_pipe(pipe_class_default); 8181 %} 8182 8183 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8184 match(Set res (GetAndAddS mem_ptr src)); 8185 predicate(!VM_Version::has_lqarx()); 8186 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8187 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8188 ins_encode %{ 8189 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8190 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8191 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8192 __ isync(); 8193 } else { 8194 __ sync(); 8195 } 8196 %} 8197 ins_pipe(pipe_class_default); 8198 %} 8199 8200 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8201 match(Set res (GetAndAddI mem_ptr src)); 8202 effect(TEMP_DEF res, TEMP cr0); 8203 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8204 ins_encode %{ 8205 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8206 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8207 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8208 __ isync(); 8209 } else { 8210 __ sync(); 8211 } 8212 %} 8213 ins_pipe(pipe_class_default); 8214 %} 8215 8216 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8217 match(Set res (GetAndAddL mem_ptr src)); 8218 effect(TEMP_DEF res, TEMP cr0); 8219 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8220 ins_encode %{ 8221 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8222 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8223 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8224 __ isync(); 8225 } else { 8226 __ sync(); 8227 } 8228 %} 8229 ins_pipe(pipe_class_default); 8230 %} 8231 8232 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8233 match(Set res (GetAndSetB mem_ptr src)); 8234 predicate(VM_Version::has_lqarx()); 8235 effect(TEMP_DEF res, TEMP cr0); 8236 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8237 ins_encode %{ 8238 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8239 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8240 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8241 __ isync(); 8242 } else { 8243 __ sync(); 8244 } 8245 %} 8246 ins_pipe(pipe_class_default); 8247 %} 8248 8249 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8250 match(Set res (GetAndSetB mem_ptr src)); 8251 predicate(!VM_Version::has_lqarx()); 8252 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8253 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8254 ins_encode %{ 8255 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8256 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8257 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8258 __ isync(); 8259 } else { 8260 __ sync(); 8261 } 8262 %} 8263 ins_pipe(pipe_class_default); 8264 %} 8265 8266 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8267 match(Set res (GetAndSetS mem_ptr src)); 8268 predicate(VM_Version::has_lqarx()); 8269 effect(TEMP_DEF res, TEMP cr0); 8270 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8271 ins_encode %{ 8272 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8273 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8274 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8275 __ isync(); 8276 } else { 8277 __ sync(); 8278 } 8279 %} 8280 ins_pipe(pipe_class_default); 8281 %} 8282 8283 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8284 match(Set res (GetAndSetS mem_ptr src)); 8285 predicate(!VM_Version::has_lqarx()); 8286 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8287 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8288 ins_encode %{ 8289 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8290 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8291 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8292 __ isync(); 8293 } else { 8294 __ sync(); 8295 } 8296 %} 8297 ins_pipe(pipe_class_default); 8298 %} 8299 8300 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8301 match(Set res (GetAndSetI mem_ptr src)); 8302 effect(TEMP_DEF res, TEMP cr0); 8303 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8304 ins_encode %{ 8305 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8306 MacroAssembler::cmpxchgx_hint_atomic_update()); 8307 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8308 __ isync(); 8309 } else { 8310 __ sync(); 8311 } 8312 %} 8313 ins_pipe(pipe_class_default); 8314 %} 8315 8316 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8317 match(Set res (GetAndSetL mem_ptr src)); 8318 effect(TEMP_DEF res, TEMP cr0); 8319 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8320 ins_encode %{ 8321 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8322 MacroAssembler::cmpxchgx_hint_atomic_update()); 8323 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8324 __ isync(); 8325 } else { 8326 __ sync(); 8327 } 8328 %} 8329 ins_pipe(pipe_class_default); 8330 %} 8331 8332 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8333 match(Set res (GetAndSetP mem_ptr src)); 8334 effect(TEMP_DEF res, TEMP cr0); 8335 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8336 ins_encode %{ 8337 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8338 MacroAssembler::cmpxchgx_hint_atomic_update()); 8339 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8340 __ isync(); 8341 } else { 8342 __ sync(); 8343 } 8344 %} 8345 ins_pipe(pipe_class_default); 8346 %} 8347 8348 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8349 match(Set res (GetAndSetN mem_ptr src)); 8350 effect(TEMP_DEF res, TEMP cr0); 8351 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8352 ins_encode %{ 8353 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8354 MacroAssembler::cmpxchgx_hint_atomic_update()); 8355 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8356 __ isync(); 8357 } else { 8358 __ sync(); 8359 } 8360 %} 8361 ins_pipe(pipe_class_default); 8362 %} 8363 8364 //----------Arithmetic Instructions-------------------------------------------- 8365 // Addition Instructions 8366 8367 // Register Addition 8368 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8369 match(Set dst (AddI src1 src2)); 8370 format %{ "ADD $dst, $src1, $src2" %} 8371 size(4); 8372 ins_encode %{ 8373 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8374 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8375 %} 8376 ins_pipe(pipe_class_default); 8377 %} 8378 8379 // Expand does not work with above instruct. (??) 8380 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8381 // no match-rule 8382 effect(DEF dst, USE src1, USE src2); 8383 format %{ "ADD $dst, $src1, $src2" %} 8384 size(4); 8385 ins_encode %{ 8386 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8387 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8388 %} 8389 ins_pipe(pipe_class_default); 8390 %} 8391 8392 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8393 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8394 ins_cost(DEFAULT_COST*3); 8395 8396 expand %{ 8397 // FIXME: we should do this in the ideal world. 8398 iRegIdst tmp1; 8399 iRegIdst tmp2; 8400 addI_reg_reg(tmp1, src1, src2); 8401 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8402 addI_reg_reg(dst, tmp1, tmp2); 8403 %} 8404 %} 8405 8406 // Immediate Addition 8407 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8408 match(Set dst (AddI src1 src2)); 8409 format %{ "ADDI $dst, $src1, $src2" %} 8410 size(4); 8411 ins_encode %{ 8412 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8413 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8414 %} 8415 ins_pipe(pipe_class_default); 8416 %} 8417 8418 // Immediate Addition with 16-bit shifted operand 8419 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8420 match(Set dst (AddI src1 src2)); 8421 format %{ "ADDIS $dst, $src1, $src2" %} 8422 size(4); 8423 ins_encode %{ 8424 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8425 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8426 %} 8427 ins_pipe(pipe_class_default); 8428 %} 8429 8430 // Long Addition 8431 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8432 match(Set dst (AddL src1 src2)); 8433 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8434 size(4); 8435 ins_encode %{ 8436 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8437 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8438 %} 8439 ins_pipe(pipe_class_default); 8440 %} 8441 8442 // Expand does not work with above instruct. (??) 8443 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8444 // no match-rule 8445 effect(DEF dst, USE src1, USE src2); 8446 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8447 size(4); 8448 ins_encode %{ 8449 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8450 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8451 %} 8452 ins_pipe(pipe_class_default); 8453 %} 8454 8455 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8456 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8457 ins_cost(DEFAULT_COST*3); 8458 8459 expand %{ 8460 // FIXME: we should do this in the ideal world. 8461 iRegLdst tmp1; 8462 iRegLdst tmp2; 8463 addL_reg_reg(tmp1, src1, src2); 8464 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8465 addL_reg_reg(dst, tmp1, tmp2); 8466 %} 8467 %} 8468 8469 // AddL + ConvL2I. 8470 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8471 match(Set dst (ConvL2I (AddL src1 src2))); 8472 8473 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8474 size(4); 8475 ins_encode %{ 8476 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8477 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8478 %} 8479 ins_pipe(pipe_class_default); 8480 %} 8481 8482 // No constant pool entries required. 8483 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8484 match(Set dst (AddL src1 src2)); 8485 8486 format %{ "ADDI $dst, $src1, $src2" %} 8487 size(4); 8488 ins_encode %{ 8489 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8490 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8491 %} 8492 ins_pipe(pipe_class_default); 8493 %} 8494 8495 // Long Immediate Addition with 16-bit shifted operand. 8496 // No constant pool entries required. 8497 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8498 match(Set dst (AddL src1 src2)); 8499 8500 format %{ "ADDIS $dst, $src1, $src2" %} 8501 size(4); 8502 ins_encode %{ 8503 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8504 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8505 %} 8506 ins_pipe(pipe_class_default); 8507 %} 8508 8509 // Pointer Register Addition 8510 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8511 match(Set dst (AddP src1 src2)); 8512 format %{ "ADD $dst, $src1, $src2" %} 8513 size(4); 8514 ins_encode %{ 8515 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8516 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8517 %} 8518 ins_pipe(pipe_class_default); 8519 %} 8520 8521 // Pointer Immediate Addition 8522 // No constant pool entries required. 8523 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8524 match(Set dst (AddP src1 src2)); 8525 8526 format %{ "ADDI $dst, $src1, $src2" %} 8527 size(4); 8528 ins_encode %{ 8529 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8530 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8531 %} 8532 ins_pipe(pipe_class_default); 8533 %} 8534 8535 // Pointer Immediate Addition with 16-bit shifted operand. 8536 // No constant pool entries required. 8537 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8538 match(Set dst (AddP src1 src2)); 8539 8540 format %{ "ADDIS $dst, $src1, $src2" %} 8541 size(4); 8542 ins_encode %{ 8543 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8544 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8545 %} 8546 ins_pipe(pipe_class_default); 8547 %} 8548 8549 //--------------------- 8550 // Subtraction Instructions 8551 8552 // Register Subtraction 8553 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8554 match(Set dst (SubI src1 src2)); 8555 format %{ "SUBF $dst, $src2, $src1" %} 8556 size(4); 8557 ins_encode %{ 8558 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8559 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8560 %} 8561 ins_pipe(pipe_class_default); 8562 %} 8563 8564 // Immediate Subtraction 8565 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 8566 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 8567 8568 // SubI from constant (using subfic). 8569 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 8570 match(Set dst (SubI src1 src2)); 8571 format %{ "SUBI $dst, $src1, $src2" %} 8572 8573 size(4); 8574 ins_encode %{ 8575 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 8576 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 8577 %} 8578 ins_pipe(pipe_class_default); 8579 %} 8580 8581 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 8582 // positive integers and 0xF...F for negative ones. 8583 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 8584 // no match-rule, false predicate 8585 effect(DEF dst, USE src); 8586 predicate(false); 8587 8588 format %{ "SRAWI $dst, $src, #31" %} 8589 size(4); 8590 ins_encode %{ 8591 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 8592 __ srawi($dst$$Register, $src$$Register, 0x1f); 8593 %} 8594 ins_pipe(pipe_class_default); 8595 %} 8596 8597 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 8598 match(Set dst (AbsI src)); 8599 ins_cost(DEFAULT_COST*3); 8600 8601 expand %{ 8602 iRegIdst tmp1; 8603 iRegIdst tmp2; 8604 signmask32I_regI(tmp1, src); 8605 xorI_reg_reg(tmp2, tmp1, src); 8606 subI_reg_reg(dst, tmp2, tmp1); 8607 %} 8608 %} 8609 8610 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 8611 match(Set dst (SubI zero src2)); 8612 format %{ "NEG $dst, $src2" %} 8613 size(4); 8614 ins_encode %{ 8615 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8616 __ neg($dst$$Register, $src2$$Register); 8617 %} 8618 ins_pipe(pipe_class_default); 8619 %} 8620 8621 // Long subtraction 8622 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8623 match(Set dst (SubL src1 src2)); 8624 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 8625 size(4); 8626 ins_encode %{ 8627 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8628 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8629 %} 8630 ins_pipe(pipe_class_default); 8631 %} 8632 8633 // SubL + convL2I. 8634 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8635 match(Set dst (ConvL2I (SubL src1 src2))); 8636 8637 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 8638 size(4); 8639 ins_encode %{ 8640 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8641 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8642 %} 8643 ins_pipe(pipe_class_default); 8644 %} 8645 8646 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8647 // positive longs and 0xF...F for negative ones. 8648 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 8649 // no match-rule, false predicate 8650 effect(DEF dst, USE src); 8651 predicate(false); 8652 8653 format %{ "SRADI $dst, $src, #63" %} 8654 size(4); 8655 ins_encode %{ 8656 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8657 __ sradi($dst$$Register, $src$$Register, 0x3f); 8658 %} 8659 ins_pipe(pipe_class_default); 8660 %} 8661 8662 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8663 // positive longs and 0xF...F for negative ones. 8664 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 8665 // no match-rule, false predicate 8666 effect(DEF dst, USE src); 8667 predicate(false); 8668 8669 format %{ "SRADI $dst, $src, #63" %} 8670 size(4); 8671 ins_encode %{ 8672 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8673 __ sradi($dst$$Register, $src$$Register, 0x3f); 8674 %} 8675 ins_pipe(pipe_class_default); 8676 %} 8677 8678 // Long negation 8679 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 8680 match(Set dst (SubL zero src2)); 8681 format %{ "NEG $dst, $src2 \t// long" %} 8682 size(4); 8683 ins_encode %{ 8684 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8685 __ neg($dst$$Register, $src2$$Register); 8686 %} 8687 ins_pipe(pipe_class_default); 8688 %} 8689 8690 // NegL + ConvL2I. 8691 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 8692 match(Set dst (ConvL2I (SubL zero src2))); 8693 8694 format %{ "NEG $dst, $src2 \t// long + l2i" %} 8695 size(4); 8696 ins_encode %{ 8697 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8698 __ neg($dst$$Register, $src2$$Register); 8699 %} 8700 ins_pipe(pipe_class_default); 8701 %} 8702 8703 // Multiplication Instructions 8704 // Integer Multiplication 8705 8706 // Register Multiplication 8707 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8708 match(Set dst (MulI src1 src2)); 8709 ins_cost(DEFAULT_COST); 8710 8711 format %{ "MULLW $dst, $src1, $src2" %} 8712 size(4); 8713 ins_encode %{ 8714 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 8715 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 8716 %} 8717 ins_pipe(pipe_class_default); 8718 %} 8719 8720 // Immediate Multiplication 8721 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8722 match(Set dst (MulI src1 src2)); 8723 ins_cost(DEFAULT_COST); 8724 8725 format %{ "MULLI $dst, $src1, $src2" %} 8726 size(4); 8727 ins_encode %{ 8728 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8729 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8730 %} 8731 ins_pipe(pipe_class_default); 8732 %} 8733 8734 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8735 match(Set dst (MulL src1 src2)); 8736 ins_cost(DEFAULT_COST); 8737 8738 format %{ "MULLD $dst $src1, $src2 \t// long" %} 8739 size(4); 8740 ins_encode %{ 8741 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 8742 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 8743 %} 8744 ins_pipe(pipe_class_default); 8745 %} 8746 8747 // Multiply high for optimized long division by constant. 8748 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8749 match(Set dst (MulHiL src1 src2)); 8750 ins_cost(DEFAULT_COST); 8751 8752 format %{ "MULHD $dst $src1, $src2 \t// long" %} 8753 size(4); 8754 ins_encode %{ 8755 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 8756 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 8757 %} 8758 ins_pipe(pipe_class_default); 8759 %} 8760 8761 // Immediate Multiplication 8762 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8763 match(Set dst (MulL src1 src2)); 8764 ins_cost(DEFAULT_COST); 8765 8766 format %{ "MULLI $dst, $src1, $src2" %} 8767 size(4); 8768 ins_encode %{ 8769 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8770 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8771 %} 8772 ins_pipe(pipe_class_default); 8773 %} 8774 8775 // Integer Division with Immediate -1: Negate. 8776 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 8777 match(Set dst (DivI src1 src2)); 8778 ins_cost(DEFAULT_COST); 8779 8780 format %{ "NEG $dst, $src1 \t// /-1" %} 8781 size(4); 8782 ins_encode %{ 8783 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8784 __ neg($dst$$Register, $src1$$Register); 8785 %} 8786 ins_pipe(pipe_class_default); 8787 %} 8788 8789 // Integer Division with constant, but not -1. 8790 // We should be able to improve this by checking the type of src2. 8791 // It might well be that src2 is known to be positive. 8792 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8793 match(Set dst (DivI src1 src2)); 8794 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 8795 ins_cost(2*DEFAULT_COST); 8796 8797 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 8798 size(4); 8799 ins_encode %{ 8800 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 8801 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 8802 %} 8803 ins_pipe(pipe_class_default); 8804 %} 8805 8806 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 8807 effect(USE_DEF dst, USE src1, USE crx); 8808 predicate(false); 8809 8810 ins_variable_size_depending_on_alignment(true); 8811 8812 format %{ "CMOVE $dst, neg($src1), $crx" %} 8813 // Worst case is branch + move + stop, no stop without scheduler. 8814 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8815 ins_encode %{ 8816 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8817 Label done; 8818 __ bne($crx$$CondRegister, done); 8819 __ neg($dst$$Register, $src1$$Register); 8820 // TODO PPC port __ endgroup_if_needed(_size == 12); 8821 __ bind(done); 8822 %} 8823 ins_pipe(pipe_class_default); 8824 %} 8825 8826 // Integer Division with Registers not containing constants. 8827 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8828 match(Set dst (DivI src1 src2)); 8829 ins_cost(10*DEFAULT_COST); 8830 8831 expand %{ 8832 immI16 imm %{ (int)-1 %} 8833 flagsReg tmp1; 8834 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8835 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8836 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8837 %} 8838 %} 8839 8840 // Long Division with Immediate -1: Negate. 8841 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 8842 match(Set dst (DivL src1 src2)); 8843 ins_cost(DEFAULT_COST); 8844 8845 format %{ "NEG $dst, $src1 \t// /-1, long" %} 8846 size(4); 8847 ins_encode %{ 8848 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8849 __ neg($dst$$Register, $src1$$Register); 8850 %} 8851 ins_pipe(pipe_class_default); 8852 %} 8853 8854 // Long Division with constant, but not -1. 8855 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8856 match(Set dst (DivL src1 src2)); 8857 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 8858 ins_cost(2*DEFAULT_COST); 8859 8860 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 8861 size(4); 8862 ins_encode %{ 8863 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 8864 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 8865 %} 8866 ins_pipe(pipe_class_default); 8867 %} 8868 8869 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 8870 effect(USE_DEF dst, USE src1, USE crx); 8871 predicate(false); 8872 8873 ins_variable_size_depending_on_alignment(true); 8874 8875 format %{ "CMOVE $dst, neg($src1), $crx" %} 8876 // Worst case is branch + move + stop, no stop without scheduler. 8877 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8878 ins_encode %{ 8879 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8880 Label done; 8881 __ bne($crx$$CondRegister, done); 8882 __ neg($dst$$Register, $src1$$Register); 8883 // TODO PPC port __ endgroup_if_needed(_size == 12); 8884 __ bind(done); 8885 %} 8886 ins_pipe(pipe_class_default); 8887 %} 8888 8889 // Long Division with Registers not containing constants. 8890 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8891 match(Set dst (DivL src1 src2)); 8892 ins_cost(10*DEFAULT_COST); 8893 8894 expand %{ 8895 immL16 imm %{ (int)-1 %} 8896 flagsReg tmp1; 8897 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8898 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8899 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8900 %} 8901 %} 8902 8903 // Integer Remainder with registers. 8904 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8905 match(Set dst (ModI src1 src2)); 8906 ins_cost(10*DEFAULT_COST); 8907 8908 expand %{ 8909 immI16 imm %{ (int)-1 %} 8910 flagsReg tmp1; 8911 iRegIdst tmp2; 8912 iRegIdst tmp3; 8913 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8914 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8915 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8916 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8917 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8918 %} 8919 %} 8920 8921 // Long Remainder with registers 8922 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8923 match(Set dst (ModL src1 src2)); 8924 ins_cost(10*DEFAULT_COST); 8925 8926 expand %{ 8927 immL16 imm %{ (int)-1 %} 8928 flagsReg tmp1; 8929 iRegLdst tmp2; 8930 iRegLdst tmp3; 8931 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8932 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8933 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8934 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8935 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8936 %} 8937 %} 8938 8939 // Integer Shift Instructions 8940 8941 // Register Shift Left 8942 8943 // Clear all but the lowest #mask bits. 8944 // Used to normalize shift amounts in registers. 8945 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 8946 // no match-rule, false predicate 8947 effect(DEF dst, USE src, USE mask); 8948 predicate(false); 8949 8950 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 8951 size(4); 8952 ins_encode %{ 8953 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 8954 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 8955 %} 8956 ins_pipe(pipe_class_default); 8957 %} 8958 8959 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8960 // no match-rule, false predicate 8961 effect(DEF dst, USE src1, USE src2); 8962 predicate(false); 8963 8964 format %{ "SLW $dst, $src1, $src2" %} 8965 size(4); 8966 ins_encode %{ 8967 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 8968 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 8969 %} 8970 ins_pipe(pipe_class_default); 8971 %} 8972 8973 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8974 match(Set dst (LShiftI src1 src2)); 8975 ins_cost(DEFAULT_COST*2); 8976 expand %{ 8977 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 8978 iRegIdst tmpI; 8979 maskI_reg_imm(tmpI, src2, mask); 8980 lShiftI_reg_reg(dst, src1, tmpI); 8981 %} 8982 %} 8983 8984 // Register Shift Left Immediate 8985 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 8986 match(Set dst (LShiftI src1 src2)); 8987 8988 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 8989 size(4); 8990 ins_encode %{ 8991 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 8992 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 8993 %} 8994 ins_pipe(pipe_class_default); 8995 %} 8996 8997 // AndI with negpow2-constant + LShiftI 8998 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 8999 match(Set dst (LShiftI (AndI src1 src2) src3)); 9000 predicate(UseRotateAndMaskInstructionsPPC64); 9001 9002 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9003 size(4); 9004 ins_encode %{ 9005 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9006 long src2 = $src2$$constant; 9007 long src3 = $src3$$constant; 9008 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9009 if (maskbits >= 32) { 9010 __ li($dst$$Register, 0); // addi 9011 } else { 9012 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9013 } 9014 %} 9015 ins_pipe(pipe_class_default); 9016 %} 9017 9018 // RShiftI + AndI with negpow2-constant + LShiftI 9019 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9020 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9021 predicate(UseRotateAndMaskInstructionsPPC64); 9022 9023 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9024 size(4); 9025 ins_encode %{ 9026 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9027 long src2 = $src2$$constant; 9028 long src3 = $src3$$constant; 9029 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9030 if (maskbits >= 32) { 9031 __ li($dst$$Register, 0); // addi 9032 } else { 9033 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9034 } 9035 %} 9036 ins_pipe(pipe_class_default); 9037 %} 9038 9039 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9040 // no match-rule, false predicate 9041 effect(DEF dst, USE src1, USE src2); 9042 predicate(false); 9043 9044 format %{ "SLD $dst, $src1, $src2" %} 9045 size(4); 9046 ins_encode %{ 9047 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9048 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9049 %} 9050 ins_pipe(pipe_class_default); 9051 %} 9052 9053 // Register Shift Left 9054 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9055 match(Set dst (LShiftL src1 src2)); 9056 ins_cost(DEFAULT_COST*2); 9057 expand %{ 9058 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9059 iRegIdst tmpI; 9060 maskI_reg_imm(tmpI, src2, mask); 9061 lShiftL_regL_regI(dst, src1, tmpI); 9062 %} 9063 %} 9064 9065 // Register Shift Left Immediate 9066 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9067 match(Set dst (LShiftL src1 src2)); 9068 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9069 size(4); 9070 ins_encode %{ 9071 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9072 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9073 %} 9074 ins_pipe(pipe_class_default); 9075 %} 9076 9077 // If we shift more than 32 bits, we need not convert I2L. 9078 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9079 match(Set dst (LShiftL (ConvI2L src1) src2)); 9080 ins_cost(DEFAULT_COST); 9081 9082 size(4); 9083 format %{ "SLDI $dst, i2l($src1), $src2" %} 9084 ins_encode %{ 9085 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9086 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9087 %} 9088 ins_pipe(pipe_class_default); 9089 %} 9090 9091 // Shift a postivie int to the left. 9092 // Clrlsldi clears the upper 32 bits and shifts. 9093 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9094 match(Set dst (LShiftL (ConvI2L src1) src2)); 9095 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9096 9097 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9098 size(4); 9099 ins_encode %{ 9100 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9101 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9102 %} 9103 ins_pipe(pipe_class_default); 9104 %} 9105 9106 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9107 // no match-rule, false predicate 9108 effect(DEF dst, USE src1, USE src2); 9109 predicate(false); 9110 9111 format %{ "SRAW $dst, $src1, $src2" %} 9112 size(4); 9113 ins_encode %{ 9114 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9115 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9116 %} 9117 ins_pipe(pipe_class_default); 9118 %} 9119 9120 // Register Arithmetic Shift Right 9121 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9122 match(Set dst (RShiftI src1 src2)); 9123 ins_cost(DEFAULT_COST*2); 9124 expand %{ 9125 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9126 iRegIdst tmpI; 9127 maskI_reg_imm(tmpI, src2, mask); 9128 arShiftI_reg_reg(dst, src1, tmpI); 9129 %} 9130 %} 9131 9132 // Register Arithmetic Shift Right Immediate 9133 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9134 match(Set dst (RShiftI src1 src2)); 9135 9136 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9137 size(4); 9138 ins_encode %{ 9139 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9140 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9141 %} 9142 ins_pipe(pipe_class_default); 9143 %} 9144 9145 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9146 // no match-rule, false predicate 9147 effect(DEF dst, USE src1, USE src2); 9148 predicate(false); 9149 9150 format %{ "SRAD $dst, $src1, $src2" %} 9151 size(4); 9152 ins_encode %{ 9153 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9154 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9155 %} 9156 ins_pipe(pipe_class_default); 9157 %} 9158 9159 // Register Shift Right Arithmetic Long 9160 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9161 match(Set dst (RShiftL src1 src2)); 9162 ins_cost(DEFAULT_COST*2); 9163 9164 expand %{ 9165 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9166 iRegIdst tmpI; 9167 maskI_reg_imm(tmpI, src2, mask); 9168 arShiftL_regL_regI(dst, src1, tmpI); 9169 %} 9170 %} 9171 9172 // Register Shift Right Immediate 9173 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9174 match(Set dst (RShiftL src1 src2)); 9175 9176 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9177 size(4); 9178 ins_encode %{ 9179 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9180 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9181 %} 9182 ins_pipe(pipe_class_default); 9183 %} 9184 9185 // RShiftL + ConvL2I 9186 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9187 match(Set dst (ConvL2I (RShiftL src1 src2))); 9188 9189 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9190 size(4); 9191 ins_encode %{ 9192 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9193 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9194 %} 9195 ins_pipe(pipe_class_default); 9196 %} 9197 9198 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9199 // no match-rule, false predicate 9200 effect(DEF dst, USE src1, USE src2); 9201 predicate(false); 9202 9203 format %{ "SRW $dst, $src1, $src2" %} 9204 size(4); 9205 ins_encode %{ 9206 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9207 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9208 %} 9209 ins_pipe(pipe_class_default); 9210 %} 9211 9212 // Register Shift Right 9213 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9214 match(Set dst (URShiftI src1 src2)); 9215 ins_cost(DEFAULT_COST*2); 9216 9217 expand %{ 9218 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9219 iRegIdst tmpI; 9220 maskI_reg_imm(tmpI, src2, mask); 9221 urShiftI_reg_reg(dst, src1, tmpI); 9222 %} 9223 %} 9224 9225 // Register Shift Right Immediate 9226 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9227 match(Set dst (URShiftI src1 src2)); 9228 9229 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9230 size(4); 9231 ins_encode %{ 9232 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9233 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9234 %} 9235 ins_pipe(pipe_class_default); 9236 %} 9237 9238 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9239 // no match-rule, false predicate 9240 effect(DEF dst, USE src1, USE src2); 9241 predicate(false); 9242 9243 format %{ "SRD $dst, $src1, $src2" %} 9244 size(4); 9245 ins_encode %{ 9246 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9247 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9248 %} 9249 ins_pipe(pipe_class_default); 9250 %} 9251 9252 // Register Shift Right 9253 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9254 match(Set dst (URShiftL src1 src2)); 9255 ins_cost(DEFAULT_COST*2); 9256 9257 expand %{ 9258 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9259 iRegIdst tmpI; 9260 maskI_reg_imm(tmpI, src2, mask); 9261 urShiftL_regL_regI(dst, src1, tmpI); 9262 %} 9263 %} 9264 9265 // Register Shift Right Immediate 9266 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9267 match(Set dst (URShiftL src1 src2)); 9268 9269 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9270 size(4); 9271 ins_encode %{ 9272 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9273 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9274 %} 9275 ins_pipe(pipe_class_default); 9276 %} 9277 9278 // URShiftL + ConvL2I. 9279 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9280 match(Set dst (ConvL2I (URShiftL src1 src2))); 9281 9282 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9283 size(4); 9284 ins_encode %{ 9285 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9286 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9287 %} 9288 ins_pipe(pipe_class_default); 9289 %} 9290 9291 // Register Shift Right Immediate with a CastP2X 9292 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9293 match(Set dst (URShiftL (CastP2X src1) src2)); 9294 9295 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9296 size(4); 9297 ins_encode %{ 9298 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9299 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9300 %} 9301 ins_pipe(pipe_class_default); 9302 %} 9303 9304 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9305 match(Set dst (ConvL2I (ConvI2L src))); 9306 9307 format %{ "EXTSW $dst, $src \t// int->int" %} 9308 size(4); 9309 ins_encode %{ 9310 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9311 __ extsw($dst$$Register, $src$$Register); 9312 %} 9313 ins_pipe(pipe_class_default); 9314 %} 9315 9316 //----------Rotate Instructions------------------------------------------------ 9317 9318 // Rotate Left by 8-bit immediate 9319 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9320 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9321 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9322 9323 format %{ "ROTLWI $dst, $src, $lshift" %} 9324 size(4); 9325 ins_encode %{ 9326 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9327 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9328 %} 9329 ins_pipe(pipe_class_default); 9330 %} 9331 9332 // Rotate Right by 8-bit immediate 9333 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9334 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9335 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9336 9337 format %{ "ROTRWI $dst, $rshift" %} 9338 size(4); 9339 ins_encode %{ 9340 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9341 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9342 %} 9343 ins_pipe(pipe_class_default); 9344 %} 9345 9346 //----------Floating Point Arithmetic Instructions----------------------------- 9347 9348 // Add float single precision 9349 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9350 match(Set dst (AddF src1 src2)); 9351 9352 format %{ "FADDS $dst, $src1, $src2" %} 9353 size(4); 9354 ins_encode %{ 9355 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9356 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9357 %} 9358 ins_pipe(pipe_class_default); 9359 %} 9360 9361 // Add float double precision 9362 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9363 match(Set dst (AddD src1 src2)); 9364 9365 format %{ "FADD $dst, $src1, $src2" %} 9366 size(4); 9367 ins_encode %{ 9368 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9369 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9370 %} 9371 ins_pipe(pipe_class_default); 9372 %} 9373 9374 // Sub float single precision 9375 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9376 match(Set dst (SubF src1 src2)); 9377 9378 format %{ "FSUBS $dst, $src1, $src2" %} 9379 size(4); 9380 ins_encode %{ 9381 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9382 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9383 %} 9384 ins_pipe(pipe_class_default); 9385 %} 9386 9387 // Sub float double precision 9388 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9389 match(Set dst (SubD src1 src2)); 9390 format %{ "FSUB $dst, $src1, $src2" %} 9391 size(4); 9392 ins_encode %{ 9393 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9394 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9395 %} 9396 ins_pipe(pipe_class_default); 9397 %} 9398 9399 // Mul float single precision 9400 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9401 match(Set dst (MulF src1 src2)); 9402 format %{ "FMULS $dst, $src1, $src2" %} 9403 size(4); 9404 ins_encode %{ 9405 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9406 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9407 %} 9408 ins_pipe(pipe_class_default); 9409 %} 9410 9411 // Mul float double precision 9412 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9413 match(Set dst (MulD src1 src2)); 9414 format %{ "FMUL $dst, $src1, $src2" %} 9415 size(4); 9416 ins_encode %{ 9417 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9418 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9419 %} 9420 ins_pipe(pipe_class_default); 9421 %} 9422 9423 // Div float single precision 9424 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9425 match(Set dst (DivF src1 src2)); 9426 format %{ "FDIVS $dst, $src1, $src2" %} 9427 size(4); 9428 ins_encode %{ 9429 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9430 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9431 %} 9432 ins_pipe(pipe_class_default); 9433 %} 9434 9435 // Div float double precision 9436 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9437 match(Set dst (DivD src1 src2)); 9438 format %{ "FDIV $dst, $src1, $src2" %} 9439 size(4); 9440 ins_encode %{ 9441 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9442 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9443 %} 9444 ins_pipe(pipe_class_default); 9445 %} 9446 9447 // Absolute float single precision 9448 instruct absF_reg(regF dst, regF src) %{ 9449 match(Set dst (AbsF src)); 9450 format %{ "FABS $dst, $src \t// float" %} 9451 size(4); 9452 ins_encode %{ 9453 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9454 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9455 %} 9456 ins_pipe(pipe_class_default); 9457 %} 9458 9459 // Absolute float double precision 9460 instruct absD_reg(regD dst, regD src) %{ 9461 match(Set dst (AbsD src)); 9462 format %{ "FABS $dst, $src \t// double" %} 9463 size(4); 9464 ins_encode %{ 9465 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9466 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9467 %} 9468 ins_pipe(pipe_class_default); 9469 %} 9470 9471 instruct negF_reg(regF dst, regF src) %{ 9472 match(Set dst (NegF src)); 9473 format %{ "FNEG $dst, $src \t// float" %} 9474 size(4); 9475 ins_encode %{ 9476 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9477 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9478 %} 9479 ins_pipe(pipe_class_default); 9480 %} 9481 9482 instruct negD_reg(regD dst, regD src) %{ 9483 match(Set dst (NegD src)); 9484 format %{ "FNEG $dst, $src \t// double" %} 9485 size(4); 9486 ins_encode %{ 9487 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9488 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9489 %} 9490 ins_pipe(pipe_class_default); 9491 %} 9492 9493 // AbsF + NegF. 9494 instruct negF_absF_reg(regF dst, regF src) %{ 9495 match(Set dst (NegF (AbsF src))); 9496 format %{ "FNABS $dst, $src \t// float" %} 9497 size(4); 9498 ins_encode %{ 9499 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9500 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9501 %} 9502 ins_pipe(pipe_class_default); 9503 %} 9504 9505 // AbsD + NegD. 9506 instruct negD_absD_reg(regD dst, regD src) %{ 9507 match(Set dst (NegD (AbsD src))); 9508 format %{ "FNABS $dst, $src \t// double" %} 9509 size(4); 9510 ins_encode %{ 9511 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9512 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9513 %} 9514 ins_pipe(pipe_class_default); 9515 %} 9516 9517 // VM_Version::has_fsqrt() decides if this node will be used. 9518 // Sqrt float double precision 9519 instruct sqrtD_reg(regD dst, regD src) %{ 9520 match(Set dst (SqrtD src)); 9521 format %{ "FSQRT $dst, $src" %} 9522 size(4); 9523 ins_encode %{ 9524 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 9525 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 9526 %} 9527 ins_pipe(pipe_class_default); 9528 %} 9529 9530 // Single-precision sqrt. 9531 instruct sqrtF_reg(regF dst, regF src) %{ 9532 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 9533 predicate(VM_Version::has_fsqrts()); 9534 ins_cost(DEFAULT_COST); 9535 9536 format %{ "FSQRTS $dst, $src" %} 9537 size(4); 9538 ins_encode %{ 9539 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 9540 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 9541 %} 9542 ins_pipe(pipe_class_default); 9543 %} 9544 9545 instruct roundDouble_nop(regD dst) %{ 9546 match(Set dst (RoundDouble dst)); 9547 ins_cost(0); 9548 9549 format %{ " -- \t// RoundDouble not needed - empty" %} 9550 size(0); 9551 // PPC results are already "rounded" (i.e., normal-format IEEE). 9552 ins_encode( /*empty*/ ); 9553 ins_pipe(pipe_class_default); 9554 %} 9555 9556 instruct roundFloat_nop(regF dst) %{ 9557 match(Set dst (RoundFloat dst)); 9558 ins_cost(0); 9559 9560 format %{ " -- \t// RoundFloat not needed - empty" %} 9561 size(0); 9562 // PPC results are already "rounded" (i.e., normal-format IEEE). 9563 ins_encode( /*empty*/ ); 9564 ins_pipe(pipe_class_default); 9565 %} 9566 9567 //----------Logical Instructions----------------------------------------------- 9568 9569 // And Instructions 9570 9571 // Register And 9572 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9573 match(Set dst (AndI src1 src2)); 9574 format %{ "AND $dst, $src1, $src2" %} 9575 size(4); 9576 ins_encode %{ 9577 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9578 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9579 %} 9580 ins_pipe(pipe_class_default); 9581 %} 9582 9583 // Left shifted Immediate And 9584 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 9585 match(Set dst (AndI src1 src2)); 9586 effect(KILL cr0); 9587 format %{ "ANDIS $dst, $src1, $src2.hi" %} 9588 size(4); 9589 ins_encode %{ 9590 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 9591 __ andis_($dst$$Register, $src1$$Register, (int)((short)(($src2$$constant & 0xFFFF0000) >> 16))); 9592 %} 9593 ins_pipe(pipe_class_default); 9594 %} 9595 9596 // Immediate And 9597 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 9598 match(Set dst (AndI src1 src2)); 9599 effect(KILL cr0); 9600 9601 format %{ "ANDI $dst, $src1, $src2" %} 9602 size(4); 9603 ins_encode %{ 9604 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9605 // FIXME: avoid andi_ ? 9606 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9607 %} 9608 ins_pipe(pipe_class_default); 9609 %} 9610 9611 // Immediate And where the immediate is a negative power of 2. 9612 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 9613 match(Set dst (AndI src1 src2)); 9614 format %{ "ANDWI $dst, $src1, $src2" %} 9615 size(4); 9616 ins_encode %{ 9617 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9618 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 9619 %} 9620 ins_pipe(pipe_class_default); 9621 %} 9622 9623 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 9624 match(Set dst (AndI src1 src2)); 9625 format %{ "ANDWI $dst, $src1, $src2" %} 9626 size(4); 9627 ins_encode %{ 9628 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9629 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9630 %} 9631 ins_pipe(pipe_class_default); 9632 %} 9633 9634 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 9635 match(Set dst (AndI src1 src2)); 9636 predicate(UseRotateAndMaskInstructionsPPC64); 9637 format %{ "ANDWI $dst, $src1, $src2" %} 9638 size(4); 9639 ins_encode %{ 9640 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9641 __ rlwinm($dst$$Register, $src1$$Register, 0, 9642 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 9643 %} 9644 ins_pipe(pipe_class_default); 9645 %} 9646 9647 // Register And Long 9648 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9649 match(Set dst (AndL src1 src2)); 9650 ins_cost(DEFAULT_COST); 9651 9652 format %{ "AND $dst, $src1, $src2 \t// long" %} 9653 size(4); 9654 ins_encode %{ 9655 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9656 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9657 %} 9658 ins_pipe(pipe_class_default); 9659 %} 9660 9661 // Immediate And long 9662 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 9663 match(Set dst (AndL src1 src2)); 9664 effect(KILL cr0); 9665 9666 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 9667 size(4); 9668 ins_encode %{ 9669 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9670 // FIXME: avoid andi_ ? 9671 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9672 %} 9673 ins_pipe(pipe_class_default); 9674 %} 9675 9676 // Immediate And Long where the immediate is a negative power of 2. 9677 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 9678 match(Set dst (AndL src1 src2)); 9679 format %{ "ANDDI $dst, $src1, $src2" %} 9680 size(4); 9681 ins_encode %{ 9682 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9683 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 9684 %} 9685 ins_pipe(pipe_class_default); 9686 %} 9687 9688 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9689 match(Set dst (AndL src1 src2)); 9690 format %{ "ANDDI $dst, $src1, $src2" %} 9691 size(4); 9692 ins_encode %{ 9693 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9694 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9695 %} 9696 ins_pipe(pipe_class_default); 9697 %} 9698 9699 // AndL + ConvL2I. 9700 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9701 match(Set dst (ConvL2I (AndL src1 src2))); 9702 ins_cost(DEFAULT_COST); 9703 9704 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 9705 size(4); 9706 ins_encode %{ 9707 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9708 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9709 %} 9710 ins_pipe(pipe_class_default); 9711 %} 9712 9713 // Or Instructions 9714 9715 // Register Or 9716 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9717 match(Set dst (OrI src1 src2)); 9718 format %{ "OR $dst, $src1, $src2" %} 9719 size(4); 9720 ins_encode %{ 9721 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9722 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9723 %} 9724 ins_pipe(pipe_class_default); 9725 %} 9726 9727 // Expand does not work with above instruct. (??) 9728 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9729 // no match-rule 9730 effect(DEF dst, USE src1, USE src2); 9731 format %{ "OR $dst, $src1, $src2" %} 9732 size(4); 9733 ins_encode %{ 9734 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9735 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9736 %} 9737 ins_pipe(pipe_class_default); 9738 %} 9739 9740 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9741 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 9742 ins_cost(DEFAULT_COST*3); 9743 9744 expand %{ 9745 // FIXME: we should do this in the ideal world. 9746 iRegIdst tmp1; 9747 iRegIdst tmp2; 9748 orI_reg_reg(tmp1, src1, src2); 9749 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 9750 orI_reg_reg(dst, tmp1, tmp2); 9751 %} 9752 %} 9753 9754 // Immediate Or 9755 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9756 match(Set dst (OrI src1 src2)); 9757 format %{ "ORI $dst, $src1, $src2" %} 9758 size(4); 9759 ins_encode %{ 9760 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9761 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 9762 %} 9763 ins_pipe(pipe_class_default); 9764 %} 9765 9766 // Register Or Long 9767 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9768 match(Set dst (OrL src1 src2)); 9769 ins_cost(DEFAULT_COST); 9770 9771 size(4); 9772 format %{ "OR $dst, $src1, $src2 \t// long" %} 9773 ins_encode %{ 9774 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9775 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9776 %} 9777 ins_pipe(pipe_class_default); 9778 %} 9779 9780 // OrL + ConvL2I. 9781 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9782 match(Set dst (ConvL2I (OrL src1 src2))); 9783 ins_cost(DEFAULT_COST); 9784 9785 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 9786 size(4); 9787 ins_encode %{ 9788 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9789 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9790 %} 9791 ins_pipe(pipe_class_default); 9792 %} 9793 9794 // Immediate Or long 9795 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 9796 match(Set dst (OrL src1 con)); 9797 ins_cost(DEFAULT_COST); 9798 9799 format %{ "ORI $dst, $src1, $con \t// long" %} 9800 size(4); 9801 ins_encode %{ 9802 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9803 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 9804 %} 9805 ins_pipe(pipe_class_default); 9806 %} 9807 9808 // Xor Instructions 9809 9810 // Register Xor 9811 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9812 match(Set dst (XorI src1 src2)); 9813 format %{ "XOR $dst, $src1, $src2" %} 9814 size(4); 9815 ins_encode %{ 9816 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9817 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9818 %} 9819 ins_pipe(pipe_class_default); 9820 %} 9821 9822 // Expand does not work with above instruct. (??) 9823 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9824 // no match-rule 9825 effect(DEF dst, USE src1, USE src2); 9826 format %{ "XOR $dst, $src1, $src2" %} 9827 size(4); 9828 ins_encode %{ 9829 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9830 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9831 %} 9832 ins_pipe(pipe_class_default); 9833 %} 9834 9835 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9836 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 9837 ins_cost(DEFAULT_COST*3); 9838 9839 expand %{ 9840 // FIXME: we should do this in the ideal world. 9841 iRegIdst tmp1; 9842 iRegIdst tmp2; 9843 xorI_reg_reg(tmp1, src1, src2); 9844 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 9845 xorI_reg_reg(dst, tmp1, tmp2); 9846 %} 9847 %} 9848 9849 // Immediate Xor 9850 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9851 match(Set dst (XorI src1 src2)); 9852 format %{ "XORI $dst, $src1, $src2" %} 9853 size(4); 9854 ins_encode %{ 9855 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 9856 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 9857 %} 9858 ins_pipe(pipe_class_default); 9859 %} 9860 9861 // Register Xor Long 9862 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9863 match(Set dst (XorL src1 src2)); 9864 ins_cost(DEFAULT_COST); 9865 9866 format %{ "XOR $dst, $src1, $src2 \t// long" %} 9867 size(4); 9868 ins_encode %{ 9869 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9870 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9871 %} 9872 ins_pipe(pipe_class_default); 9873 %} 9874 9875 // XorL + ConvL2I. 9876 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9877 match(Set dst (ConvL2I (XorL src1 src2))); 9878 ins_cost(DEFAULT_COST); 9879 9880 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 9881 size(4); 9882 ins_encode %{ 9883 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9884 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9885 %} 9886 ins_pipe(pipe_class_default); 9887 %} 9888 9889 // Immediate Xor Long 9890 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 9891 match(Set dst (XorL src1 src2)); 9892 ins_cost(DEFAULT_COST); 9893 9894 format %{ "XORI $dst, $src1, $src2 \t// long" %} 9895 size(4); 9896 ins_encode %{ 9897 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 9898 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 9899 %} 9900 ins_pipe(pipe_class_default); 9901 %} 9902 9903 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9904 match(Set dst (XorI src1 src2)); 9905 ins_cost(DEFAULT_COST); 9906 9907 format %{ "NOT $dst, $src1 ($src2)" %} 9908 size(4); 9909 ins_encode %{ 9910 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 9911 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 9912 %} 9913 ins_pipe(pipe_class_default); 9914 %} 9915 9916 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9917 match(Set dst (XorL src1 src2)); 9918 ins_cost(DEFAULT_COST); 9919 9920 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 9921 size(4); 9922 ins_encode %{ 9923 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 9924 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 9925 %} 9926 ins_pipe(pipe_class_default); 9927 %} 9928 9929 // And-complement 9930 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 9931 match(Set dst (AndI (XorI src1 src2) src3)); 9932 ins_cost(DEFAULT_COST); 9933 9934 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 9935 size(4); 9936 ins_encode( enc_andc(dst, src3, src1) ); 9937 ins_pipe(pipe_class_default); 9938 %} 9939 9940 // And-complement 9941 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9942 // no match-rule, false predicate 9943 effect(DEF dst, USE src1, USE src2); 9944 predicate(false); 9945 9946 format %{ "ANDC $dst, $src1, $src2" %} 9947 size(4); 9948 ins_encode %{ 9949 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 9950 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 9951 %} 9952 ins_pipe(pipe_class_default); 9953 %} 9954 9955 //----------Moves between int/long and float/double---------------------------- 9956 // 9957 // The following rules move values from int/long registers/stack-locations 9958 // to float/double registers/stack-locations and vice versa, without doing any 9959 // conversions. These rules are used to implement the bit-conversion methods 9960 // of java.lang.Float etc., e.g. 9961 // int floatToIntBits(float value) 9962 // float intBitsToFloat(int bits) 9963 // 9964 // Notes on the implementation on ppc64: 9965 // We only provide rules which move between a register and a stack-location, 9966 // because we always have to go through memory when moving between a float 9967 // register and an integer register. 9968 9969 //---------- Chain stack slots between similar types -------- 9970 9971 // These are needed so that the rules below can match. 9972 9973 // Load integer from stack slot 9974 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 9975 match(Set dst src); 9976 ins_cost(MEMORY_REF_COST); 9977 9978 format %{ "LWZ $dst, $src" %} 9979 size(4); 9980 ins_encode( enc_lwz(dst, src) ); 9981 ins_pipe(pipe_class_memory); 9982 %} 9983 9984 // Store integer to stack slot 9985 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 9986 match(Set dst src); 9987 ins_cost(MEMORY_REF_COST); 9988 9989 format %{ "STW $src, $dst \t// stk" %} 9990 size(4); 9991 ins_encode( enc_stw(src, dst) ); // rs=rt 9992 ins_pipe(pipe_class_memory); 9993 %} 9994 9995 // Load long from stack slot 9996 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 9997 match(Set dst src); 9998 ins_cost(MEMORY_REF_COST); 9999 10000 format %{ "LD $dst, $src \t// long" %} 10001 size(4); 10002 ins_encode( enc_ld(dst, src) ); 10003 ins_pipe(pipe_class_memory); 10004 %} 10005 10006 // Store long to stack slot 10007 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10008 match(Set dst src); 10009 ins_cost(MEMORY_REF_COST); 10010 10011 format %{ "STD $src, $dst \t// long" %} 10012 size(4); 10013 ins_encode( enc_std(src, dst) ); // rs=rt 10014 ins_pipe(pipe_class_memory); 10015 %} 10016 10017 //----------Moves between int and float 10018 10019 // Move float value from float stack-location to integer register. 10020 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10021 match(Set dst (MoveF2I src)); 10022 ins_cost(MEMORY_REF_COST); 10023 10024 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10025 size(4); 10026 ins_encode( enc_lwz(dst, src) ); 10027 ins_pipe(pipe_class_memory); 10028 %} 10029 10030 // Move float value from float register to integer stack-location. 10031 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10032 match(Set dst (MoveF2I src)); 10033 ins_cost(MEMORY_REF_COST); 10034 10035 format %{ "STFS $src, $dst \t// MoveF2I" %} 10036 size(4); 10037 ins_encode( enc_stfs(src, dst) ); 10038 ins_pipe(pipe_class_memory); 10039 %} 10040 10041 // Move integer value from integer stack-location to float register. 10042 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10043 match(Set dst (MoveI2F src)); 10044 ins_cost(MEMORY_REF_COST); 10045 10046 format %{ "LFS $dst, $src \t// MoveI2F" %} 10047 size(4); 10048 ins_encode %{ 10049 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10050 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10051 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10052 %} 10053 ins_pipe(pipe_class_memory); 10054 %} 10055 10056 // Move integer value from integer register to float stack-location. 10057 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10058 match(Set dst (MoveI2F src)); 10059 ins_cost(MEMORY_REF_COST); 10060 10061 format %{ "STW $src, $dst \t// MoveI2F" %} 10062 size(4); 10063 ins_encode( enc_stw(src, dst) ); 10064 ins_pipe(pipe_class_memory); 10065 %} 10066 10067 //----------Moves between long and float 10068 10069 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10070 // no match-rule, false predicate 10071 effect(DEF dst, USE src); 10072 predicate(false); 10073 10074 format %{ "storeD $src, $dst \t// STACK" %} 10075 size(4); 10076 ins_encode( enc_stfd(src, dst) ); 10077 ins_pipe(pipe_class_default); 10078 %} 10079 10080 //----------Moves between long and double 10081 10082 // Move double value from double stack-location to long register. 10083 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10084 match(Set dst (MoveD2L src)); 10085 ins_cost(MEMORY_REF_COST); 10086 size(4); 10087 format %{ "LD $dst, $src \t// MoveD2L" %} 10088 ins_encode( enc_ld(dst, src) ); 10089 ins_pipe(pipe_class_memory); 10090 %} 10091 10092 // Move double value from double register to long stack-location. 10093 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10094 match(Set dst (MoveD2L src)); 10095 effect(DEF dst, USE src); 10096 ins_cost(MEMORY_REF_COST); 10097 10098 format %{ "STFD $src, $dst \t// MoveD2L" %} 10099 size(4); 10100 ins_encode( enc_stfd(src, dst) ); 10101 ins_pipe(pipe_class_memory); 10102 %} 10103 10104 // Move long value from long stack-location to double register. 10105 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10106 match(Set dst (MoveL2D src)); 10107 ins_cost(MEMORY_REF_COST); 10108 10109 format %{ "LFD $dst, $src \t// MoveL2D" %} 10110 size(4); 10111 ins_encode( enc_lfd(dst, src) ); 10112 ins_pipe(pipe_class_memory); 10113 %} 10114 10115 // Move long value from long register to double stack-location. 10116 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10117 match(Set dst (MoveL2D src)); 10118 ins_cost(MEMORY_REF_COST); 10119 10120 format %{ "STD $src, $dst \t// MoveL2D" %} 10121 size(4); 10122 ins_encode( enc_std(src, dst) ); 10123 ins_pipe(pipe_class_memory); 10124 %} 10125 10126 //----------Register Move Instructions----------------------------------------- 10127 10128 // Replicate for Superword 10129 10130 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10131 predicate(false); 10132 effect(DEF dst, USE src); 10133 10134 format %{ "MR $dst, $src \t// replicate " %} 10135 // variable size, 0 or 4. 10136 ins_encode %{ 10137 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10138 __ mr_if_needed($dst$$Register, $src$$Register); 10139 %} 10140 ins_pipe(pipe_class_default); 10141 %} 10142 10143 //----------Cast instructions (Java-level type cast)--------------------------- 10144 10145 // Cast Long to Pointer for unsafe natives. 10146 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10147 match(Set dst (CastX2P src)); 10148 10149 format %{ "MR $dst, $src \t// Long->Ptr" %} 10150 // variable size, 0 or 4. 10151 ins_encode %{ 10152 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10153 __ mr_if_needed($dst$$Register, $src$$Register); 10154 %} 10155 ins_pipe(pipe_class_default); 10156 %} 10157 10158 // Cast Pointer to Long for unsafe natives. 10159 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10160 match(Set dst (CastP2X src)); 10161 10162 format %{ "MR $dst, $src \t// Ptr->Long" %} 10163 // variable size, 0 or 4. 10164 ins_encode %{ 10165 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10166 __ mr_if_needed($dst$$Register, $src$$Register); 10167 %} 10168 ins_pipe(pipe_class_default); 10169 %} 10170 10171 instruct castPP(iRegPdst dst) %{ 10172 match(Set dst (CastPP dst)); 10173 format %{ " -- \t// castPP of $dst" %} 10174 size(0); 10175 ins_encode( /*empty*/ ); 10176 ins_pipe(pipe_class_default); 10177 %} 10178 10179 instruct castII(iRegIdst dst) %{ 10180 match(Set dst (CastII dst)); 10181 format %{ " -- \t// castII of $dst" %} 10182 size(0); 10183 ins_encode( /*empty*/ ); 10184 ins_pipe(pipe_class_default); 10185 %} 10186 10187 instruct checkCastPP(iRegPdst dst) %{ 10188 match(Set dst (CheckCastPP dst)); 10189 format %{ " -- \t// checkcastPP of $dst" %} 10190 size(0); 10191 ins_encode( /*empty*/ ); 10192 ins_pipe(pipe_class_default); 10193 %} 10194 10195 //----------Convert instructions----------------------------------------------- 10196 10197 // Convert to boolean. 10198 10199 // int_to_bool(src) : { 1 if src != 0 10200 // { 0 else 10201 // 10202 // strategy: 10203 // 1) Count leading zeros of 32 bit-value src, 10204 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10205 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10206 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10207 10208 // convI2Bool 10209 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10210 match(Set dst (Conv2B src)); 10211 predicate(UseCountLeadingZerosInstructionsPPC64); 10212 ins_cost(DEFAULT_COST); 10213 10214 expand %{ 10215 immI shiftAmount %{ 0x5 %} 10216 uimmI16 mask %{ 0x1 %} 10217 iRegIdst tmp1; 10218 iRegIdst tmp2; 10219 countLeadingZerosI(tmp1, src); 10220 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10221 xorI_reg_uimm16(dst, tmp2, mask); 10222 %} 10223 %} 10224 10225 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10226 match(Set dst (Conv2B src)); 10227 effect(TEMP crx); 10228 predicate(!UseCountLeadingZerosInstructionsPPC64); 10229 ins_cost(DEFAULT_COST); 10230 10231 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10232 "LI $dst, #0\n\t" 10233 "BEQ $crx, done\n\t" 10234 "LI $dst, #1\n" 10235 "done:" %} 10236 size(16); 10237 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10238 ins_pipe(pipe_class_compare); 10239 %} 10240 10241 // ConvI2B + XorI 10242 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10243 match(Set dst (XorI (Conv2B src) mask)); 10244 predicate(UseCountLeadingZerosInstructionsPPC64); 10245 ins_cost(DEFAULT_COST); 10246 10247 expand %{ 10248 immI shiftAmount %{ 0x5 %} 10249 iRegIdst tmp1; 10250 countLeadingZerosI(tmp1, src); 10251 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10252 %} 10253 %} 10254 10255 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10256 match(Set dst (XorI (Conv2B src) mask)); 10257 effect(TEMP crx); 10258 predicate(!UseCountLeadingZerosInstructionsPPC64); 10259 ins_cost(DEFAULT_COST); 10260 10261 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10262 "LI $dst, #1\n\t" 10263 "BEQ $crx, done\n\t" 10264 "LI $dst, #0\n" 10265 "done:" %} 10266 size(16); 10267 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10268 ins_pipe(pipe_class_compare); 10269 %} 10270 10271 // AndI 0b0..010..0 + ConvI2B 10272 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10273 match(Set dst (Conv2B (AndI src mask))); 10274 predicate(UseRotateAndMaskInstructionsPPC64); 10275 ins_cost(DEFAULT_COST); 10276 10277 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10278 size(4); 10279 ins_encode %{ 10280 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10281 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10282 %} 10283 ins_pipe(pipe_class_default); 10284 %} 10285 10286 // Convert pointer to boolean. 10287 // 10288 // ptr_to_bool(src) : { 1 if src != 0 10289 // { 0 else 10290 // 10291 // strategy: 10292 // 1) Count leading zeros of 64 bit-value src, 10293 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10294 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10295 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10296 10297 // ConvP2B 10298 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10299 match(Set dst (Conv2B src)); 10300 predicate(UseCountLeadingZerosInstructionsPPC64); 10301 ins_cost(DEFAULT_COST); 10302 10303 expand %{ 10304 immI shiftAmount %{ 0x6 %} 10305 uimmI16 mask %{ 0x1 %} 10306 iRegIdst tmp1; 10307 iRegIdst tmp2; 10308 countLeadingZerosP(tmp1, src); 10309 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10310 xorI_reg_uimm16(dst, tmp2, mask); 10311 %} 10312 %} 10313 10314 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10315 match(Set dst (Conv2B src)); 10316 effect(TEMP crx); 10317 predicate(!UseCountLeadingZerosInstructionsPPC64); 10318 ins_cost(DEFAULT_COST); 10319 10320 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10321 "LI $dst, #0\n\t" 10322 "BEQ $crx, done\n\t" 10323 "LI $dst, #1\n" 10324 "done:" %} 10325 size(16); 10326 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10327 ins_pipe(pipe_class_compare); 10328 %} 10329 10330 // ConvP2B + XorI 10331 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10332 match(Set dst (XorI (Conv2B src) mask)); 10333 predicate(UseCountLeadingZerosInstructionsPPC64); 10334 ins_cost(DEFAULT_COST); 10335 10336 expand %{ 10337 immI shiftAmount %{ 0x6 %} 10338 iRegIdst tmp1; 10339 countLeadingZerosP(tmp1, src); 10340 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10341 %} 10342 %} 10343 10344 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10345 match(Set dst (XorI (Conv2B src) mask)); 10346 effect(TEMP crx); 10347 predicate(!UseCountLeadingZerosInstructionsPPC64); 10348 ins_cost(DEFAULT_COST); 10349 10350 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10351 "LI $dst, #1\n\t" 10352 "BEQ $crx, done\n\t" 10353 "LI $dst, #0\n" 10354 "done:" %} 10355 size(16); 10356 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10357 ins_pipe(pipe_class_compare); 10358 %} 10359 10360 // if src1 < src2, return -1 else return 0 10361 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10362 match(Set dst (CmpLTMask src1 src2)); 10363 ins_cost(DEFAULT_COST*4); 10364 10365 expand %{ 10366 iRegLdst src1s; 10367 iRegLdst src2s; 10368 iRegLdst diff; 10369 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10370 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10371 subL_reg_reg(diff, src1s, src2s); 10372 // Need to consider >=33 bit result, therefore we need signmaskL. 10373 signmask64I_regL(dst, diff); 10374 %} 10375 %} 10376 10377 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 10378 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 10379 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 10380 size(4); 10381 ins_encode %{ 10382 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 10383 __ srawi($dst$$Register, $src1$$Register, 0x1f); 10384 %} 10385 ins_pipe(pipe_class_default); 10386 %} 10387 10388 //----------Arithmetic Conversion Instructions--------------------------------- 10389 10390 // Convert to Byte -- nop 10391 // Convert to Short -- nop 10392 10393 // Convert to Int 10394 10395 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 10396 match(Set dst (RShiftI (LShiftI src amount) amount)); 10397 format %{ "EXTSB $dst, $src \t// byte->int" %} 10398 size(4); 10399 ins_encode %{ 10400 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 10401 __ extsb($dst$$Register, $src$$Register); 10402 %} 10403 ins_pipe(pipe_class_default); 10404 %} 10405 10406 // LShiftI 16 + RShiftI 16 converts short to int. 10407 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 10408 match(Set dst (RShiftI (LShiftI src amount) amount)); 10409 format %{ "EXTSH $dst, $src \t// short->int" %} 10410 size(4); 10411 ins_encode %{ 10412 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 10413 __ extsh($dst$$Register, $src$$Register); 10414 %} 10415 ins_pipe(pipe_class_default); 10416 %} 10417 10418 // ConvL2I + ConvI2L: Sign extend int in long register. 10419 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 10420 match(Set dst (ConvI2L (ConvL2I src))); 10421 10422 format %{ "EXTSW $dst, $src \t// long->long" %} 10423 size(4); 10424 ins_encode %{ 10425 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10426 __ extsw($dst$$Register, $src$$Register); 10427 %} 10428 ins_pipe(pipe_class_default); 10429 %} 10430 10431 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 10432 match(Set dst (ConvL2I src)); 10433 format %{ "MR $dst, $src \t// long->int" %} 10434 // variable size, 0 or 4 10435 ins_encode %{ 10436 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10437 __ mr_if_needed($dst$$Register, $src$$Register); 10438 %} 10439 ins_pipe(pipe_class_default); 10440 %} 10441 10442 instruct convD2IRaw_regD(regD dst, regD src) %{ 10443 // no match-rule, false predicate 10444 effect(DEF dst, USE src); 10445 predicate(false); 10446 10447 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 10448 size(4); 10449 ins_encode %{ 10450 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 10451 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10452 %} 10453 ins_pipe(pipe_class_default); 10454 %} 10455 10456 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 10457 // no match-rule, false predicate 10458 effect(DEF dst, USE crx, USE src); 10459 predicate(false); 10460 10461 ins_variable_size_depending_on_alignment(true); 10462 10463 format %{ "cmovI $crx, $dst, $src" %} 10464 // Worst case is branch + move + stop, no stop without scheduler. 10465 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 10466 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10467 ins_pipe(pipe_class_default); 10468 %} 10469 10470 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10471 // no match-rule, false predicate 10472 effect(DEF dst, USE crx, USE mem); 10473 predicate(false); 10474 10475 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 10476 postalloc_expand %{ 10477 // 10478 // replaces 10479 // 10480 // region dst crx mem 10481 // \ | | / 10482 // dst=cmovI_bso_stackSlotL_conLvalue0 10483 // 10484 // with 10485 // 10486 // region dst 10487 // \ / 10488 // dst=loadConI16(0) 10489 // | 10490 // ^ region dst crx mem 10491 // | \ | | / 10492 // dst=cmovI_bso_stackSlotL 10493 // 10494 10495 // Create new nodes. 10496 MachNode *m1 = new loadConI16Node(); 10497 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 10498 10499 // inputs for new nodes 10500 m1->add_req(n_region); 10501 m2->add_req(n_region, n_crx, n_mem); 10502 10503 // precedences for new nodes 10504 m2->add_prec(m1); 10505 10506 // operands for new nodes 10507 m1->_opnds[0] = op_dst; 10508 m1->_opnds[1] = new immI16Oper(0); 10509 10510 m2->_opnds[0] = op_dst; 10511 m2->_opnds[1] = op_crx; 10512 m2->_opnds[2] = op_mem; 10513 10514 // registers for new nodes 10515 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10516 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10517 10518 // Insert new nodes. 10519 nodes->push(m1); 10520 nodes->push(m2); 10521 %} 10522 %} 10523 10524 // Double to Int conversion, NaN is mapped to 0. 10525 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 10526 match(Set dst (ConvD2I src)); 10527 ins_cost(DEFAULT_COST); 10528 10529 expand %{ 10530 regD tmpD; 10531 stackSlotL tmpS; 10532 flagsReg crx; 10533 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10534 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10535 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10536 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10537 %} 10538 %} 10539 10540 instruct convF2IRaw_regF(regF dst, regF src) %{ 10541 // no match-rule, false predicate 10542 effect(DEF dst, USE src); 10543 predicate(false); 10544 10545 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 10546 size(4); 10547 ins_encode %{ 10548 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10549 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10550 %} 10551 ins_pipe(pipe_class_default); 10552 %} 10553 10554 // Float to Int conversion, NaN is mapped to 0. 10555 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 10556 match(Set dst (ConvF2I src)); 10557 ins_cost(DEFAULT_COST); 10558 10559 expand %{ 10560 regF tmpF; 10561 stackSlotL tmpS; 10562 flagsReg crx; 10563 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10564 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10565 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10566 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10567 %} 10568 %} 10569 10570 // Convert to Long 10571 10572 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 10573 match(Set dst (ConvI2L src)); 10574 format %{ "EXTSW $dst, $src \t// int->long" %} 10575 size(4); 10576 ins_encode %{ 10577 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10578 __ extsw($dst$$Register, $src$$Register); 10579 %} 10580 ins_pipe(pipe_class_default); 10581 %} 10582 10583 // Zero-extend: convert unsigned int to long (convUI2L). 10584 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 10585 match(Set dst (AndL (ConvI2L src) mask)); 10586 ins_cost(DEFAULT_COST); 10587 10588 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10589 size(4); 10590 ins_encode %{ 10591 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10592 __ clrldi($dst$$Register, $src$$Register, 32); 10593 %} 10594 ins_pipe(pipe_class_default); 10595 %} 10596 10597 // Zero-extend: convert unsigned int to long in long register. 10598 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 10599 match(Set dst (AndL src mask)); 10600 ins_cost(DEFAULT_COST); 10601 10602 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10603 size(4); 10604 ins_encode %{ 10605 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10606 __ clrldi($dst$$Register, $src$$Register, 32); 10607 %} 10608 ins_pipe(pipe_class_default); 10609 %} 10610 10611 instruct convF2LRaw_regF(regF dst, regF src) %{ 10612 // no match-rule, false predicate 10613 effect(DEF dst, USE src); 10614 predicate(false); 10615 10616 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 10617 size(4); 10618 ins_encode %{ 10619 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10620 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10621 %} 10622 ins_pipe(pipe_class_default); 10623 %} 10624 10625 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 10626 // no match-rule, false predicate 10627 effect(DEF dst, USE crx, USE src); 10628 predicate(false); 10629 10630 ins_variable_size_depending_on_alignment(true); 10631 10632 format %{ "cmovL $crx, $dst, $src" %} 10633 // Worst case is branch + move + stop, no stop without scheduler. 10634 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 10635 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10636 ins_pipe(pipe_class_default); 10637 %} 10638 10639 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10640 // no match-rule, false predicate 10641 effect(DEF dst, USE crx, USE mem); 10642 predicate(false); 10643 10644 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 10645 postalloc_expand %{ 10646 // 10647 // replaces 10648 // 10649 // region dst crx mem 10650 // \ | | / 10651 // dst=cmovL_bso_stackSlotL_conLvalue0 10652 // 10653 // with 10654 // 10655 // region dst 10656 // \ / 10657 // dst=loadConL16(0) 10658 // | 10659 // ^ region dst crx mem 10660 // | \ | | / 10661 // dst=cmovL_bso_stackSlotL 10662 // 10663 10664 // Create new nodes. 10665 MachNode *m1 = new loadConL16Node(); 10666 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 10667 10668 // inputs for new nodes 10669 m1->add_req(n_region); 10670 m2->add_req(n_region, n_crx, n_mem); 10671 m2->add_prec(m1); 10672 10673 // operands for new nodes 10674 m1->_opnds[0] = op_dst; 10675 m1->_opnds[1] = new immL16Oper(0); 10676 m2->_opnds[0] = op_dst; 10677 m2->_opnds[1] = op_crx; 10678 m2->_opnds[2] = op_mem; 10679 10680 // registers for new nodes 10681 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10682 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10683 10684 // Insert new nodes. 10685 nodes->push(m1); 10686 nodes->push(m2); 10687 %} 10688 %} 10689 10690 // Float to Long conversion, NaN is mapped to 0. 10691 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 10692 match(Set dst (ConvF2L src)); 10693 ins_cost(DEFAULT_COST); 10694 10695 expand %{ 10696 regF tmpF; 10697 stackSlotL tmpS; 10698 flagsReg crx; 10699 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10700 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 10701 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10702 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10703 %} 10704 %} 10705 10706 instruct convD2LRaw_regD(regD dst, regD src) %{ 10707 // no match-rule, false predicate 10708 effect(DEF dst, USE src); 10709 predicate(false); 10710 10711 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 10712 size(4); 10713 ins_encode %{ 10714 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10715 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10716 %} 10717 ins_pipe(pipe_class_default); 10718 %} 10719 10720 // Double to Long conversion, NaN is mapped to 0. 10721 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 10722 match(Set dst (ConvD2L src)); 10723 ins_cost(DEFAULT_COST); 10724 10725 expand %{ 10726 regD tmpD; 10727 stackSlotL tmpS; 10728 flagsReg crx; 10729 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10730 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 10731 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10732 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10733 %} 10734 %} 10735 10736 // Convert to Float 10737 10738 // Placed here as needed in expand. 10739 instruct convL2DRaw_regD(regD dst, regD src) %{ 10740 // no match-rule, false predicate 10741 effect(DEF dst, USE src); 10742 predicate(false); 10743 10744 format %{ "FCFID $dst, $src \t// convL2D" %} 10745 size(4); 10746 ins_encode %{ 10747 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10748 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 10749 %} 10750 ins_pipe(pipe_class_default); 10751 %} 10752 10753 // Placed here as needed in expand. 10754 instruct convD2F_reg(regF dst, regD src) %{ 10755 match(Set dst (ConvD2F src)); 10756 format %{ "FRSP $dst, $src \t// convD2F" %} 10757 size(4); 10758 ins_encode %{ 10759 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 10760 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 10761 %} 10762 ins_pipe(pipe_class_default); 10763 %} 10764 10765 // Integer to Float conversion. 10766 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 10767 match(Set dst (ConvI2F src)); 10768 predicate(!VM_Version::has_fcfids()); 10769 ins_cost(DEFAULT_COST); 10770 10771 expand %{ 10772 iRegLdst tmpL; 10773 stackSlotL tmpS; 10774 regD tmpD; 10775 regD tmpD2; 10776 convI2L_reg(tmpL, src); // Sign-extension int to long. 10777 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10778 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10779 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 10780 convD2F_reg(dst, tmpD2); // Convert double to float. 10781 %} 10782 %} 10783 10784 instruct convL2FRaw_regF(regF dst, regD src) %{ 10785 // no match-rule, false predicate 10786 effect(DEF dst, USE src); 10787 predicate(false); 10788 10789 format %{ "FCFIDS $dst, $src \t// convL2F" %} 10790 size(4); 10791 ins_encode %{ 10792 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10793 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 10794 %} 10795 ins_pipe(pipe_class_default); 10796 %} 10797 10798 // Integer to Float conversion. Special version for Power7. 10799 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 10800 match(Set dst (ConvI2F src)); 10801 predicate(VM_Version::has_fcfids()); 10802 ins_cost(DEFAULT_COST); 10803 10804 expand %{ 10805 iRegLdst tmpL; 10806 stackSlotL tmpS; 10807 regD tmpD; 10808 convI2L_reg(tmpL, src); // Sign-extension int to long. 10809 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10810 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10811 convL2FRaw_regF(dst, tmpD); // Convert to float. 10812 %} 10813 %} 10814 10815 // L2F to avoid runtime call. 10816 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 10817 match(Set dst (ConvL2F src)); 10818 predicate(VM_Version::has_fcfids()); 10819 ins_cost(DEFAULT_COST); 10820 10821 expand %{ 10822 stackSlotL tmpS; 10823 regD tmpD; 10824 regL_to_stkL(tmpS, src); // Store long to stack. 10825 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10826 convL2FRaw_regF(dst, tmpD); // Convert to float. 10827 %} 10828 %} 10829 10830 // Moved up as used in expand. 10831 //instruct convD2F_reg(regF dst, regD src) %{%} 10832 10833 // Convert to Double 10834 10835 // Integer to Double conversion. 10836 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 10837 match(Set dst (ConvI2D src)); 10838 ins_cost(DEFAULT_COST); 10839 10840 expand %{ 10841 iRegLdst tmpL; 10842 stackSlotL tmpS; 10843 regD tmpD; 10844 convI2L_reg(tmpL, src); // Sign-extension int to long. 10845 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10846 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10847 convL2DRaw_regD(dst, tmpD); // Convert to double. 10848 %} 10849 %} 10850 10851 // Long to Double conversion 10852 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 10853 match(Set dst (ConvL2D src)); 10854 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 10855 10856 expand %{ 10857 regD tmpD; 10858 moveL2D_stack_reg(tmpD, src); 10859 convL2DRaw_regD(dst, tmpD); 10860 %} 10861 %} 10862 10863 instruct convF2D_reg(regD dst, regF src) %{ 10864 match(Set dst (ConvF2D src)); 10865 format %{ "FMR $dst, $src \t// float->double" %} 10866 // variable size, 0 or 4 10867 ins_encode %{ 10868 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 10869 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 10870 %} 10871 ins_pipe(pipe_class_default); 10872 %} 10873 10874 //----------Control Flow Instructions------------------------------------------ 10875 // Compare Instructions 10876 10877 // Compare Integers 10878 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 10879 match(Set crx (CmpI src1 src2)); 10880 size(4); 10881 format %{ "CMPW $crx, $src1, $src2" %} 10882 ins_encode %{ 10883 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 10884 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 10885 %} 10886 ins_pipe(pipe_class_compare); 10887 %} 10888 10889 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 10890 match(Set crx (CmpI src1 src2)); 10891 format %{ "CMPWI $crx, $src1, $src2" %} 10892 size(4); 10893 ins_encode %{ 10894 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 10895 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 10896 %} 10897 ins_pipe(pipe_class_compare); 10898 %} 10899 10900 // (src1 & src2) == 0? 10901 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 10902 match(Set cr0 (CmpI (AndI src1 src2) zero)); 10903 // r0 is killed 10904 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 10905 size(4); 10906 ins_encode %{ 10907 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10908 __ andi_(R0, $src1$$Register, $src2$$constant); 10909 %} 10910 ins_pipe(pipe_class_compare); 10911 %} 10912 10913 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 10914 match(Set crx (CmpL src1 src2)); 10915 format %{ "CMPD $crx, $src1, $src2" %} 10916 size(4); 10917 ins_encode %{ 10918 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 10919 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 10920 %} 10921 ins_pipe(pipe_class_compare); 10922 %} 10923 10924 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 10925 match(Set crx (CmpL src1 src2)); 10926 format %{ "CMPDI $crx, $src1, $src2" %} 10927 size(4); 10928 ins_encode %{ 10929 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 10930 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 10931 %} 10932 ins_pipe(pipe_class_compare); 10933 %} 10934 10935 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 10936 match(Set cr0 (CmpL (AndL src1 src2) zero)); 10937 // r0 is killed 10938 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 10939 size(4); 10940 ins_encode %{ 10941 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 10942 __ and_(R0, $src1$$Register, $src2$$Register); 10943 %} 10944 ins_pipe(pipe_class_compare); 10945 %} 10946 10947 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 10948 match(Set cr0 (CmpL (AndL src1 src2) zero)); 10949 // r0 is killed 10950 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 10951 size(4); 10952 ins_encode %{ 10953 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10954 __ andi_(R0, $src1$$Register, $src2$$constant); 10955 %} 10956 ins_pipe(pipe_class_compare); 10957 %} 10958 10959 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 10960 // no match-rule, false predicate 10961 effect(DEF dst, USE crx); 10962 predicate(false); 10963 10964 ins_variable_size_depending_on_alignment(true); 10965 10966 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 10967 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 10968 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16); 10969 ins_encode %{ 10970 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 10971 Label done; 10972 // li(Rdst, 0); // equal -> 0 10973 __ beq($crx$$CondRegister, done); 10974 __ li($dst$$Register, 1); // greater -> +1 10975 __ bgt($crx$$CondRegister, done); 10976 __ li($dst$$Register, -1); // unordered or less -> -1 10977 // TODO: PPC port__ endgroup_if_needed(_size == 20); 10978 __ bind(done); 10979 %} 10980 ins_pipe(pipe_class_compare); 10981 %} 10982 10983 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 10984 // no match-rule, false predicate 10985 effect(DEF dst, USE crx); 10986 predicate(false); 10987 10988 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 10989 postalloc_expand %{ 10990 // 10991 // replaces 10992 // 10993 // region crx 10994 // \ | 10995 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 10996 // 10997 // with 10998 // 10999 // region 11000 // \ 11001 // dst=loadConI16(0) 11002 // | 11003 // ^ region crx 11004 // | \ | 11005 // dst=cmovI_conIvalueMinus1_conIvalue1 11006 // 11007 11008 // Create new nodes. 11009 MachNode *m1 = new loadConI16Node(); 11010 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11011 11012 // inputs for new nodes 11013 m1->add_req(n_region); 11014 m2->add_req(n_region, n_crx); 11015 m2->add_prec(m1); 11016 11017 // operands for new nodes 11018 m1->_opnds[0] = op_dst; 11019 m1->_opnds[1] = new immI16Oper(0); 11020 m2->_opnds[0] = op_dst; 11021 m2->_opnds[1] = op_crx; 11022 11023 // registers for new nodes 11024 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11025 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11026 11027 // Insert new nodes. 11028 nodes->push(m1); 11029 nodes->push(m2); 11030 %} 11031 %} 11032 11033 // Manifest a CmpL3 result in an integer register. Very painful. 11034 // This is the test to avoid. 11035 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11036 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11037 match(Set dst (CmpL3 src1 src2)); 11038 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11039 11040 expand %{ 11041 flagsReg tmp1; 11042 cmpL_reg_reg(tmp1, src1, src2); 11043 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11044 %} 11045 %} 11046 11047 // Implicit range checks. 11048 // A range check in the ideal world has one of the following shapes: 11049 // - (If le (CmpU length index)), (IfTrue throw exception) 11050 // - (If lt (CmpU index length)), (IfFalse throw exception) 11051 // 11052 // Match range check 'If le (CmpU length index)'. 11053 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11054 match(If cmp (CmpU src_length index)); 11055 effect(USE labl); 11056 predicate(TrapBasedRangeChecks && 11057 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11058 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11059 (Matcher::branches_to_uncommon_trap(_leaf))); 11060 11061 ins_is_TrapBasedCheckNode(true); 11062 11063 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11064 size(4); 11065 ins_encode %{ 11066 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11067 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11068 __ trap_range_check_le($src_length$$Register, $index$$constant); 11069 } else { 11070 // Both successors are uncommon traps, probability is 0. 11071 // Node got flipped during fixup flow. 11072 assert($cmp$$cmpcode == 0x9, "must be greater"); 11073 __ trap_range_check_g($src_length$$Register, $index$$constant); 11074 } 11075 %} 11076 ins_pipe(pipe_class_trap); 11077 %} 11078 11079 // Match range check 'If lt (CmpU index length)'. 11080 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11081 match(If cmp (CmpU src_index src_length)); 11082 effect(USE labl); 11083 predicate(TrapBasedRangeChecks && 11084 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11085 _leaf->as_If()->_prob >= PROB_ALWAYS && 11086 (Matcher::branches_to_uncommon_trap(_leaf))); 11087 11088 ins_is_TrapBasedCheckNode(true); 11089 11090 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 11091 size(4); 11092 ins_encode %{ 11093 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 11094 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11095 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 11096 } else { 11097 // Both successors are uncommon traps, probability is 0. 11098 // Node got flipped during fixup flow. 11099 assert($cmp$$cmpcode == 0x8, "must be less"); 11100 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 11101 } 11102 %} 11103 ins_pipe(pipe_class_trap); 11104 %} 11105 11106 // Match range check 'If lt (CmpU index length)'. 11107 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 11108 match(If cmp (CmpU src_index length)); 11109 effect(USE labl); 11110 predicate(TrapBasedRangeChecks && 11111 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11112 _leaf->as_If()->_prob >= PROB_ALWAYS && 11113 (Matcher::branches_to_uncommon_trap(_leaf))); 11114 11115 ins_is_TrapBasedCheckNode(true); 11116 11117 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 11118 size(4); 11119 ins_encode %{ 11120 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11121 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11122 __ trap_range_check_ge($src_index$$Register, $length$$constant); 11123 } else { 11124 // Both successors are uncommon traps, probability is 0. 11125 // Node got flipped during fixup flow. 11126 assert($cmp$$cmpcode == 0x8, "must be less"); 11127 __ trap_range_check_l($src_index$$Register, $length$$constant); 11128 } 11129 %} 11130 ins_pipe(pipe_class_trap); 11131 %} 11132 11133 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11134 match(Set crx (CmpU src1 src2)); 11135 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 11136 size(4); 11137 ins_encode %{ 11138 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11139 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11140 %} 11141 ins_pipe(pipe_class_compare); 11142 %} 11143 11144 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 11145 match(Set crx (CmpU src1 src2)); 11146 size(4); 11147 format %{ "CMPLWI $crx, $src1, $src2" %} 11148 ins_encode %{ 11149 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11150 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11151 %} 11152 ins_pipe(pipe_class_compare); 11153 %} 11154 11155 // Implicit zero checks (more implicit null checks). 11156 // No constant pool entries required. 11157 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 11158 match(If cmp (CmpN value zero)); 11159 effect(USE labl); 11160 predicate(TrapBasedNullChecks && 11161 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11162 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11163 Matcher::branches_to_uncommon_trap(_leaf)); 11164 ins_cost(1); 11165 11166 ins_is_TrapBasedCheckNode(true); 11167 11168 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 11169 size(4); 11170 ins_encode %{ 11171 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11172 if ($cmp$$cmpcode == 0xA) { 11173 __ trap_null_check($value$$Register); 11174 } else { 11175 // Both successors are uncommon traps, probability is 0. 11176 // Node got flipped during fixup flow. 11177 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11178 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11179 } 11180 %} 11181 ins_pipe(pipe_class_trap); 11182 %} 11183 11184 // Compare narrow oops. 11185 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 11186 match(Set crx (CmpN src1 src2)); 11187 11188 size(4); 11189 ins_cost(2); 11190 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 11191 ins_encode %{ 11192 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11193 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11194 %} 11195 ins_pipe(pipe_class_compare); 11196 %} 11197 11198 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 11199 match(Set crx (CmpN src1 src2)); 11200 // Make this more expensive than zeroCheckN_iReg_imm0. 11201 ins_cost(2); 11202 11203 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 11204 size(4); 11205 ins_encode %{ 11206 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11207 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11208 %} 11209 ins_pipe(pipe_class_compare); 11210 %} 11211 11212 // Implicit zero checks (more implicit null checks). 11213 // No constant pool entries required. 11214 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 11215 match(If cmp (CmpP value zero)); 11216 effect(USE labl); 11217 predicate(TrapBasedNullChecks && 11218 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11219 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11220 Matcher::branches_to_uncommon_trap(_leaf)); 11221 ins_cost(1); // Should not be cheaper than zeroCheckN. 11222 11223 ins_is_TrapBasedCheckNode(true); 11224 11225 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 11226 size(4); 11227 ins_encode %{ 11228 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11229 if ($cmp$$cmpcode == 0xA) { 11230 __ trap_null_check($value$$Register); 11231 } else { 11232 // Both successors are uncommon traps, probability is 0. 11233 // Node got flipped during fixup flow. 11234 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11235 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11236 } 11237 %} 11238 ins_pipe(pipe_class_trap); 11239 %} 11240 11241 // Compare Pointers 11242 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 11243 match(Set crx (CmpP src1 src2)); 11244 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 11245 size(4); 11246 ins_encode %{ 11247 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11248 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11249 %} 11250 ins_pipe(pipe_class_compare); 11251 %} 11252 11253 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 11254 match(Set crx (CmpP src1 src2)); 11255 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 11256 size(4); 11257 ins_encode %{ 11258 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11259 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 11260 %} 11261 ins_pipe(pipe_class_compare); 11262 %} 11263 11264 // Used in postalloc expand. 11265 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 11266 // This match rule prevents reordering of node before a safepoint. 11267 // This only makes sense if this instructions is used exclusively 11268 // for the expansion of EncodeP! 11269 match(Set crx (CmpP src1 src2)); 11270 predicate(false); 11271 11272 format %{ "CMPDI $crx, $src1, $src2" %} 11273 size(4); 11274 ins_encode %{ 11275 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11276 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11277 %} 11278 ins_pipe(pipe_class_compare); 11279 %} 11280 11281 //----------Float Compares---------------------------------------------------- 11282 11283 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 11284 // Needs matchrule, see cmpDUnordered. 11285 match(Set crx (CmpF src1 src2)); 11286 // no match-rule, false predicate 11287 predicate(false); 11288 11289 format %{ "cmpFUrd $crx, $src1, $src2" %} 11290 size(4); 11291 ins_encode %{ 11292 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11293 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11294 %} 11295 ins_pipe(pipe_class_default); 11296 %} 11297 11298 instruct cmov_bns_less(flagsReg crx) %{ 11299 // no match-rule, false predicate 11300 effect(DEF crx); 11301 predicate(false); 11302 11303 ins_variable_size_depending_on_alignment(true); 11304 11305 format %{ "cmov $crx" %} 11306 // Worst case is branch + move + stop, no stop without scheduler. 11307 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12); 11308 ins_encode %{ 11309 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 11310 Label done; 11311 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 11312 __ li(R0, 0); 11313 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 11314 // TODO PPC port __ endgroup_if_needed(_size == 16); 11315 __ bind(done); 11316 %} 11317 ins_pipe(pipe_class_default); 11318 %} 11319 11320 // Compare floating, generate condition code. 11321 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 11322 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 11323 // 11324 // The following code sequence occurs a lot in mpegaudio: 11325 // 11326 // block BXX: 11327 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 11328 // cmpFUrd CCR6, F11, F9 11329 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 11330 // cmov CCR6 11331 // 8: instruct branchConSched: 11332 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 11333 match(Set crx (CmpF src1 src2)); 11334 ins_cost(DEFAULT_COST+BRANCH_COST); 11335 11336 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 11337 postalloc_expand %{ 11338 // 11339 // replaces 11340 // 11341 // region src1 src2 11342 // \ | | 11343 // crx=cmpF_reg_reg 11344 // 11345 // with 11346 // 11347 // region src1 src2 11348 // \ | | 11349 // crx=cmpFUnordered_reg_reg 11350 // | 11351 // ^ region 11352 // | \ 11353 // crx=cmov_bns_less 11354 // 11355 11356 // Create new nodes. 11357 MachNode *m1 = new cmpFUnordered_reg_regNode(); 11358 MachNode *m2 = new cmov_bns_lessNode(); 11359 11360 // inputs for new nodes 11361 m1->add_req(n_region, n_src1, n_src2); 11362 m2->add_req(n_region); 11363 m2->add_prec(m1); 11364 11365 // operands for new nodes 11366 m1->_opnds[0] = op_crx; 11367 m1->_opnds[1] = op_src1; 11368 m1->_opnds[2] = op_src2; 11369 m2->_opnds[0] = op_crx; 11370 11371 // registers for new nodes 11372 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11373 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11374 11375 // Insert new nodes. 11376 nodes->push(m1); 11377 nodes->push(m2); 11378 %} 11379 %} 11380 11381 // Compare float, generate -1,0,1 11382 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 11383 match(Set dst (CmpF3 src1 src2)); 11384 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11385 11386 expand %{ 11387 flagsReg tmp1; 11388 cmpFUnordered_reg_reg(tmp1, src1, src2); 11389 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11390 %} 11391 %} 11392 11393 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 11394 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 11395 // node right before the conditional move using it. 11396 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 11397 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 11398 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 11399 // conditional move was supposed to be spilled. 11400 match(Set crx (CmpD src1 src2)); 11401 // False predicate, shall not be matched. 11402 predicate(false); 11403 11404 format %{ "cmpFUrd $crx, $src1, $src2" %} 11405 size(4); 11406 ins_encode %{ 11407 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11408 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11409 %} 11410 ins_pipe(pipe_class_default); 11411 %} 11412 11413 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 11414 match(Set crx (CmpD src1 src2)); 11415 ins_cost(DEFAULT_COST+BRANCH_COST); 11416 11417 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 11418 postalloc_expand %{ 11419 // 11420 // replaces 11421 // 11422 // region src1 src2 11423 // \ | | 11424 // crx=cmpD_reg_reg 11425 // 11426 // with 11427 // 11428 // region src1 src2 11429 // \ | | 11430 // crx=cmpDUnordered_reg_reg 11431 // | 11432 // ^ region 11433 // | \ 11434 // crx=cmov_bns_less 11435 // 11436 11437 // create new nodes 11438 MachNode *m1 = new cmpDUnordered_reg_regNode(); 11439 MachNode *m2 = new cmov_bns_lessNode(); 11440 11441 // inputs for new nodes 11442 m1->add_req(n_region, n_src1, n_src2); 11443 m2->add_req(n_region); 11444 m2->add_prec(m1); 11445 11446 // operands for new nodes 11447 m1->_opnds[0] = op_crx; 11448 m1->_opnds[1] = op_src1; 11449 m1->_opnds[2] = op_src2; 11450 m2->_opnds[0] = op_crx; 11451 11452 // registers for new nodes 11453 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11454 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11455 11456 // Insert new nodes. 11457 nodes->push(m1); 11458 nodes->push(m2); 11459 %} 11460 %} 11461 11462 // Compare double, generate -1,0,1 11463 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 11464 match(Set dst (CmpD3 src1 src2)); 11465 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11466 11467 expand %{ 11468 flagsReg tmp1; 11469 cmpDUnordered_reg_reg(tmp1, src1, src2); 11470 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11471 %} 11472 %} 11473 11474 //----------Branches--------------------------------------------------------- 11475 // Jump 11476 11477 // Direct Branch. 11478 instruct branch(label labl) %{ 11479 match(Goto); 11480 effect(USE labl); 11481 ins_cost(BRANCH_COST); 11482 11483 format %{ "B $labl" %} 11484 size(4); 11485 ins_encode %{ 11486 // TODO: PPC port $archOpcode(ppc64Opcode_b); 11487 Label d; // dummy 11488 __ bind(d); 11489 Label* p = $labl$$label; 11490 // `p' is `NULL' when this encoding class is used only to 11491 // determine the size of the encoded instruction. 11492 Label& l = (NULL == p)? d : *(p); 11493 __ b(l); 11494 %} 11495 ins_pipe(pipe_class_default); 11496 %} 11497 11498 // Conditional Near Branch 11499 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11500 // Same match rule as `branchConFar'. 11501 match(If cmp crx); 11502 effect(USE lbl); 11503 ins_cost(BRANCH_COST); 11504 11505 // If set to 1 this indicates that the current instruction is a 11506 // short variant of a long branch. This avoids using this 11507 // instruction in first-pass matching. It will then only be used in 11508 // the `Shorten_branches' pass. 11509 ins_short_branch(1); 11510 11511 format %{ "B$cmp $crx, $lbl" %} 11512 size(4); 11513 ins_encode( enc_bc(crx, cmp, lbl) ); 11514 ins_pipe(pipe_class_default); 11515 %} 11516 11517 // This is for cases when the ppc64 `bc' instruction does not 11518 // reach far enough. So we emit a far branch here, which is more 11519 // expensive. 11520 // 11521 // Conditional Far Branch 11522 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11523 // Same match rule as `branchCon'. 11524 match(If cmp crx); 11525 effect(USE crx, USE lbl); 11526 predicate(!false /* TODO: PPC port HB_Schedule*/); 11527 // Higher cost than `branchCon'. 11528 ins_cost(5*BRANCH_COST); 11529 11530 // This is not a short variant of a branch, but the long variant. 11531 ins_short_branch(0); 11532 11533 format %{ "B_FAR$cmp $crx, $lbl" %} 11534 size(8); 11535 ins_encode( enc_bc_far(crx, cmp, lbl) ); 11536 ins_pipe(pipe_class_default); 11537 %} 11538 11539 // Conditional Branch used with Power6 scheduler (can be far or short). 11540 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11541 // Same match rule as `branchCon'. 11542 match(If cmp crx); 11543 effect(USE crx, USE lbl); 11544 predicate(false /* TODO: PPC port HB_Schedule*/); 11545 // Higher cost than `branchCon'. 11546 ins_cost(5*BRANCH_COST); 11547 11548 // Actually size doesn't depend on alignment but on shortening. 11549 ins_variable_size_depending_on_alignment(true); 11550 // long variant. 11551 ins_short_branch(0); 11552 11553 format %{ "B_FAR$cmp $crx, $lbl" %} 11554 size(8); // worst case 11555 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 11556 ins_pipe(pipe_class_default); 11557 %} 11558 11559 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11560 match(CountedLoopEnd cmp crx); 11561 effect(USE labl); 11562 ins_cost(BRANCH_COST); 11563 11564 // short variant. 11565 ins_short_branch(1); 11566 11567 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 11568 size(4); 11569 ins_encode( enc_bc(crx, cmp, labl) ); 11570 ins_pipe(pipe_class_default); 11571 %} 11572 11573 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11574 match(CountedLoopEnd cmp crx); 11575 effect(USE labl); 11576 predicate(!false /* TODO: PPC port HB_Schedule */); 11577 ins_cost(BRANCH_COST); 11578 11579 // Long variant. 11580 ins_short_branch(0); 11581 11582 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11583 size(8); 11584 ins_encode( enc_bc_far(crx, cmp, labl) ); 11585 ins_pipe(pipe_class_default); 11586 %} 11587 11588 // Conditional Branch used with Power6 scheduler (can be far or short). 11589 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11590 match(CountedLoopEnd cmp crx); 11591 effect(USE labl); 11592 predicate(false /* TODO: PPC port HB_Schedule */); 11593 // Higher cost than `branchCon'. 11594 ins_cost(5*BRANCH_COST); 11595 11596 // Actually size doesn't depend on alignment but on shortening. 11597 ins_variable_size_depending_on_alignment(true); 11598 // Long variant. 11599 ins_short_branch(0); 11600 11601 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11602 size(8); // worst case 11603 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 11604 ins_pipe(pipe_class_default); 11605 %} 11606 11607 // ============================================================================ 11608 // Java runtime operations, intrinsics and other complex operations. 11609 11610 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 11611 // array for an instance of the superklass. Set a hidden internal cache on a 11612 // hit (cache is checked with exposed code in gen_subtype_check()). Return 11613 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 11614 // 11615 // GL TODO: Improve this. 11616 // - result should not be a TEMP 11617 // - Add match rule as on sparc avoiding additional Cmp. 11618 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 11619 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 11620 match(Set result (PartialSubtypeCheck subklass superklass)); 11621 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 11622 ins_cost(DEFAULT_COST*10); 11623 11624 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 11625 ins_encode %{ 11626 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11627 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 11628 $tmp_klass$$Register, NULL, $result$$Register); 11629 %} 11630 ins_pipe(pipe_class_default); 11631 %} 11632 11633 // inlined locking and unlocking 11634 11635 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 11636 match(Set crx (FastLock oop box)); 11637 effect(TEMP tmp1, TEMP tmp2); 11638 predicate(!Compile::current()->use_rtm()); 11639 11640 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 11641 ins_encode %{ 11642 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11643 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11644 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 11645 UseBiasedLocking && !UseOptoBiasInlining); 11646 // If locking was successfull, crx should indicate 'EQ'. 11647 // The compiler generates a branch to the runtime call to 11648 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11649 %} 11650 ins_pipe(pipe_class_compare); 11651 %} 11652 11653 // Separate version for TM. Use bound register for box to enable USE_KILL. 11654 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11655 match(Set crx (FastLock oop box)); 11656 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 11657 predicate(Compile::current()->use_rtm()); 11658 11659 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 11660 ins_encode %{ 11661 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11662 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11663 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11664 /*Biased Locking*/ false, 11665 _rtm_counters, _stack_rtm_counters, 11666 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 11667 /*TM*/ true, ra_->C->profile_rtm()); 11668 // If locking was successfull, crx should indicate 'EQ'. 11669 // The compiler generates a branch to the runtime call to 11670 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11671 %} 11672 ins_pipe(pipe_class_compare); 11673 %} 11674 11675 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11676 match(Set crx (FastUnlock oop box)); 11677 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11678 predicate(!Compile::current()->use_rtm()); 11679 11680 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 11681 ins_encode %{ 11682 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11683 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11684 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11685 UseBiasedLocking && !UseOptoBiasInlining, 11686 false); 11687 // If unlocking was successfull, crx should indicate 'EQ'. 11688 // The compiler generates a branch to the runtime call to 11689 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11690 %} 11691 ins_pipe(pipe_class_compare); 11692 %} 11693 11694 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11695 match(Set crx (FastUnlock oop box)); 11696 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11697 predicate(Compile::current()->use_rtm()); 11698 11699 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 11700 ins_encode %{ 11701 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11702 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11703 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11704 /*Biased Locking*/ false, /*TM*/ true); 11705 // If unlocking was successfull, crx should indicate 'EQ'. 11706 // The compiler generates a branch to the runtime call to 11707 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11708 %} 11709 ins_pipe(pipe_class_compare); 11710 %} 11711 11712 // Align address. 11713 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 11714 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 11715 11716 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 11717 size(4); 11718 ins_encode %{ 11719 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 11720 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 11721 %} 11722 ins_pipe(pipe_class_default); 11723 %} 11724 11725 // Array size computation. 11726 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 11727 match(Set dst (SubL (CastP2X end) (CastP2X start))); 11728 11729 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 11730 size(4); 11731 ins_encode %{ 11732 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 11733 __ subf($dst$$Register, $start$$Register, $end$$Register); 11734 %} 11735 ins_pipe(pipe_class_default); 11736 %} 11737 11738 // Clear-array with dynamic array-size. 11739 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 11740 match(Set dummy (ClearArray cnt base)); 11741 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 11742 ins_cost(MEMORY_REF_COST); 11743 11744 ins_alignment(4); // 'compute_padding()' gets called, up to this number-1 nops will get inserted. 11745 11746 format %{ "ClearArray $cnt, $base" %} 11747 ins_encode %{ 11748 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11749 __ clear_memory_doubleword($base$$Register, $cnt$$Register); // kills cnt, base, R0 11750 %} 11751 ins_pipe(pipe_class_default); 11752 %} 11753 11754 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11755 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11756 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11757 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11758 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11759 ins_cost(300); 11760 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11761 ins_encode %{ 11762 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11763 __ string_compare($str1$$Register, $str2$$Register, 11764 $cnt1$$Register, $cnt2$$Register, 11765 $tmp$$Register, 11766 $result$$Register, StrIntrinsicNode::LL); 11767 %} 11768 ins_pipe(pipe_class_default); 11769 %} 11770 11771 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11772 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11773 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11774 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11775 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11776 ins_cost(300); 11777 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11778 ins_encode %{ 11779 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11780 __ string_compare($str1$$Register, $str2$$Register, 11781 $cnt1$$Register, $cnt2$$Register, 11782 $tmp$$Register, 11783 $result$$Register, StrIntrinsicNode::UU); 11784 %} 11785 ins_pipe(pipe_class_default); 11786 %} 11787 11788 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11789 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11790 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11791 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11792 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11793 ins_cost(300); 11794 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11795 ins_encode %{ 11796 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11797 __ string_compare($str1$$Register, $str2$$Register, 11798 $cnt1$$Register, $cnt2$$Register, 11799 $tmp$$Register, 11800 $result$$Register, StrIntrinsicNode::LU); 11801 %} 11802 ins_pipe(pipe_class_default); 11803 %} 11804 11805 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11806 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11807 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11808 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11809 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11810 ins_cost(300); 11811 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11812 ins_encode %{ 11813 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11814 __ string_compare($str2$$Register, $str1$$Register, 11815 $cnt2$$Register, $cnt1$$Register, 11816 $tmp$$Register, 11817 $result$$Register, StrIntrinsicNode::UL); 11818 %} 11819 ins_pipe(pipe_class_default); 11820 %} 11821 11822 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 11823 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11824 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 11825 match(Set result (StrEquals (Binary str1 str2) cnt)); 11826 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 11827 ins_cost(300); 11828 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 11829 ins_encode %{ 11830 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11831 __ array_equals(false, $str1$$Register, $str2$$Register, 11832 $cnt$$Register, $tmp$$Register, 11833 $result$$Register, true /* byte */); 11834 %} 11835 ins_pipe(pipe_class_default); 11836 %} 11837 11838 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 11839 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11840 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 11841 match(Set result (StrEquals (Binary str1 str2) cnt)); 11842 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 11843 ins_cost(300); 11844 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 11845 ins_encode %{ 11846 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11847 __ array_equals(false, $str1$$Register, $str2$$Register, 11848 $cnt$$Register, $tmp$$Register, 11849 $result$$Register, false /* byte */); 11850 %} 11851 ins_pipe(pipe_class_default); 11852 %} 11853 11854 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 11855 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 11856 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11857 match(Set result (AryEq ary1 ary2)); 11858 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 11859 ins_cost(300); 11860 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 11861 ins_encode %{ 11862 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11863 __ array_equals(true, $ary1$$Register, $ary2$$Register, 11864 $tmp1$$Register, $tmp2$$Register, 11865 $result$$Register, true /* byte */); 11866 %} 11867 ins_pipe(pipe_class_default); 11868 %} 11869 11870 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 11871 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 11872 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11873 match(Set result (AryEq ary1 ary2)); 11874 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 11875 ins_cost(300); 11876 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 11877 ins_encode %{ 11878 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11879 __ array_equals(true, $ary1$$Register, $ary2$$Register, 11880 $tmp1$$Register, $tmp2$$Register, 11881 $result$$Register, false /* byte */); 11882 %} 11883 ins_pipe(pipe_class_default); 11884 %} 11885 11886 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11887 immP needleImm, immL offsetImm, immI_1 needlecntImm, 11888 iRegIdst tmp1, iRegIdst tmp2, 11889 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11890 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 11891 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11892 // Required for EA: check if it is still a type_array. 11893 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 11894 ins_cost(150); 11895 11896 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 11897 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 11898 11899 ins_encode %{ 11900 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11901 immPOper *needleOper = (immPOper *)$needleImm; 11902 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 11903 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 11904 jchar chr; 11905 #ifdef VM_LITTLE_ENDIAN 11906 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 11907 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 11908 #else 11909 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 11910 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 11911 #endif 11912 __ string_indexof_char($result$$Register, 11913 $haystack$$Register, $haycnt$$Register, 11914 R0, chr, 11915 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 11916 %} 11917 ins_pipe(pipe_class_compare); 11918 %} 11919 11920 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11921 immP needleImm, immL offsetImm, immI_1 needlecntImm, 11922 iRegIdst tmp1, iRegIdst tmp2, 11923 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11924 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 11925 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11926 // Required for EA: check if it is still a type_array. 11927 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 11928 ins_cost(150); 11929 11930 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 11931 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 11932 11933 ins_encode %{ 11934 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11935 immPOper *needleOper = (immPOper *)$needleImm; 11936 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 11937 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 11938 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 11939 __ string_indexof_char($result$$Register, 11940 $haystack$$Register, $haycnt$$Register, 11941 R0, chr, 11942 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 11943 %} 11944 ins_pipe(pipe_class_compare); 11945 %} 11946 11947 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11948 immP needleImm, immL offsetImm, immI_1 needlecntImm, 11949 iRegIdst tmp1, iRegIdst tmp2, 11950 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11951 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 11952 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11953 // Required for EA: check if it is still a type_array. 11954 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 11955 ins_cost(150); 11956 11957 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 11958 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 11959 11960 ins_encode %{ 11961 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11962 immPOper *needleOper = (immPOper *)$needleImm; 11963 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 11964 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 11965 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 11966 __ string_indexof_char($result$$Register, 11967 $haystack$$Register, $haycnt$$Register, 11968 R0, chr, 11969 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 11970 %} 11971 ins_pipe(pipe_class_compare); 11972 %} 11973 11974 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11975 rscratch2RegP needle, immI_1 needlecntImm, 11976 iRegIdst tmp1, iRegIdst tmp2, 11977 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11978 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 11979 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11980 // Required for EA: check if it is still a type_array. 11981 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 11982 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 11983 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 11984 ins_cost(180); 11985 11986 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 11987 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 11988 ins_encode %{ 11989 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11990 Node *ndl = in(operand_index($needle)); // The node that defines needle. 11991 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 11992 guarantee(needle_values, "sanity"); 11993 jchar chr; 11994 #ifdef VM_LITTLE_ENDIAN 11995 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 11996 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 11997 #else 11998 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 11999 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12000 #endif 12001 __ string_indexof_char($result$$Register, 12002 $haystack$$Register, $haycnt$$Register, 12003 R0, chr, 12004 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12005 %} 12006 ins_pipe(pipe_class_compare); 12007 %} 12008 12009 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12010 rscratch2RegP needle, immI_1 needlecntImm, 12011 iRegIdst tmp1, iRegIdst tmp2, 12012 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12013 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12014 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12015 // Required for EA: check if it is still a type_array. 12016 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12017 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12018 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12019 ins_cost(180); 12020 12021 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12022 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12023 ins_encode %{ 12024 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12025 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12026 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12027 guarantee(needle_values, "sanity"); 12028 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12029 __ string_indexof_char($result$$Register, 12030 $haystack$$Register, $haycnt$$Register, 12031 R0, chr, 12032 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12033 %} 12034 ins_pipe(pipe_class_compare); 12035 %} 12036 12037 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12038 rscratch2RegP needle, immI_1 needlecntImm, 12039 iRegIdst tmp1, iRegIdst tmp2, 12040 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12041 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12042 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12043 // Required for EA: check if it is still a type_array. 12044 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12045 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12046 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12047 ins_cost(180); 12048 12049 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12050 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12051 ins_encode %{ 12052 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12053 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12054 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12055 guarantee(needle_values, "sanity"); 12056 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12057 __ string_indexof_char($result$$Register, 12058 $haystack$$Register, $haycnt$$Register, 12059 R0, chr, 12060 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12061 %} 12062 ins_pipe(pipe_class_compare); 12063 %} 12064 12065 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12066 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12067 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12068 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12069 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12070 ins_cost(180); 12071 12072 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 12073 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12074 ins_encode %{ 12075 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12076 __ string_indexof_char($result$$Register, 12077 $haystack$$Register, $haycnt$$Register, 12078 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12079 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12080 %} 12081 ins_pipe(pipe_class_compare); 12082 %} 12083 12084 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12085 iRegPsrc needle, uimmI15 needlecntImm, 12086 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12087 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12088 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12089 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12090 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12091 // Required for EA: check if it is still a type_array. 12092 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12093 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12094 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12095 ins_cost(250); 12096 12097 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12098 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12099 ins_encode %{ 12100 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12101 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12102 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12103 12104 __ string_indexof($result$$Register, 12105 $haystack$$Register, $haycnt$$Register, 12106 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12107 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12108 %} 12109 ins_pipe(pipe_class_compare); 12110 %} 12111 12112 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12113 iRegPsrc needle, uimmI15 needlecntImm, 12114 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12115 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12116 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12117 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12118 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12119 // Required for EA: check if it is still a type_array. 12120 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12121 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12122 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12123 ins_cost(250); 12124 12125 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12126 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12127 ins_encode %{ 12128 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12129 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12130 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12131 12132 __ string_indexof($result$$Register, 12133 $haystack$$Register, $haycnt$$Register, 12134 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12135 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12136 %} 12137 ins_pipe(pipe_class_compare); 12138 %} 12139 12140 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12141 iRegPsrc needle, uimmI15 needlecntImm, 12142 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12143 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12144 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12145 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12146 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12147 // Required for EA: check if it is still a type_array. 12148 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12149 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12150 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12151 ins_cost(250); 12152 12153 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12154 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12155 ins_encode %{ 12156 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12157 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12158 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12159 12160 __ string_indexof($result$$Register, 12161 $haystack$$Register, $haycnt$$Register, 12162 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12163 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12164 %} 12165 ins_pipe(pipe_class_compare); 12166 %} 12167 12168 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12169 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12170 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12171 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12172 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12173 TEMP_DEF result, 12174 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12175 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12176 ins_cost(300); 12177 12178 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12179 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12180 ins_encode %{ 12181 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12182 __ string_indexof($result$$Register, 12183 $haystack$$Register, $haycnt$$Register, 12184 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12185 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12186 %} 12187 ins_pipe(pipe_class_compare); 12188 %} 12189 12190 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12191 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12192 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12193 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12194 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12195 TEMP_DEF result, 12196 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12197 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12198 ins_cost(300); 12199 12200 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12201 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12202 ins_encode %{ 12203 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12204 __ string_indexof($result$$Register, 12205 $haystack$$Register, $haycnt$$Register, 12206 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12207 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12208 %} 12209 ins_pipe(pipe_class_compare); 12210 %} 12211 12212 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12213 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12214 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12215 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12216 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12217 TEMP_DEF result, 12218 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12219 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12220 ins_cost(300); 12221 12222 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12223 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12224 ins_encode %{ 12225 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12226 __ string_indexof($result$$Register, 12227 $haystack$$Register, $haycnt$$Register, 12228 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12229 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12230 %} 12231 ins_pipe(pipe_class_compare); 12232 %} 12233 12234 // char[] to byte[] compression 12235 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12236 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12237 match(Set result (StrCompressedCopy src (Binary dst len))); 12238 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12239 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12240 ins_cost(300); 12241 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12242 ins_encode %{ 12243 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12244 Label Lskip, Ldone; 12245 __ li($result$$Register, 0); 12246 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12247 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 12248 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12249 __ beq(CCR0, Lskip); 12250 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 12251 __ bind(Lskip); 12252 __ mr($result$$Register, $len$$Register); 12253 __ bind(Ldone); 12254 %} 12255 ins_pipe(pipe_class_default); 12256 %} 12257 12258 // byte[] to char[] inflation 12259 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 12260 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12261 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12262 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12263 ins_cost(300); 12264 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12265 ins_encode %{ 12266 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12267 Label Ldone; 12268 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12269 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 12270 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12271 __ beq(CCR0, Ldone); 12272 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 12273 __ bind(Ldone); 12274 %} 12275 ins_pipe(pipe_class_default); 12276 %} 12277 12278 // StringCoding.java intrinsics 12279 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 12280 regCTR ctr, flagsRegCR0 cr0) 12281 %{ 12282 match(Set result (HasNegatives ary1 len)); 12283 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 12284 ins_cost(300); 12285 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 12286 ins_encode %{ 12287 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12288 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 12289 $tmp1$$Register, $tmp2$$Register); 12290 %} 12291 ins_pipe(pipe_class_default); 12292 %} 12293 12294 // encode char[] to byte[] in ISO_8859_1 12295 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12296 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12297 match(Set result (EncodeISOArray src (Binary dst len))); 12298 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12299 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12300 ins_cost(300); 12301 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12302 ins_encode %{ 12303 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12304 Label Lslow, Lfailure1, Lfailure2, Ldone; 12305 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12306 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 12307 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12308 __ beq(CCR0, Ldone); 12309 __ bind(Lslow); 12310 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 12311 __ li($result$$Register, 0); 12312 __ b(Ldone); 12313 12314 __ bind(Lfailure1); 12315 __ mr($result$$Register, $len$$Register); 12316 __ mfctr($tmp1$$Register); 12317 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 12318 __ beq(CCR0, Ldone); 12319 __ b(Lslow); 12320 12321 __ bind(Lfailure2); 12322 __ mfctr($result$$Register); // Remaining characters. 12323 12324 __ bind(Ldone); 12325 __ subf($result$$Register, $result$$Register, $len$$Register); 12326 %} 12327 ins_pipe(pipe_class_default); 12328 %} 12329 12330 12331 //---------- Min/Max Instructions --------------------------------------------- 12332 12333 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12334 match(Set dst (MinI src1 src2)); 12335 ins_cost(DEFAULT_COST*6); 12336 12337 expand %{ 12338 iRegLdst src1s; 12339 iRegLdst src2s; 12340 iRegLdst diff; 12341 iRegLdst sm; 12342 iRegLdst doz; // difference or zero 12343 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12344 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12345 subL_reg_reg(diff, src2s, src1s); 12346 // Need to consider >=33 bit result, therefore we need signmaskL. 12347 signmask64L_regL(sm, diff); 12348 andL_reg_reg(doz, diff, sm); // <=0 12349 addI_regL_regL(dst, doz, src1s); 12350 %} 12351 %} 12352 12353 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12354 match(Set dst (MinI src1 src2)); 12355 effect(KILL cr0); 12356 predicate(VM_Version::has_isel()); 12357 ins_cost(DEFAULT_COST*2); 12358 12359 ins_encode %{ 12360 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12361 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12362 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 12363 %} 12364 ins_pipe(pipe_class_default); 12365 %} 12366 12367 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12368 match(Set dst (MaxI src1 src2)); 12369 ins_cost(DEFAULT_COST*6); 12370 12371 expand %{ 12372 iRegLdst src1s; 12373 iRegLdst src2s; 12374 iRegLdst diff; 12375 iRegLdst sm; 12376 iRegLdst doz; // difference or zero 12377 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12378 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12379 subL_reg_reg(diff, src2s, src1s); 12380 // Need to consider >=33 bit result, therefore we need signmaskL. 12381 signmask64L_regL(sm, diff); 12382 andcL_reg_reg(doz, diff, sm); // >=0 12383 addI_regL_regL(dst, doz, src1s); 12384 %} 12385 %} 12386 12387 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12388 match(Set dst (MaxI src1 src2)); 12389 effect(KILL cr0); 12390 predicate(VM_Version::has_isel()); 12391 ins_cost(DEFAULT_COST*2); 12392 12393 ins_encode %{ 12394 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12395 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12396 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 12397 %} 12398 ins_pipe(pipe_class_default); 12399 %} 12400 12401 //---------- Population Count Instructions ------------------------------------ 12402 12403 // Popcnt for Power7. 12404 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 12405 match(Set dst (PopCountI src)); 12406 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12407 ins_cost(DEFAULT_COST); 12408 12409 format %{ "POPCNTW $dst, $src" %} 12410 size(4); 12411 ins_encode %{ 12412 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12413 __ popcntw($dst$$Register, $src$$Register); 12414 %} 12415 ins_pipe(pipe_class_default); 12416 %} 12417 12418 // Popcnt for Power7. 12419 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 12420 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12421 match(Set dst (PopCountL src)); 12422 ins_cost(DEFAULT_COST); 12423 12424 format %{ "POPCNTD $dst, $src" %} 12425 size(4); 12426 ins_encode %{ 12427 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12428 __ popcntd($dst$$Register, $src$$Register); 12429 %} 12430 ins_pipe(pipe_class_default); 12431 %} 12432 12433 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 12434 match(Set dst (CountLeadingZerosI src)); 12435 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12436 ins_cost(DEFAULT_COST); 12437 12438 format %{ "CNTLZW $dst, $src" %} 12439 size(4); 12440 ins_encode %{ 12441 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 12442 __ cntlzw($dst$$Register, $src$$Register); 12443 %} 12444 ins_pipe(pipe_class_default); 12445 %} 12446 12447 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 12448 match(Set dst (CountLeadingZerosL src)); 12449 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12450 ins_cost(DEFAULT_COST); 12451 12452 format %{ "CNTLZD $dst, $src" %} 12453 size(4); 12454 ins_encode %{ 12455 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12456 __ cntlzd($dst$$Register, $src$$Register); 12457 %} 12458 ins_pipe(pipe_class_default); 12459 %} 12460 12461 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 12462 // no match-rule, false predicate 12463 effect(DEF dst, USE src); 12464 predicate(false); 12465 12466 format %{ "CNTLZD $dst, $src" %} 12467 size(4); 12468 ins_encode %{ 12469 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12470 __ cntlzd($dst$$Register, $src$$Register); 12471 %} 12472 ins_pipe(pipe_class_default); 12473 %} 12474 12475 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 12476 match(Set dst (CountTrailingZerosI src)); 12477 predicate(UseCountLeadingZerosInstructionsPPC64); 12478 ins_cost(DEFAULT_COST); 12479 12480 expand %{ 12481 immI16 imm1 %{ (int)-1 %} 12482 immI16 imm2 %{ (int)32 %} 12483 immI_minus1 m1 %{ -1 %} 12484 iRegIdst tmpI1; 12485 iRegIdst tmpI2; 12486 iRegIdst tmpI3; 12487 addI_reg_imm16(tmpI1, src, imm1); 12488 andcI_reg_reg(tmpI2, src, m1, tmpI1); 12489 countLeadingZerosI(tmpI3, tmpI2); 12490 subI_imm16_reg(dst, imm2, tmpI3); 12491 %} 12492 %} 12493 12494 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 12495 match(Set dst (CountTrailingZerosL src)); 12496 predicate(UseCountLeadingZerosInstructionsPPC64); 12497 ins_cost(DEFAULT_COST); 12498 12499 expand %{ 12500 immL16 imm1 %{ (long)-1 %} 12501 immI16 imm2 %{ (int)64 %} 12502 iRegLdst tmpL1; 12503 iRegLdst tmpL2; 12504 iRegIdst tmpL3; 12505 addL_reg_imm16(tmpL1, src, imm1); 12506 andcL_reg_reg(tmpL2, tmpL1, src); 12507 countLeadingZerosL(tmpL3, tmpL2); 12508 subI_imm16_reg(dst, imm2, tmpL3); 12509 %} 12510 %} 12511 12512 // Expand nodes for byte_reverse_int. 12513 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12514 effect(DEF dst, USE src, USE pos, USE shift); 12515 predicate(false); 12516 12517 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12518 size(4); 12519 ins_encode %{ 12520 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12521 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12522 %} 12523 ins_pipe(pipe_class_default); 12524 %} 12525 12526 // As insrwi_a, but with USE_DEF. 12527 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12528 effect(USE_DEF dst, USE src, USE pos, USE shift); 12529 predicate(false); 12530 12531 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12532 size(4); 12533 ins_encode %{ 12534 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12535 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12536 %} 12537 ins_pipe(pipe_class_default); 12538 %} 12539 12540 // Just slightly faster than java implementation. 12541 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 12542 match(Set dst (ReverseBytesI src)); 12543 predicate(UseCountLeadingZerosInstructionsPPC64); 12544 ins_cost(DEFAULT_COST); 12545 12546 expand %{ 12547 immI16 imm24 %{ (int) 24 %} 12548 immI16 imm16 %{ (int) 16 %} 12549 immI16 imm8 %{ (int) 8 %} 12550 immI16 imm4 %{ (int) 4 %} 12551 immI16 imm0 %{ (int) 0 %} 12552 iRegLdst tmpI1; 12553 iRegLdst tmpI2; 12554 iRegLdst tmpI3; 12555 12556 urShiftI_reg_imm(tmpI1, src, imm24); 12557 insrwi_a(dst, tmpI1, imm24, imm8); 12558 urShiftI_reg_imm(tmpI2, src, imm16); 12559 insrwi(dst, tmpI2, imm8, imm16); 12560 urShiftI_reg_imm(tmpI3, src, imm8); 12561 insrwi(dst, tmpI3, imm8, imm8); 12562 insrwi(dst, src, imm0, imm8); 12563 %} 12564 %} 12565 12566 //---------- Replicate Vector Instructions ------------------------------------ 12567 12568 // Insrdi does replicate if src == dst. 12569 instruct repl32(iRegLdst dst) %{ 12570 predicate(false); 12571 effect(USE_DEF dst); 12572 12573 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 12574 size(4); 12575 ins_encode %{ 12576 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12577 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 12578 %} 12579 ins_pipe(pipe_class_default); 12580 %} 12581 12582 // Insrdi does replicate if src == dst. 12583 instruct repl48(iRegLdst dst) %{ 12584 predicate(false); 12585 effect(USE_DEF dst); 12586 12587 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 12588 size(4); 12589 ins_encode %{ 12590 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12591 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 12592 %} 12593 ins_pipe(pipe_class_default); 12594 %} 12595 12596 // Insrdi does replicate if src == dst. 12597 instruct repl56(iRegLdst dst) %{ 12598 predicate(false); 12599 effect(USE_DEF dst); 12600 12601 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 12602 size(4); 12603 ins_encode %{ 12604 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12605 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 12606 %} 12607 ins_pipe(pipe_class_default); 12608 %} 12609 12610 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12611 match(Set dst (ReplicateB src)); 12612 predicate(n->as_Vector()->length() == 8); 12613 expand %{ 12614 moveReg(dst, src); 12615 repl56(dst); 12616 repl48(dst); 12617 repl32(dst); 12618 %} 12619 %} 12620 12621 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 12622 match(Set dst (ReplicateB zero)); 12623 predicate(n->as_Vector()->length() == 8); 12624 format %{ "LI $dst, #0 \t// replicate8B" %} 12625 size(4); 12626 ins_encode %{ 12627 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12628 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12629 %} 12630 ins_pipe(pipe_class_default); 12631 %} 12632 12633 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12634 match(Set dst (ReplicateB src)); 12635 predicate(n->as_Vector()->length() == 8); 12636 format %{ "LI $dst, #-1 \t// replicate8B" %} 12637 size(4); 12638 ins_encode %{ 12639 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12640 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12641 %} 12642 ins_pipe(pipe_class_default); 12643 %} 12644 12645 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12646 match(Set dst (ReplicateS src)); 12647 predicate(n->as_Vector()->length() == 4); 12648 expand %{ 12649 moveReg(dst, src); 12650 repl48(dst); 12651 repl32(dst); 12652 %} 12653 %} 12654 12655 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 12656 match(Set dst (ReplicateS zero)); 12657 predicate(n->as_Vector()->length() == 4); 12658 format %{ "LI $dst, #0 \t// replicate4C" %} 12659 size(4); 12660 ins_encode %{ 12661 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12662 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12663 %} 12664 ins_pipe(pipe_class_default); 12665 %} 12666 12667 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12668 match(Set dst (ReplicateS src)); 12669 predicate(n->as_Vector()->length() == 4); 12670 format %{ "LI $dst, -1 \t// replicate4C" %} 12671 size(4); 12672 ins_encode %{ 12673 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12674 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12675 %} 12676 ins_pipe(pipe_class_default); 12677 %} 12678 12679 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12680 match(Set dst (ReplicateI src)); 12681 predicate(n->as_Vector()->length() == 2); 12682 ins_cost(2 * DEFAULT_COST); 12683 expand %{ 12684 moveReg(dst, src); 12685 repl32(dst); 12686 %} 12687 %} 12688 12689 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 12690 match(Set dst (ReplicateI zero)); 12691 predicate(n->as_Vector()->length() == 2); 12692 format %{ "LI $dst, #0 \t// replicate4C" %} 12693 size(4); 12694 ins_encode %{ 12695 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12696 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12697 %} 12698 ins_pipe(pipe_class_default); 12699 %} 12700 12701 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12702 match(Set dst (ReplicateI src)); 12703 predicate(n->as_Vector()->length() == 2); 12704 format %{ "LI $dst, -1 \t// replicate4C" %} 12705 size(4); 12706 ins_encode %{ 12707 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12708 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12709 %} 12710 ins_pipe(pipe_class_default); 12711 %} 12712 12713 // Move float to int register via stack, replicate. 12714 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 12715 match(Set dst (ReplicateF src)); 12716 predicate(n->as_Vector()->length() == 2); 12717 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 12718 expand %{ 12719 stackSlotL tmpS; 12720 iRegIdst tmpI; 12721 moveF2I_reg_stack(tmpS, src); // Move float to stack. 12722 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 12723 moveReg(dst, tmpI); // Move int to long reg. 12724 repl32(dst); // Replicate bitpattern. 12725 %} 12726 %} 12727 12728 // Replicate scalar constant to packed float values in Double register 12729 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 12730 match(Set dst (ReplicateF src)); 12731 predicate(n->as_Vector()->length() == 2); 12732 ins_cost(5 * DEFAULT_COST); 12733 12734 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 12735 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 12736 %} 12737 12738 // Replicate scalar zero constant to packed float values in Double register 12739 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 12740 match(Set dst (ReplicateF zero)); 12741 predicate(n->as_Vector()->length() == 2); 12742 12743 format %{ "LI $dst, #0 \t// replicate2F" %} 12744 ins_encode %{ 12745 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12746 __ li($dst$$Register, 0x0); 12747 %} 12748 ins_pipe(pipe_class_default); 12749 %} 12750 12751 12752 //----------Overflow Math Instructions----------------------------------------- 12753 12754 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 12755 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 12756 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 12757 12758 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12759 match(Set cr0 (OverflowAddL op1 op2)); 12760 12761 format %{ "add_ $op1, $op2\t# overflow check long" %} 12762 ins_encode %{ 12763 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12764 __ li(R0, 0); 12765 __ mtxer(R0); // clear XER.SO 12766 __ addo_(R0, $op1$$Register, $op2$$Register); 12767 %} 12768 ins_pipe(pipe_class_default); 12769 %} 12770 12771 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12772 match(Set cr0 (OverflowSubL op1 op2)); 12773 12774 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 12775 ins_encode %{ 12776 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12777 __ li(R0, 0); 12778 __ mtxer(R0); // clear XER.SO 12779 __ subfo_(R0, $op2$$Register, $op1$$Register); 12780 %} 12781 ins_pipe(pipe_class_default); 12782 %} 12783 12784 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 12785 match(Set cr0 (OverflowSubL zero op2)); 12786 12787 format %{ "nego_ R0, $op2\t# overflow check long" %} 12788 ins_encode %{ 12789 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12790 __ li(R0, 0); 12791 __ mtxer(R0); // clear XER.SO 12792 __ nego_(R0, $op2$$Register); 12793 %} 12794 ins_pipe(pipe_class_default); 12795 %} 12796 12797 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12798 match(Set cr0 (OverflowMulL op1 op2)); 12799 12800 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 12801 ins_encode %{ 12802 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12803 __ li(R0, 0); 12804 __ mtxer(R0); // clear XER.SO 12805 __ mulldo_(R0, $op1$$Register, $op2$$Register); 12806 %} 12807 ins_pipe(pipe_class_default); 12808 %} 12809 12810 12811 // ============================================================================ 12812 // Safepoint Instruction 12813 12814 instruct safePoint_poll(iRegPdst poll) %{ 12815 match(SafePoint poll); 12816 predicate(LoadPollAddressFromThread); 12817 12818 // It caused problems to add the effect that r0 is killed, but this 12819 // effect no longer needs to be mentioned, since r0 is not contained 12820 // in a reg_class. 12821 12822 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 12823 size(4); 12824 ins_encode( enc_poll(0x0, poll) ); 12825 ins_pipe(pipe_class_default); 12826 %} 12827 12828 // Safepoint without per-thread support. Load address of page to poll 12829 // as constant. 12830 // Rscratch2RegP is R12. 12831 // LoadConPollAddr node is added in pd_post_matching_hook(). It must be 12832 // a seperate node so that the oop map is at the right location. 12833 instruct safePoint_poll_conPollAddr(rscratch2RegP poll) %{ 12834 match(SafePoint poll); 12835 predicate(!LoadPollAddressFromThread); 12836 12837 // It caused problems to add the effect that r0 is killed, but this 12838 // effect no longer needs to be mentioned, since r0 is not contained 12839 // in a reg_class. 12840 12841 format %{ "LD R0, #0, R12 \t// Safepoint poll for GC" %} 12842 ins_encode( enc_poll(0x0, poll) ); 12843 ins_pipe(pipe_class_default); 12844 %} 12845 12846 // ============================================================================ 12847 // Call Instructions 12848 12849 // Call Java Static Instruction 12850 12851 // Schedulable version of call static node. 12852 instruct CallStaticJavaDirect(method meth) %{ 12853 match(CallStaticJava); 12854 effect(USE meth); 12855 ins_cost(CALL_COST); 12856 12857 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 12858 12859 format %{ "CALL,static $meth \t// ==> " %} 12860 size(4); 12861 ins_encode( enc_java_static_call(meth) ); 12862 ins_pipe(pipe_class_call); 12863 %} 12864 12865 // Call Java Dynamic Instruction 12866 12867 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 12868 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 12869 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 12870 // The call destination must still be placed in the constant pool. 12871 instruct CallDynamicJavaDirectSched(method meth) %{ 12872 match(CallDynamicJava); // To get all the data fields we need ... 12873 effect(USE meth); 12874 predicate(false); // ... but never match. 12875 12876 ins_field_load_ic_hi_node(loadConL_hiNode*); 12877 ins_field_load_ic_node(loadConLNode*); 12878 ins_num_consts(1 /* 1 patchable constant: call destination */); 12879 12880 format %{ "BL \t// dynamic $meth ==> " %} 12881 size(4); 12882 ins_encode( enc_java_dynamic_call_sched(meth) ); 12883 ins_pipe(pipe_class_call); 12884 %} 12885 12886 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 12887 // We use postalloc expanded calls if we use inline caches 12888 // and do not update method data. 12889 // 12890 // This instruction has two constants: inline cache (IC) and call destination. 12891 // Loading the inline cache will be postalloc expanded, thus leaving a call with 12892 // one constant. 12893 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 12894 match(CallDynamicJava); 12895 effect(USE meth); 12896 predicate(UseInlineCaches); 12897 ins_cost(CALL_COST); 12898 12899 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 12900 12901 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 12902 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 12903 %} 12904 12905 // Compound version of call dynamic java 12906 // We use postalloc expanded calls if we use inline caches 12907 // and do not update method data. 12908 instruct CallDynamicJavaDirect(method meth) %{ 12909 match(CallDynamicJava); 12910 effect(USE meth); 12911 predicate(!UseInlineCaches); 12912 ins_cost(CALL_COST); 12913 12914 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 12915 ins_num_consts(4); 12916 12917 format %{ "CALL,dynamic $meth \t// ==> " %} 12918 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 12919 ins_pipe(pipe_class_call); 12920 %} 12921 12922 // Call Runtime Instruction 12923 12924 instruct CallRuntimeDirect(method meth) %{ 12925 match(CallRuntime); 12926 effect(USE meth); 12927 ins_cost(CALL_COST); 12928 12929 // Enc_java_to_runtime_call needs up to 3 constants: call target, 12930 // env for callee, C-toc. 12931 ins_num_consts(3); 12932 12933 format %{ "CALL,runtime" %} 12934 ins_encode( enc_java_to_runtime_call(meth) ); 12935 ins_pipe(pipe_class_call); 12936 %} 12937 12938 // Call Leaf 12939 12940 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 12941 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 12942 effect(DEF dst, USE src); 12943 12944 ins_num_consts(1); 12945 12946 format %{ "MTCTR $src" %} 12947 size(4); 12948 ins_encode( enc_leaf_call_mtctr(src) ); 12949 ins_pipe(pipe_class_default); 12950 %} 12951 12952 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 12953 instruct CallLeafDirect(method meth) %{ 12954 match(CallLeaf); // To get the data all the data fields we need ... 12955 effect(USE meth); 12956 predicate(false); // but never match. 12957 12958 format %{ "BCTRL \t// leaf call $meth ==> " %} 12959 size(4); 12960 ins_encode %{ 12961 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 12962 __ bctrl(); 12963 %} 12964 ins_pipe(pipe_class_call); 12965 %} 12966 12967 // postalloc expand of CallLeafDirect. 12968 // Load adress to call from TOC, then bl to it. 12969 instruct CallLeafDirect_Ex(method meth) %{ 12970 match(CallLeaf); 12971 effect(USE meth); 12972 ins_cost(CALL_COST); 12973 12974 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 12975 // env for callee, C-toc. 12976 ins_num_consts(3); 12977 12978 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 12979 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 12980 %} 12981 12982 // Call runtime without safepoint - same as CallLeaf. 12983 // postalloc expand of CallLeafNoFPDirect. 12984 // Load adress to call from TOC, then bl to it. 12985 instruct CallLeafNoFPDirect_Ex(method meth) %{ 12986 match(CallLeafNoFP); 12987 effect(USE meth); 12988 ins_cost(CALL_COST); 12989 12990 // Enc_java_to_runtime_call needs up to 3 constants: call target, 12991 // env for callee, C-toc. 12992 ins_num_consts(3); 12993 12994 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 12995 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 12996 %} 12997 12998 // Tail Call; Jump from runtime stub to Java code. 12999 // Also known as an 'interprocedural jump'. 13000 // Target of jump will eventually return to caller. 13001 // TailJump below removes the return address. 13002 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 13003 match(TailCall jump_target method_oop); 13004 ins_cost(CALL_COST); 13005 13006 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 13007 "BCTR \t// tail call" %} 13008 size(8); 13009 ins_encode %{ 13010 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13011 __ mtctr($jump_target$$Register); 13012 __ bctr(); 13013 %} 13014 ins_pipe(pipe_class_call); 13015 %} 13016 13017 // Return Instruction 13018 instruct Ret() %{ 13019 match(Return); 13020 format %{ "BLR \t// branch to link register" %} 13021 size(4); 13022 ins_encode %{ 13023 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 13024 // LR is restored in MachEpilogNode. Just do the RET here. 13025 __ blr(); 13026 %} 13027 ins_pipe(pipe_class_default); 13028 %} 13029 13030 // Tail Jump; remove the return address; jump to target. 13031 // TailCall above leaves the return address around. 13032 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 13033 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 13034 // "restore" before this instruction (in Epilogue), we need to materialize it 13035 // in %i0. 13036 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 13037 match(TailJump jump_target ex_oop); 13038 ins_cost(CALL_COST); 13039 13040 format %{ "LD R4_ARG2 = LR\n\t" 13041 "MTCTR $jump_target\n\t" 13042 "BCTR \t// TailJump, exception oop: $ex_oop" %} 13043 size(12); 13044 ins_encode %{ 13045 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13046 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 13047 __ mtctr($jump_target$$Register); 13048 __ bctr(); 13049 %} 13050 ins_pipe(pipe_class_call); 13051 %} 13052 13053 // Create exception oop: created by stack-crawling runtime code. 13054 // Created exception is now available to this handler, and is setup 13055 // just prior to jumping to this handler. No code emitted. 13056 instruct CreateException(rarg1RegP ex_oop) %{ 13057 match(Set ex_oop (CreateEx)); 13058 ins_cost(0); 13059 13060 format %{ " -- \t// exception oop; no code emitted" %} 13061 size(0); 13062 ins_encode( /*empty*/ ); 13063 ins_pipe(pipe_class_default); 13064 %} 13065 13066 // Rethrow exception: The exception oop will come in the first 13067 // argument position. Then JUMP (not call) to the rethrow stub code. 13068 instruct RethrowException() %{ 13069 match(Rethrow); 13070 ins_cost(CALL_COST); 13071 13072 format %{ "Jmp rethrow_stub" %} 13073 ins_encode %{ 13074 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13075 cbuf.set_insts_mark(); 13076 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 13077 %} 13078 ins_pipe(pipe_class_call); 13079 %} 13080 13081 // Die now. 13082 instruct ShouldNotReachHere() %{ 13083 match(Halt); 13084 ins_cost(CALL_COST); 13085 13086 format %{ "ShouldNotReachHere" %} 13087 size(4); 13088 ins_encode %{ 13089 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 13090 __ trap_should_not_reach_here(); 13091 %} 13092 ins_pipe(pipe_class_default); 13093 %} 13094 13095 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 13096 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 13097 // Get a DEF on threadRegP, no costs, no encoding, use 13098 // 'ins_should_rematerialize(true)' to avoid spilling. 13099 instruct tlsLoadP(threadRegP dst) %{ 13100 match(Set dst (ThreadLocal)); 13101 ins_cost(0); 13102 13103 ins_should_rematerialize(true); 13104 13105 format %{ " -- \t// $dst=Thread::current(), empty" %} 13106 size(0); 13107 ins_encode( /*empty*/ ); 13108 ins_pipe(pipe_class_empty); 13109 %} 13110 13111 //---Some PPC specific nodes--------------------------------------------------- 13112 13113 // Stop a group. 13114 instruct endGroup() %{ 13115 ins_cost(0); 13116 13117 ins_is_nop(true); 13118 13119 format %{ "End Bundle (ori r1, r1, 0)" %} 13120 size(4); 13121 ins_encode %{ 13122 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 13123 __ endgroup(); 13124 %} 13125 ins_pipe(pipe_class_default); 13126 %} 13127 13128 // Nop instructions 13129 13130 instruct fxNop() %{ 13131 ins_cost(0); 13132 13133 ins_is_nop(true); 13134 13135 format %{ "fxNop" %} 13136 size(4); 13137 ins_encode %{ 13138 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13139 __ nop(); 13140 %} 13141 ins_pipe(pipe_class_default); 13142 %} 13143 13144 instruct fpNop0() %{ 13145 ins_cost(0); 13146 13147 ins_is_nop(true); 13148 13149 format %{ "fpNop0" %} 13150 size(4); 13151 ins_encode %{ 13152 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13153 __ fpnop0(); 13154 %} 13155 ins_pipe(pipe_class_default); 13156 %} 13157 13158 instruct fpNop1() %{ 13159 ins_cost(0); 13160 13161 ins_is_nop(true); 13162 13163 format %{ "fpNop1" %} 13164 size(4); 13165 ins_encode %{ 13166 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13167 __ fpnop1(); 13168 %} 13169 ins_pipe(pipe_class_default); 13170 %} 13171 13172 instruct brNop0() %{ 13173 ins_cost(0); 13174 size(4); 13175 format %{ "brNop0" %} 13176 ins_encode %{ 13177 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13178 __ brnop0(); 13179 %} 13180 ins_is_nop(true); 13181 ins_pipe(pipe_class_default); 13182 %} 13183 13184 instruct brNop1() %{ 13185 ins_cost(0); 13186 13187 ins_is_nop(true); 13188 13189 format %{ "brNop1" %} 13190 size(4); 13191 ins_encode %{ 13192 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13193 __ brnop1(); 13194 %} 13195 ins_pipe(pipe_class_default); 13196 %} 13197 13198 instruct brNop2() %{ 13199 ins_cost(0); 13200 13201 ins_is_nop(true); 13202 13203 format %{ "brNop2" %} 13204 size(4); 13205 ins_encode %{ 13206 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13207 __ brnop2(); 13208 %} 13209 ins_pipe(pipe_class_default); 13210 %} 13211 13212 //----------PEEPHOLE RULES----------------------------------------------------- 13213 // These must follow all instruction definitions as they use the names 13214 // defined in the instructions definitions. 13215 // 13216 // peepmatch ( root_instr_name [preceeding_instruction]* ); 13217 // 13218 // peepconstraint %{ 13219 // (instruction_number.operand_name relational_op instruction_number.operand_name 13220 // [, ...] ); 13221 // // instruction numbers are zero-based using left to right order in peepmatch 13222 // 13223 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 13224 // // provide an instruction_number.operand_name for each operand that appears 13225 // // in the replacement instruction's match rule 13226 // 13227 // ---------VM FLAGS--------------------------------------------------------- 13228 // 13229 // All peephole optimizations can be turned off using -XX:-OptoPeephole 13230 // 13231 // Each peephole rule is given an identifying number starting with zero and 13232 // increasing by one in the order seen by the parser. An individual peephole 13233 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 13234 // on the command-line. 13235 // 13236 // ---------CURRENT LIMITATIONS---------------------------------------------- 13237 // 13238 // Only match adjacent instructions in same basic block 13239 // Only equality constraints 13240 // Only constraints between operands, not (0.dest_reg == EAX_enc) 13241 // Only one replacement instruction 13242 // 13243 // ---------EXAMPLE---------------------------------------------------------- 13244 // 13245 // // pertinent parts of existing instructions in architecture description 13246 // instruct movI(eRegI dst, eRegI src) %{ 13247 // match(Set dst (CopyI src)); 13248 // %} 13249 // 13250 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 13251 // match(Set dst (AddI dst src)); 13252 // effect(KILL cr); 13253 // %} 13254 // 13255 // // Change (inc mov) to lea 13256 // peephole %{ 13257 // // increment preceeded by register-register move 13258 // peepmatch ( incI_eReg movI ); 13259 // // require that the destination register of the increment 13260 // // match the destination register of the move 13261 // peepconstraint ( 0.dst == 1.dst ); 13262 // // construct a replacement instruction that sets 13263 // // the destination to ( move's source register + one ) 13264 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13265 // %} 13266 // 13267 // Implementation no longer uses movX instructions since 13268 // machine-independent system no longer uses CopyX nodes. 13269 // 13270 // peephole %{ 13271 // peepmatch ( incI_eReg movI ); 13272 // peepconstraint ( 0.dst == 1.dst ); 13273 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13274 // %} 13275 // 13276 // peephole %{ 13277 // peepmatch ( decI_eReg movI ); 13278 // peepconstraint ( 0.dst == 1.dst ); 13279 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13280 // %} 13281 // 13282 // peephole %{ 13283 // peepmatch ( addI_eReg_imm movI ); 13284 // peepconstraint ( 0.dst == 1.dst ); 13285 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13286 // %} 13287 // 13288 // peephole %{ 13289 // peepmatch ( addP_eReg_imm movP ); 13290 // peepconstraint ( 0.dst == 1.dst ); 13291 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 13292 // %} 13293 13294 // // Change load of spilled value to only a spill 13295 // instruct storeI(memory mem, eRegI src) %{ 13296 // match(Set mem (StoreI mem src)); 13297 // %} 13298 // 13299 // instruct loadI(eRegI dst, memory mem) %{ 13300 // match(Set dst (LoadI mem)); 13301 // %} 13302 // 13303 peephole %{ 13304 peepmatch ( loadI storeI ); 13305 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13306 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 13307 %} 13308 13309 peephole %{ 13310 peepmatch ( loadL storeL ); 13311 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13312 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 13313 %} 13314 13315 peephole %{ 13316 peepmatch ( loadP storeP ); 13317 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 13318 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 13319 %} 13320 13321 //----------SMARTSPILL RULES--------------------------------------------------- 13322 // These must follow all instruction definitions as they use the names 13323 // defined in the instructions definitions.