1 // 2 // Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2016 SAP SE. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // 27 // PPC64 Architecture Description File 28 // 29 30 //----------REGISTER DEFINITION BLOCK------------------------------------------ 31 // This information is used by the matcher and the register allocator to 32 // describe individual registers and classes of registers within the target 33 // architecture. 34 register %{ 35 //----------Architecture Description Register Definitions---------------------- 36 // General Registers 37 // "reg_def" name (register save type, C convention save type, 38 // ideal register type, encoding); 39 // 40 // Register Save Types: 41 // 42 // NS = No-Save: The register allocator assumes that these registers 43 // can be used without saving upon entry to the method, & 44 // that they do not need to be saved at call sites. 45 // 46 // SOC = Save-On-Call: The register allocator assumes that these registers 47 // can be used without saving upon entry to the method, 48 // but that they must be saved at call sites. 49 // These are called "volatiles" on ppc. 50 // 51 // SOE = Save-On-Entry: The register allocator assumes that these registers 52 // must be saved before using them upon entry to the 53 // method, but they do not need to be saved at call 54 // sites. 55 // These are called "nonvolatiles" on ppc. 56 // 57 // AS = Always-Save: The register allocator assumes that these registers 58 // must be saved before using them upon entry to the 59 // method, & that they must be saved at call sites. 60 // 61 // Ideal Register Type is used to determine how to save & restore a 62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 64 // 65 // The encoding number is the actual bit-pattern placed into the opcodes. 66 // 67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI 68 // Supplement Version 1.7 as of 2003-10-29. 69 // 70 // For each 64-bit register we must define two registers: the register 71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half', 72 // e.g. R3_H, which is needed by the allocator, but is not used 73 // for stores, loads, etc. 74 75 // ---------------------------- 76 // Integer/Long Registers 77 // ---------------------------- 78 79 // PPC64 has 32 64-bit integer registers. 80 81 // types: v = volatile, nv = non-volatile, s = system 82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs 83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() ); 84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP 85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() ); 86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC 87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() ); 88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret 89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() ); 90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2 91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() ); 92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3 93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() ); 94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4 95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() ); 96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5 97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() ); 98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6 99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() ); 100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7 101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() ); 102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8 103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next()); 104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch 105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next()); 106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch 107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next()); 108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id 109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next()); 110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv 111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next()); 112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv 113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next()); 114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv 115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next()); 116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv 117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next()); 118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv 119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next()); 120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv 121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next()); 122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv 123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next()); 124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv 125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next()); 126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv 127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next()); 128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv 129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next()); 130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv 131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next()); 132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv 133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next()); 134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv 135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next()); 136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv 137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next()); 138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv 139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next()); 140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv 141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next()); 142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv 143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next()); 144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv 145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next()); 146 147 148 // ---------------------------- 149 // Float/Double Registers 150 // ---------------------------- 151 152 // Double Registers 153 // The rules of ADL require that double registers be defined in pairs. 154 // Each pair must be two 32-bit values, but not necessarily a pair of 155 // single float registers. In each pair, ADLC-assigned register numbers 156 // must be adjacent, with the lower number even. Finally, when the 157 // CPU stores such a register pair to memory, the word associated with 158 // the lower ADLC-assigned number must be stored to the lower address. 159 160 // PPC64 has 32 64-bit floating-point registers. Each can store a single 161 // or double precision floating-point value. 162 163 // types: v = volatile, nv = non-volatile, s = system 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch 165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret 167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2 169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3 171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4 173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5 175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6 177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7 179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8 181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9 183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10 185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next()); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11 187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next()); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12 189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next()); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13 191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next()); 192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv 193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next()); 194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv 195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next()); 196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv 197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next()); 198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv 199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next()); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv 201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next()); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv 203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next()); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv 205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next()); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv 207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next()); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv 209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next()); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv 211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next()); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv 213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next()); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv 215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next()); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv 217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next()); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv 219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next()); 220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv 221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next()); 222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv 223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next()); 224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv 225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next()); 226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv 227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next()); 228 229 // ---------------------------- 230 // Special Registers 231 // ---------------------------- 232 233 // Condition Codes Flag Registers 234 235 // PPC64 has 8 condition code "registers" which are all contained 236 // in the CR register. 237 238 // types: v = volatile, nv = non-volatile, s = system 239 reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v 240 reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v 241 reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv 242 reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv 243 reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv 244 reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v 245 reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v 246 reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg()); // v 247 248 // Special registers of PPC64 249 250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v 251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v 252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v 253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v 254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v 255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v 256 257 258 // ---------------------------- 259 // Specify priority of register selection within phases of register 260 // allocation. Highest priority is first. A useful heuristic is to 261 // give registers a low priority when they are required by machine 262 // instructions, like EAX and EDX on I486, and choose no-save registers 263 // before save-on-call, & save-on-call before save-on-entry. Registers 264 // which participate in fixed calling sequences should come last. 265 // Registers which are used as pairs must fall on an even boundary. 266 267 // It's worth about 1% on SPEC geomean to get this right. 268 269 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 270 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 271 // R3_num. Therefore, R3_num may not be (and in reality is not) 272 // the same as R3->encoding()! Furthermore, we cannot make any 273 // assumptions on ordering, e.g. R3_num may be less than R2_num. 274 // Additionally, the function 275 // static enum RC rc_class(OptoReg::Name reg ) 276 // maps a given <register>_num value to its chunk type (except for flags) 277 // and its current implementation relies on chunk0 and chunk1 having a 278 // size of 64 each. 279 280 // If you change this allocation class, please have a look at the 281 // default values for the parameters RoundRobinIntegerRegIntervalStart 282 // and RoundRobinFloatRegIntervalStart 283 284 alloc_class chunk0 ( 285 // Chunk0 contains *all* 64 integer registers halves. 286 287 // "non-volatile" registers 288 R14, R14_H, 289 R15, R15_H, 290 R17, R17_H, 291 R18, R18_H, 292 R19, R19_H, 293 R20, R20_H, 294 R21, R21_H, 295 R22, R22_H, 296 R23, R23_H, 297 R24, R24_H, 298 R25, R25_H, 299 R26, R26_H, 300 R27, R27_H, 301 R28, R28_H, 302 R29, R29_H, 303 R30, R30_H, 304 R31, R31_H, 305 306 // scratch/special registers 307 R11, R11_H, 308 R12, R12_H, 309 310 // argument registers 311 R10, R10_H, 312 R9, R9_H, 313 R8, R8_H, 314 R7, R7_H, 315 R6, R6_H, 316 R5, R5_H, 317 R4, R4_H, 318 R3, R3_H, 319 320 // special registers, not available for allocation 321 R16, R16_H, // R16_thread 322 R13, R13_H, // system thread id 323 R2, R2_H, // may be used for TOC 324 R1, R1_H, // SP 325 R0, R0_H // R0 (scratch) 326 ); 327 328 // If you change this allocation class, please have a look at the 329 // default values for the parameters RoundRobinIntegerRegIntervalStart 330 // and RoundRobinFloatRegIntervalStart 331 332 alloc_class chunk1 ( 333 // Chunk1 contains *all* 64 floating-point registers halves. 334 335 // scratch register 336 F0, F0_H, 337 338 // argument registers 339 F13, F13_H, 340 F12, F12_H, 341 F11, F11_H, 342 F10, F10_H, 343 F9, F9_H, 344 F8, F8_H, 345 F7, F7_H, 346 F6, F6_H, 347 F5, F5_H, 348 F4, F4_H, 349 F3, F3_H, 350 F2, F2_H, 351 F1, F1_H, 352 353 // non-volatile registers 354 F14, F14_H, 355 F15, F15_H, 356 F16, F16_H, 357 F17, F17_H, 358 F18, F18_H, 359 F19, F19_H, 360 F20, F20_H, 361 F21, F21_H, 362 F22, F22_H, 363 F23, F23_H, 364 F24, F24_H, 365 F25, F25_H, 366 F26, F26_H, 367 F27, F27_H, 368 F28, F28_H, 369 F29, F29_H, 370 F30, F30_H, 371 F31, F31_H 372 ); 373 374 alloc_class chunk2 ( 375 // Chunk2 contains *all* 8 condition code registers. 376 377 CCR0, 378 CCR1, 379 CCR2, 380 CCR3, 381 CCR4, 382 CCR5, 383 CCR6, 384 CCR7 385 ); 386 387 alloc_class chunk3 ( 388 // special registers 389 // These registers are not allocated, but used for nodes generated by postalloc expand. 390 SR_XER, 391 SR_LR, 392 SR_CTR, 393 SR_VRSAVE, 394 SR_SPEFSCR, 395 SR_PPR 396 ); 397 398 //-------Architecture Description Register Classes----------------------- 399 400 // Several register classes are automatically defined based upon 401 // information in this architecture description. 402 403 // 1) reg_class inline_cache_reg ( as defined in frame section ) 404 // 2) reg_class compiler_method_oop_reg ( as defined in frame section ) 405 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 406 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 407 // 408 409 // ---------------------------- 410 // 32 Bit Register Classes 411 // ---------------------------- 412 413 // We specify registers twice, once as read/write, and once read-only. 414 // We use the read-only registers for source operands. With this, we 415 // can include preset read only registers in this class, as a hard-coded 416 // '0'-register. (We used to simulate this on ppc.) 417 418 // 32 bit registers that can be read and written i.e. these registers 419 // can be dest (or src) of normal instructions. 420 reg_class bits32_reg_rw( 421 /*R0*/ // R0 422 /*R1*/ // SP 423 R2, // TOC 424 R3, 425 R4, 426 R5, 427 R6, 428 R7, 429 R8, 430 R9, 431 R10, 432 R11, 433 R12, 434 /*R13*/ // system thread id 435 R14, 436 R15, 437 /*R16*/ // R16_thread 438 R17, 439 R18, 440 R19, 441 R20, 442 R21, 443 R22, 444 R23, 445 R24, 446 R25, 447 R26, 448 R27, 449 R28, 450 /*R29,*/ // global TOC 451 R30, 452 R31 453 ); 454 455 // 32 bit registers that can only be read i.e. these registers can 456 // only be src of all instructions. 457 reg_class bits32_reg_ro( 458 /*R0*/ // R0 459 /*R1*/ // SP 460 R2 // TOC 461 R3, 462 R4, 463 R5, 464 R6, 465 R7, 466 R8, 467 R9, 468 R10, 469 R11, 470 R12, 471 /*R13*/ // system thread id 472 R14, 473 R15, 474 /*R16*/ // R16_thread 475 R17, 476 R18, 477 R19, 478 R20, 479 R21, 480 R22, 481 R23, 482 R24, 483 R25, 484 R26, 485 R27, 486 R28, 487 /*R29,*/ 488 R30, 489 R31 490 ); 491 492 reg_class rscratch1_bits32_reg(R11); 493 reg_class rscratch2_bits32_reg(R12); 494 reg_class rarg1_bits32_reg(R3); 495 reg_class rarg2_bits32_reg(R4); 496 reg_class rarg3_bits32_reg(R5); 497 reg_class rarg4_bits32_reg(R6); 498 499 // ---------------------------- 500 // 64 Bit Register Classes 501 // ---------------------------- 502 // 64-bit build means 64-bit pointers means hi/lo pairs 503 504 reg_class rscratch1_bits64_reg(R11_H, R11); 505 reg_class rscratch2_bits64_reg(R12_H, R12); 506 reg_class rarg1_bits64_reg(R3_H, R3); 507 reg_class rarg2_bits64_reg(R4_H, R4); 508 reg_class rarg3_bits64_reg(R5_H, R5); 509 reg_class rarg4_bits64_reg(R6_H, R6); 510 // Thread register, 'written' by tlsLoadP, see there. 511 reg_class thread_bits64_reg(R16_H, R16); 512 513 reg_class r19_bits64_reg(R19_H, R19); 514 515 // 64 bit registers that can be read and written i.e. these registers 516 // can be dest (or src) of normal instructions. 517 reg_class bits64_reg_rw( 518 /*R0_H, R0*/ // R0 519 /*R1_H, R1*/ // SP 520 R2_H, R2, // TOC 521 R3_H, R3, 522 R4_H, R4, 523 R5_H, R5, 524 R6_H, R6, 525 R7_H, R7, 526 R8_H, R8, 527 R9_H, R9, 528 R10_H, R10, 529 R11_H, R11, 530 R12_H, R12, 531 /*R13_H, R13*/ // system thread id 532 R14_H, R14, 533 R15_H, R15, 534 /*R16_H, R16*/ // R16_thread 535 R17_H, R17, 536 R18_H, R18, 537 R19_H, R19, 538 R20_H, R20, 539 R21_H, R21, 540 R22_H, R22, 541 R23_H, R23, 542 R24_H, R24, 543 R25_H, R25, 544 R26_H, R26, 545 R27_H, R27, 546 R28_H, R28, 547 /*R29_H, R29,*/ 548 R30_H, R30, 549 R31_H, R31 550 ); 551 552 // 64 bit registers used excluding r2, r11 and r12 553 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses 554 // r2, r11 and r12 internally. 555 reg_class bits64_reg_leaf_call( 556 /*R0_H, R0*/ // R0 557 /*R1_H, R1*/ // SP 558 /*R2_H, R2*/ // TOC 559 R3_H, R3, 560 R4_H, R4, 561 R5_H, R5, 562 R6_H, R6, 563 R7_H, R7, 564 R8_H, R8, 565 R9_H, R9, 566 R10_H, R10, 567 /*R11_H, R11*/ 568 /*R12_H, R12*/ 569 /*R13_H, R13*/ // system thread id 570 R14_H, R14, 571 R15_H, R15, 572 /*R16_H, R16*/ // R16_thread 573 R17_H, R17, 574 R18_H, R18, 575 R19_H, R19, 576 R20_H, R20, 577 R21_H, R21, 578 R22_H, R22, 579 R23_H, R23, 580 R24_H, R24, 581 R25_H, R25, 582 R26_H, R26, 583 R27_H, R27, 584 R28_H, R28, 585 /*R29_H, R29,*/ 586 R30_H, R30, 587 R31_H, R31 588 ); 589 590 // Used to hold the TOC to avoid collisions with expanded DynamicCall 591 // which uses r19 as inline cache internally and expanded LeafCall which uses 592 // r2, r11 and r12 internally. 593 reg_class bits64_constant_table_base( 594 /*R0_H, R0*/ // R0 595 /*R1_H, R1*/ // SP 596 /*R2_H, R2*/ // TOC 597 R3_H, R3, 598 R4_H, R4, 599 R5_H, R5, 600 R6_H, R6, 601 R7_H, R7, 602 R8_H, R8, 603 R9_H, R9, 604 R10_H, R10, 605 /*R11_H, R11*/ 606 /*R12_H, R12*/ 607 /*R13_H, R13*/ // system thread id 608 R14_H, R14, 609 R15_H, R15, 610 /*R16_H, R16*/ // R16_thread 611 R17_H, R17, 612 R18_H, R18, 613 /*R19_H, R19*/ 614 R20_H, R20, 615 R21_H, R21, 616 R22_H, R22, 617 R23_H, R23, 618 R24_H, R24, 619 R25_H, R25, 620 R26_H, R26, 621 R27_H, R27, 622 R28_H, R28, 623 /*R29_H, R29,*/ 624 R30_H, R30, 625 R31_H, R31 626 ); 627 628 // 64 bit registers that can only be read i.e. these registers can 629 // only be src of all instructions. 630 reg_class bits64_reg_ro( 631 /*R0_H, R0*/ // R0 632 R1_H, R1, 633 R2_H, R2, // TOC 634 R3_H, R3, 635 R4_H, R4, 636 R5_H, R5, 637 R6_H, R6, 638 R7_H, R7, 639 R8_H, R8, 640 R9_H, R9, 641 R10_H, R10, 642 R11_H, R11, 643 R12_H, R12, 644 /*R13_H, R13*/ // system thread id 645 R14_H, R14, 646 R15_H, R15, 647 R16_H, R16, // R16_thread 648 R17_H, R17, 649 R18_H, R18, 650 R19_H, R19, 651 R20_H, R20, 652 R21_H, R21, 653 R22_H, R22, 654 R23_H, R23, 655 R24_H, R24, 656 R25_H, R25, 657 R26_H, R26, 658 R27_H, R27, 659 R28_H, R28, 660 /*R29_H, R29,*/ // TODO: let allocator handle TOC!! 661 R30_H, R30, 662 R31_H, R31 663 ); 664 665 666 // ---------------------------- 667 // Special Class for Condition Code Flags Register 668 669 reg_class int_flags( 670 /*CCR0*/ // scratch 671 /*CCR1*/ // scratch 672 /*CCR2*/ // nv! 673 /*CCR3*/ // nv! 674 /*CCR4*/ // nv! 675 CCR5, 676 CCR6, 677 CCR7 678 ); 679 680 reg_class int_flags_ro( 681 CCR0, 682 CCR1, 683 CCR2, 684 CCR3, 685 CCR4, 686 CCR5, 687 CCR6, 688 CCR7 689 ); 690 691 reg_class int_flags_CR0(CCR0); 692 reg_class int_flags_CR1(CCR1); 693 reg_class int_flags_CR6(CCR6); 694 reg_class ctr_reg(SR_CTR); 695 696 // ---------------------------- 697 // Float Register Classes 698 // ---------------------------- 699 700 reg_class flt_reg( 701 F0, 702 F1, 703 F2, 704 F3, 705 F4, 706 F5, 707 F6, 708 F7, 709 F8, 710 F9, 711 F10, 712 F11, 713 F12, 714 F13, 715 F14, // nv! 716 F15, // nv! 717 F16, // nv! 718 F17, // nv! 719 F18, // nv! 720 F19, // nv! 721 F20, // nv! 722 F21, // nv! 723 F22, // nv! 724 F23, // nv! 725 F24, // nv! 726 F25, // nv! 727 F26, // nv! 728 F27, // nv! 729 F28, // nv! 730 F29, // nv! 731 F30, // nv! 732 F31 // nv! 733 ); 734 735 // Double precision float registers have virtual `high halves' that 736 // are needed by the allocator. 737 reg_class dbl_reg( 738 F0, F0_H, 739 F1, F1_H, 740 F2, F2_H, 741 F3, F3_H, 742 F4, F4_H, 743 F5, F5_H, 744 F6, F6_H, 745 F7, F7_H, 746 F8, F8_H, 747 F9, F9_H, 748 F10, F10_H, 749 F11, F11_H, 750 F12, F12_H, 751 F13, F13_H, 752 F14, F14_H, // nv! 753 F15, F15_H, // nv! 754 F16, F16_H, // nv! 755 F17, F17_H, // nv! 756 F18, F18_H, // nv! 757 F19, F19_H, // nv! 758 F20, F20_H, // nv! 759 F21, F21_H, // nv! 760 F22, F22_H, // nv! 761 F23, F23_H, // nv! 762 F24, F24_H, // nv! 763 F25, F25_H, // nv! 764 F26, F26_H, // nv! 765 F27, F27_H, // nv! 766 F28, F28_H, // nv! 767 F29, F29_H, // nv! 768 F30, F30_H, // nv! 769 F31, F31_H // nv! 770 ); 771 772 %} 773 774 //----------DEFINITION BLOCK--------------------------------------------------- 775 // Define name --> value mappings to inform the ADLC of an integer valued name 776 // Current support includes integer values in the range [0, 0x7FFFFFFF] 777 // Format: 778 // int_def <name> ( <int_value>, <expression>); 779 // Generated Code in ad_<arch>.hpp 780 // #define <name> (<expression>) 781 // // value == <int_value> 782 // Generated code in ad_<arch>.cpp adlc_verification() 783 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 784 // 785 definitions %{ 786 // The default cost (of an ALU instruction). 787 int_def DEFAULT_COST_LOW ( 30, 30); 788 int_def DEFAULT_COST ( 100, 100); 789 int_def HUGE_COST (1000000, 1000000); 790 791 // Memory refs 792 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 793 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 794 795 // Branches are even more expensive. 796 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 797 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 798 %} 799 800 801 //----------SOURCE BLOCK------------------------------------------------------- 802 // This is a block of C++ code which provides values, functions, and 803 // definitions necessary in the rest of the architecture description. 804 source_hpp %{ 805 // Header information of the source block. 806 // Method declarations/definitions which are used outside 807 // the ad-scope can conveniently be defined here. 808 // 809 // To keep related declarations/definitions/uses close together, 810 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 811 812 // Returns true if Node n is followed by a MemBar node that 813 // will do an acquire. If so, this node must not do the acquire 814 // operation. 815 bool followed_by_acquire(const Node *n); 816 %} 817 818 source %{ 819 820 // Should the Matcher clone shifts on addressing modes, expecting them 821 // to be subsumed into complex addressing expressions or compute them 822 // into registers? 823 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 824 return clone_base_plus_offset_address(m, mstack, address_visited); 825 } 826 827 void Compile::reshape_address(AddPNode* addp) { 828 } 829 830 // Optimize load-acquire. 831 // 832 // Check if acquire is unnecessary due to following operation that does 833 // acquire anyways. 834 // Walk the pattern: 835 // 836 // n: Load.acq 837 // | 838 // MemBarAcquire 839 // | | 840 // Proj(ctrl) Proj(mem) 841 // | | 842 // MemBarRelease/Volatile 843 // 844 bool followed_by_acquire(const Node *load) { 845 assert(load->is_Load(), "So far implemented only for loads."); 846 847 // Find MemBarAcquire. 848 const Node *mba = NULL; 849 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 850 const Node *out = load->fast_out(i); 851 if (out->Opcode() == Op_MemBarAcquire) { 852 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 853 mba = out; 854 break; 855 } 856 } 857 if (!mba) return false; 858 859 // Find following MemBar node. 860 // 861 // The following node must be reachable by control AND memory 862 // edge to assure no other operations are in between the two nodes. 863 // 864 // So first get the Proj node, mem_proj, to use it to iterate forward. 865 Node *mem_proj = NULL; 866 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 867 mem_proj = mba->fast_out(i); // Throw out-of-bounds if proj not found 868 assert(mem_proj->is_Proj(), "only projections here"); 869 ProjNode *proj = mem_proj->as_Proj(); 870 if (proj->_con == TypeFunc::Memory && 871 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 872 break; 873 } 874 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 875 876 // Search MemBar behind Proj. If there are other memory operations 877 // behind the Proj we lost. 878 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 879 Node *x = mem_proj->fast_out(j); 880 // Proj might have an edge to a store or load node which precedes the membar. 881 if (x->is_Mem()) return false; 882 883 // On PPC64 release and volatile are implemented by an instruction 884 // that also has acquire semantics. I.e. there is no need for an 885 // acquire before these. 886 int xop = x->Opcode(); 887 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 888 // Make sure we're not missing Call/Phi/MergeMem by checking 889 // control edges. The control edge must directly lead back 890 // to the MemBarAcquire 891 Node *ctrl_proj = x->in(0); 892 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 893 return true; 894 } 895 } 896 } 897 898 return false; 899 } 900 901 #define __ _masm. 902 903 // Tertiary op of a LoadP or StoreP encoding. 904 #define REGP_OP true 905 906 // **************************************************************************** 907 908 // REQUIRED FUNCTIONALITY 909 910 // !!!!! Special hack to get all type of calls to specify the byte offset 911 // from the start of the call to the point where the return address 912 // will point. 913 914 // PPC port: Removed use of lazy constant construct. 915 916 int MachCallStaticJavaNode::ret_addr_offset() { 917 // It's only a single branch-and-link instruction. 918 return 4; 919 } 920 921 int MachCallDynamicJavaNode::ret_addr_offset() { 922 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 923 // postalloc expanded calls if we use inline caches and do not update method data. 924 if (UseInlineCaches) 925 return 4; 926 927 int vtable_index = this->_vtable_index; 928 if (vtable_index < 0) { 929 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 930 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 931 return 12; 932 } else { 933 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 934 return 24; 935 } 936 } 937 938 int MachCallRuntimeNode::ret_addr_offset() { 939 #if defined(ABI_ELFv2) 940 return 28; 941 #else 942 return 40; 943 #endif 944 } 945 946 //============================================================================= 947 948 // condition code conversions 949 950 static int cc_to_boint(int cc) { 951 return Assembler::bcondCRbiIs0 | (cc & 8); 952 } 953 954 static int cc_to_inverse_boint(int cc) { 955 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 956 } 957 958 static int cc_to_biint(int cc, int flags_reg) { 959 return (flags_reg << 2) | (cc & 3); 960 } 961 962 //============================================================================= 963 964 // Compute padding required for nodes which need alignment. The padding 965 // is the number of bytes (not instructions) which will be inserted before 966 // the instruction. The padding must match the size of a NOP instruction. 967 968 // Currently not used on this platform. 969 970 //============================================================================= 971 972 // Indicate if the safepoint node needs the polling page as an input. 973 bool SafePointNode::needs_polling_address_input() { 974 // The address is loaded from thread by a seperate node. 975 return true; 976 } 977 978 //============================================================================= 979 980 // Emit an interrupt that is caught by the debugger (for debugging compiler). 981 void emit_break(CodeBuffer &cbuf) { 982 MacroAssembler _masm(&cbuf); 983 __ illtrap(); 984 } 985 986 #ifndef PRODUCT 987 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 988 st->print("BREAKPOINT"); 989 } 990 #endif 991 992 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 993 emit_break(cbuf); 994 } 995 996 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 997 return MachNode::size(ra_); 998 } 999 1000 //============================================================================= 1001 1002 void emit_nop(CodeBuffer &cbuf) { 1003 MacroAssembler _masm(&cbuf); 1004 __ nop(); 1005 } 1006 1007 static inline void emit_long(CodeBuffer &cbuf, int value) { 1008 *((int*)(cbuf.insts_end())) = value; 1009 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1010 } 1011 1012 //============================================================================= 1013 1014 %} // interrupt source 1015 1016 source_hpp %{ // Header information of the source block. 1017 1018 //-------------------------------------------------------------- 1019 //---< Used for optimization in Compile::Shorten_branches >--- 1020 //-------------------------------------------------------------- 1021 1022 class CallStubImpl { 1023 1024 public: 1025 1026 // Emit call stub, compiled java to interpreter. 1027 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1028 1029 // Size of call trampoline stub. 1030 // This doesn't need to be accurate to the byte, but it 1031 // must be larger than or equal to the real size of the stub. 1032 static uint size_call_trampoline() { 1033 return MacroAssembler::trampoline_stub_size; 1034 } 1035 1036 // number of relocations needed by a call trampoline stub 1037 static uint reloc_call_trampoline() { 1038 return 5; 1039 } 1040 1041 }; 1042 1043 %} // end source_hpp 1044 1045 source %{ 1046 1047 // Emit a trampoline stub for a call to a target which is too far away. 1048 // 1049 // code sequences: 1050 // 1051 // call-site: 1052 // branch-and-link to <destination> or <trampoline stub> 1053 // 1054 // Related trampoline stub for this call-site in the stub section: 1055 // load the call target from the constant pool 1056 // branch via CTR (LR/link still points to the call-site above) 1057 1058 void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1059 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1060 if (stub == NULL) { 1061 ciEnv::current()->record_out_of_memory_failure(); 1062 } 1063 } 1064 1065 //============================================================================= 1066 1067 // Emit an inline branch-and-link call and a related trampoline stub. 1068 // 1069 // code sequences: 1070 // 1071 // call-site: 1072 // branch-and-link to <destination> or <trampoline stub> 1073 // 1074 // Related trampoline stub for this call-site in the stub section: 1075 // load the call target from the constant pool 1076 // branch via CTR (LR/link still points to the call-site above) 1077 // 1078 1079 typedef struct { 1080 int insts_call_instruction_offset; 1081 int ret_addr_offset; 1082 } EmitCallOffsets; 1083 1084 // Emit a branch-and-link instruction that branches to a trampoline. 1085 // - Remember the offset of the branch-and-link instruction. 1086 // - Add a relocation at the branch-and-link instruction. 1087 // - Emit a branch-and-link. 1088 // - Remember the return pc offset. 1089 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1090 EmitCallOffsets offsets = { -1, -1 }; 1091 const int start_offset = __ offset(); 1092 offsets.insts_call_instruction_offset = __ offset(); 1093 1094 // No entry point given, use the current pc. 1095 if (entry_point == NULL) entry_point = __ pc(); 1096 1097 // Put the entry point as a constant into the constant pool. 1098 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1099 if (entry_point_toc_addr == NULL) { 1100 ciEnv::current()->record_out_of_memory_failure(); 1101 return offsets; 1102 } 1103 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1104 1105 // Emit the trampoline stub which will be related to the branch-and-link below. 1106 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1107 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1108 __ relocate(rtype); 1109 1110 // Note: At this point we do not have the address of the trampoline 1111 // stub, and the entry point might be too far away for bl, so __ pc() 1112 // serves as dummy and the bl will be patched later. 1113 __ bl((address) __ pc()); 1114 1115 offsets.ret_addr_offset = __ offset() - start_offset; 1116 1117 return offsets; 1118 } 1119 1120 //============================================================================= 1121 1122 // Factory for creating loadConL* nodes for large/small constant pool. 1123 1124 static inline jlong replicate_immF(float con) { 1125 // Replicate float con 2 times and pack into vector. 1126 int val = *((int*)&con); 1127 jlong lval = val; 1128 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1129 return lval; 1130 } 1131 1132 //============================================================================= 1133 1134 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1135 int Compile::ConstantTable::calculate_table_base_offset() const { 1136 return 0; // absolute addressing, no offset 1137 } 1138 1139 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1140 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1141 iRegPdstOper *op_dst = new iRegPdstOper(); 1142 MachNode *m1 = new loadToc_hiNode(); 1143 MachNode *m2 = new loadToc_loNode(); 1144 1145 m1->add_req(NULL); 1146 m2->add_req(NULL, m1); 1147 m1->_opnds[0] = op_dst; 1148 m2->_opnds[0] = op_dst; 1149 m2->_opnds[1] = op_dst; 1150 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1151 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1152 nodes->push(m1); 1153 nodes->push(m2); 1154 } 1155 1156 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1157 // Is postalloc expanded. 1158 ShouldNotReachHere(); 1159 } 1160 1161 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1162 return 0; 1163 } 1164 1165 #ifndef PRODUCT 1166 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1167 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1168 } 1169 #endif 1170 1171 //============================================================================= 1172 1173 #ifndef PRODUCT 1174 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1175 Compile* C = ra_->C; 1176 const long framesize = C->frame_slots() << LogBytesPerInt; 1177 1178 st->print("PROLOG\n\t"); 1179 if (C->need_stack_bang(framesize)) { 1180 st->print("stack_overflow_check\n\t"); 1181 } 1182 1183 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1184 st->print("save return pc\n\t"); 1185 st->print("push frame %ld\n\t", -framesize); 1186 } 1187 } 1188 #endif 1189 1190 // Macro used instead of the common __ to emulate the pipes of PPC. 1191 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1192 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1193 // still no scheduling of this code is possible, the micro scheduler is aware of the 1194 // code and can update its internal data. The following mechanism is used to achieve this: 1195 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1196 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1197 #if 0 // TODO: PPC port 1198 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1199 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1200 _masm. 1201 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1202 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1203 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1204 C->hb_scheduling()->_pdScheduling->advance_offset 1205 #else 1206 #define ___(op) if (UsePower6SchedulerPPC64) \ 1207 Unimplemented(); \ 1208 _masm. 1209 #define ___stop if (UsePower6SchedulerPPC64) \ 1210 Unimplemented() 1211 #define ___advance if (UsePower6SchedulerPPC64) \ 1212 Unimplemented() 1213 #endif 1214 1215 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1216 Compile* C = ra_->C; 1217 MacroAssembler _masm(&cbuf); 1218 1219 const long framesize = C->frame_size_in_bytes(); 1220 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1221 1222 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1223 1224 const Register return_pc = R20; // Must match return_addr() in frame section. 1225 const Register callers_sp = R21; 1226 const Register push_frame_temp = R22; 1227 const Register toc_temp = R23; 1228 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1229 1230 if (method_is_frameless) { 1231 // Add nop at beginning of all frameless methods to prevent any 1232 // oop instructions from getting overwritten by make_not_entrant 1233 // (patching attempt would fail). 1234 ___(nop) nop(); 1235 } else { 1236 // Get return pc. 1237 ___(mflr) mflr(return_pc); 1238 } 1239 1240 // Calls to C2R adapters often do not accept exceptional returns. 1241 // We require that their callers must bang for them. But be 1242 // careful, because some VM calls (such as call site linkage) can 1243 // use several kilobytes of stack. But the stack safety zone should 1244 // account for that. See bugs 4446381, 4468289, 4497237. 1245 1246 int bangsize = C->bang_size_in_bytes(); 1247 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1248 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1249 // Unfortunately we cannot use the function provided in 1250 // assembler.cpp as we have to emulate the pipes. So I had to 1251 // insert the code of generate_stack_overflow_check(), see 1252 // assembler.cpp for some illuminative comments. 1253 const int page_size = os::vm_page_size(); 1254 int bang_end = JavaThread::stack_shadow_zone_size(); 1255 1256 // This is how far the previous frame's stack banging extended. 1257 const int bang_end_safe = bang_end; 1258 1259 if (bangsize > page_size) { 1260 bang_end += bangsize; 1261 } 1262 1263 int bang_offset = bang_end_safe; 1264 1265 while (bang_offset <= bang_end) { 1266 // Need at least one stack bang at end of shadow zone. 1267 1268 // Again I had to copy code, this time from assembler_ppc.cpp, 1269 // bang_stack_with_offset - see there for comments. 1270 1271 // Stack grows down, caller passes positive offset. 1272 assert(bang_offset > 0, "must bang with positive offset"); 1273 1274 long stdoffset = -bang_offset; 1275 1276 if (Assembler::is_simm(stdoffset, 16)) { 1277 // Signed 16 bit offset, a simple std is ok. 1278 if (UseLoadInstructionsForStackBangingPPC64) { 1279 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1280 } else { 1281 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1282 } 1283 } else if (Assembler::is_simm(stdoffset, 31)) { 1284 // Use largeoffset calculations for addis & ld/std. 1285 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1286 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1287 1288 Register tmp = R11; 1289 ___(addis) addis(tmp, R1_SP, hi); 1290 if (UseLoadInstructionsForStackBangingPPC64) { 1291 ___(ld) ld(R0, lo, tmp); 1292 } else { 1293 ___(std) std(R0, lo, tmp); 1294 } 1295 } else { 1296 ShouldNotReachHere(); 1297 } 1298 1299 bang_offset += page_size; 1300 } 1301 // R11 trashed 1302 } // C->need_stack_bang(framesize) && UseStackBanging 1303 1304 unsigned int bytes = (unsigned int)framesize; 1305 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1306 ciMethod *currMethod = C->method(); 1307 1308 // Optimized version for most common case. 1309 if (UsePower6SchedulerPPC64 && 1310 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1311 !(false /* ConstantsALot TODO: PPC port*/)) { 1312 ___(or) mr(callers_sp, R1_SP); 1313 ___(std) std(return_pc, _abi(lr), R1_SP); 1314 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1315 return; 1316 } 1317 1318 if (!method_is_frameless) { 1319 // Get callers sp. 1320 ___(or) mr(callers_sp, R1_SP); 1321 1322 // Push method's frame, modifies SP. 1323 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1324 // The ABI is already accounted for in 'framesize' via the 1325 // 'out_preserve' area. 1326 Register tmp = push_frame_temp; 1327 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1328 if (Assembler::is_simm(-offset, 16)) { 1329 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1330 } else { 1331 long x = -offset; 1332 // Had to insert load_const(tmp, -offset). 1333 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1334 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1335 ___(rldicr) sldi(tmp, tmp, 32); 1336 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1337 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1338 1339 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1340 } 1341 } 1342 #if 0 // TODO: PPC port 1343 // For testing large constant pools, emit a lot of constants to constant pool. 1344 // "Randomize" const_size. 1345 if (ConstantsALot) { 1346 const int num_consts = const_size(); 1347 for (int i = 0; i < num_consts; i++) { 1348 __ long_constant(0xB0B5B00BBABE); 1349 } 1350 } 1351 #endif 1352 if (!method_is_frameless) { 1353 // Save return pc. 1354 ___(std) std(return_pc, _abi(lr), callers_sp); 1355 } 1356 1357 C->set_frame_complete(cbuf.insts_size()); 1358 } 1359 #undef ___ 1360 #undef ___stop 1361 #undef ___advance 1362 1363 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1364 // Variable size. determine dynamically. 1365 return MachNode::size(ra_); 1366 } 1367 1368 int MachPrologNode::reloc() const { 1369 // Return number of relocatable values contained in this instruction. 1370 return 1; // 1 reloc entry for load_const(toc). 1371 } 1372 1373 //============================================================================= 1374 1375 #ifndef PRODUCT 1376 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1377 Compile* C = ra_->C; 1378 1379 st->print("EPILOG\n\t"); 1380 st->print("restore return pc\n\t"); 1381 st->print("pop frame\n\t"); 1382 1383 if (do_polling() && C->is_method_compilation()) { 1384 st->print("touch polling page\n\t"); 1385 } 1386 } 1387 #endif 1388 1389 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1390 Compile* C = ra_->C; 1391 MacroAssembler _masm(&cbuf); 1392 1393 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1394 assert(framesize >= 0, "negative frame-size?"); 1395 1396 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1397 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1398 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1399 const Register polling_page = R12; 1400 1401 if (!method_is_frameless) { 1402 // Restore return pc relative to callers' sp. 1403 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1404 } 1405 1406 if (method_needs_polling) { 1407 if (LoadPollAddressFromThread) { 1408 // TODO: PPC port __ ld(polling_page, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1409 Unimplemented(); 1410 } else { 1411 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); // TODO: PPC port: get_standard_polling_page() 1412 } 1413 } 1414 1415 if (!method_is_frameless) { 1416 // Move return pc to LR. 1417 __ mtlr(return_pc); 1418 // Pop frame (fixed frame-size). 1419 __ addi(R1_SP, R1_SP, (int)framesize); 1420 } 1421 1422 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1423 __ reserved_stack_check(return_pc); 1424 } 1425 1426 if (method_needs_polling) { 1427 // We need to mark the code position where the load from the safepoint 1428 // polling page was emitted as relocInfo::poll_return_type here. 1429 __ relocate(relocInfo::poll_return_type); 1430 __ load_from_polling_page(polling_page); 1431 } 1432 } 1433 1434 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1435 // Variable size. Determine dynamically. 1436 return MachNode::size(ra_); 1437 } 1438 1439 int MachEpilogNode::reloc() const { 1440 // Return number of relocatable values contained in this instruction. 1441 return 1; // 1 for load_from_polling_page. 1442 } 1443 1444 const Pipeline * MachEpilogNode::pipeline() const { 1445 return MachNode::pipeline_class(); 1446 } 1447 1448 // This method seems to be obsolete. It is declared in machnode.hpp 1449 // and defined in all *.ad files, but it is never called. Should we 1450 // get rid of it? 1451 int MachEpilogNode::safepoint_offset() const { 1452 assert(do_polling(), "no return for this epilog node"); 1453 return 0; 1454 } 1455 1456 #if 0 // TODO: PPC port 1457 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1458 MacroAssembler _masm(&cbuf); 1459 if (LoadPollAddressFromThread) { 1460 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1461 } else { 1462 _masm.nop(); 1463 } 1464 } 1465 1466 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1467 if (LoadPollAddressFromThread) { 1468 return 4; 1469 } else { 1470 return 4; 1471 } 1472 } 1473 1474 #ifndef PRODUCT 1475 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1476 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1477 } 1478 #endif 1479 1480 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1481 return RSCRATCH1_BITS64_REG_mask(); 1482 } 1483 #endif // PPC port 1484 1485 // ============================================================================= 1486 1487 // Figure out which register class each belongs in: rc_int, rc_float or 1488 // rc_stack. 1489 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1490 1491 static enum RC rc_class(OptoReg::Name reg) { 1492 // Return the register class for the given register. The given register 1493 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1494 // enumeration in adGlobals_ppc.hpp. 1495 1496 if (reg == OptoReg::Bad) return rc_bad; 1497 1498 // We have 64 integer register halves, starting at index 0. 1499 if (reg < 64) return rc_int; 1500 1501 // We have 64 floating-point register halves, starting at index 64. 1502 if (reg < 64+64) return rc_float; 1503 1504 // Between float regs & stack are the flags regs. 1505 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1506 1507 return rc_stack; 1508 } 1509 1510 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1511 bool do_print, Compile* C, outputStream *st) { 1512 1513 assert(opcode == Assembler::LD_OPCODE || 1514 opcode == Assembler::STD_OPCODE || 1515 opcode == Assembler::LWZ_OPCODE || 1516 opcode == Assembler::STW_OPCODE || 1517 opcode == Assembler::LFD_OPCODE || 1518 opcode == Assembler::STFD_OPCODE || 1519 opcode == Assembler::LFS_OPCODE || 1520 opcode == Assembler::STFS_OPCODE, 1521 "opcode not supported"); 1522 1523 if (cbuf) { 1524 int d = 1525 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1526 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1527 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1528 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1529 } 1530 #ifndef PRODUCT 1531 else if (do_print) { 1532 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1533 op_str, 1534 Matcher::regName[reg], 1535 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1536 } 1537 #endif 1538 return 4; // size 1539 } 1540 1541 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1542 Compile* C = ra_->C; 1543 1544 // Get registers to move. 1545 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1546 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1547 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1548 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1549 1550 enum RC src_hi_rc = rc_class(src_hi); 1551 enum RC src_lo_rc = rc_class(src_lo); 1552 enum RC dst_hi_rc = rc_class(dst_hi); 1553 enum RC dst_lo_rc = rc_class(dst_lo); 1554 1555 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1556 if (src_hi != OptoReg::Bad) 1557 assert((src_lo&1)==0 && src_lo+1==src_hi && 1558 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1559 "expected aligned-adjacent pairs"); 1560 // Generate spill code! 1561 int size = 0; 1562 1563 if (src_lo == dst_lo && src_hi == dst_hi) 1564 return size; // Self copy, no move. 1565 1566 // -------------------------------------- 1567 // Memory->Memory Spill. Use R0 to hold the value. 1568 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1569 int src_offset = ra_->reg2offset(src_lo); 1570 int dst_offset = ra_->reg2offset(dst_lo); 1571 if (src_hi != OptoReg::Bad) { 1572 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1573 "expected same type of move for high parts"); 1574 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1575 if (!cbuf && !do_size) st->print("\n\t"); 1576 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1577 } else { 1578 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1579 if (!cbuf && !do_size) st->print("\n\t"); 1580 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1581 } 1582 return size; 1583 } 1584 1585 // -------------------------------------- 1586 // Check for float->int copy; requires a trip through memory. 1587 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1588 Unimplemented(); 1589 } 1590 1591 // -------------------------------------- 1592 // Check for integer reg-reg copy. 1593 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1594 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1595 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1596 size = (Rsrc != Rdst) ? 4 : 0; 1597 1598 if (cbuf) { 1599 MacroAssembler _masm(cbuf); 1600 if (size) { 1601 __ mr(Rdst, Rsrc); 1602 } 1603 } 1604 #ifndef PRODUCT 1605 else if (!do_size) { 1606 if (size) { 1607 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1608 } else { 1609 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1610 } 1611 } 1612 #endif 1613 return size; 1614 } 1615 1616 // Check for integer store. 1617 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1618 int dst_offset = ra_->reg2offset(dst_lo); 1619 if (src_hi != OptoReg::Bad) { 1620 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1621 "expected same type of move for high parts"); 1622 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1623 } else { 1624 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1625 } 1626 return size; 1627 } 1628 1629 // Check for integer load. 1630 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1631 int src_offset = ra_->reg2offset(src_lo); 1632 if (src_hi != OptoReg::Bad) { 1633 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1634 "expected same type of move for high parts"); 1635 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1636 } else { 1637 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1638 } 1639 return size; 1640 } 1641 1642 // Check for float reg-reg copy. 1643 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1644 if (cbuf) { 1645 MacroAssembler _masm(cbuf); 1646 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1647 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1648 __ fmr(Rdst, Rsrc); 1649 } 1650 #ifndef PRODUCT 1651 else if (!do_size) { 1652 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1653 } 1654 #endif 1655 return 4; 1656 } 1657 1658 // Check for float store. 1659 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1660 int dst_offset = ra_->reg2offset(dst_lo); 1661 if (src_hi != OptoReg::Bad) { 1662 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1663 "expected same type of move for high parts"); 1664 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1665 } else { 1666 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1667 } 1668 return size; 1669 } 1670 1671 // Check for float load. 1672 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1673 int src_offset = ra_->reg2offset(src_lo); 1674 if (src_hi != OptoReg::Bad) { 1675 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1676 "expected same type of move for high parts"); 1677 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1678 } else { 1679 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1680 } 1681 return size; 1682 } 1683 1684 // -------------------------------------------------------------------- 1685 // Check for hi bits still needing moving. Only happens for misaligned 1686 // arguments to native calls. 1687 if (src_hi == dst_hi) 1688 return size; // Self copy; no move. 1689 1690 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1691 ShouldNotReachHere(); // Unimplemented 1692 return 0; 1693 } 1694 1695 #ifndef PRODUCT 1696 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1697 if (!ra_) 1698 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1699 else 1700 implementation(NULL, ra_, false, st); 1701 } 1702 #endif 1703 1704 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1705 implementation(&cbuf, ra_, false, NULL); 1706 } 1707 1708 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1709 return implementation(NULL, ra_, true, NULL); 1710 } 1711 1712 #if 0 // TODO: PPC port 1713 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1714 #ifndef PRODUCT 1715 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1716 #endif 1717 assert(ra_->node_regs_max_index() != 0, ""); 1718 1719 // Get registers to move. 1720 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1721 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1722 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1723 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1724 1725 enum RC src_lo_rc = rc_class(src_lo); 1726 enum RC dst_lo_rc = rc_class(dst_lo); 1727 1728 if (src_lo == dst_lo && src_hi == dst_hi) 1729 return ppc64Opcode_none; // Self copy, no move. 1730 1731 // -------------------------------------- 1732 // Memory->Memory Spill. Use R0 to hold the value. 1733 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1734 return ppc64Opcode_compound; 1735 } 1736 1737 // -------------------------------------- 1738 // Check for float->int copy; requires a trip through memory. 1739 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1740 Unimplemented(); 1741 } 1742 1743 // -------------------------------------- 1744 // Check for integer reg-reg copy. 1745 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1746 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1747 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1748 if (Rsrc == Rdst) { 1749 return ppc64Opcode_none; 1750 } else { 1751 return ppc64Opcode_or; 1752 } 1753 } 1754 1755 // Check for integer store. 1756 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1757 if (src_hi != OptoReg::Bad) { 1758 return ppc64Opcode_std; 1759 } else { 1760 return ppc64Opcode_stw; 1761 } 1762 } 1763 1764 // Check for integer load. 1765 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1766 if (src_hi != OptoReg::Bad) { 1767 return ppc64Opcode_ld; 1768 } else { 1769 return ppc64Opcode_lwz; 1770 } 1771 } 1772 1773 // Check for float reg-reg copy. 1774 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1775 return ppc64Opcode_fmr; 1776 } 1777 1778 // Check for float store. 1779 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1780 if (src_hi != OptoReg::Bad) { 1781 return ppc64Opcode_stfd; 1782 } else { 1783 return ppc64Opcode_stfs; 1784 } 1785 } 1786 1787 // Check for float load. 1788 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1789 if (src_hi != OptoReg::Bad) { 1790 return ppc64Opcode_lfd; 1791 } else { 1792 return ppc64Opcode_lfs; 1793 } 1794 } 1795 1796 // -------------------------------------------------------------------- 1797 // Check for hi bits still needing moving. Only happens for misaligned 1798 // arguments to native calls. 1799 if (src_hi == dst_hi) { 1800 return ppc64Opcode_none; // Self copy; no move. 1801 } 1802 1803 ShouldNotReachHere(); 1804 return ppc64Opcode_undefined; 1805 } 1806 #endif // PPC port 1807 1808 #ifndef PRODUCT 1809 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1810 st->print("NOP \t// %d nops to pad for loops.", _count); 1811 } 1812 #endif 1813 1814 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 1815 MacroAssembler _masm(&cbuf); 1816 // _count contains the number of nops needed for padding. 1817 for (int i = 0; i < _count; i++) { 1818 __ nop(); 1819 } 1820 } 1821 1822 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 1823 return _count * 4; 1824 } 1825 1826 #ifndef PRODUCT 1827 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1828 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1829 char reg_str[128]; 1830 ra_->dump_register(this, reg_str); 1831 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 1832 } 1833 #endif 1834 1835 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1836 MacroAssembler _masm(&cbuf); 1837 1838 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1839 int reg = ra_->get_encode(this); 1840 1841 if (Assembler::is_simm(offset, 16)) { 1842 __ addi(as_Register(reg), R1, offset); 1843 } else { 1844 ShouldNotReachHere(); 1845 } 1846 } 1847 1848 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1849 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1850 return 4; 1851 } 1852 1853 #ifndef PRODUCT 1854 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1855 st->print_cr("---- MachUEPNode ----"); 1856 st->print_cr("..."); 1857 } 1858 #endif 1859 1860 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1861 // This is the unverified entry point. 1862 MacroAssembler _masm(&cbuf); 1863 1864 // Inline_cache contains a klass. 1865 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 1866 Register receiver_klass = R12_scratch2; // tmp 1867 1868 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 1869 assert(R11_scratch1 == R11, "need prologue scratch register"); 1870 1871 // Check for NULL argument if we don't have implicit null checks. 1872 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 1873 if (TrapBasedNullChecks) { 1874 __ trap_null_check(R3_ARG1); 1875 } else { 1876 Label valid; 1877 __ cmpdi(CCR0, R3_ARG1, 0); 1878 __ bne_predict_taken(CCR0, valid); 1879 // We have a null argument, branch to ic_miss_stub. 1880 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 1881 relocInfo::runtime_call_type); 1882 __ bind(valid); 1883 } 1884 } 1885 // Assume argument is not NULL, load klass from receiver. 1886 __ load_klass(receiver_klass, R3_ARG1); 1887 1888 if (TrapBasedICMissChecks) { 1889 __ trap_ic_miss_check(receiver_klass, ic_klass); 1890 } else { 1891 Label valid; 1892 __ cmpd(CCR0, receiver_klass, ic_klass); 1893 __ beq_predict_taken(CCR0, valid); 1894 // We have an unexpected klass, branch to ic_miss_stub. 1895 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 1896 relocInfo::runtime_call_type); 1897 __ bind(valid); 1898 } 1899 1900 // Argument is valid and klass is as expected, continue. 1901 } 1902 1903 #if 0 // TODO: PPC port 1904 // Optimize UEP code on z (save a load_const() call in main path). 1905 int MachUEPNode::ep_offset() { 1906 return 0; 1907 } 1908 #endif 1909 1910 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 1911 // Variable size. Determine dynamically. 1912 return MachNode::size(ra_); 1913 } 1914 1915 //============================================================================= 1916 1917 %} // interrupt source 1918 1919 source_hpp %{ // Header information of the source block. 1920 1921 class HandlerImpl { 1922 1923 public: 1924 1925 static int emit_exception_handler(CodeBuffer &cbuf); 1926 static int emit_deopt_handler(CodeBuffer& cbuf); 1927 1928 static uint size_exception_handler() { 1929 // The exception_handler is a b64_patchable. 1930 return MacroAssembler::b64_patchable_size; 1931 } 1932 1933 static uint size_deopt_handler() { 1934 // The deopt_handler is a bl64_patchable. 1935 return MacroAssembler::bl64_patchable_size; 1936 } 1937 1938 }; 1939 1940 %} // end source_hpp 1941 1942 source %{ 1943 1944 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 1945 MacroAssembler _masm(&cbuf); 1946 1947 address base = __ start_a_stub(size_exception_handler()); 1948 if (base == NULL) return 0; // CodeBuffer::expand failed 1949 1950 int offset = __ offset(); 1951 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 1952 relocInfo::runtime_call_type); 1953 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 1954 __ end_a_stub(); 1955 1956 return offset; 1957 } 1958 1959 // The deopt_handler is like the exception handler, but it calls to 1960 // the deoptimization blob instead of jumping to the exception blob. 1961 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 1962 MacroAssembler _masm(&cbuf); 1963 1964 address base = __ start_a_stub(size_deopt_handler()); 1965 if (base == NULL) return 0; // CodeBuffer::expand failed 1966 1967 int offset = __ offset(); 1968 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 1969 relocInfo::runtime_call_type); 1970 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 1971 __ end_a_stub(); 1972 1973 return offset; 1974 } 1975 1976 //============================================================================= 1977 1978 // Use a frame slots bias for frameless methods if accessing the stack. 1979 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 1980 if (as_Register(reg_enc) == R1_SP) { 1981 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 1982 } 1983 return 0; 1984 } 1985 1986 const bool Matcher::match_rule_supported(int opcode) { 1987 if (!has_match_rule(opcode)) 1988 return false; 1989 1990 switch (opcode) { 1991 case Op_SqrtD: 1992 return VM_Version::has_fsqrt(); 1993 case Op_CountLeadingZerosI: 1994 case Op_CountLeadingZerosL: 1995 case Op_CountTrailingZerosI: 1996 case Op_CountTrailingZerosL: 1997 if (!UseCountLeadingZerosInstructionsPPC64) 1998 return false; 1999 break; 2000 2001 case Op_PopCountI: 2002 case Op_PopCountL: 2003 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2004 2005 case Op_StrComp: 2006 return SpecialStringCompareTo; 2007 case Op_StrEquals: 2008 return SpecialStringEquals; 2009 case Op_StrIndexOf: 2010 return SpecialStringIndexOf; 2011 case Op_StrIndexOfChar: 2012 return SpecialStringIndexOf; 2013 } 2014 2015 return true; // Per default match rules are supported. 2016 } 2017 2018 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2019 2020 // TODO 2021 // identify extra cases that we might want to provide match rules for 2022 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2023 bool ret_value = match_rule_supported(opcode); 2024 // Add rules here. 2025 2026 return ret_value; // Per default match rules are supported. 2027 } 2028 2029 const bool Matcher::has_predicated_vectors(void) { 2030 return false; 2031 } 2032 2033 const int Matcher::float_pressure(int default_pressure_threshold) { 2034 return default_pressure_threshold; 2035 } 2036 2037 int Matcher::regnum_to_fpu_offset(int regnum) { 2038 // No user for this method? 2039 Unimplemented(); 2040 return 999; 2041 } 2042 2043 const bool Matcher::convL2FSupported(void) { 2044 // fcfids can do the conversion (>= Power7). 2045 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2046 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2047 } 2048 2049 // Vector width in bytes. 2050 const int Matcher::vector_width_in_bytes(BasicType bt) { 2051 assert(MaxVectorSize == 8, ""); 2052 return 8; 2053 } 2054 2055 // Vector ideal reg. 2056 const int Matcher::vector_ideal_reg(int size) { 2057 assert(MaxVectorSize == 8 && size == 8, ""); 2058 return Op_RegL; 2059 } 2060 2061 const int Matcher::vector_shift_count_ideal_reg(int size) { 2062 fatal("vector shift is not supported"); 2063 return Node::NotAMachineReg; 2064 } 2065 2066 // Limits on vector size (number of elements) loaded into vector. 2067 const int Matcher::max_vector_size(const BasicType bt) { 2068 assert(is_java_primitive(bt), "only primitive type vectors"); 2069 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2070 } 2071 2072 const int Matcher::min_vector_size(const BasicType bt) { 2073 return max_vector_size(bt); // Same as max. 2074 } 2075 2076 // PPC doesn't support misaligned vectors store/load. 2077 const bool Matcher::misaligned_vectors_ok() { 2078 return false; 2079 } 2080 2081 // PPC AES support not yet implemented 2082 const bool Matcher::pass_original_key_for_aes() { 2083 return false; 2084 } 2085 2086 // RETURNS: whether this branch offset is short enough that a short 2087 // branch can be used. 2088 // 2089 // If the platform does not provide any short branch variants, then 2090 // this method should return `false' for offset 0. 2091 // 2092 // `Compile::Fill_buffer' will decide on basis of this information 2093 // whether to do the pass `Compile::Shorten_branches' at all. 2094 // 2095 // And `Compile::Shorten_branches' will decide on basis of this 2096 // information whether to replace particular branch sites by short 2097 // ones. 2098 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2099 // Is the offset within the range of a ppc64 pc relative branch? 2100 bool b; 2101 2102 const int safety_zone = 3 * BytesPerInstWord; 2103 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2104 29 - 16 + 1 + 2); 2105 return b; 2106 } 2107 2108 const bool Matcher::isSimpleConstant64(jlong value) { 2109 // Probably always true, even if a temp register is required. 2110 return true; 2111 } 2112 /* TODO: PPC port 2113 // Make a new machine dependent decode node (with its operands). 2114 MachTypeNode *Matcher::make_decode_node() { 2115 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2116 "This method is only implemented for unscaled cOops mode so far"); 2117 MachTypeNode *decode = new decodeN_unscaledNode(); 2118 decode->set_opnd_array(0, new iRegPdstOper()); 2119 decode->set_opnd_array(1, new iRegNsrcOper()); 2120 return decode; 2121 } 2122 */ 2123 2124 // false => size gets scaled to BytesPerLong, ok. 2125 const bool Matcher::init_array_count_is_in_bytes = false; 2126 2127 // Use conditional move (CMOVL) on Power7. 2128 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2129 2130 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2131 // fsel doesn't accept a condition register as input, so this would be slightly different. 2132 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2133 2134 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2135 const bool Matcher::require_postalloc_expand = true; 2136 2137 // Do we need to mask the count passed to shift instructions or does 2138 // the cpu only look at the lower 5/6 bits anyway? 2139 // PowerPC requires masked shift counts. 2140 const bool Matcher::need_masked_shift_count = true; 2141 2142 // This affects two different things: 2143 // - how Decode nodes are matched 2144 // - how ImplicitNullCheck opportunities are recognized 2145 // If true, the matcher will try to remove all Decodes and match them 2146 // (as operands) into nodes. NullChecks are not prepared to deal with 2147 // Decodes by final_graph_reshaping(). 2148 // If false, final_graph_reshaping() forces the decode behind the Cmp 2149 // for a NullCheck. The matcher matches the Decode node into a register. 2150 // Implicit_null_check optimization moves the Decode along with the 2151 // memory operation back up before the NullCheck. 2152 bool Matcher::narrow_oop_use_complex_address() { 2153 // TODO: PPC port if (MatchDecodeNodes) return true; 2154 return false; 2155 } 2156 2157 bool Matcher::narrow_klass_use_complex_address() { 2158 NOT_LP64(ShouldNotCallThis()); 2159 assert(UseCompressedClassPointers, "only for compressed klass code"); 2160 // TODO: PPC port if (MatchDecodeNodes) return true; 2161 return false; 2162 } 2163 2164 bool Matcher::const_oop_prefer_decode() { 2165 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2166 return Universe::narrow_oop_base() == NULL; 2167 } 2168 2169 bool Matcher::const_klass_prefer_decode() { 2170 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2171 return Universe::narrow_klass_base() == NULL; 2172 } 2173 2174 // Is it better to copy float constants, or load them directly from memory? 2175 // Intel can load a float constant from a direct address, requiring no 2176 // extra registers. Most RISCs will have to materialize an address into a 2177 // register first, so they would do better to copy the constant from stack. 2178 const bool Matcher::rematerialize_float_constants = false; 2179 2180 // If CPU can load and store mis-aligned doubles directly then no fixup is 2181 // needed. Else we split the double into 2 integer pieces and move it 2182 // piece-by-piece. Only happens when passing doubles into C code as the 2183 // Java calling convention forces doubles to be aligned. 2184 const bool Matcher::misaligned_doubles_ok = true; 2185 2186 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2187 Unimplemented(); 2188 } 2189 2190 // Advertise here if the CPU requires explicit rounding operations 2191 // to implement the UseStrictFP mode. 2192 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2193 2194 // Do floats take an entire double register or just half? 2195 // 2196 // A float occupies a ppc64 double register. For the allocator, a 2197 // ppc64 double register appears as a pair of float registers. 2198 bool Matcher::float_in_double() { return true; } 2199 2200 // Do ints take an entire long register or just half? 2201 // The relevant question is how the int is callee-saved: 2202 // the whole long is written but de-opt'ing will have to extract 2203 // the relevant 32 bits. 2204 const bool Matcher::int_in_long = true; 2205 2206 // Constants for c2c and c calling conventions. 2207 2208 const MachRegisterNumbers iarg_reg[8] = { 2209 R3_num, R4_num, R5_num, R6_num, 2210 R7_num, R8_num, R9_num, R10_num 2211 }; 2212 2213 const MachRegisterNumbers farg_reg[13] = { 2214 F1_num, F2_num, F3_num, F4_num, 2215 F5_num, F6_num, F7_num, F8_num, 2216 F9_num, F10_num, F11_num, F12_num, 2217 F13_num 2218 }; 2219 2220 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2221 2222 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2223 2224 // Return whether or not this register is ever used as an argument. This 2225 // function is used on startup to build the trampoline stubs in generateOptoStub. 2226 // Registers not mentioned will be killed by the VM call in the trampoline, and 2227 // arguments in those registers not be available to the callee. 2228 bool Matcher::can_be_java_arg(int reg) { 2229 // We return true for all registers contained in iarg_reg[] and 2230 // farg_reg[] and their virtual halves. 2231 // We must include the virtual halves in order to get STDs and LDs 2232 // instead of STWs and LWs in the trampoline stubs. 2233 2234 if ( reg == R3_num || reg == R3_H_num 2235 || reg == R4_num || reg == R4_H_num 2236 || reg == R5_num || reg == R5_H_num 2237 || reg == R6_num || reg == R6_H_num 2238 || reg == R7_num || reg == R7_H_num 2239 || reg == R8_num || reg == R8_H_num 2240 || reg == R9_num || reg == R9_H_num 2241 || reg == R10_num || reg == R10_H_num) 2242 return true; 2243 2244 if ( reg == F1_num || reg == F1_H_num 2245 || reg == F2_num || reg == F2_H_num 2246 || reg == F3_num || reg == F3_H_num 2247 || reg == F4_num || reg == F4_H_num 2248 || reg == F5_num || reg == F5_H_num 2249 || reg == F6_num || reg == F6_H_num 2250 || reg == F7_num || reg == F7_H_num 2251 || reg == F8_num || reg == F8_H_num 2252 || reg == F9_num || reg == F9_H_num 2253 || reg == F10_num || reg == F10_H_num 2254 || reg == F11_num || reg == F11_H_num 2255 || reg == F12_num || reg == F12_H_num 2256 || reg == F13_num || reg == F13_H_num) 2257 return true; 2258 2259 return false; 2260 } 2261 2262 bool Matcher::is_spillable_arg(int reg) { 2263 return can_be_java_arg(reg); 2264 } 2265 2266 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2267 return false; 2268 } 2269 2270 // Register for DIVI projection of divmodI. 2271 RegMask Matcher::divI_proj_mask() { 2272 ShouldNotReachHere(); 2273 return RegMask(); 2274 } 2275 2276 // Register for MODI projection of divmodI. 2277 RegMask Matcher::modI_proj_mask() { 2278 ShouldNotReachHere(); 2279 return RegMask(); 2280 } 2281 2282 // Register for DIVL projection of divmodL. 2283 RegMask Matcher::divL_proj_mask() { 2284 ShouldNotReachHere(); 2285 return RegMask(); 2286 } 2287 2288 // Register for MODL projection of divmodL. 2289 RegMask Matcher::modL_proj_mask() { 2290 ShouldNotReachHere(); 2291 return RegMask(); 2292 } 2293 2294 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2295 return RegMask(); 2296 } 2297 2298 const bool Matcher::convi2l_type_required = true; 2299 2300 %} 2301 2302 //----------ENCODING BLOCK----------------------------------------------------- 2303 // This block specifies the encoding classes used by the compiler to output 2304 // byte streams. Encoding classes are parameterized macros used by 2305 // Machine Instruction Nodes in order to generate the bit encoding of the 2306 // instruction. Operands specify their base encoding interface with the 2307 // interface keyword. There are currently supported four interfaces, 2308 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2309 // operand to generate a function which returns its register number when 2310 // queried. CONST_INTER causes an operand to generate a function which 2311 // returns the value of the constant when queried. MEMORY_INTER causes an 2312 // operand to generate four functions which return the Base Register, the 2313 // Index Register, the Scale Value, and the Offset Value of the operand when 2314 // queried. COND_INTER causes an operand to generate six functions which 2315 // return the encoding code (ie - encoding bits for the instruction) 2316 // associated with each basic boolean condition for a conditional instruction. 2317 // 2318 // Instructions specify two basic values for encoding. Again, a function 2319 // is available to check if the constant displacement is an oop. They use the 2320 // ins_encode keyword to specify their encoding classes (which must be 2321 // a sequence of enc_class names, and their parameters, specified in 2322 // the encoding block), and they use the 2323 // opcode keyword to specify, in order, their primary, secondary, and 2324 // tertiary opcode. Only the opcode sections which a particular instruction 2325 // needs for encoding need to be specified. 2326 encode %{ 2327 enc_class enc_unimplemented %{ 2328 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2329 MacroAssembler _masm(&cbuf); 2330 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2331 %} 2332 2333 enc_class enc_untested %{ 2334 #ifdef ASSERT 2335 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2336 MacroAssembler _masm(&cbuf); 2337 __ untested("Untested mach node encoding in AD file."); 2338 #else 2339 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2340 #endif 2341 %} 2342 2343 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2344 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2345 MacroAssembler _masm(&cbuf); 2346 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2347 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2348 %} 2349 2350 // Load acquire. 2351 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2352 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2353 MacroAssembler _masm(&cbuf); 2354 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2355 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2356 __ twi_0($dst$$Register); 2357 __ isync(); 2358 %} 2359 2360 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2361 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2362 2363 MacroAssembler _masm(&cbuf); 2364 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2365 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2366 %} 2367 2368 // Load acquire. 2369 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2370 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2371 2372 MacroAssembler _masm(&cbuf); 2373 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2374 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2375 __ twi_0($dst$$Register); 2376 __ isync(); 2377 %} 2378 2379 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2380 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2381 2382 MacroAssembler _masm(&cbuf); 2383 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2384 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2385 %} 2386 2387 // Load acquire. 2388 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2389 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2390 2391 MacroAssembler _masm(&cbuf); 2392 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2393 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2394 __ twi_0($dst$$Register); 2395 __ isync(); 2396 %} 2397 2398 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2399 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2400 MacroAssembler _masm(&cbuf); 2401 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2402 // Operand 'ds' requires 4-alignment. 2403 assert((Idisp & 0x3) == 0, "unaligned offset"); 2404 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2405 %} 2406 2407 // Load acquire. 2408 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2409 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2410 MacroAssembler _masm(&cbuf); 2411 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2412 // Operand 'ds' requires 4-alignment. 2413 assert((Idisp & 0x3) == 0, "unaligned offset"); 2414 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2415 __ twi_0($dst$$Register); 2416 __ isync(); 2417 %} 2418 2419 enc_class enc_lfd(RegF dst, memory mem) %{ 2420 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2421 MacroAssembler _masm(&cbuf); 2422 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2423 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2424 %} 2425 2426 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2427 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2428 2429 MacroAssembler _masm(&cbuf); 2430 int toc_offset = 0; 2431 2432 address const_toc_addr; 2433 // Create a non-oop constant, no relocation needed. 2434 // If it is an IC, it has a virtual_call_Relocation. 2435 const_toc_addr = __ long_constant((jlong)$src$$constant); 2436 if (const_toc_addr == NULL) { 2437 ciEnv::current()->record_out_of_memory_failure(); 2438 return; 2439 } 2440 2441 // Get the constant's TOC offset. 2442 toc_offset = __ offset_to_method_toc(const_toc_addr); 2443 2444 // Keep the current instruction offset in mind. 2445 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2446 2447 __ ld($dst$$Register, toc_offset, $toc$$Register); 2448 %} 2449 2450 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2451 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2452 2453 MacroAssembler _masm(&cbuf); 2454 2455 if (!ra_->C->in_scratch_emit_size()) { 2456 address const_toc_addr; 2457 // Create a non-oop constant, no relocation needed. 2458 // If it is an IC, it has a virtual_call_Relocation. 2459 const_toc_addr = __ long_constant((jlong)$src$$constant); 2460 if (const_toc_addr == NULL) { 2461 ciEnv::current()->record_out_of_memory_failure(); 2462 return; 2463 } 2464 2465 // Get the constant's TOC offset. 2466 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2467 // Store the toc offset of the constant. 2468 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2469 2470 // Also keep the current instruction offset in mind. 2471 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2472 } 2473 2474 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2475 %} 2476 2477 %} // encode 2478 2479 source %{ 2480 2481 typedef struct { 2482 loadConL_hiNode *_large_hi; 2483 loadConL_loNode *_large_lo; 2484 loadConLNode *_small; 2485 MachNode *_last; 2486 } loadConLNodesTuple; 2487 2488 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2489 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2490 loadConLNodesTuple nodes; 2491 2492 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2493 if (large_constant_pool) { 2494 // Create new nodes. 2495 loadConL_hiNode *m1 = new loadConL_hiNode(); 2496 loadConL_loNode *m2 = new loadConL_loNode(); 2497 2498 // inputs for new nodes 2499 m1->add_req(NULL, toc); 2500 m2->add_req(NULL, m1); 2501 2502 // operands for new nodes 2503 m1->_opnds[0] = new iRegLdstOper(); // dst 2504 m1->_opnds[1] = immSrc; // src 2505 m1->_opnds[2] = new iRegPdstOper(); // toc 2506 m2->_opnds[0] = new iRegLdstOper(); // dst 2507 m2->_opnds[1] = immSrc; // src 2508 m2->_opnds[2] = new iRegLdstOper(); // base 2509 2510 // Initialize ins_attrib TOC fields. 2511 m1->_const_toc_offset = -1; 2512 m2->_const_toc_offset_hi_node = m1; 2513 2514 // Initialize ins_attrib instruction offset. 2515 m1->_cbuf_insts_offset = -1; 2516 2517 // register allocation for new nodes 2518 ra_->set_pair(m1->_idx, reg_second, reg_first); 2519 ra_->set_pair(m2->_idx, reg_second, reg_first); 2520 2521 // Create result. 2522 nodes._large_hi = m1; 2523 nodes._large_lo = m2; 2524 nodes._small = NULL; 2525 nodes._last = nodes._large_lo; 2526 assert(m2->bottom_type()->isa_long(), "must be long"); 2527 } else { 2528 loadConLNode *m2 = new loadConLNode(); 2529 2530 // inputs for new nodes 2531 m2->add_req(NULL, toc); 2532 2533 // operands for new nodes 2534 m2->_opnds[0] = new iRegLdstOper(); // dst 2535 m2->_opnds[1] = immSrc; // src 2536 m2->_opnds[2] = new iRegPdstOper(); // toc 2537 2538 // Initialize ins_attrib instruction offset. 2539 m2->_cbuf_insts_offset = -1; 2540 2541 // register allocation for new nodes 2542 ra_->set_pair(m2->_idx, reg_second, reg_first); 2543 2544 // Create result. 2545 nodes._large_hi = NULL; 2546 nodes._large_lo = NULL; 2547 nodes._small = m2; 2548 nodes._last = nodes._small; 2549 assert(m2->bottom_type()->isa_long(), "must be long"); 2550 } 2551 2552 return nodes; 2553 } 2554 2555 %} // source 2556 2557 encode %{ 2558 // Postalloc expand emitter for loading a long constant from the method's TOC. 2559 // Enc_class needed as consttanttablebase is not supported by postalloc 2560 // expand. 2561 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2562 // Create new nodes. 2563 loadConLNodesTuple loadConLNodes = 2564 loadConLNodesTuple_create(ra_, n_toc, op_src, 2565 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2566 2567 // Push new nodes. 2568 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2569 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2570 2571 // some asserts 2572 assert(nodes->length() >= 1, "must have created at least 1 node"); 2573 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2574 %} 2575 2576 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2577 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2578 2579 MacroAssembler _masm(&cbuf); 2580 int toc_offset = 0; 2581 2582 intptr_t val = $src$$constant; 2583 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2584 address const_toc_addr; 2585 if (constant_reloc == relocInfo::oop_type) { 2586 // Create an oop constant and a corresponding relocation. 2587 AddressLiteral a = __ allocate_oop_address((jobject)val); 2588 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2589 __ relocate(a.rspec()); 2590 } else if (constant_reloc == relocInfo::metadata_type) { 2591 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2592 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2593 __ relocate(a.rspec()); 2594 } else { 2595 // Create a non-oop constant, no relocation needed. 2596 const_toc_addr = __ long_constant((jlong)$src$$constant); 2597 } 2598 2599 if (const_toc_addr == NULL) { 2600 ciEnv::current()->record_out_of_memory_failure(); 2601 return; 2602 } 2603 // Get the constant's TOC offset. 2604 toc_offset = __ offset_to_method_toc(const_toc_addr); 2605 2606 __ ld($dst$$Register, toc_offset, $toc$$Register); 2607 %} 2608 2609 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2610 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2611 2612 MacroAssembler _masm(&cbuf); 2613 if (!ra_->C->in_scratch_emit_size()) { 2614 intptr_t val = $src$$constant; 2615 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2616 address const_toc_addr; 2617 if (constant_reloc == relocInfo::oop_type) { 2618 // Create an oop constant and a corresponding relocation. 2619 AddressLiteral a = __ allocate_oop_address((jobject)val); 2620 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2621 __ relocate(a.rspec()); 2622 } else if (constant_reloc == relocInfo::metadata_type) { 2623 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2624 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2625 __ relocate(a.rspec()); 2626 } else { // non-oop pointers, e.g. card mark base, heap top 2627 // Create a non-oop constant, no relocation needed. 2628 const_toc_addr = __ long_constant((jlong)$src$$constant); 2629 } 2630 2631 if (const_toc_addr == NULL) { 2632 ciEnv::current()->record_out_of_memory_failure(); 2633 return; 2634 } 2635 // Get the constant's TOC offset. 2636 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2637 // Store the toc offset of the constant. 2638 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 2639 } 2640 2641 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2642 %} 2643 2644 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 2645 // Enc_class needed as consttanttablebase is not supported by postalloc 2646 // expand. 2647 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 2648 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2649 if (large_constant_pool) { 2650 // Create new nodes. 2651 loadConP_hiNode *m1 = new loadConP_hiNode(); 2652 loadConP_loNode *m2 = new loadConP_loNode(); 2653 2654 // inputs for new nodes 2655 m1->add_req(NULL, n_toc); 2656 m2->add_req(NULL, m1); 2657 2658 // operands for new nodes 2659 m1->_opnds[0] = new iRegPdstOper(); // dst 2660 m1->_opnds[1] = op_src; // src 2661 m1->_opnds[2] = new iRegPdstOper(); // toc 2662 m2->_opnds[0] = new iRegPdstOper(); // dst 2663 m2->_opnds[1] = op_src; // src 2664 m2->_opnds[2] = new iRegLdstOper(); // base 2665 2666 // Initialize ins_attrib TOC fields. 2667 m1->_const_toc_offset = -1; 2668 m2->_const_toc_offset_hi_node = m1; 2669 2670 // Register allocation for new nodes. 2671 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2672 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2673 2674 nodes->push(m1); 2675 nodes->push(m2); 2676 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2677 } else { 2678 loadConPNode *m2 = new loadConPNode(); 2679 2680 // inputs for new nodes 2681 m2->add_req(NULL, n_toc); 2682 2683 // operands for new nodes 2684 m2->_opnds[0] = new iRegPdstOper(); // dst 2685 m2->_opnds[1] = op_src; // src 2686 m2->_opnds[2] = new iRegPdstOper(); // toc 2687 2688 // Register allocation for new nodes. 2689 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2690 2691 nodes->push(m2); 2692 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2693 } 2694 %} 2695 2696 // Enc_class needed as consttanttablebase is not supported by postalloc 2697 // expand. 2698 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 2699 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2700 2701 MachNode *m2; 2702 if (large_constant_pool) { 2703 m2 = new loadConFCompNode(); 2704 } else { 2705 m2 = new loadConFNode(); 2706 } 2707 // inputs for new nodes 2708 m2->add_req(NULL, n_toc); 2709 2710 // operands for new nodes 2711 m2->_opnds[0] = op_dst; 2712 m2->_opnds[1] = op_src; 2713 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2714 2715 // register allocation for new nodes 2716 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2717 nodes->push(m2); 2718 %} 2719 2720 // Enc_class needed as consttanttablebase is not supported by postalloc 2721 // expand. 2722 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 2723 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2724 2725 MachNode *m2; 2726 if (large_constant_pool) { 2727 m2 = new loadConDCompNode(); 2728 } else { 2729 m2 = new loadConDNode(); 2730 } 2731 // inputs for new nodes 2732 m2->add_req(NULL, n_toc); 2733 2734 // operands for new nodes 2735 m2->_opnds[0] = op_dst; 2736 m2->_opnds[1] = op_src; 2737 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2738 2739 // register allocation for new nodes 2740 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2741 nodes->push(m2); 2742 %} 2743 2744 enc_class enc_stw(iRegIsrc src, memory mem) %{ 2745 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 2746 MacroAssembler _masm(&cbuf); 2747 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2748 __ stw($src$$Register, Idisp, $mem$$base$$Register); 2749 %} 2750 2751 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 2752 // TODO: PPC port $archOpcode(ppc64Opcode_std); 2753 MacroAssembler _masm(&cbuf); 2754 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2755 // Operand 'ds' requires 4-alignment. 2756 assert((Idisp & 0x3) == 0, "unaligned offset"); 2757 __ std($src$$Register, Idisp, $mem$$base$$Register); 2758 %} 2759 2760 enc_class enc_stfs(RegF src, memory mem) %{ 2761 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 2762 MacroAssembler _masm(&cbuf); 2763 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2764 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 2765 %} 2766 2767 enc_class enc_stfd(RegF src, memory mem) %{ 2768 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 2769 MacroAssembler _masm(&cbuf); 2770 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2771 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 2772 %} 2773 2774 // Use release_store for card-marking to ensure that previous 2775 // oop-stores are visible before the card-mark change. 2776 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 2777 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2778 // FIXME: Implement this as a cmove and use a fixed condition code 2779 // register which is written on every transition to compiled code, 2780 // e.g. in call-stub and when returning from runtime stubs. 2781 // 2782 // Proposed code sequence for the cmove implementation: 2783 // 2784 // Label skip_release; 2785 // __ beq(CCRfixed, skip_release); 2786 // __ release(); 2787 // __ bind(skip_release); 2788 // __ stb(card mark); 2789 2790 MacroAssembler _masm(&cbuf); 2791 Label skip_storestore; 2792 2793 #if 0 // TODO: PPC port 2794 // Check CMSCollectorCardTableModRefBSExt::_requires_release and do the 2795 // StoreStore barrier conditionally. 2796 __ lwz(R0, 0, $releaseFieldAddr$$Register); 2797 __ cmpwi($crx$$CondRegister, R0, 0); 2798 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 2799 #endif 2800 __ li(R0, 0); 2801 __ membar(Assembler::StoreStore); 2802 #if 0 // TODO: PPC port 2803 __ bind(skip_storestore); 2804 #endif 2805 2806 // Do the store. 2807 if ($mem$$index == 0) { 2808 __ stb(R0, $mem$$disp, $mem$$base$$Register); 2809 } else { 2810 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 2811 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 2812 } 2813 %} 2814 2815 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 2816 2817 if (VM_Version::has_isel()) { 2818 // use isel instruction with Power 7 2819 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2820 encodeP_subNode *n_sub_base = new encodeP_subNode(); 2821 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2822 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 2823 2824 n_compare->add_req(n_region, n_src); 2825 n_compare->_opnds[0] = op_crx; 2826 n_compare->_opnds[1] = op_src; 2827 n_compare->_opnds[2] = new immL16Oper(0); 2828 2829 n_sub_base->add_req(n_region, n_src); 2830 n_sub_base->_opnds[0] = op_dst; 2831 n_sub_base->_opnds[1] = op_src; 2832 n_sub_base->_bottom_type = _bottom_type; 2833 2834 n_shift->add_req(n_region, n_sub_base); 2835 n_shift->_opnds[0] = op_dst; 2836 n_shift->_opnds[1] = op_dst; 2837 n_shift->_bottom_type = _bottom_type; 2838 2839 n_cond_set->add_req(n_region, n_compare, n_shift); 2840 n_cond_set->_opnds[0] = op_dst; 2841 n_cond_set->_opnds[1] = op_crx; 2842 n_cond_set->_opnds[2] = op_dst; 2843 n_cond_set->_bottom_type = _bottom_type; 2844 2845 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2846 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2847 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2848 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2849 2850 nodes->push(n_compare); 2851 nodes->push(n_sub_base); 2852 nodes->push(n_shift); 2853 nodes->push(n_cond_set); 2854 2855 } else { 2856 // before Power 7 2857 moveRegNode *n_move = new moveRegNode(); 2858 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2859 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2860 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 2861 2862 n_move->add_req(n_region, n_src); 2863 n_move->_opnds[0] = op_dst; 2864 n_move->_opnds[1] = op_src; 2865 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 2866 2867 n_compare->add_req(n_region, n_src); 2868 n_compare->add_prec(n_move); 2869 2870 n_compare->_opnds[0] = op_crx; 2871 n_compare->_opnds[1] = op_src; 2872 n_compare->_opnds[2] = new immL16Oper(0); 2873 2874 n_sub_base->add_req(n_region, n_compare, n_src); 2875 n_sub_base->_opnds[0] = op_dst; 2876 n_sub_base->_opnds[1] = op_crx; 2877 n_sub_base->_opnds[2] = op_src; 2878 n_sub_base->_bottom_type = _bottom_type; 2879 2880 n_shift->add_req(n_region, n_sub_base); 2881 n_shift->_opnds[0] = op_dst; 2882 n_shift->_opnds[1] = op_dst; 2883 n_shift->_bottom_type = _bottom_type; 2884 2885 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2886 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2887 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2888 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2889 2890 nodes->push(n_move); 2891 nodes->push(n_compare); 2892 nodes->push(n_sub_base); 2893 nodes->push(n_shift); 2894 } 2895 2896 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 2897 %} 2898 2899 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 2900 2901 encodeP_subNode *n1 = new encodeP_subNode(); 2902 n1->add_req(n_region, n_src); 2903 n1->_opnds[0] = op_dst; 2904 n1->_opnds[1] = op_src; 2905 n1->_bottom_type = _bottom_type; 2906 2907 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 2908 n2->add_req(n_region, n1); 2909 n2->_opnds[0] = op_dst; 2910 n2->_opnds[1] = op_dst; 2911 n2->_bottom_type = _bottom_type; 2912 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2913 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2914 2915 nodes->push(n1); 2916 nodes->push(n2); 2917 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 2918 %} 2919 2920 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 2921 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 2922 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 2923 2924 n_compare->add_req(n_region, n_src); 2925 n_compare->_opnds[0] = op_crx; 2926 n_compare->_opnds[1] = op_src; 2927 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 2928 2929 n_shift->add_req(n_region, n_src); 2930 n_shift->_opnds[0] = op_dst; 2931 n_shift->_opnds[1] = op_src; 2932 n_shift->_bottom_type = _bottom_type; 2933 2934 if (VM_Version::has_isel()) { 2935 // use isel instruction with Power 7 2936 2937 decodeN_addNode *n_add_base = new decodeN_addNode(); 2938 n_add_base->add_req(n_region, n_shift); 2939 n_add_base->_opnds[0] = op_dst; 2940 n_add_base->_opnds[1] = op_dst; 2941 n_add_base->_bottom_type = _bottom_type; 2942 2943 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 2944 n_cond_set->add_req(n_region, n_compare, n_add_base); 2945 n_cond_set->_opnds[0] = op_dst; 2946 n_cond_set->_opnds[1] = op_crx; 2947 n_cond_set->_opnds[2] = op_dst; 2948 n_cond_set->_bottom_type = _bottom_type; 2949 2950 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 2951 ra_->set_oop(n_cond_set, true); 2952 2953 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2954 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2955 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2956 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2957 2958 nodes->push(n_compare); 2959 nodes->push(n_shift); 2960 nodes->push(n_add_base); 2961 nodes->push(n_cond_set); 2962 2963 } else { 2964 // before Power 7 2965 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 2966 2967 n_add_base->add_req(n_region, n_compare, n_shift); 2968 n_add_base->_opnds[0] = op_dst; 2969 n_add_base->_opnds[1] = op_crx; 2970 n_add_base->_opnds[2] = op_dst; 2971 n_add_base->_bottom_type = _bottom_type; 2972 2973 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 2974 ra_->set_oop(n_add_base, true); 2975 2976 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2977 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2978 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2979 2980 nodes->push(n_compare); 2981 nodes->push(n_shift); 2982 nodes->push(n_add_base); 2983 } 2984 %} 2985 2986 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 2987 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 2988 n1->add_req(n_region, n_src); 2989 n1->_opnds[0] = op_dst; 2990 n1->_opnds[1] = op_src; 2991 n1->_bottom_type = _bottom_type; 2992 2993 decodeN_addNode *n2 = new decodeN_addNode(); 2994 n2->add_req(n_region, n1); 2995 n2->_opnds[0] = op_dst; 2996 n2->_opnds[1] = op_dst; 2997 n2->_bottom_type = _bottom_type; 2998 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2999 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3000 3001 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3002 ra_->set_oop(n2, true); 3003 3004 nodes->push(n1); 3005 nodes->push(n2); 3006 %} 3007 3008 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3009 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3010 3011 MacroAssembler _masm(&cbuf); 3012 int cc = $cmp$$cmpcode; 3013 int flags_reg = $crx$$reg; 3014 Label done; 3015 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3016 // Branch if not (cmp crx). 3017 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3018 __ mr($dst$$Register, $src$$Register); 3019 // TODO PPC port __ endgroup_if_needed(_size == 12); 3020 __ bind(done); 3021 %} 3022 3023 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3024 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3025 3026 MacroAssembler _masm(&cbuf); 3027 Label done; 3028 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3029 // Branch if not (cmp crx). 3030 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3031 __ li($dst$$Register, $src$$constant); 3032 // TODO PPC port __ endgroup_if_needed(_size == 12); 3033 __ bind(done); 3034 %} 3035 3036 // This enc_class is needed so that scheduler gets proper 3037 // input mapping for latency computation. 3038 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3039 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3040 MacroAssembler _masm(&cbuf); 3041 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3042 %} 3043 3044 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3045 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3046 3047 MacroAssembler _masm(&cbuf); 3048 3049 Label done; 3050 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3051 __ li($dst$$Register, $zero$$constant); 3052 __ beq($crx$$CondRegister, done); 3053 __ li($dst$$Register, $notzero$$constant); 3054 __ bind(done); 3055 %} 3056 3057 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3058 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3059 3060 MacroAssembler _masm(&cbuf); 3061 3062 Label done; 3063 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3064 __ li($dst$$Register, $zero$$constant); 3065 __ beq($crx$$CondRegister, done); 3066 __ li($dst$$Register, $notzero$$constant); 3067 __ bind(done); 3068 %} 3069 3070 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3071 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3072 3073 MacroAssembler _masm(&cbuf); 3074 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3075 Label done; 3076 __ bso($crx$$CondRegister, done); 3077 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3078 // TODO PPC port __ endgroup_if_needed(_size == 12); 3079 __ bind(done); 3080 %} 3081 3082 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3083 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3084 3085 MacroAssembler _masm(&cbuf); 3086 Label d; // dummy 3087 __ bind(d); 3088 Label* p = ($lbl$$label); 3089 // `p' is `NULL' when this encoding class is used only to 3090 // determine the size of the encoded instruction. 3091 Label& l = (NULL == p)? d : *(p); 3092 int cc = $cmp$$cmpcode; 3093 int flags_reg = $crx$$reg; 3094 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3095 int bhint = Assembler::bhintNoHint; 3096 3097 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3098 if (_prob <= PROB_NEVER) { 3099 bhint = Assembler::bhintIsNotTaken; 3100 } else if (_prob >= PROB_ALWAYS) { 3101 bhint = Assembler::bhintIsTaken; 3102 } 3103 } 3104 3105 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3106 cc_to_biint(cc, flags_reg), 3107 l); 3108 %} 3109 3110 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3111 // The scheduler doesn't know about branch shortening, so we set the opcode 3112 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3113 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3114 3115 MacroAssembler _masm(&cbuf); 3116 Label d; // dummy 3117 __ bind(d); 3118 Label* p = ($lbl$$label); 3119 // `p' is `NULL' when this encoding class is used only to 3120 // determine the size of the encoded instruction. 3121 Label& l = (NULL == p)? d : *(p); 3122 int cc = $cmp$$cmpcode; 3123 int flags_reg = $crx$$reg; 3124 int bhint = Assembler::bhintNoHint; 3125 3126 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3127 if (_prob <= PROB_NEVER) { 3128 bhint = Assembler::bhintIsNotTaken; 3129 } else if (_prob >= PROB_ALWAYS) { 3130 bhint = Assembler::bhintIsTaken; 3131 } 3132 } 3133 3134 // Tell the conditional far branch to optimize itself when being relocated. 3135 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3136 cc_to_biint(cc, flags_reg), 3137 l, 3138 MacroAssembler::bc_far_optimize_on_relocate); 3139 %} 3140 3141 // Branch used with Power6 scheduling (can be shortened without changing the node). 3142 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3143 // The scheduler doesn't know about branch shortening, so we set the opcode 3144 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3145 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3146 3147 MacroAssembler _masm(&cbuf); 3148 Label d; // dummy 3149 __ bind(d); 3150 Label* p = ($lbl$$label); 3151 // `p' is `NULL' when this encoding class is used only to 3152 // determine the size of the encoded instruction. 3153 Label& l = (NULL == p)? d : *(p); 3154 int cc = $cmp$$cmpcode; 3155 int flags_reg = $crx$$reg; 3156 int bhint = Assembler::bhintNoHint; 3157 3158 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3159 if (_prob <= PROB_NEVER) { 3160 bhint = Assembler::bhintIsNotTaken; 3161 } else if (_prob >= PROB_ALWAYS) { 3162 bhint = Assembler::bhintIsTaken; 3163 } 3164 } 3165 3166 #if 0 // TODO: PPC port 3167 if (_size == 8) { 3168 // Tell the conditional far branch to optimize itself when being relocated. 3169 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3170 cc_to_biint(cc, flags_reg), 3171 l, 3172 MacroAssembler::bc_far_optimize_on_relocate); 3173 } else { 3174 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3175 cc_to_biint(cc, flags_reg), 3176 l); 3177 } 3178 #endif 3179 Unimplemented(); 3180 %} 3181 3182 // Postalloc expand emitter for loading a replicatef float constant from 3183 // the method's TOC. 3184 // Enc_class needed as consttanttablebase is not supported by postalloc 3185 // expand. 3186 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3187 // Create new nodes. 3188 3189 // Make an operand with the bit pattern to load as float. 3190 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3191 3192 loadConLNodesTuple loadConLNodes = 3193 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3194 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3195 3196 // Push new nodes. 3197 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3198 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3199 3200 assert(nodes->length() >= 1, "must have created at least 1 node"); 3201 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3202 %} 3203 3204 // This enc_class is needed so that scheduler gets proper 3205 // input mapping for latency computation. 3206 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3207 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3208 // Fake operand dst needed for PPC scheduler. 3209 assert($dst$$constant == 0x0, "dst must be 0x0"); 3210 3211 MacroAssembler _masm(&cbuf); 3212 // Mark the code position where the load from the safepoint 3213 // polling page was emitted as relocInfo::poll_type. 3214 __ relocate(relocInfo::poll_type); 3215 __ load_from_polling_page($poll$$Register); 3216 %} 3217 3218 // A Java static call or a runtime call. 3219 // 3220 // Branch-and-link relative to a trampoline. 3221 // The trampoline loads the target address and does a long branch to there. 3222 // In case we call java, the trampoline branches to a interpreter_stub 3223 // which loads the inline cache and the real call target from the constant pool. 3224 // 3225 // This basically looks like this: 3226 // 3227 // >>>> consts -+ -+ 3228 // | |- offset1 3229 // [call target1] | <-+ 3230 // [IC cache] |- offset2 3231 // [call target2] <--+ 3232 // 3233 // <<<< consts 3234 // >>>> insts 3235 // 3236 // bl offset16 -+ -+ ??? // How many bits available? 3237 // | | 3238 // <<<< insts | | 3239 // >>>> stubs | | 3240 // | |- trampoline_stub_Reloc 3241 // trampoline stub: | <-+ 3242 // r2 = toc | 3243 // r2 = [r2 + offset1] | // Load call target1 from const section 3244 // mtctr r2 | 3245 // bctr |- static_stub_Reloc 3246 // comp_to_interp_stub: <---+ 3247 // r1 = toc 3248 // ICreg = [r1 + IC_offset] // Load IC from const section 3249 // r1 = [r1 + offset2] // Load call target2 from const section 3250 // mtctr r1 3251 // bctr 3252 // 3253 // <<<< stubs 3254 // 3255 // The call instruction in the code either 3256 // - Branches directly to a compiled method if the offset is encodable in instruction. 3257 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3258 // - Branches to the compiled_to_interp stub if the target is interpreted. 3259 // 3260 // Further there are three relocations from the loads to the constants in 3261 // the constant section. 3262 // 3263 // Usage of r1 and r2 in the stubs allows to distinguish them. 3264 enc_class enc_java_static_call(method meth) %{ 3265 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3266 3267 MacroAssembler _masm(&cbuf); 3268 address entry_point = (address)$meth$$method; 3269 3270 if (!_method) { 3271 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3272 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3273 } else { 3274 // Remember the offset not the address. 3275 const int start_offset = __ offset(); 3276 3277 // The trampoline stub. 3278 // No entry point given, use the current pc. 3279 // Make sure branch fits into 3280 if (entry_point == 0) entry_point = __ pc(); 3281 3282 // Put the entry point as a constant into the constant pool. 3283 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3284 if (entry_point_toc_addr == NULL) { 3285 ciEnv::current()->record_out_of_memory_failure(); 3286 return; 3287 } 3288 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3289 3290 // Emit the trampoline stub which will be related to the branch-and-link below. 3291 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3292 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3293 int method_index = resolved_method_index(cbuf); 3294 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3295 : static_call_Relocation::spec(method_index)); 3296 3297 // The real call. 3298 // Note: At this point we do not have the address of the trampoline 3299 // stub, and the entry point might be too far away for bl, so __ pc() 3300 // serves as dummy and the bl will be patched later. 3301 cbuf.set_insts_mark(); 3302 __ bl(__ pc()); // Emits a relocation. 3303 3304 // The stub for call to interpreter. 3305 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3306 if (stub == NULL) { 3307 ciEnv::current()->record_failure("CodeCache is full"); 3308 return; 3309 } 3310 } 3311 %} 3312 3313 // Second node of expanded dynamic call - the call. 3314 enc_class enc_java_dynamic_call_sched(method meth) %{ 3315 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3316 3317 MacroAssembler _masm(&cbuf); 3318 3319 if (!ra_->C->in_scratch_emit_size()) { 3320 // Create a call trampoline stub for the given method. 3321 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3322 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3323 if (entry_point_const == NULL) { 3324 ciEnv::current()->record_out_of_memory_failure(); 3325 return; 3326 } 3327 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3328 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3329 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3330 3331 // Build relocation at call site with ic position as data. 3332 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3333 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3334 "must have one, but can't have both"); 3335 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3336 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3337 "must contain instruction offset"); 3338 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3339 ? _load_ic_hi_node->_cbuf_insts_offset 3340 : _load_ic_node->_cbuf_insts_offset; 3341 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3342 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3343 "should be load from TOC"); 3344 int method_index = resolved_method_index(cbuf); 3345 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3346 } 3347 3348 // At this point I do not have the address of the trampoline stub, 3349 // and the entry point might be too far away for bl. Pc() serves 3350 // as dummy and bl will be patched later. 3351 __ bl((address) __ pc()); 3352 %} 3353 3354 // postalloc expand emitter for virtual calls. 3355 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3356 3357 // Create the nodes for loading the IC from the TOC. 3358 loadConLNodesTuple loadConLNodes_IC = 3359 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3360 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3361 3362 // Create the call node. 3363 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3364 call->_method_handle_invoke = _method_handle_invoke; 3365 call->_vtable_index = _vtable_index; 3366 call->_method = _method; 3367 call->_bci = _bci; 3368 call->_optimized_virtual = _optimized_virtual; 3369 call->_tf = _tf; 3370 call->_entry_point = _entry_point; 3371 call->_cnt = _cnt; 3372 call->_argsize = _argsize; 3373 call->_oop_map = _oop_map; 3374 call->_jvms = _jvms; 3375 call->_jvmadj = _jvmadj; 3376 call->_in_rms = _in_rms; 3377 call->_nesting = _nesting; 3378 call->_override_symbolic_info = _override_symbolic_info; 3379 3380 // New call needs all inputs of old call. 3381 // Req... 3382 for (uint i = 0; i < req(); ++i) { 3383 // The expanded node does not need toc any more. 3384 // Add the inline cache constant here instead. This expresses the 3385 // register of the inline cache must be live at the call. 3386 // Else we would have to adapt JVMState by -1. 3387 if (i == mach_constant_base_node_input()) { 3388 call->add_req(loadConLNodes_IC._last); 3389 } else { 3390 call->add_req(in(i)); 3391 } 3392 } 3393 // ...as well as prec 3394 for (uint i = req(); i < len(); ++i) { 3395 call->add_prec(in(i)); 3396 } 3397 3398 // Remember nodes loading the inline cache into r19. 3399 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3400 call->_load_ic_node = loadConLNodes_IC._small; 3401 3402 // Operands for new nodes. 3403 call->_opnds[0] = _opnds[0]; 3404 call->_opnds[1] = _opnds[1]; 3405 3406 // Only the inline cache is associated with a register. 3407 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3408 3409 // Push new nodes. 3410 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3411 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3412 nodes->push(call); 3413 %} 3414 3415 // Compound version of call dynamic 3416 // Toc is only passed so that it can be used in ins_encode statement. 3417 // In the code we have to use $constanttablebase. 3418 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3419 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3420 MacroAssembler _masm(&cbuf); 3421 int start_offset = __ offset(); 3422 3423 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3424 #if 0 3425 int vtable_index = this->_vtable_index; 3426 if (_vtable_index < 0) { 3427 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3428 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3429 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3430 3431 // Virtual call relocation will point to ic load. 3432 address virtual_call_meta_addr = __ pc(); 3433 // Load a clear inline cache. 3434 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3435 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3436 if (!success) { 3437 ciEnv::current()->record_out_of_memory_failure(); 3438 return; 3439 } 3440 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3441 // to determine who we intended to call. 3442 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3443 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3444 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3445 "Fix constant in ret_addr_offset()"); 3446 } else { 3447 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3448 // Go thru the vtable. Get receiver klass. Receiver already 3449 // checked for non-null. If we'll go thru a C2I adapter, the 3450 // interpreter expects method in R19_method. 3451 3452 __ load_klass(R11_scratch1, R3); 3453 3454 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3455 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3456 __ li(R19_method, v_off); 3457 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3458 // NOTE: for vtable dispatches, the vtable entry will never be 3459 // null. However it may very well end up in handle_wrong_method 3460 // if the method is abstract for the particular class. 3461 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3462 // Call target. Either compiled code or C2I adapter. 3463 __ mtctr(R11_scratch1); 3464 __ bctrl(); 3465 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3466 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3467 } 3468 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3469 "Fix constant in ret_addr_offset()"); 3470 } 3471 #endif 3472 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3473 %} 3474 3475 // a runtime call 3476 enc_class enc_java_to_runtime_call (method meth) %{ 3477 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3478 3479 MacroAssembler _masm(&cbuf); 3480 const address start_pc = __ pc(); 3481 3482 #if defined(ABI_ELFv2) 3483 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3484 __ call_c(entry, relocInfo::runtime_call_type); 3485 #else 3486 // The function we're going to call. 3487 FunctionDescriptor fdtemp; 3488 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3489 3490 Register Rtoc = R12_scratch2; 3491 // Calculate the method's TOC. 3492 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3493 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3494 // pool entries; call_c_using_toc will optimize the call. 3495 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3496 if (!success) { 3497 ciEnv::current()->record_out_of_memory_failure(); 3498 return; 3499 } 3500 #endif 3501 3502 // Check the ret_addr_offset. 3503 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3504 "Fix constant in ret_addr_offset()"); 3505 %} 3506 3507 // Move to ctr for leaf call. 3508 // This enc_class is needed so that scheduler gets proper 3509 // input mapping for latency computation. 3510 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3511 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3512 MacroAssembler _masm(&cbuf); 3513 __ mtctr($src$$Register); 3514 %} 3515 3516 // Postalloc expand emitter for runtime leaf calls. 3517 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3518 loadConLNodesTuple loadConLNodes_Entry; 3519 #if defined(ABI_ELFv2) 3520 jlong entry_address = (jlong) this->entry_point(); 3521 assert(entry_address, "need address here"); 3522 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3523 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3524 #else 3525 // Get the struct that describes the function we are about to call. 3526 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3527 assert(fd, "need fd here"); 3528 jlong entry_address = (jlong) fd->entry(); 3529 // new nodes 3530 loadConLNodesTuple loadConLNodes_Env; 3531 loadConLNodesTuple loadConLNodes_Toc; 3532 3533 // Create nodes and operands for loading the entry point. 3534 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3535 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3536 3537 3538 // Create nodes and operands for loading the env pointer. 3539 if (fd->env() != NULL) { 3540 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3541 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3542 } else { 3543 loadConLNodes_Env._large_hi = NULL; 3544 loadConLNodes_Env._large_lo = NULL; 3545 loadConLNodes_Env._small = NULL; 3546 loadConLNodes_Env._last = new loadConL16Node(); 3547 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3548 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3549 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3550 } 3551 3552 // Create nodes and operands for loading the Toc point. 3553 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3554 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3555 #endif // ABI_ELFv2 3556 // mtctr node 3557 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3558 3559 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3560 mtctr->add_req(0, loadConLNodes_Entry._last); 3561 3562 mtctr->_opnds[0] = new iRegLdstOper(); 3563 mtctr->_opnds[1] = new iRegLdstOper(); 3564 3565 // call node 3566 MachCallLeafNode *call = new CallLeafDirectNode(); 3567 3568 call->_opnds[0] = _opnds[0]; 3569 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3570 3571 // Make the new call node look like the old one. 3572 call->_name = _name; 3573 call->_tf = _tf; 3574 call->_entry_point = _entry_point; 3575 call->_cnt = _cnt; 3576 call->_argsize = _argsize; 3577 call->_oop_map = _oop_map; 3578 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3579 call->_jvms = NULL; 3580 call->_jvmadj = _jvmadj; 3581 call->_in_rms = _in_rms; 3582 call->_nesting = _nesting; 3583 3584 3585 // New call needs all inputs of old call. 3586 // Req... 3587 for (uint i = 0; i < req(); ++i) { 3588 if (i != mach_constant_base_node_input()) { 3589 call->add_req(in(i)); 3590 } 3591 } 3592 3593 // These must be reqired edges, as the registers are live up to 3594 // the call. Else the constants are handled as kills. 3595 call->add_req(mtctr); 3596 #if !defined(ABI_ELFv2) 3597 call->add_req(loadConLNodes_Env._last); 3598 call->add_req(loadConLNodes_Toc._last); 3599 #endif 3600 3601 // ...as well as prec 3602 for (uint i = req(); i < len(); ++i) { 3603 call->add_prec(in(i)); 3604 } 3605 3606 // registers 3607 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 3608 3609 // Insert the new nodes. 3610 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 3611 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 3612 #if !defined(ABI_ELFv2) 3613 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 3614 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 3615 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 3616 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 3617 #endif 3618 nodes->push(mtctr); 3619 nodes->push(call); 3620 %} 3621 %} 3622 3623 //----------FRAME-------------------------------------------------------------- 3624 // Definition of frame structure and management information. 3625 3626 frame %{ 3627 // What direction does stack grow in (assumed to be same for native & Java). 3628 stack_direction(TOWARDS_LOW); 3629 3630 // These two registers define part of the calling convention between 3631 // compiled code and the interpreter. 3632 3633 // Inline Cache Register or method for I2C. 3634 inline_cache_reg(R19); // R19_method 3635 3636 // Method Oop Register when calling interpreter. 3637 interpreter_method_oop_reg(R19); // R19_method 3638 3639 // Optional: name the operand used by cisc-spilling to access 3640 // [stack_pointer + offset]. 3641 cisc_spilling_operand_name(indOffset); 3642 3643 // Number of stack slots consumed by a Monitor enter. 3644 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 3645 3646 // Compiled code's Frame Pointer. 3647 frame_pointer(R1); // R1_SP 3648 3649 // Interpreter stores its frame pointer in a register which is 3650 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 3651 // interpreted java to compiled java. 3652 // 3653 // R14_state holds pointer to caller's cInterpreter. 3654 interpreter_frame_pointer(R14); // R14_state 3655 3656 stack_alignment(frame::alignment_in_bytes); 3657 3658 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 3659 3660 // Number of outgoing stack slots killed above the 3661 // out_preserve_stack_slots for calls to C. Supports the var-args 3662 // backing area for register parms. 3663 // 3664 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 3665 3666 // The after-PROLOG location of the return address. Location of 3667 // return address specifies a type (REG or STACK) and a number 3668 // representing the register number (i.e. - use a register name) or 3669 // stack slot. 3670 // 3671 // A: Link register is stored in stack slot ... 3672 // M: ... but it's in the caller's frame according to PPC-64 ABI. 3673 // J: Therefore, we make sure that the link register is also in R11_scratch1 3674 // at the end of the prolog. 3675 // B: We use R20, now. 3676 //return_addr(REG R20); 3677 3678 // G: After reading the comments made by all the luminaries on their 3679 // failure to tell the compiler where the return address really is, 3680 // I hardly dare to try myself. However, I'm convinced it's in slot 3681 // 4 what apparently works and saves us some spills. 3682 return_addr(STACK 4); 3683 3684 // This is the body of the function 3685 // 3686 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 3687 // uint length, // length of array 3688 // bool is_outgoing) 3689 // 3690 // The `sig' array is to be updated. sig[j] represents the location 3691 // of the j-th argument, either a register or a stack slot. 3692 3693 // Comment taken from i486.ad: 3694 // Body of function which returns an integer array locating 3695 // arguments either in registers or in stack slots. Passed an array 3696 // of ideal registers called "sig" and a "length" count. Stack-slot 3697 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3698 // arguments for a CALLEE. Incoming stack arguments are 3699 // automatically biased by the preserve_stack_slots field above. 3700 calling_convention %{ 3701 // No difference between ingoing/outgoing. Just pass false. 3702 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3703 %} 3704 3705 // Comment taken from i486.ad: 3706 // Body of function which returns an integer array locating 3707 // arguments either in registers or in stack slots. Passed an array 3708 // of ideal registers called "sig" and a "length" count. Stack-slot 3709 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3710 // arguments for a CALLEE. Incoming stack arguments are 3711 // automatically biased by the preserve_stack_slots field above. 3712 c_calling_convention %{ 3713 // This is obviously always outgoing. 3714 // C argument in register AND stack slot. 3715 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 3716 %} 3717 3718 // Location of native (C/C++) and interpreter return values. This 3719 // is specified to be the same as Java. In the 32-bit VM, long 3720 // values are actually returned from native calls in O0:O1 and 3721 // returned to the interpreter in I0:I1. The copying to and from 3722 // the register pairs is done by the appropriate call and epilog 3723 // opcodes. This simplifies the register allocator. 3724 c_return_value %{ 3725 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3726 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 3727 "only return normal values"); 3728 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3729 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3730 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3731 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3732 %} 3733 3734 // Location of compiled Java return values. Same as C 3735 return_value %{ 3736 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3737 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 3738 "only return normal values"); 3739 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3740 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3741 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3742 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3743 %} 3744 %} 3745 3746 3747 //----------ATTRIBUTES--------------------------------------------------------- 3748 3749 //----------Operand Attributes------------------------------------------------- 3750 op_attrib op_cost(1); // Required cost attribute. 3751 3752 //----------Instruction Attributes--------------------------------------------- 3753 3754 // Cost attribute. required. 3755 ins_attrib ins_cost(DEFAULT_COST); 3756 3757 // Is this instruction a non-matching short branch variant of some 3758 // long branch? Not required. 3759 ins_attrib ins_short_branch(0); 3760 3761 ins_attrib ins_is_TrapBasedCheckNode(true); 3762 3763 // Number of constants. 3764 // This instruction uses the given number of constants 3765 // (optional attribute). 3766 // This is needed to determine in time whether the constant pool will 3767 // exceed 4000 entries. Before postalloc_expand the overall number of constants 3768 // is determined. It's also used to compute the constant pool size 3769 // in Output(). 3770 ins_attrib ins_num_consts(0); 3771 3772 // Required alignment attribute (must be a power of 2) specifies the 3773 // alignment that some part of the instruction (not necessarily the 3774 // start) requires. If > 1, a compute_padding() function must be 3775 // provided for the instruction. 3776 ins_attrib ins_alignment(1); 3777 3778 // Enforce/prohibit rematerializations. 3779 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 3780 // then rematerialization of that instruction is prohibited and the 3781 // instruction's value will be spilled if necessary. 3782 // Causes that MachNode::rematerialize() returns false. 3783 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 3784 // then rematerialization should be enforced and a copy of the instruction 3785 // should be inserted if possible; rematerialization is not guaranteed. 3786 // Note: this may result in rematerializations in front of every use. 3787 // Causes that MachNode::rematerialize() can return true. 3788 // (optional attribute) 3789 ins_attrib ins_cannot_rematerialize(false); 3790 ins_attrib ins_should_rematerialize(false); 3791 3792 // Instruction has variable size depending on alignment. 3793 ins_attrib ins_variable_size_depending_on_alignment(false); 3794 3795 // Instruction is a nop. 3796 ins_attrib ins_is_nop(false); 3797 3798 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 3799 ins_attrib ins_use_mach_if_fast_lock_node(false); 3800 3801 // Field for the toc offset of a constant. 3802 // 3803 // This is needed if the toc offset is not encodable as an immediate in 3804 // the PPC load instruction. If so, the upper (hi) bits of the offset are 3805 // added to the toc, and from this a load with immediate is performed. 3806 // With postalloc expand, we get two nodes that require the same offset 3807 // but which don't know about each other. The offset is only known 3808 // when the constant is added to the constant pool during emitting. 3809 // It is generated in the 'hi'-node adding the upper bits, and saved 3810 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 3811 // the offset from there when it gets encoded. 3812 ins_attrib ins_field_const_toc_offset(0); 3813 ins_attrib ins_field_const_toc_offset_hi_node(0); 3814 3815 // A field that can hold the instructions offset in the code buffer. 3816 // Set in the nodes emitter. 3817 ins_attrib ins_field_cbuf_insts_offset(-1); 3818 3819 // Fields for referencing a call's load-IC-node. 3820 // If the toc offset can not be encoded as an immediate in a load, we 3821 // use two nodes. 3822 ins_attrib ins_field_load_ic_hi_node(0); 3823 ins_attrib ins_field_load_ic_node(0); 3824 3825 //----------OPERANDS----------------------------------------------------------- 3826 // Operand definitions must precede instruction definitions for correct 3827 // parsing in the ADLC because operands constitute user defined types 3828 // which are used in instruction definitions. 3829 // 3830 // Formats are generated automatically for constants and base registers. 3831 3832 //----------Simple Operands---------------------------------------------------- 3833 // Immediate Operands 3834 3835 // Integer Immediate: 32-bit 3836 operand immI() %{ 3837 match(ConI); 3838 op_cost(40); 3839 format %{ %} 3840 interface(CONST_INTER); 3841 %} 3842 3843 operand immI8() %{ 3844 predicate(Assembler::is_simm(n->get_int(), 8)); 3845 op_cost(0); 3846 match(ConI); 3847 format %{ %} 3848 interface(CONST_INTER); 3849 %} 3850 3851 // Integer Immediate: 16-bit 3852 operand immI16() %{ 3853 predicate(Assembler::is_simm(n->get_int(), 16)); 3854 op_cost(0); 3855 match(ConI); 3856 format %{ %} 3857 interface(CONST_INTER); 3858 %} 3859 3860 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 3861 operand immIhi16() %{ 3862 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 3863 match(ConI); 3864 op_cost(0); 3865 format %{ %} 3866 interface(CONST_INTER); 3867 %} 3868 3869 operand immInegpow2() %{ 3870 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 3871 match(ConI); 3872 op_cost(0); 3873 format %{ %} 3874 interface(CONST_INTER); 3875 %} 3876 3877 operand immIpow2minus1() %{ 3878 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 3879 match(ConI); 3880 op_cost(0); 3881 format %{ %} 3882 interface(CONST_INTER); 3883 %} 3884 3885 operand immIpowerOf2() %{ 3886 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 3887 match(ConI); 3888 op_cost(0); 3889 format %{ %} 3890 interface(CONST_INTER); 3891 %} 3892 3893 // Unsigned Integer Immediate: the values 0-31 3894 operand uimmI5() %{ 3895 predicate(Assembler::is_uimm(n->get_int(), 5)); 3896 match(ConI); 3897 op_cost(0); 3898 format %{ %} 3899 interface(CONST_INTER); 3900 %} 3901 3902 // Unsigned Integer Immediate: 6-bit 3903 operand uimmI6() %{ 3904 predicate(Assembler::is_uimm(n->get_int(), 6)); 3905 match(ConI); 3906 op_cost(0); 3907 format %{ %} 3908 interface(CONST_INTER); 3909 %} 3910 3911 // Unsigned Integer Immediate: 6-bit int, greater than 32 3912 operand uimmI6_ge32() %{ 3913 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 3914 match(ConI); 3915 op_cost(0); 3916 format %{ %} 3917 interface(CONST_INTER); 3918 %} 3919 3920 // Unsigned Integer Immediate: 15-bit 3921 operand uimmI15() %{ 3922 predicate(Assembler::is_uimm(n->get_int(), 15)); 3923 match(ConI); 3924 op_cost(0); 3925 format %{ %} 3926 interface(CONST_INTER); 3927 %} 3928 3929 // Unsigned Integer Immediate: 16-bit 3930 operand uimmI16() %{ 3931 predicate(Assembler::is_uimm(n->get_int(), 16)); 3932 match(ConI); 3933 op_cost(0); 3934 format %{ %} 3935 interface(CONST_INTER); 3936 %} 3937 3938 // constant 'int 0'. 3939 operand immI_0() %{ 3940 predicate(n->get_int() == 0); 3941 match(ConI); 3942 op_cost(0); 3943 format %{ %} 3944 interface(CONST_INTER); 3945 %} 3946 3947 // constant 'int 1'. 3948 operand immI_1() %{ 3949 predicate(n->get_int() == 1); 3950 match(ConI); 3951 op_cost(0); 3952 format %{ %} 3953 interface(CONST_INTER); 3954 %} 3955 3956 // constant 'int -1'. 3957 operand immI_minus1() %{ 3958 predicate(n->get_int() == -1); 3959 match(ConI); 3960 op_cost(0); 3961 format %{ %} 3962 interface(CONST_INTER); 3963 %} 3964 3965 // int value 16. 3966 operand immI_16() %{ 3967 predicate(n->get_int() == 16); 3968 match(ConI); 3969 op_cost(0); 3970 format %{ %} 3971 interface(CONST_INTER); 3972 %} 3973 3974 // int value 24. 3975 operand immI_24() %{ 3976 predicate(n->get_int() == 24); 3977 match(ConI); 3978 op_cost(0); 3979 format %{ %} 3980 interface(CONST_INTER); 3981 %} 3982 3983 // Compressed oops constants 3984 // Pointer Immediate 3985 operand immN() %{ 3986 match(ConN); 3987 3988 op_cost(10); 3989 format %{ %} 3990 interface(CONST_INTER); 3991 %} 3992 3993 // NULL Pointer Immediate 3994 operand immN_0() %{ 3995 predicate(n->get_narrowcon() == 0); 3996 match(ConN); 3997 3998 op_cost(0); 3999 format %{ %} 4000 interface(CONST_INTER); 4001 %} 4002 4003 // Compressed klass constants 4004 operand immNKlass() %{ 4005 match(ConNKlass); 4006 4007 op_cost(0); 4008 format %{ %} 4009 interface(CONST_INTER); 4010 %} 4011 4012 // This operand can be used to avoid matching of an instruct 4013 // with chain rule. 4014 operand immNKlass_NM() %{ 4015 match(ConNKlass); 4016 predicate(false); 4017 op_cost(0); 4018 format %{ %} 4019 interface(CONST_INTER); 4020 %} 4021 4022 // Pointer Immediate: 64-bit 4023 operand immP() %{ 4024 match(ConP); 4025 op_cost(0); 4026 format %{ %} 4027 interface(CONST_INTER); 4028 %} 4029 4030 // Operand to avoid match of loadConP. 4031 // This operand can be used to avoid matching of an instruct 4032 // with chain rule. 4033 operand immP_NM() %{ 4034 match(ConP); 4035 predicate(false); 4036 op_cost(0); 4037 format %{ %} 4038 interface(CONST_INTER); 4039 %} 4040 4041 // costant 'pointer 0'. 4042 operand immP_0() %{ 4043 predicate(n->get_ptr() == 0); 4044 match(ConP); 4045 op_cost(0); 4046 format %{ %} 4047 interface(CONST_INTER); 4048 %} 4049 4050 // pointer 0x0 or 0x1 4051 operand immP_0or1() %{ 4052 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4053 match(ConP); 4054 op_cost(0); 4055 format %{ %} 4056 interface(CONST_INTER); 4057 %} 4058 4059 operand immL() %{ 4060 match(ConL); 4061 op_cost(40); 4062 format %{ %} 4063 interface(CONST_INTER); 4064 %} 4065 4066 operand immLmax30() %{ 4067 predicate((n->get_long() <= 30)); 4068 match(ConL); 4069 op_cost(0); 4070 format %{ %} 4071 interface(CONST_INTER); 4072 %} 4073 4074 // Long Immediate: 16-bit 4075 operand immL16() %{ 4076 predicate(Assembler::is_simm(n->get_long(), 16)); 4077 match(ConL); 4078 op_cost(0); 4079 format %{ %} 4080 interface(CONST_INTER); 4081 %} 4082 4083 // Long Immediate: 16-bit, 4-aligned 4084 operand immL16Alg4() %{ 4085 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4086 match(ConL); 4087 op_cost(0); 4088 format %{ %} 4089 interface(CONST_INTER); 4090 %} 4091 4092 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4093 operand immL32hi16() %{ 4094 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4095 match(ConL); 4096 op_cost(0); 4097 format %{ %} 4098 interface(CONST_INTER); 4099 %} 4100 4101 // Long Immediate: 32-bit 4102 operand immL32() %{ 4103 predicate(Assembler::is_simm(n->get_long(), 32)); 4104 match(ConL); 4105 op_cost(0); 4106 format %{ %} 4107 interface(CONST_INTER); 4108 %} 4109 4110 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4111 operand immLhighest16() %{ 4112 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4113 match(ConL); 4114 op_cost(0); 4115 format %{ %} 4116 interface(CONST_INTER); 4117 %} 4118 4119 operand immLnegpow2() %{ 4120 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4121 match(ConL); 4122 op_cost(0); 4123 format %{ %} 4124 interface(CONST_INTER); 4125 %} 4126 4127 operand immLpow2minus1() %{ 4128 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4129 (n->get_long() != (jlong)0xffffffffffffffffL)); 4130 match(ConL); 4131 op_cost(0); 4132 format %{ %} 4133 interface(CONST_INTER); 4134 %} 4135 4136 // constant 'long 0'. 4137 operand immL_0() %{ 4138 predicate(n->get_long() == 0L); 4139 match(ConL); 4140 op_cost(0); 4141 format %{ %} 4142 interface(CONST_INTER); 4143 %} 4144 4145 // constat ' long -1'. 4146 operand immL_minus1() %{ 4147 predicate(n->get_long() == -1L); 4148 match(ConL); 4149 op_cost(0); 4150 format %{ %} 4151 interface(CONST_INTER); 4152 %} 4153 4154 // Long Immediate: low 32-bit mask 4155 operand immL_32bits() %{ 4156 predicate(n->get_long() == 0xFFFFFFFFL); 4157 match(ConL); 4158 op_cost(0); 4159 format %{ %} 4160 interface(CONST_INTER); 4161 %} 4162 4163 // Unsigned Long Immediate: 16-bit 4164 operand uimmL16() %{ 4165 predicate(Assembler::is_uimm(n->get_long(), 16)); 4166 match(ConL); 4167 op_cost(0); 4168 format %{ %} 4169 interface(CONST_INTER); 4170 %} 4171 4172 // Float Immediate 4173 operand immF() %{ 4174 match(ConF); 4175 op_cost(40); 4176 format %{ %} 4177 interface(CONST_INTER); 4178 %} 4179 4180 // Float Immediate: +0.0f. 4181 operand immF_0() %{ 4182 predicate(jint_cast(n->getf()) == 0); 4183 match(ConF); 4184 4185 op_cost(0); 4186 format %{ %} 4187 interface(CONST_INTER); 4188 %} 4189 4190 // Double Immediate 4191 operand immD() %{ 4192 match(ConD); 4193 op_cost(40); 4194 format %{ %} 4195 interface(CONST_INTER); 4196 %} 4197 4198 // Integer Register Operands 4199 // Integer Destination Register 4200 // See definition of reg_class bits32_reg_rw. 4201 operand iRegIdst() %{ 4202 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4203 match(RegI); 4204 match(rscratch1RegI); 4205 match(rscratch2RegI); 4206 match(rarg1RegI); 4207 match(rarg2RegI); 4208 match(rarg3RegI); 4209 match(rarg4RegI); 4210 format %{ %} 4211 interface(REG_INTER); 4212 %} 4213 4214 // Integer Source Register 4215 // See definition of reg_class bits32_reg_ro. 4216 operand iRegIsrc() %{ 4217 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4218 match(RegI); 4219 match(rscratch1RegI); 4220 match(rscratch2RegI); 4221 match(rarg1RegI); 4222 match(rarg2RegI); 4223 match(rarg3RegI); 4224 match(rarg4RegI); 4225 format %{ %} 4226 interface(REG_INTER); 4227 %} 4228 4229 operand rscratch1RegI() %{ 4230 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4231 match(iRegIdst); 4232 format %{ %} 4233 interface(REG_INTER); 4234 %} 4235 4236 operand rscratch2RegI() %{ 4237 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4238 match(iRegIdst); 4239 format %{ %} 4240 interface(REG_INTER); 4241 %} 4242 4243 operand rarg1RegI() %{ 4244 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4245 match(iRegIdst); 4246 format %{ %} 4247 interface(REG_INTER); 4248 %} 4249 4250 operand rarg2RegI() %{ 4251 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4252 match(iRegIdst); 4253 format %{ %} 4254 interface(REG_INTER); 4255 %} 4256 4257 operand rarg3RegI() %{ 4258 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4259 match(iRegIdst); 4260 format %{ %} 4261 interface(REG_INTER); 4262 %} 4263 4264 operand rarg4RegI() %{ 4265 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4266 match(iRegIdst); 4267 format %{ %} 4268 interface(REG_INTER); 4269 %} 4270 4271 operand rarg1RegL() %{ 4272 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4273 match(iRegLdst); 4274 format %{ %} 4275 interface(REG_INTER); 4276 %} 4277 4278 operand rarg2RegL() %{ 4279 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4280 match(iRegLdst); 4281 format %{ %} 4282 interface(REG_INTER); 4283 %} 4284 4285 operand rarg3RegL() %{ 4286 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4287 match(iRegLdst); 4288 format %{ %} 4289 interface(REG_INTER); 4290 %} 4291 4292 operand rarg4RegL() %{ 4293 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4294 match(iRegLdst); 4295 format %{ %} 4296 interface(REG_INTER); 4297 %} 4298 4299 // Pointer Destination Register 4300 // See definition of reg_class bits64_reg_rw. 4301 operand iRegPdst() %{ 4302 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4303 match(RegP); 4304 match(rscratch1RegP); 4305 match(rscratch2RegP); 4306 match(rarg1RegP); 4307 match(rarg2RegP); 4308 match(rarg3RegP); 4309 match(rarg4RegP); 4310 format %{ %} 4311 interface(REG_INTER); 4312 %} 4313 4314 // Pointer Destination Register 4315 // Operand not using r11 and r12 (killed in epilog). 4316 operand iRegPdstNoScratch() %{ 4317 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4318 match(RegP); 4319 match(rarg1RegP); 4320 match(rarg2RegP); 4321 match(rarg3RegP); 4322 match(rarg4RegP); 4323 format %{ %} 4324 interface(REG_INTER); 4325 %} 4326 4327 // Pointer Source Register 4328 // See definition of reg_class bits64_reg_ro. 4329 operand iRegPsrc() %{ 4330 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4331 match(RegP); 4332 match(iRegPdst); 4333 match(rscratch1RegP); 4334 match(rscratch2RegP); 4335 match(rarg1RegP); 4336 match(rarg2RegP); 4337 match(rarg3RegP); 4338 match(rarg4RegP); 4339 match(threadRegP); 4340 format %{ %} 4341 interface(REG_INTER); 4342 %} 4343 4344 // Thread operand. 4345 operand threadRegP() %{ 4346 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4347 match(iRegPdst); 4348 format %{ "R16" %} 4349 interface(REG_INTER); 4350 %} 4351 4352 operand rscratch1RegP() %{ 4353 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4354 match(iRegPdst); 4355 format %{ "R11" %} 4356 interface(REG_INTER); 4357 %} 4358 4359 operand rscratch2RegP() %{ 4360 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4361 match(iRegPdst); 4362 format %{ %} 4363 interface(REG_INTER); 4364 %} 4365 4366 operand rarg1RegP() %{ 4367 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4368 match(iRegPdst); 4369 format %{ %} 4370 interface(REG_INTER); 4371 %} 4372 4373 operand rarg2RegP() %{ 4374 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4375 match(iRegPdst); 4376 format %{ %} 4377 interface(REG_INTER); 4378 %} 4379 4380 operand rarg3RegP() %{ 4381 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4382 match(iRegPdst); 4383 format %{ %} 4384 interface(REG_INTER); 4385 %} 4386 4387 operand rarg4RegP() %{ 4388 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4389 match(iRegPdst); 4390 format %{ %} 4391 interface(REG_INTER); 4392 %} 4393 4394 operand iRegNsrc() %{ 4395 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4396 match(RegN); 4397 match(iRegNdst); 4398 4399 format %{ %} 4400 interface(REG_INTER); 4401 %} 4402 4403 operand iRegNdst() %{ 4404 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4405 match(RegN); 4406 4407 format %{ %} 4408 interface(REG_INTER); 4409 %} 4410 4411 // Long Destination Register 4412 // See definition of reg_class bits64_reg_rw. 4413 operand iRegLdst() %{ 4414 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4415 match(RegL); 4416 match(rscratch1RegL); 4417 match(rscratch2RegL); 4418 format %{ %} 4419 interface(REG_INTER); 4420 %} 4421 4422 // Long Source Register 4423 // See definition of reg_class bits64_reg_ro. 4424 operand iRegLsrc() %{ 4425 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4426 match(RegL); 4427 match(iRegLdst); 4428 match(rscratch1RegL); 4429 match(rscratch2RegL); 4430 format %{ %} 4431 interface(REG_INTER); 4432 %} 4433 4434 // Special operand for ConvL2I. 4435 operand iRegL2Isrc(iRegLsrc reg) %{ 4436 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4437 match(ConvL2I reg); 4438 format %{ "ConvL2I($reg)" %} 4439 interface(REG_INTER) 4440 %} 4441 4442 operand rscratch1RegL() %{ 4443 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4444 match(RegL); 4445 format %{ %} 4446 interface(REG_INTER); 4447 %} 4448 4449 operand rscratch2RegL() %{ 4450 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4451 match(RegL); 4452 format %{ %} 4453 interface(REG_INTER); 4454 %} 4455 4456 // Condition Code Flag Registers 4457 operand flagsReg() %{ 4458 constraint(ALLOC_IN_RC(int_flags)); 4459 match(RegFlags); 4460 format %{ %} 4461 interface(REG_INTER); 4462 %} 4463 4464 operand flagsRegSrc() %{ 4465 constraint(ALLOC_IN_RC(int_flags_ro)); 4466 match(RegFlags); 4467 match(flagsReg); 4468 match(flagsRegCR0); 4469 format %{ %} 4470 interface(REG_INTER); 4471 %} 4472 4473 // Condition Code Flag Register CR0 4474 operand flagsRegCR0() %{ 4475 constraint(ALLOC_IN_RC(int_flags_CR0)); 4476 match(RegFlags); 4477 format %{ "CR0" %} 4478 interface(REG_INTER); 4479 %} 4480 4481 operand flagsRegCR1() %{ 4482 constraint(ALLOC_IN_RC(int_flags_CR1)); 4483 match(RegFlags); 4484 format %{ "CR1" %} 4485 interface(REG_INTER); 4486 %} 4487 4488 operand flagsRegCR6() %{ 4489 constraint(ALLOC_IN_RC(int_flags_CR6)); 4490 match(RegFlags); 4491 format %{ "CR6" %} 4492 interface(REG_INTER); 4493 %} 4494 4495 operand regCTR() %{ 4496 constraint(ALLOC_IN_RC(ctr_reg)); 4497 // RegFlags should work. Introducing a RegSpecial type would cause a 4498 // lot of changes. 4499 match(RegFlags); 4500 format %{"SR_CTR" %} 4501 interface(REG_INTER); 4502 %} 4503 4504 operand regD() %{ 4505 constraint(ALLOC_IN_RC(dbl_reg)); 4506 match(RegD); 4507 format %{ %} 4508 interface(REG_INTER); 4509 %} 4510 4511 operand regF() %{ 4512 constraint(ALLOC_IN_RC(flt_reg)); 4513 match(RegF); 4514 format %{ %} 4515 interface(REG_INTER); 4516 %} 4517 4518 // Special Registers 4519 4520 // Method Register 4521 operand inline_cache_regP(iRegPdst reg) %{ 4522 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4523 match(reg); 4524 format %{ %} 4525 interface(REG_INTER); 4526 %} 4527 4528 operand compiler_method_oop_regP(iRegPdst reg) %{ 4529 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4530 match(reg); 4531 format %{ %} 4532 interface(REG_INTER); 4533 %} 4534 4535 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4536 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4537 match(reg); 4538 format %{ %} 4539 interface(REG_INTER); 4540 %} 4541 4542 // Operands to remove register moves in unscaled mode. 4543 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4544 operand iRegP2N(iRegPsrc reg) %{ 4545 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4546 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4547 match(EncodeP reg); 4548 format %{ "$reg" %} 4549 interface(REG_INTER) 4550 %} 4551 4552 operand iRegN2P(iRegNsrc reg) %{ 4553 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4554 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4555 match(DecodeN reg); 4556 format %{ "$reg" %} 4557 interface(REG_INTER) 4558 %} 4559 4560 operand iRegN2P_klass(iRegNsrc reg) %{ 4561 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4562 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4563 match(DecodeNKlass reg); 4564 format %{ "$reg" %} 4565 interface(REG_INTER) 4566 %} 4567 4568 //----------Complex Operands--------------------------------------------------- 4569 // Indirect Memory Reference 4570 operand indirect(iRegPsrc reg) %{ 4571 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4572 match(reg); 4573 op_cost(100); 4574 format %{ "[$reg]" %} 4575 interface(MEMORY_INTER) %{ 4576 base($reg); 4577 index(0x0); 4578 scale(0x0); 4579 disp(0x0); 4580 %} 4581 %} 4582 4583 // Indirect with Offset 4584 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 4585 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4586 match(AddP reg offset); 4587 op_cost(100); 4588 format %{ "[$reg + $offset]" %} 4589 interface(MEMORY_INTER) %{ 4590 base($reg); 4591 index(0x0); 4592 scale(0x0); 4593 disp($offset); 4594 %} 4595 %} 4596 4597 // Indirect with 4-aligned Offset 4598 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 4599 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4600 match(AddP reg offset); 4601 op_cost(100); 4602 format %{ "[$reg + $offset]" %} 4603 interface(MEMORY_INTER) %{ 4604 base($reg); 4605 index(0x0); 4606 scale(0x0); 4607 disp($offset); 4608 %} 4609 %} 4610 4611 //----------Complex Operands for Compressed OOPs------------------------------- 4612 // Compressed OOPs with narrow_oop_shift == 0. 4613 4614 // Indirect Memory Reference, compressed OOP 4615 operand indirectNarrow(iRegNsrc reg) %{ 4616 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4617 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4618 match(DecodeN reg); 4619 op_cost(100); 4620 format %{ "[$reg]" %} 4621 interface(MEMORY_INTER) %{ 4622 base($reg); 4623 index(0x0); 4624 scale(0x0); 4625 disp(0x0); 4626 %} 4627 %} 4628 4629 operand indirectNarrow_klass(iRegNsrc reg) %{ 4630 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4631 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4632 match(DecodeNKlass reg); 4633 op_cost(100); 4634 format %{ "[$reg]" %} 4635 interface(MEMORY_INTER) %{ 4636 base($reg); 4637 index(0x0); 4638 scale(0x0); 4639 disp(0x0); 4640 %} 4641 %} 4642 4643 // Indirect with Offset, compressed OOP 4644 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 4645 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4646 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4647 match(AddP (DecodeN reg) offset); 4648 op_cost(100); 4649 format %{ "[$reg + $offset]" %} 4650 interface(MEMORY_INTER) %{ 4651 base($reg); 4652 index(0x0); 4653 scale(0x0); 4654 disp($offset); 4655 %} 4656 %} 4657 4658 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 4659 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4660 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4661 match(AddP (DecodeNKlass reg) offset); 4662 op_cost(100); 4663 format %{ "[$reg + $offset]" %} 4664 interface(MEMORY_INTER) %{ 4665 base($reg); 4666 index(0x0); 4667 scale(0x0); 4668 disp($offset); 4669 %} 4670 %} 4671 4672 // Indirect with 4-aligned Offset, compressed OOP 4673 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 4674 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4675 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4676 match(AddP (DecodeN reg) offset); 4677 op_cost(100); 4678 format %{ "[$reg + $offset]" %} 4679 interface(MEMORY_INTER) %{ 4680 base($reg); 4681 index(0x0); 4682 scale(0x0); 4683 disp($offset); 4684 %} 4685 %} 4686 4687 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 4688 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4689 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4690 match(AddP (DecodeNKlass reg) offset); 4691 op_cost(100); 4692 format %{ "[$reg + $offset]" %} 4693 interface(MEMORY_INTER) %{ 4694 base($reg); 4695 index(0x0); 4696 scale(0x0); 4697 disp($offset); 4698 %} 4699 %} 4700 4701 //----------Special Memory Operands-------------------------------------------- 4702 // Stack Slot Operand 4703 // 4704 // This operand is used for loading and storing temporary values on 4705 // the stack where a match requires a value to flow through memory. 4706 operand stackSlotI(sRegI reg) %{ 4707 constraint(ALLOC_IN_RC(stack_slots)); 4708 op_cost(100); 4709 //match(RegI); 4710 format %{ "[sp+$reg]" %} 4711 interface(MEMORY_INTER) %{ 4712 base(0x1); // R1_SP 4713 index(0x0); 4714 scale(0x0); 4715 disp($reg); // Stack Offset 4716 %} 4717 %} 4718 4719 operand stackSlotL(sRegL reg) %{ 4720 constraint(ALLOC_IN_RC(stack_slots)); 4721 op_cost(100); 4722 //match(RegL); 4723 format %{ "[sp+$reg]" %} 4724 interface(MEMORY_INTER) %{ 4725 base(0x1); // R1_SP 4726 index(0x0); 4727 scale(0x0); 4728 disp($reg); // Stack Offset 4729 %} 4730 %} 4731 4732 operand stackSlotP(sRegP reg) %{ 4733 constraint(ALLOC_IN_RC(stack_slots)); 4734 op_cost(100); 4735 //match(RegP); 4736 format %{ "[sp+$reg]" %} 4737 interface(MEMORY_INTER) %{ 4738 base(0x1); // R1_SP 4739 index(0x0); 4740 scale(0x0); 4741 disp($reg); // Stack Offset 4742 %} 4743 %} 4744 4745 operand stackSlotF(sRegF reg) %{ 4746 constraint(ALLOC_IN_RC(stack_slots)); 4747 op_cost(100); 4748 //match(RegF); 4749 format %{ "[sp+$reg]" %} 4750 interface(MEMORY_INTER) %{ 4751 base(0x1); // R1_SP 4752 index(0x0); 4753 scale(0x0); 4754 disp($reg); // Stack Offset 4755 %} 4756 %} 4757 4758 operand stackSlotD(sRegD reg) %{ 4759 constraint(ALLOC_IN_RC(stack_slots)); 4760 op_cost(100); 4761 //match(RegD); 4762 format %{ "[sp+$reg]" %} 4763 interface(MEMORY_INTER) %{ 4764 base(0x1); // R1_SP 4765 index(0x0); 4766 scale(0x0); 4767 disp($reg); // Stack Offset 4768 %} 4769 %} 4770 4771 // Operands for expressing Control Flow 4772 // NOTE: Label is a predefined operand which should not be redefined in 4773 // the AD file. It is generically handled within the ADLC. 4774 4775 //----------Conditional Branch Operands---------------------------------------- 4776 // Comparison Op 4777 // 4778 // This is the operation of the comparison, and is limited to the 4779 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 4780 // (!=). 4781 // 4782 // Other attributes of the comparison, such as unsignedness, are specified 4783 // by the comparison instruction that sets a condition code flags register. 4784 // That result is represented by a flags operand whose subtype is appropriate 4785 // to the unsignedness (etc.) of the comparison. 4786 // 4787 // Later, the instruction which matches both the Comparison Op (a Bool) and 4788 // the flags (produced by the Cmp) specifies the coding of the comparison op 4789 // by matching a specific subtype of Bool operand below. 4790 4791 // When used for floating point comparisons: unordered same as less. 4792 operand cmpOp() %{ 4793 match(Bool); 4794 format %{ "" %} 4795 interface(COND_INTER) %{ 4796 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 4797 // BO & BI 4798 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 4799 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 4800 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 4801 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 4802 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 4803 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 4804 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 4805 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 4806 %} 4807 %} 4808 4809 //----------OPERAND CLASSES---------------------------------------------------- 4810 // Operand Classes are groups of operands that are used to simplify 4811 // instruction definitions by not requiring the AD writer to specify 4812 // seperate instructions for every form of operand when the 4813 // instruction accepts multiple operand types with the same basic 4814 // encoding and format. The classic case of this is memory operands. 4815 // Indirect is not included since its use is limited to Compare & Swap. 4816 4817 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 4818 // Memory operand where offsets are 4-aligned. Required for ld, std. 4819 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 4820 opclass indirectMemory(indirect, indirectNarrow); 4821 4822 // Special opclass for I and ConvL2I. 4823 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 4824 4825 // Operand classes to match encode and decode. iRegN_P2N is only used 4826 // for storeN. I have never seen an encode node elsewhere. 4827 opclass iRegN_P2N(iRegNsrc, iRegP2N); 4828 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 4829 4830 //----------PIPELINE----------------------------------------------------------- 4831 4832 pipeline %{ 4833 4834 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 4835 // J. Res. & Dev., No. 1, Jan. 2002. 4836 4837 //----------ATTRIBUTES--------------------------------------------------------- 4838 attributes %{ 4839 4840 // Power4 instructions are of fixed length. 4841 fixed_size_instructions; 4842 4843 // TODO: if `bundle' means number of instructions fetched 4844 // per cycle, this is 8. If `bundle' means Power4 `group', that is 4845 // max instructions issued per cycle, this is 5. 4846 max_instructions_per_bundle = 8; 4847 4848 // A Power4 instruction is 4 bytes long. 4849 instruction_unit_size = 4; 4850 4851 // The Power4 processor fetches 64 bytes... 4852 instruction_fetch_unit_size = 64; 4853 4854 // ...in one line 4855 instruction_fetch_units = 1 4856 4857 // Unused, list one so that array generated by adlc is not empty. 4858 // Aix compiler chokes if _nop_count = 0. 4859 nops(fxNop); 4860 %} 4861 4862 //----------RESOURCES---------------------------------------------------------- 4863 // Resources are the functional units available to the machine 4864 resources( 4865 PPC_BR, // branch unit 4866 PPC_CR, // condition unit 4867 PPC_FX1, // integer arithmetic unit 1 4868 PPC_FX2, // integer arithmetic unit 2 4869 PPC_LDST1, // load/store unit 1 4870 PPC_LDST2, // load/store unit 2 4871 PPC_FP1, // float arithmetic unit 1 4872 PPC_FP2, // float arithmetic unit 2 4873 PPC_LDST = PPC_LDST1 | PPC_LDST2, 4874 PPC_FX = PPC_FX1 | PPC_FX2, 4875 PPC_FP = PPC_FP1 | PPC_FP2 4876 ); 4877 4878 //----------PIPELINE DESCRIPTION----------------------------------------------- 4879 // Pipeline Description specifies the stages in the machine's pipeline 4880 pipe_desc( 4881 // Power4 longest pipeline path 4882 PPC_IF, // instruction fetch 4883 PPC_IC, 4884 //PPC_BP, // branch prediction 4885 PPC_D0, // decode 4886 PPC_D1, // decode 4887 PPC_D2, // decode 4888 PPC_D3, // decode 4889 PPC_Xfer1, 4890 PPC_GD, // group definition 4891 PPC_MP, // map 4892 PPC_ISS, // issue 4893 PPC_RF, // resource fetch 4894 PPC_EX1, // execute (all units) 4895 PPC_EX2, // execute (FP, LDST) 4896 PPC_EX3, // execute (FP, LDST) 4897 PPC_EX4, // execute (FP) 4898 PPC_EX5, // execute (FP) 4899 PPC_EX6, // execute (FP) 4900 PPC_WB, // write back 4901 PPC_Xfer2, 4902 PPC_CP 4903 ); 4904 4905 //----------PIPELINE CLASSES--------------------------------------------------- 4906 // Pipeline Classes describe the stages in which input and output are 4907 // referenced by the hardware pipeline. 4908 4909 // Simple pipeline classes. 4910 4911 // Default pipeline class. 4912 pipe_class pipe_class_default() %{ 4913 single_instruction; 4914 fixed_latency(2); 4915 %} 4916 4917 // Pipeline class for empty instructions. 4918 pipe_class pipe_class_empty() %{ 4919 single_instruction; 4920 fixed_latency(0); 4921 %} 4922 4923 // Pipeline class for compares. 4924 pipe_class pipe_class_compare() %{ 4925 single_instruction; 4926 fixed_latency(16); 4927 %} 4928 4929 // Pipeline class for traps. 4930 pipe_class pipe_class_trap() %{ 4931 single_instruction; 4932 fixed_latency(100); 4933 %} 4934 4935 // Pipeline class for memory operations. 4936 pipe_class pipe_class_memory() %{ 4937 single_instruction; 4938 fixed_latency(16); 4939 %} 4940 4941 // Pipeline class for call. 4942 pipe_class pipe_class_call() %{ 4943 single_instruction; 4944 fixed_latency(100); 4945 %} 4946 4947 // Define the class for the Nop node. 4948 define %{ 4949 MachNop = pipe_class_default; 4950 %} 4951 4952 %} 4953 4954 //----------INSTRUCTIONS------------------------------------------------------- 4955 4956 // Naming of instructions: 4957 // opA_operB / opA_operB_operC: 4958 // Operation 'op' with one or two source operands 'oper'. Result 4959 // type is A, source operand types are B and C. 4960 // Iff A == B == C, B and C are left out. 4961 // 4962 // The instructions are ordered according to the following scheme: 4963 // - loads 4964 // - load constants 4965 // - prefetch 4966 // - store 4967 // - encode/decode 4968 // - membar 4969 // - conditional moves 4970 // - compare & swap 4971 // - arithmetic and logic operations 4972 // * int: Add, Sub, Mul, Div, Mod 4973 // * int: lShift, arShift, urShift, rot 4974 // * float: Add, Sub, Mul, Div 4975 // * and, or, xor ... 4976 // - register moves: float <-> int, reg <-> stack, repl 4977 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 4978 // - conv (low level type cast requiring bit changes (sign extend etc) 4979 // - compares, range & zero checks. 4980 // - branches 4981 // - complex operations, intrinsics, min, max, replicate 4982 // - lock 4983 // - Calls 4984 // 4985 // If there are similar instructions with different types they are sorted: 4986 // int before float 4987 // small before big 4988 // signed before unsigned 4989 // e.g., loadS before loadUS before loadI before loadF. 4990 4991 4992 //----------Load/Store Instructions-------------------------------------------- 4993 4994 //----------Load Instructions-------------------------------------------------- 4995 4996 // Converts byte to int. 4997 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 4998 // reuses the 'amount' operand, but adlc expects that operand specification 4999 // and operands in match rule are equivalent. 5000 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5001 effect(DEF dst, USE src); 5002 format %{ "EXTSB $dst, $src \t// byte->int" %} 5003 size(4); 5004 ins_encode %{ 5005 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5006 __ extsb($dst$$Register, $src$$Register); 5007 %} 5008 ins_pipe(pipe_class_default); 5009 %} 5010 5011 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5012 // match-rule, false predicate 5013 match(Set dst (LoadB mem)); 5014 predicate(false); 5015 5016 format %{ "LBZ $dst, $mem" %} 5017 size(4); 5018 ins_encode( enc_lbz(dst, mem) ); 5019 ins_pipe(pipe_class_memory); 5020 %} 5021 5022 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5023 // match-rule, false predicate 5024 match(Set dst (LoadB mem)); 5025 predicate(false); 5026 5027 format %{ "LBZ $dst, $mem\n\t" 5028 "TWI $dst\n\t" 5029 "ISYNC" %} 5030 size(12); 5031 ins_encode( enc_lbz_ac(dst, mem) ); 5032 ins_pipe(pipe_class_memory); 5033 %} 5034 5035 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5036 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5037 match(Set dst (LoadB mem)); 5038 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5039 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5040 expand %{ 5041 iRegIdst tmp; 5042 loadUB_indirect(tmp, mem); 5043 convB2I_reg_2(dst, tmp); 5044 %} 5045 %} 5046 5047 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5048 match(Set dst (LoadB mem)); 5049 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5050 expand %{ 5051 iRegIdst tmp; 5052 loadUB_indirect_ac(tmp, mem); 5053 convB2I_reg_2(dst, tmp); 5054 %} 5055 %} 5056 5057 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5058 // match-rule, false predicate 5059 match(Set dst (LoadB mem)); 5060 predicate(false); 5061 5062 format %{ "LBZ $dst, $mem" %} 5063 size(4); 5064 ins_encode( enc_lbz(dst, mem) ); 5065 ins_pipe(pipe_class_memory); 5066 %} 5067 5068 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5069 // match-rule, false predicate 5070 match(Set dst (LoadB mem)); 5071 predicate(false); 5072 5073 format %{ "LBZ $dst, $mem\n\t" 5074 "TWI $dst\n\t" 5075 "ISYNC" %} 5076 size(12); 5077 ins_encode( enc_lbz_ac(dst, mem) ); 5078 ins_pipe(pipe_class_memory); 5079 %} 5080 5081 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5082 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5083 match(Set dst (LoadB mem)); 5084 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5085 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5086 5087 expand %{ 5088 iRegIdst tmp; 5089 loadUB_indOffset16(tmp, mem); 5090 convB2I_reg_2(dst, tmp); 5091 %} 5092 %} 5093 5094 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5095 match(Set dst (LoadB mem)); 5096 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5097 5098 expand %{ 5099 iRegIdst tmp; 5100 loadUB_indOffset16_ac(tmp, mem); 5101 convB2I_reg_2(dst, tmp); 5102 %} 5103 %} 5104 5105 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5106 instruct loadUB(iRegIdst dst, memory mem) %{ 5107 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5108 match(Set dst (LoadUB mem)); 5109 ins_cost(MEMORY_REF_COST); 5110 5111 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5112 size(4); 5113 ins_encode( enc_lbz(dst, mem) ); 5114 ins_pipe(pipe_class_memory); 5115 %} 5116 5117 // Load Unsigned Byte (8bit UNsigned) acquire. 5118 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5119 match(Set dst (LoadUB mem)); 5120 ins_cost(3*MEMORY_REF_COST); 5121 5122 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5123 "TWI $dst\n\t" 5124 "ISYNC" %} 5125 size(12); 5126 ins_encode( enc_lbz_ac(dst, mem) ); 5127 ins_pipe(pipe_class_memory); 5128 %} 5129 5130 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5131 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5132 match(Set dst (ConvI2L (LoadUB mem))); 5133 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5134 ins_cost(MEMORY_REF_COST); 5135 5136 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5137 size(4); 5138 ins_encode( enc_lbz(dst, mem) ); 5139 ins_pipe(pipe_class_memory); 5140 %} 5141 5142 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5143 match(Set dst (ConvI2L (LoadUB mem))); 5144 ins_cost(3*MEMORY_REF_COST); 5145 5146 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5147 "TWI $dst\n\t" 5148 "ISYNC" %} 5149 size(12); 5150 ins_encode( enc_lbz_ac(dst, mem) ); 5151 ins_pipe(pipe_class_memory); 5152 %} 5153 5154 // Load Short (16bit signed) 5155 instruct loadS(iRegIdst dst, memory mem) %{ 5156 match(Set dst (LoadS mem)); 5157 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5158 ins_cost(MEMORY_REF_COST); 5159 5160 format %{ "LHA $dst, $mem" %} 5161 size(4); 5162 ins_encode %{ 5163 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5164 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5165 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5166 %} 5167 ins_pipe(pipe_class_memory); 5168 %} 5169 5170 // Load Short (16bit signed) acquire. 5171 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5172 match(Set dst (LoadS mem)); 5173 ins_cost(3*MEMORY_REF_COST); 5174 5175 format %{ "LHA $dst, $mem\t acquire\n\t" 5176 "TWI $dst\n\t" 5177 "ISYNC" %} 5178 size(12); 5179 ins_encode %{ 5180 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5181 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5182 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5183 __ twi_0($dst$$Register); 5184 __ isync(); 5185 %} 5186 ins_pipe(pipe_class_memory); 5187 %} 5188 5189 // Load Char (16bit unsigned) 5190 instruct loadUS(iRegIdst dst, memory mem) %{ 5191 match(Set dst (LoadUS mem)); 5192 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5193 ins_cost(MEMORY_REF_COST); 5194 5195 format %{ "LHZ $dst, $mem" %} 5196 size(4); 5197 ins_encode( enc_lhz(dst, mem) ); 5198 ins_pipe(pipe_class_memory); 5199 %} 5200 5201 // Load Char (16bit unsigned) acquire. 5202 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5203 match(Set dst (LoadUS mem)); 5204 ins_cost(3*MEMORY_REF_COST); 5205 5206 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5207 "TWI $dst\n\t" 5208 "ISYNC" %} 5209 size(12); 5210 ins_encode( enc_lhz_ac(dst, mem) ); 5211 ins_pipe(pipe_class_memory); 5212 %} 5213 5214 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5215 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5216 match(Set dst (ConvI2L (LoadUS mem))); 5217 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5218 ins_cost(MEMORY_REF_COST); 5219 5220 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5221 size(4); 5222 ins_encode( enc_lhz(dst, mem) ); 5223 ins_pipe(pipe_class_memory); 5224 %} 5225 5226 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5227 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5228 match(Set dst (ConvI2L (LoadUS mem))); 5229 ins_cost(3*MEMORY_REF_COST); 5230 5231 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5232 "TWI $dst\n\t" 5233 "ISYNC" %} 5234 size(12); 5235 ins_encode( enc_lhz_ac(dst, mem) ); 5236 ins_pipe(pipe_class_memory); 5237 %} 5238 5239 // Load Integer. 5240 instruct loadI(iRegIdst dst, memory mem) %{ 5241 match(Set dst (LoadI mem)); 5242 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5243 ins_cost(MEMORY_REF_COST); 5244 5245 format %{ "LWZ $dst, $mem" %} 5246 size(4); 5247 ins_encode( enc_lwz(dst, mem) ); 5248 ins_pipe(pipe_class_memory); 5249 %} 5250 5251 // Load Integer acquire. 5252 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5253 match(Set dst (LoadI mem)); 5254 ins_cost(3*MEMORY_REF_COST); 5255 5256 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5257 "TWI $dst\n\t" 5258 "ISYNC" %} 5259 size(12); 5260 ins_encode( enc_lwz_ac(dst, mem) ); 5261 ins_pipe(pipe_class_memory); 5262 %} 5263 5264 // Match loading integer and casting it to unsigned int in 5265 // long register. 5266 // LoadI + ConvI2L + AndL 0xffffffff. 5267 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5268 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5269 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5270 ins_cost(MEMORY_REF_COST); 5271 5272 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5273 size(4); 5274 ins_encode( enc_lwz(dst, mem) ); 5275 ins_pipe(pipe_class_memory); 5276 %} 5277 5278 // Match loading integer and casting it to long. 5279 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5280 match(Set dst (ConvI2L (LoadI mem))); 5281 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5282 ins_cost(MEMORY_REF_COST); 5283 5284 format %{ "LWA $dst, $mem \t// loadI2L" %} 5285 size(4); 5286 ins_encode %{ 5287 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5288 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5289 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5290 %} 5291 ins_pipe(pipe_class_memory); 5292 %} 5293 5294 // Match loading integer and casting it to long - acquire. 5295 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5296 match(Set dst (ConvI2L (LoadI mem))); 5297 ins_cost(3*MEMORY_REF_COST); 5298 5299 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5300 "TWI $dst\n\t" 5301 "ISYNC" %} 5302 size(12); 5303 ins_encode %{ 5304 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5305 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5306 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5307 __ twi_0($dst$$Register); 5308 __ isync(); 5309 %} 5310 ins_pipe(pipe_class_memory); 5311 %} 5312 5313 // Load Long - aligned 5314 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5315 match(Set dst (LoadL mem)); 5316 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5317 ins_cost(MEMORY_REF_COST); 5318 5319 format %{ "LD $dst, $mem \t// long" %} 5320 size(4); 5321 ins_encode( enc_ld(dst, mem) ); 5322 ins_pipe(pipe_class_memory); 5323 %} 5324 5325 // Load Long - aligned acquire. 5326 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5327 match(Set dst (LoadL mem)); 5328 ins_cost(3*MEMORY_REF_COST); 5329 5330 format %{ "LD $dst, $mem \t// long acquire\n\t" 5331 "TWI $dst\n\t" 5332 "ISYNC" %} 5333 size(12); 5334 ins_encode( enc_ld_ac(dst, mem) ); 5335 ins_pipe(pipe_class_memory); 5336 %} 5337 5338 // Load Long - UNaligned 5339 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5340 match(Set dst (LoadL_unaligned mem)); 5341 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5342 ins_cost(MEMORY_REF_COST); 5343 5344 format %{ "LD $dst, $mem \t// unaligned long" %} 5345 size(4); 5346 ins_encode( enc_ld(dst, mem) ); 5347 ins_pipe(pipe_class_memory); 5348 %} 5349 5350 // Load nodes for superwords 5351 5352 // Load Aligned Packed Byte 5353 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5354 predicate(n->as_LoadVector()->memory_size() == 8); 5355 match(Set dst (LoadVector mem)); 5356 ins_cost(MEMORY_REF_COST); 5357 5358 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5359 size(4); 5360 ins_encode( enc_ld(dst, mem) ); 5361 ins_pipe(pipe_class_memory); 5362 %} 5363 5364 // Load Range, range = array length (=jint) 5365 instruct loadRange(iRegIdst dst, memory mem) %{ 5366 match(Set dst (LoadRange mem)); 5367 ins_cost(MEMORY_REF_COST); 5368 5369 format %{ "LWZ $dst, $mem \t// range" %} 5370 size(4); 5371 ins_encode( enc_lwz(dst, mem) ); 5372 ins_pipe(pipe_class_memory); 5373 %} 5374 5375 // Load Compressed Pointer 5376 instruct loadN(iRegNdst dst, memory mem) %{ 5377 match(Set dst (LoadN mem)); 5378 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5379 ins_cost(MEMORY_REF_COST); 5380 5381 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5382 size(4); 5383 ins_encode( enc_lwz(dst, mem) ); 5384 ins_pipe(pipe_class_memory); 5385 %} 5386 5387 // Load Compressed Pointer acquire. 5388 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5389 match(Set dst (LoadN mem)); 5390 ins_cost(3*MEMORY_REF_COST); 5391 5392 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5393 "TWI $dst\n\t" 5394 "ISYNC" %} 5395 size(12); 5396 ins_encode( enc_lwz_ac(dst, mem) ); 5397 ins_pipe(pipe_class_memory); 5398 %} 5399 5400 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5401 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5402 match(Set dst (DecodeN (LoadN mem))); 5403 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5404 ins_cost(MEMORY_REF_COST); 5405 5406 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5407 size(4); 5408 ins_encode( enc_lwz(dst, mem) ); 5409 ins_pipe(pipe_class_memory); 5410 %} 5411 5412 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5413 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5414 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5415 _kids[0]->_leaf->as_Load()->is_unordered()); 5416 ins_cost(MEMORY_REF_COST); 5417 5418 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5419 size(4); 5420 ins_encode( enc_lwz(dst, mem) ); 5421 ins_pipe(pipe_class_memory); 5422 %} 5423 5424 // Load Pointer 5425 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5426 match(Set dst (LoadP mem)); 5427 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5428 ins_cost(MEMORY_REF_COST); 5429 5430 format %{ "LD $dst, $mem \t// ptr" %} 5431 size(4); 5432 ins_encode( enc_ld(dst, mem) ); 5433 ins_pipe(pipe_class_memory); 5434 %} 5435 5436 // Load Pointer acquire. 5437 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5438 match(Set dst (LoadP mem)); 5439 ins_cost(3*MEMORY_REF_COST); 5440 5441 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5442 "TWI $dst\n\t" 5443 "ISYNC" %} 5444 size(12); 5445 ins_encode( enc_ld_ac(dst, mem) ); 5446 ins_pipe(pipe_class_memory); 5447 %} 5448 5449 // LoadP + CastP2L 5450 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5451 match(Set dst (CastP2X (LoadP mem))); 5452 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5453 ins_cost(MEMORY_REF_COST); 5454 5455 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5456 size(4); 5457 ins_encode( enc_ld(dst, mem) ); 5458 ins_pipe(pipe_class_memory); 5459 %} 5460 5461 // Load compressed klass pointer. 5462 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5463 match(Set dst (LoadNKlass mem)); 5464 ins_cost(MEMORY_REF_COST); 5465 5466 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5467 size(4); 5468 ins_encode( enc_lwz(dst, mem) ); 5469 ins_pipe(pipe_class_memory); 5470 %} 5471 5472 // Load Klass Pointer 5473 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5474 match(Set dst (LoadKlass mem)); 5475 ins_cost(MEMORY_REF_COST); 5476 5477 format %{ "LD $dst, $mem \t// klass ptr" %} 5478 size(4); 5479 ins_encode( enc_ld(dst, mem) ); 5480 ins_pipe(pipe_class_memory); 5481 %} 5482 5483 // Load Float 5484 instruct loadF(regF dst, memory mem) %{ 5485 match(Set dst (LoadF mem)); 5486 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5487 ins_cost(MEMORY_REF_COST); 5488 5489 format %{ "LFS $dst, $mem" %} 5490 size(4); 5491 ins_encode %{ 5492 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5493 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5494 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5495 %} 5496 ins_pipe(pipe_class_memory); 5497 %} 5498 5499 // Load Float acquire. 5500 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5501 match(Set dst (LoadF mem)); 5502 effect(TEMP cr0); 5503 ins_cost(3*MEMORY_REF_COST); 5504 5505 format %{ "LFS $dst, $mem \t// acquire\n\t" 5506 "FCMPU cr0, $dst, $dst\n\t" 5507 "BNE cr0, next\n" 5508 "next:\n\t" 5509 "ISYNC" %} 5510 size(16); 5511 ins_encode %{ 5512 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5513 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5514 Label next; 5515 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5516 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5517 __ bne(CCR0, next); 5518 __ bind(next); 5519 __ isync(); 5520 %} 5521 ins_pipe(pipe_class_memory); 5522 %} 5523 5524 // Load Double - aligned 5525 instruct loadD(regD dst, memory mem) %{ 5526 match(Set dst (LoadD mem)); 5527 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5528 ins_cost(MEMORY_REF_COST); 5529 5530 format %{ "LFD $dst, $mem" %} 5531 size(4); 5532 ins_encode( enc_lfd(dst, mem) ); 5533 ins_pipe(pipe_class_memory); 5534 %} 5535 5536 // Load Double - aligned acquire. 5537 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5538 match(Set dst (LoadD mem)); 5539 effect(TEMP cr0); 5540 ins_cost(3*MEMORY_REF_COST); 5541 5542 format %{ "LFD $dst, $mem \t// acquire\n\t" 5543 "FCMPU cr0, $dst, $dst\n\t" 5544 "BNE cr0, next\n" 5545 "next:\n\t" 5546 "ISYNC" %} 5547 size(16); 5548 ins_encode %{ 5549 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5550 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5551 Label next; 5552 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5553 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5554 __ bne(CCR0, next); 5555 __ bind(next); 5556 __ isync(); 5557 %} 5558 ins_pipe(pipe_class_memory); 5559 %} 5560 5561 // Load Double - UNaligned 5562 instruct loadD_unaligned(regD dst, memory mem) %{ 5563 match(Set dst (LoadD_unaligned mem)); 5564 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5565 ins_cost(MEMORY_REF_COST); 5566 5567 format %{ "LFD $dst, $mem" %} 5568 size(4); 5569 ins_encode( enc_lfd(dst, mem) ); 5570 ins_pipe(pipe_class_memory); 5571 %} 5572 5573 //----------Constants-------------------------------------------------------- 5574 5575 // Load MachConstantTableBase: add hi offset to global toc. 5576 // TODO: Handle hidden register r29 in bundler! 5577 instruct loadToc_hi(iRegLdst dst) %{ 5578 effect(DEF dst); 5579 ins_cost(DEFAULT_COST); 5580 5581 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 5582 size(4); 5583 ins_encode %{ 5584 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5585 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 5586 %} 5587 ins_pipe(pipe_class_default); 5588 %} 5589 5590 // Load MachConstantTableBase: add lo offset to global toc. 5591 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 5592 effect(DEF dst, USE src); 5593 ins_cost(DEFAULT_COST); 5594 5595 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 5596 size(4); 5597 ins_encode %{ 5598 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5599 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 5600 %} 5601 ins_pipe(pipe_class_default); 5602 %} 5603 5604 // Load 16-bit integer constant 0xssss???? 5605 instruct loadConI16(iRegIdst dst, immI16 src) %{ 5606 match(Set dst src); 5607 5608 format %{ "LI $dst, $src" %} 5609 size(4); 5610 ins_encode %{ 5611 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5612 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 5613 %} 5614 ins_pipe(pipe_class_default); 5615 %} 5616 5617 // Load integer constant 0x????0000 5618 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 5619 match(Set dst src); 5620 ins_cost(DEFAULT_COST); 5621 5622 format %{ "LIS $dst, $src.hi" %} 5623 size(4); 5624 ins_encode %{ 5625 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5626 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 5627 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5628 %} 5629 ins_pipe(pipe_class_default); 5630 %} 5631 5632 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 5633 // and sign extended), this adds the low 16 bits. 5634 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 5635 // no match-rule, false predicate 5636 effect(DEF dst, USE src1, USE src2); 5637 predicate(false); 5638 5639 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 5640 size(4); 5641 ins_encode %{ 5642 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5643 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5644 %} 5645 ins_pipe(pipe_class_default); 5646 %} 5647 5648 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 5649 match(Set dst src); 5650 ins_cost(DEFAULT_COST*2); 5651 5652 expand %{ 5653 // Would like to use $src$$constant. 5654 immI16 srcLo %{ _opnds[1]->constant() %} 5655 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5656 immIhi16 srcHi %{ _opnds[1]->constant() %} 5657 iRegIdst tmpI; 5658 loadConIhi16(tmpI, srcHi); 5659 loadConI32_lo16(dst, tmpI, srcLo); 5660 %} 5661 %} 5662 5663 // No constant pool entries required. 5664 instruct loadConL16(iRegLdst dst, immL16 src) %{ 5665 match(Set dst src); 5666 5667 format %{ "LI $dst, $src \t// long" %} 5668 size(4); 5669 ins_encode %{ 5670 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5671 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 5672 %} 5673 ins_pipe(pipe_class_default); 5674 %} 5675 5676 // Load long constant 0xssssssss????0000 5677 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 5678 match(Set dst src); 5679 ins_cost(DEFAULT_COST); 5680 5681 format %{ "LIS $dst, $src.hi \t// long" %} 5682 size(4); 5683 ins_encode %{ 5684 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5685 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5686 %} 5687 ins_pipe(pipe_class_default); 5688 %} 5689 5690 // To load a 32 bit constant: merge lower 16 bits into already loaded 5691 // high 16 bits. 5692 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 5693 // no match-rule, false predicate 5694 effect(DEF dst, USE src1, USE src2); 5695 predicate(false); 5696 5697 format %{ "ORI $dst, $src1, $src2.lo" %} 5698 size(4); 5699 ins_encode %{ 5700 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5701 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5702 %} 5703 ins_pipe(pipe_class_default); 5704 %} 5705 5706 // Load 32-bit long constant 5707 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 5708 match(Set dst src); 5709 ins_cost(DEFAULT_COST*2); 5710 5711 expand %{ 5712 // Would like to use $src$$constant. 5713 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 5714 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5715 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 5716 iRegLdst tmpL; 5717 loadConL32hi16(tmpL, srcHi); 5718 loadConL32_lo16(dst, tmpL, srcLo); 5719 %} 5720 %} 5721 5722 // Load long constant 0x????000000000000. 5723 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 5724 match(Set dst src); 5725 ins_cost(DEFAULT_COST); 5726 5727 expand %{ 5728 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 5729 immI shift32 %{ 32 %} 5730 iRegLdst tmpL; 5731 loadConL32hi16(tmpL, srcHi); 5732 lshiftL_regL_immI(dst, tmpL, shift32); 5733 %} 5734 %} 5735 5736 // Expand node for constant pool load: small offset. 5737 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 5738 effect(DEF dst, USE src, USE toc); 5739 ins_cost(MEMORY_REF_COST); 5740 5741 ins_num_consts(1); 5742 // Needed so that CallDynamicJavaDirect can compute the address of this 5743 // instruction for relocation. 5744 ins_field_cbuf_insts_offset(int); 5745 5746 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 5747 size(4); 5748 ins_encode( enc_load_long_constL(dst, src, toc) ); 5749 ins_pipe(pipe_class_memory); 5750 %} 5751 5752 // Expand node for constant pool load: large offset. 5753 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 5754 effect(DEF dst, USE src, USE toc); 5755 predicate(false); 5756 5757 ins_num_consts(1); 5758 ins_field_const_toc_offset(int); 5759 // Needed so that CallDynamicJavaDirect can compute the address of this 5760 // instruction for relocation. 5761 ins_field_cbuf_insts_offset(int); 5762 5763 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 5764 size(4); 5765 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 5766 ins_pipe(pipe_class_default); 5767 %} 5768 5769 // Expand node for constant pool load: large offset. 5770 // No constant pool entries required. 5771 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 5772 effect(DEF dst, USE src, USE base); 5773 predicate(false); 5774 5775 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 5776 5777 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 5778 size(4); 5779 ins_encode %{ 5780 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 5781 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 5782 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 5783 %} 5784 ins_pipe(pipe_class_memory); 5785 %} 5786 5787 // Load long constant from constant table. Expand in case of 5788 // offset > 16 bit is needed. 5789 // Adlc adds toc node MachConstantTableBase. 5790 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 5791 match(Set dst src); 5792 ins_cost(MEMORY_REF_COST); 5793 5794 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 5795 // We can not inline the enc_class for the expand as that does not support constanttablebase. 5796 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 5797 %} 5798 5799 // Load NULL as compressed oop. 5800 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 5801 match(Set dst src); 5802 ins_cost(DEFAULT_COST); 5803 5804 format %{ "LI $dst, $src \t// compressed ptr" %} 5805 size(4); 5806 ins_encode %{ 5807 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5808 __ li($dst$$Register, 0); 5809 %} 5810 ins_pipe(pipe_class_default); 5811 %} 5812 5813 // Load hi part of compressed oop constant. 5814 instruct loadConN_hi(iRegNdst dst, immN src) %{ 5815 effect(DEF dst, USE src); 5816 ins_cost(DEFAULT_COST); 5817 5818 format %{ "LIS $dst, $src \t// narrow oop hi" %} 5819 size(4); 5820 ins_encode %{ 5821 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5822 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 5823 %} 5824 ins_pipe(pipe_class_default); 5825 %} 5826 5827 // Add lo part of compressed oop constant to already loaded hi part. 5828 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 5829 effect(DEF dst, USE src1, USE src2); 5830 ins_cost(DEFAULT_COST); 5831 5832 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 5833 size(4); 5834 ins_encode %{ 5835 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5836 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5837 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 5838 RelocationHolder rspec = oop_Relocation::spec(oop_index); 5839 __ relocate(rspec, 1); 5840 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 5841 %} 5842 ins_pipe(pipe_class_default); 5843 %} 5844 5845 // Needed to postalloc expand loadConN: ConN is loaded as ConI 5846 // leaving the upper 32 bits with sign-extension bits. 5847 // This clears these bits: dst = src & 0xFFFFFFFF. 5848 // TODO: Eventually call this maskN_regN_FFFFFFFF. 5849 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 5850 effect(DEF dst, USE src); 5851 predicate(false); 5852 5853 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 5854 size(4); 5855 ins_encode %{ 5856 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5857 __ clrldi($dst$$Register, $src$$Register, 0x20); 5858 %} 5859 ins_pipe(pipe_class_default); 5860 %} 5861 5862 // Optimize DecodeN for disjoint base. 5863 // Load base of compressed oops into a register 5864 instruct loadBase(iRegLdst dst) %{ 5865 effect(DEF dst); 5866 5867 format %{ "LoadConst $dst, heapbase" %} 5868 ins_encode %{ 5869 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5870 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 5871 %} 5872 ins_pipe(pipe_class_default); 5873 %} 5874 5875 // Loading ConN must be postalloc expanded so that edges between 5876 // the nodes are safe. They may not interfere with a safepoint. 5877 // GL TODO: This needs three instructions: better put this into the constant pool. 5878 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 5879 match(Set dst src); 5880 ins_cost(DEFAULT_COST*2); 5881 5882 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5883 postalloc_expand %{ 5884 MachNode *m1 = new loadConN_hiNode(); 5885 MachNode *m2 = new loadConN_loNode(); 5886 MachNode *m3 = new clearMs32bNode(); 5887 m1->add_req(NULL); 5888 m2->add_req(NULL, m1); 5889 m3->add_req(NULL, m2); 5890 m1->_opnds[0] = op_dst; 5891 m1->_opnds[1] = op_src; 5892 m2->_opnds[0] = op_dst; 5893 m2->_opnds[1] = op_dst; 5894 m2->_opnds[2] = op_src; 5895 m3->_opnds[0] = op_dst; 5896 m3->_opnds[1] = op_dst; 5897 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5898 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5899 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5900 nodes->push(m1); 5901 nodes->push(m2); 5902 nodes->push(m3); 5903 %} 5904 %} 5905 5906 // We have seen a safepoint between the hi and lo parts, and this node was handled 5907 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 5908 // not a narrow oop. 5909 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 5910 match(Set dst src); 5911 effect(DEF dst, USE src); 5912 ins_cost(DEFAULT_COST); 5913 5914 format %{ "LIS $dst, $src \t// narrow klass hi" %} 5915 size(4); 5916 ins_encode %{ 5917 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5918 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 5919 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 5920 %} 5921 ins_pipe(pipe_class_default); 5922 %} 5923 5924 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 5925 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5926 match(Set dst src1); 5927 effect(TEMP src2); 5928 ins_cost(DEFAULT_COST); 5929 5930 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 5931 size(4); 5932 ins_encode %{ 5933 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5934 __ clrldi($dst$$Register, $src2$$Register, 0x20); 5935 %} 5936 ins_pipe(pipe_class_default); 5937 %} 5938 5939 // This needs a match rule so that build_oop_map knows this is 5940 // not a narrow oop. 5941 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5942 match(Set dst src1); 5943 effect(TEMP src2); 5944 ins_cost(DEFAULT_COST); 5945 5946 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 5947 size(4); 5948 ins_encode %{ 5949 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5950 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 5951 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5952 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 5953 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 5954 5955 __ relocate(rspec, 1); 5956 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 5957 %} 5958 ins_pipe(pipe_class_default); 5959 %} 5960 5961 // Loading ConNKlass must be postalloc expanded so that edges between 5962 // the nodes are safe. They may not interfere with a safepoint. 5963 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 5964 match(Set dst src); 5965 ins_cost(DEFAULT_COST*2); 5966 5967 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5968 postalloc_expand %{ 5969 // Load high bits into register. Sign extended. 5970 MachNode *m1 = new loadConNKlass_hiNode(); 5971 m1->add_req(NULL); 5972 m1->_opnds[0] = op_dst; 5973 m1->_opnds[1] = op_src; 5974 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5975 nodes->push(m1); 5976 5977 MachNode *m2 = m1; 5978 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 5979 // Value might be 1-extended. Mask out these bits. 5980 m2 = new loadConNKlass_maskNode(); 5981 m2->add_req(NULL, m1); 5982 m2->_opnds[0] = op_dst; 5983 m2->_opnds[1] = op_src; 5984 m2->_opnds[2] = op_dst; 5985 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5986 nodes->push(m2); 5987 } 5988 5989 MachNode *m3 = new loadConNKlass_loNode(); 5990 m3->add_req(NULL, m2); 5991 m3->_opnds[0] = op_dst; 5992 m3->_opnds[1] = op_src; 5993 m3->_opnds[2] = op_dst; 5994 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5995 nodes->push(m3); 5996 %} 5997 %} 5998 5999 // 0x1 is used in object initialization (initial object header). 6000 // No constant pool entries required. 6001 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6002 match(Set dst src); 6003 6004 format %{ "LI $dst, $src \t// ptr" %} 6005 size(4); 6006 ins_encode %{ 6007 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6008 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6009 %} 6010 ins_pipe(pipe_class_default); 6011 %} 6012 6013 // Expand node for constant pool load: small offset. 6014 // The match rule is needed to generate the correct bottom_type(), 6015 // however this node should never match. The use of predicate is not 6016 // possible since ADLC forbids predicates for chain rules. The higher 6017 // costs do not prevent matching in this case. For that reason the 6018 // operand immP_NM with predicate(false) is used. 6019 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6020 match(Set dst src); 6021 effect(TEMP toc); 6022 6023 ins_num_consts(1); 6024 6025 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6026 size(4); 6027 ins_encode( enc_load_long_constP(dst, src, toc) ); 6028 ins_pipe(pipe_class_memory); 6029 %} 6030 6031 // Expand node for constant pool load: large offset. 6032 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6033 effect(DEF dst, USE src, USE toc); 6034 predicate(false); 6035 6036 ins_num_consts(1); 6037 ins_field_const_toc_offset(int); 6038 6039 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6040 size(4); 6041 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6042 ins_pipe(pipe_class_default); 6043 %} 6044 6045 // Expand node for constant pool load: large offset. 6046 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6047 match(Set dst src); 6048 effect(TEMP base); 6049 6050 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6051 6052 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6053 size(4); 6054 ins_encode %{ 6055 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6056 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6057 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6058 %} 6059 ins_pipe(pipe_class_memory); 6060 %} 6061 6062 // Load pointer constant from constant table. Expand in case an 6063 // offset > 16 bit is needed. 6064 // Adlc adds toc node MachConstantTableBase. 6065 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6066 match(Set dst src); 6067 ins_cost(MEMORY_REF_COST); 6068 6069 // This rule does not use "expand" because then 6070 // the result type is not known to be an Oop. An ADLC 6071 // enhancement will be needed to make that work - not worth it! 6072 6073 // If this instruction rematerializes, it prolongs the live range 6074 // of the toc node, causing illegal graphs. 6075 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6076 ins_cannot_rematerialize(true); 6077 6078 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6079 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6080 %} 6081 6082 // Expand node for constant pool load: small offset. 6083 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6084 effect(DEF dst, USE src, USE toc); 6085 ins_cost(MEMORY_REF_COST); 6086 6087 ins_num_consts(1); 6088 6089 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6090 size(4); 6091 ins_encode %{ 6092 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6093 address float_address = __ float_constant($src$$constant); 6094 if (float_address == NULL) { 6095 ciEnv::current()->record_out_of_memory_failure(); 6096 return; 6097 } 6098 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6099 %} 6100 ins_pipe(pipe_class_memory); 6101 %} 6102 6103 // Expand node for constant pool load: large offset. 6104 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6105 effect(DEF dst, USE src, USE toc); 6106 ins_cost(MEMORY_REF_COST); 6107 6108 ins_num_consts(1); 6109 6110 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6111 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6112 "ADDIS $toc, $toc, -offset_hi"%} 6113 size(12); 6114 ins_encode %{ 6115 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6116 FloatRegister Rdst = $dst$$FloatRegister; 6117 Register Rtoc = $toc$$Register; 6118 address float_address = __ float_constant($src$$constant); 6119 if (float_address == NULL) { 6120 ciEnv::current()->record_out_of_memory_failure(); 6121 return; 6122 } 6123 int offset = __ offset_to_method_toc(float_address); 6124 int hi = (offset + (1<<15))>>16; 6125 int lo = offset - hi * (1<<16); 6126 6127 __ addis(Rtoc, Rtoc, hi); 6128 __ lfs(Rdst, lo, Rtoc); 6129 __ addis(Rtoc, Rtoc, -hi); 6130 %} 6131 ins_pipe(pipe_class_memory); 6132 %} 6133 6134 // Adlc adds toc node MachConstantTableBase. 6135 instruct loadConF_Ex(regF dst, immF src) %{ 6136 match(Set dst src); 6137 ins_cost(MEMORY_REF_COST); 6138 6139 // See loadConP. 6140 ins_cannot_rematerialize(true); 6141 6142 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6143 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6144 %} 6145 6146 // Expand node for constant pool load: small offset. 6147 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6148 effect(DEF dst, USE src, USE toc); 6149 ins_cost(MEMORY_REF_COST); 6150 6151 ins_num_consts(1); 6152 6153 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6154 size(4); 6155 ins_encode %{ 6156 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6157 address float_address = __ double_constant($src$$constant); 6158 if (float_address == NULL) { 6159 ciEnv::current()->record_out_of_memory_failure(); 6160 return; 6161 } 6162 int offset = __ offset_to_method_toc(float_address); 6163 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6164 %} 6165 ins_pipe(pipe_class_memory); 6166 %} 6167 6168 // Expand node for constant pool load: large offset. 6169 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6170 effect(DEF dst, USE src, USE toc); 6171 ins_cost(MEMORY_REF_COST); 6172 6173 ins_num_consts(1); 6174 6175 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6176 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6177 "ADDIS $toc, $toc, -offset_hi" %} 6178 size(12); 6179 ins_encode %{ 6180 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6181 FloatRegister Rdst = $dst$$FloatRegister; 6182 Register Rtoc = $toc$$Register; 6183 address float_address = __ double_constant($src$$constant); 6184 if (float_address == NULL) { 6185 ciEnv::current()->record_out_of_memory_failure(); 6186 return; 6187 } 6188 int offset = __ offset_to_method_toc(float_address); 6189 int hi = (offset + (1<<15))>>16; 6190 int lo = offset - hi * (1<<16); 6191 6192 __ addis(Rtoc, Rtoc, hi); 6193 __ lfd(Rdst, lo, Rtoc); 6194 __ addis(Rtoc, Rtoc, -hi); 6195 %} 6196 ins_pipe(pipe_class_memory); 6197 %} 6198 6199 // Adlc adds toc node MachConstantTableBase. 6200 instruct loadConD_Ex(regD dst, immD src) %{ 6201 match(Set dst src); 6202 ins_cost(MEMORY_REF_COST); 6203 6204 // See loadConP. 6205 ins_cannot_rematerialize(true); 6206 6207 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6208 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6209 %} 6210 6211 // Prefetch instructions. 6212 // Must be safe to execute with invalid address (cannot fault). 6213 6214 // Special prefetch versions which use the dcbz instruction. 6215 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6216 match(PrefetchAllocation (AddP mem src)); 6217 predicate(AllocatePrefetchStyle == 3); 6218 ins_cost(MEMORY_REF_COST); 6219 6220 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6221 size(4); 6222 ins_encode %{ 6223 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6224 __ dcbz($src$$Register, $mem$$base$$Register); 6225 %} 6226 ins_pipe(pipe_class_memory); 6227 %} 6228 6229 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6230 match(PrefetchAllocation mem); 6231 predicate(AllocatePrefetchStyle == 3); 6232 ins_cost(MEMORY_REF_COST); 6233 6234 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6235 size(4); 6236 ins_encode %{ 6237 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6238 __ dcbz($mem$$base$$Register); 6239 %} 6240 ins_pipe(pipe_class_memory); 6241 %} 6242 6243 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6244 match(PrefetchAllocation (AddP mem src)); 6245 predicate(AllocatePrefetchStyle != 3); 6246 ins_cost(MEMORY_REF_COST); 6247 6248 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6249 size(4); 6250 ins_encode %{ 6251 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6252 __ dcbtst($src$$Register, $mem$$base$$Register); 6253 %} 6254 ins_pipe(pipe_class_memory); 6255 %} 6256 6257 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6258 match(PrefetchAllocation mem); 6259 predicate(AllocatePrefetchStyle != 3); 6260 ins_cost(MEMORY_REF_COST); 6261 6262 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6263 size(4); 6264 ins_encode %{ 6265 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6266 __ dcbtst($mem$$base$$Register); 6267 %} 6268 ins_pipe(pipe_class_memory); 6269 %} 6270 6271 //----------Store Instructions------------------------------------------------- 6272 6273 // Store Byte 6274 instruct storeB(memory mem, iRegIsrc src) %{ 6275 match(Set mem (StoreB mem src)); 6276 ins_cost(MEMORY_REF_COST); 6277 6278 format %{ "STB $src, $mem \t// byte" %} 6279 size(4); 6280 ins_encode %{ 6281 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6282 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6283 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6284 %} 6285 ins_pipe(pipe_class_memory); 6286 %} 6287 6288 // Store Char/Short 6289 instruct storeC(memory mem, iRegIsrc src) %{ 6290 match(Set mem (StoreC mem src)); 6291 ins_cost(MEMORY_REF_COST); 6292 6293 format %{ "STH $src, $mem \t// short" %} 6294 size(4); 6295 ins_encode %{ 6296 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6297 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6298 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6299 %} 6300 ins_pipe(pipe_class_memory); 6301 %} 6302 6303 // Store Integer 6304 instruct storeI(memory mem, iRegIsrc src) %{ 6305 match(Set mem (StoreI mem src)); 6306 ins_cost(MEMORY_REF_COST); 6307 6308 format %{ "STW $src, $mem" %} 6309 size(4); 6310 ins_encode( enc_stw(src, mem) ); 6311 ins_pipe(pipe_class_memory); 6312 %} 6313 6314 // ConvL2I + StoreI. 6315 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6316 match(Set mem (StoreI mem (ConvL2I src))); 6317 ins_cost(MEMORY_REF_COST); 6318 6319 format %{ "STW l2i($src), $mem" %} 6320 size(4); 6321 ins_encode( enc_stw(src, mem) ); 6322 ins_pipe(pipe_class_memory); 6323 %} 6324 6325 // Store Long 6326 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6327 match(Set mem (StoreL mem src)); 6328 ins_cost(MEMORY_REF_COST); 6329 6330 format %{ "STD $src, $mem \t// long" %} 6331 size(4); 6332 ins_encode( enc_std(src, mem) ); 6333 ins_pipe(pipe_class_memory); 6334 %} 6335 6336 // Store super word nodes. 6337 6338 // Store Aligned Packed Byte long register to memory 6339 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6340 predicate(n->as_StoreVector()->memory_size() == 8); 6341 match(Set mem (StoreVector mem src)); 6342 ins_cost(MEMORY_REF_COST); 6343 6344 format %{ "STD $mem, $src \t// packed8B" %} 6345 size(4); 6346 ins_encode( enc_std(src, mem) ); 6347 ins_pipe(pipe_class_memory); 6348 %} 6349 6350 // Store Compressed Oop 6351 instruct storeN(memory dst, iRegN_P2N src) %{ 6352 match(Set dst (StoreN dst src)); 6353 ins_cost(MEMORY_REF_COST); 6354 6355 format %{ "STW $src, $dst \t// compressed oop" %} 6356 size(4); 6357 ins_encode( enc_stw(src, dst) ); 6358 ins_pipe(pipe_class_memory); 6359 %} 6360 6361 // Store Compressed KLass 6362 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6363 match(Set dst (StoreNKlass dst src)); 6364 ins_cost(MEMORY_REF_COST); 6365 6366 format %{ "STW $src, $dst \t// compressed klass" %} 6367 size(4); 6368 ins_encode( enc_stw(src, dst) ); 6369 ins_pipe(pipe_class_memory); 6370 %} 6371 6372 // Store Pointer 6373 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6374 match(Set dst (StoreP dst src)); 6375 ins_cost(MEMORY_REF_COST); 6376 6377 format %{ "STD $src, $dst \t// ptr" %} 6378 size(4); 6379 ins_encode( enc_std(src, dst) ); 6380 ins_pipe(pipe_class_memory); 6381 %} 6382 6383 // Store Float 6384 instruct storeF(memory mem, regF src) %{ 6385 match(Set mem (StoreF mem src)); 6386 ins_cost(MEMORY_REF_COST); 6387 6388 format %{ "STFS $src, $mem" %} 6389 size(4); 6390 ins_encode( enc_stfs(src, mem) ); 6391 ins_pipe(pipe_class_memory); 6392 %} 6393 6394 // Store Double 6395 instruct storeD(memory mem, regD src) %{ 6396 match(Set mem (StoreD mem src)); 6397 ins_cost(MEMORY_REF_COST); 6398 6399 format %{ "STFD $src, $mem" %} 6400 size(4); 6401 ins_encode( enc_stfd(src, mem) ); 6402 ins_pipe(pipe_class_memory); 6403 %} 6404 6405 //----------Store Instructions With Zeros-------------------------------------- 6406 6407 // Card-mark for CMS garbage collection. 6408 // This cardmark does an optimization so that it must not always 6409 // do a releasing store. For this, it gets the address of 6410 // CMSCollectorCardTableModRefBSExt::_requires_release as input. 6411 // (Using releaseFieldAddr in the match rule is a hack.) 6412 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6413 match(Set mem (StoreCM mem releaseFieldAddr)); 6414 effect(TEMP crx); 6415 predicate(false); 6416 ins_cost(MEMORY_REF_COST); 6417 6418 // See loadConP. 6419 ins_cannot_rematerialize(true); 6420 6421 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6422 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6423 ins_pipe(pipe_class_memory); 6424 %} 6425 6426 // Card-mark for CMS garbage collection. 6427 // This cardmark does an optimization so that it must not always 6428 // do a releasing store. For this, it needs the constant address of 6429 // CMSCollectorCardTableModRefBSExt::_requires_release. 6430 // This constant address is split off here by expand so we can use 6431 // adlc / matcher functionality to load it from the constant section. 6432 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6433 match(Set mem (StoreCM mem zero)); 6434 predicate(UseConcMarkSweepGC); 6435 6436 expand %{ 6437 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableModRefBSExt::requires_release_address() */ %} 6438 iRegLdst releaseFieldAddress; 6439 flagsReg crx; 6440 loadConL_Ex(releaseFieldAddress, baseImm); 6441 storeCM_CMS(mem, releaseFieldAddress, crx); 6442 %} 6443 %} 6444 6445 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6446 match(Set mem (StoreCM mem zero)); 6447 predicate(UseG1GC); 6448 ins_cost(MEMORY_REF_COST); 6449 6450 ins_cannot_rematerialize(true); 6451 6452 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6453 size(8); 6454 ins_encode %{ 6455 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6456 __ li(R0, 0); 6457 //__ release(); // G1: oops are allowed to get visible after dirty marking 6458 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6459 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6460 %} 6461 ins_pipe(pipe_class_memory); 6462 %} 6463 6464 // Convert oop pointer into compressed form. 6465 6466 // Nodes for postalloc expand. 6467 6468 // Shift node for expand. 6469 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6470 // The match rule is needed to make it a 'MachTypeNode'! 6471 match(Set dst (EncodeP src)); 6472 predicate(false); 6473 6474 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6475 size(4); 6476 ins_encode %{ 6477 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6478 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6479 %} 6480 ins_pipe(pipe_class_default); 6481 %} 6482 6483 // Add node for expand. 6484 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6485 // The match rule is needed to make it a 'MachTypeNode'! 6486 match(Set dst (EncodeP src)); 6487 predicate(false); 6488 6489 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6490 ins_encode %{ 6491 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6492 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6493 %} 6494 ins_pipe(pipe_class_default); 6495 %} 6496 6497 // Conditional sub base. 6498 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6499 // The match rule is needed to make it a 'MachTypeNode'! 6500 match(Set dst (EncodeP (Binary crx src1))); 6501 predicate(false); 6502 6503 format %{ "BEQ $crx, done\n\t" 6504 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6505 "done:" %} 6506 ins_encode %{ 6507 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6508 Label done; 6509 __ beq($crx$$CondRegister, done); 6510 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6511 __ bind(done); 6512 %} 6513 ins_pipe(pipe_class_default); 6514 %} 6515 6516 // Power 7 can use isel instruction 6517 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6518 // The match rule is needed to make it a 'MachTypeNode'! 6519 match(Set dst (EncodeP (Binary crx src1))); 6520 predicate(false); 6521 6522 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6523 size(4); 6524 ins_encode %{ 6525 // This is a Power7 instruction for which no machine description exists. 6526 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6527 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6528 %} 6529 ins_pipe(pipe_class_default); 6530 %} 6531 6532 // Disjoint narrow oop base. 6533 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6534 match(Set dst (EncodeP src)); 6535 predicate(Universe::narrow_oop_base_disjoint()); 6536 6537 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6538 size(4); 6539 ins_encode %{ 6540 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6541 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 6542 %} 6543 ins_pipe(pipe_class_default); 6544 %} 6545 6546 // shift != 0, base != 0 6547 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6548 match(Set dst (EncodeP src)); 6549 effect(TEMP crx); 6550 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6551 Universe::narrow_oop_shift() != 0 && 6552 Universe::narrow_oop_base_overlaps()); 6553 6554 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 6555 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 6556 %} 6557 6558 // shift != 0, base != 0 6559 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 6560 match(Set dst (EncodeP src)); 6561 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 6562 Universe::narrow_oop_shift() != 0 && 6563 Universe::narrow_oop_base_overlaps()); 6564 6565 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 6566 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 6567 %} 6568 6569 // shift != 0, base == 0 6570 // TODO: This is the same as encodeP_shift. Merge! 6571 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 6572 match(Set dst (EncodeP src)); 6573 predicate(Universe::narrow_oop_shift() != 0 && 6574 Universe::narrow_oop_base() ==0); 6575 6576 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 6577 size(4); 6578 ins_encode %{ 6579 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6580 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6581 %} 6582 ins_pipe(pipe_class_default); 6583 %} 6584 6585 // Compressed OOPs with narrow_oop_shift == 0. 6586 // shift == 0, base == 0 6587 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 6588 match(Set dst (EncodeP src)); 6589 predicate(Universe::narrow_oop_shift() == 0); 6590 6591 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 6592 // variable size, 0 or 4. 6593 ins_encode %{ 6594 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6595 __ mr_if_needed($dst$$Register, $src$$Register); 6596 %} 6597 ins_pipe(pipe_class_default); 6598 %} 6599 6600 // Decode nodes. 6601 6602 // Shift node for expand. 6603 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 6604 // The match rule is needed to make it a 'MachTypeNode'! 6605 match(Set dst (DecodeN src)); 6606 predicate(false); 6607 6608 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 6609 size(4); 6610 ins_encode %{ 6611 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6612 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6613 %} 6614 ins_pipe(pipe_class_default); 6615 %} 6616 6617 // Add node for expand. 6618 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 6619 // The match rule is needed to make it a 'MachTypeNode'! 6620 match(Set dst (DecodeN src)); 6621 predicate(false); 6622 6623 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 6624 ins_encode %{ 6625 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6626 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6627 %} 6628 ins_pipe(pipe_class_default); 6629 %} 6630 6631 // conditianal add base for expand 6632 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 6633 // The match rule is needed to make it a 'MachTypeNode'! 6634 // NOTICE that the rule is nonsense - we just have to make sure that: 6635 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6636 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6637 match(Set dst (DecodeN (Binary crx src))); 6638 predicate(false); 6639 6640 format %{ "BEQ $crx, done\n\t" 6641 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 6642 "done:" %} 6643 ins_encode %{ 6644 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6645 Label done; 6646 __ beq($crx$$CondRegister, done); 6647 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6648 __ bind(done); 6649 %} 6650 ins_pipe(pipe_class_default); 6651 %} 6652 6653 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6654 // The match rule is needed to make it a 'MachTypeNode'! 6655 // NOTICE that the rule is nonsense - we just have to make sure that: 6656 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6657 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6658 match(Set dst (DecodeN (Binary crx src1))); 6659 predicate(false); 6660 6661 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 6662 size(4); 6663 ins_encode %{ 6664 // This is a Power7 instruction for which no machine description exists. 6665 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6666 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6667 %} 6668 ins_pipe(pipe_class_default); 6669 %} 6670 6671 // shift != 0, base != 0 6672 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6673 match(Set dst (DecodeN src)); 6674 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6675 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6676 Universe::narrow_oop_shift() != 0 && 6677 Universe::narrow_oop_base() != 0); 6678 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 6679 effect(TEMP crx); 6680 6681 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 6682 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 6683 %} 6684 6685 // shift != 0, base == 0 6686 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 6687 match(Set dst (DecodeN src)); 6688 predicate(Universe::narrow_oop_shift() != 0 && 6689 Universe::narrow_oop_base() == 0); 6690 6691 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 6692 size(4); 6693 ins_encode %{ 6694 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6695 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6696 %} 6697 ins_pipe(pipe_class_default); 6698 %} 6699 6700 // Optimize DecodeN for disjoint base. 6701 // Shift narrow oop and or it into register that already contains the heap base. 6702 // Base == dst must hold, and is assured by construction in postaloc_expand. 6703 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 6704 match(Set dst (DecodeN src)); 6705 effect(TEMP base); 6706 predicate(false); 6707 6708 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 6709 size(4); 6710 ins_encode %{ 6711 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 6712 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 6713 %} 6714 ins_pipe(pipe_class_default); 6715 %} 6716 6717 // Optimize DecodeN for disjoint base. 6718 // This node requires only one cycle on the critical path. 6719 // We must postalloc_expand as we can not express use_def effects where 6720 // the used register is L and the def'ed register P. 6721 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 6722 match(Set dst (DecodeN src)); 6723 effect(TEMP_DEF dst); 6724 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6725 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6726 Universe::narrow_oop_base_disjoint()); 6727 ins_cost(DEFAULT_COST); 6728 6729 format %{ "MOV $dst, heapbase \t\n" 6730 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 6731 postalloc_expand %{ 6732 loadBaseNode *n1 = new loadBaseNode(); 6733 n1->add_req(NULL); 6734 n1->_opnds[0] = op_dst; 6735 6736 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6737 n2->add_req(n_region, n_src, n1); 6738 n2->_opnds[0] = op_dst; 6739 n2->_opnds[1] = op_src; 6740 n2->_opnds[2] = op_dst; 6741 n2->_bottom_type = _bottom_type; 6742 6743 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6744 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6745 6746 nodes->push(n1); 6747 nodes->push(n2); 6748 %} 6749 %} 6750 6751 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6752 match(Set dst (DecodeN src)); 6753 effect(TEMP_DEF dst, TEMP crx); 6754 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6755 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6756 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 6757 ins_cost(3 * DEFAULT_COST); 6758 6759 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 6760 postalloc_expand %{ 6761 loadBaseNode *n1 = new loadBaseNode(); 6762 n1->add_req(NULL); 6763 n1->_opnds[0] = op_dst; 6764 6765 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 6766 n_compare->add_req(n_region, n_src); 6767 n_compare->_opnds[0] = op_crx; 6768 n_compare->_opnds[1] = op_src; 6769 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 6770 6771 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6772 n2->add_req(n_region, n_src, n1); 6773 n2->_opnds[0] = op_dst; 6774 n2->_opnds[1] = op_src; 6775 n2->_opnds[2] = op_dst; 6776 n2->_bottom_type = _bottom_type; 6777 6778 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 6779 n_cond_set->add_req(n_region, n_compare, n2); 6780 n_cond_set->_opnds[0] = op_dst; 6781 n_cond_set->_opnds[1] = op_crx; 6782 n_cond_set->_opnds[2] = op_dst; 6783 n_cond_set->_bottom_type = _bottom_type; 6784 6785 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 6786 ra_->set_oop(n_cond_set, true); 6787 6788 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6789 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 6790 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6791 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6792 6793 nodes->push(n1); 6794 nodes->push(n_compare); 6795 nodes->push(n2); 6796 nodes->push(n_cond_set); 6797 %} 6798 %} 6799 6800 // src != 0, shift != 0, base != 0 6801 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 6802 match(Set dst (DecodeN src)); 6803 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6804 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6805 Universe::narrow_oop_shift() != 0 && 6806 Universe::narrow_oop_base() != 0); 6807 ins_cost(2 * DEFAULT_COST); 6808 6809 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 6810 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 6811 %} 6812 6813 // Compressed OOPs with narrow_oop_shift == 0. 6814 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 6815 match(Set dst (DecodeN src)); 6816 predicate(Universe::narrow_oop_shift() == 0); 6817 ins_cost(DEFAULT_COST); 6818 6819 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 6820 // variable size, 0 or 4. 6821 ins_encode %{ 6822 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6823 __ mr_if_needed($dst$$Register, $src$$Register); 6824 %} 6825 ins_pipe(pipe_class_default); 6826 %} 6827 6828 // Convert compressed oop into int for vectors alignment masking. 6829 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 6830 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6831 predicate(Universe::narrow_oop_shift() == 0); 6832 ins_cost(DEFAULT_COST); 6833 6834 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 6835 // variable size, 0 or 4. 6836 ins_encode %{ 6837 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6838 __ mr_if_needed($dst$$Register, $src$$Register); 6839 %} 6840 ins_pipe(pipe_class_default); 6841 %} 6842 6843 // Convert klass pointer into compressed form. 6844 6845 // Nodes for postalloc expand. 6846 6847 // Shift node for expand. 6848 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 6849 // The match rule is needed to make it a 'MachTypeNode'! 6850 match(Set dst (EncodePKlass src)); 6851 predicate(false); 6852 6853 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6854 size(4); 6855 ins_encode %{ 6856 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6857 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6858 %} 6859 ins_pipe(pipe_class_default); 6860 %} 6861 6862 // Add node for expand. 6863 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6864 // The match rule is needed to make it a 'MachTypeNode'! 6865 match(Set dst (EncodePKlass (Binary base src))); 6866 predicate(false); 6867 6868 format %{ "SUB $dst, $base, $src \t// encode" %} 6869 size(4); 6870 ins_encode %{ 6871 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 6872 __ subf($dst$$Register, $base$$Register, $src$$Register); 6873 %} 6874 ins_pipe(pipe_class_default); 6875 %} 6876 6877 // Disjoint narrow oop base. 6878 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6879 match(Set dst (EncodePKlass src)); 6880 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 6881 6882 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6883 size(4); 6884 ins_encode %{ 6885 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6886 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 6887 %} 6888 ins_pipe(pipe_class_default); 6889 %} 6890 6891 // shift != 0, base != 0 6892 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 6893 match(Set dst (EncodePKlass (Binary base src))); 6894 predicate(false); 6895 6896 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6897 postalloc_expand %{ 6898 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 6899 n1->add_req(n_region, n_base, n_src); 6900 n1->_opnds[0] = op_dst; 6901 n1->_opnds[1] = op_base; 6902 n1->_opnds[2] = op_src; 6903 n1->_bottom_type = _bottom_type; 6904 6905 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 6906 n2->add_req(n_region, n1); 6907 n2->_opnds[0] = op_dst; 6908 n2->_opnds[1] = op_dst; 6909 n2->_bottom_type = _bottom_type; 6910 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6911 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6912 6913 nodes->push(n1); 6914 nodes->push(n2); 6915 %} 6916 %} 6917 6918 // shift != 0, base != 0 6919 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 6920 match(Set dst (EncodePKlass src)); 6921 //predicate(Universe::narrow_klass_shift() != 0 && 6922 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 6923 6924 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6925 ins_cost(DEFAULT_COST*2); // Don't count constant. 6926 expand %{ 6927 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 6928 iRegLdst base; 6929 loadConL_Ex(base, baseImm); 6930 encodePKlass_not_null_Ex(dst, base, src); 6931 %} 6932 %} 6933 6934 // Decode nodes. 6935 6936 // Shift node for expand. 6937 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 6938 // The match rule is needed to make it a 'MachTypeNode'! 6939 match(Set dst (DecodeNKlass src)); 6940 predicate(false); 6941 6942 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 6943 size(4); 6944 ins_encode %{ 6945 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6946 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6947 %} 6948 ins_pipe(pipe_class_default); 6949 %} 6950 6951 // Add node for expand. 6952 6953 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6954 // The match rule is needed to make it a 'MachTypeNode'! 6955 match(Set dst (DecodeNKlass (Binary base src))); 6956 predicate(false); 6957 6958 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 6959 size(4); 6960 ins_encode %{ 6961 // TODO: PPC port $archOpcode(ppc64Opcode_add); 6962 __ add($dst$$Register, $base$$Register, $src$$Register); 6963 %} 6964 ins_pipe(pipe_class_default); 6965 %} 6966 6967 // src != 0, shift != 0, base != 0 6968 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 6969 match(Set dst (DecodeNKlass (Binary base src))); 6970 //effect(kill src); // We need a register for the immediate result after shifting. 6971 predicate(false); 6972 6973 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 6974 postalloc_expand %{ 6975 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 6976 n1->add_req(n_region, n_base, n_src); 6977 n1->_opnds[0] = op_dst; 6978 n1->_opnds[1] = op_base; 6979 n1->_opnds[2] = op_src; 6980 n1->_bottom_type = _bottom_type; 6981 6982 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 6983 n2->add_req(n_region, n1); 6984 n2->_opnds[0] = op_dst; 6985 n2->_opnds[1] = op_dst; 6986 n2->_bottom_type = _bottom_type; 6987 6988 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6989 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6990 6991 nodes->push(n1); 6992 nodes->push(n2); 6993 %} 6994 %} 6995 6996 // src != 0, shift != 0, base != 0 6997 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 6998 match(Set dst (DecodeNKlass src)); 6999 // predicate(Universe::narrow_klass_shift() != 0 && 7000 // Universe::narrow_klass_base() != 0); 7001 7002 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7003 7004 ins_cost(DEFAULT_COST*2); // Don't count constant. 7005 expand %{ 7006 // We add first, then we shift. Like this, we can get along with one register less. 7007 // But we have to load the base pre-shifted. 7008 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7009 iRegLdst base; 7010 loadConL_Ex(base, baseImm); 7011 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7012 %} 7013 %} 7014 7015 //----------MemBar Instructions----------------------------------------------- 7016 // Memory barrier flavors 7017 7018 instruct membar_acquire() %{ 7019 match(LoadFence); 7020 ins_cost(4*MEMORY_REF_COST); 7021 7022 format %{ "MEMBAR-acquire" %} 7023 size(4); 7024 ins_encode %{ 7025 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7026 __ acquire(); 7027 %} 7028 ins_pipe(pipe_class_default); 7029 %} 7030 7031 instruct unnecessary_membar_acquire() %{ 7032 match(MemBarAcquire); 7033 ins_cost(0); 7034 7035 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7036 size(0); 7037 ins_encode( /*empty*/ ); 7038 ins_pipe(pipe_class_default); 7039 %} 7040 7041 instruct membar_acquire_lock() %{ 7042 match(MemBarAcquireLock); 7043 ins_cost(0); 7044 7045 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7046 size(0); 7047 ins_encode( /*empty*/ ); 7048 ins_pipe(pipe_class_default); 7049 %} 7050 7051 instruct membar_release() %{ 7052 match(MemBarRelease); 7053 match(StoreFence); 7054 ins_cost(4*MEMORY_REF_COST); 7055 7056 format %{ "MEMBAR-release" %} 7057 size(4); 7058 ins_encode %{ 7059 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7060 __ release(); 7061 %} 7062 ins_pipe(pipe_class_default); 7063 %} 7064 7065 instruct membar_storestore() %{ 7066 match(MemBarStoreStore); 7067 ins_cost(4*MEMORY_REF_COST); 7068 7069 format %{ "MEMBAR-store-store" %} 7070 size(4); 7071 ins_encode %{ 7072 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7073 __ membar(Assembler::StoreStore); 7074 %} 7075 ins_pipe(pipe_class_default); 7076 %} 7077 7078 instruct membar_release_lock() %{ 7079 match(MemBarReleaseLock); 7080 ins_cost(0); 7081 7082 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7083 size(0); 7084 ins_encode( /*empty*/ ); 7085 ins_pipe(pipe_class_default); 7086 %} 7087 7088 instruct membar_volatile() %{ 7089 match(MemBarVolatile); 7090 ins_cost(4*MEMORY_REF_COST); 7091 7092 format %{ "MEMBAR-volatile" %} 7093 size(4); 7094 ins_encode %{ 7095 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7096 __ fence(); 7097 %} 7098 ins_pipe(pipe_class_default); 7099 %} 7100 7101 // This optimization is wrong on PPC. The following pattern is not supported: 7102 // MemBarVolatile 7103 // ^ ^ 7104 // | | 7105 // CtrlProj MemProj 7106 // ^ ^ 7107 // | | 7108 // | Load 7109 // | 7110 // MemBarVolatile 7111 // 7112 // The first MemBarVolatile could get optimized out! According to 7113 // Vladimir, this pattern can not occur on Oracle platforms. 7114 // However, it does occur on PPC64 (because of membars in 7115 // inline_unsafe_load_store). 7116 // 7117 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7118 // Don't forget to look at the implementation of post_store_load_barrier again, 7119 // we did other fixes in that method. 7120 //instruct unnecessary_membar_volatile() %{ 7121 // match(MemBarVolatile); 7122 // predicate(Matcher::post_store_load_barrier(n)); 7123 // ins_cost(0); 7124 // 7125 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7126 // size(0); 7127 // ins_encode( /*empty*/ ); 7128 // ins_pipe(pipe_class_default); 7129 //%} 7130 7131 instruct membar_CPUOrder() %{ 7132 match(MemBarCPUOrder); 7133 ins_cost(0); 7134 7135 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7136 size(0); 7137 ins_encode( /*empty*/ ); 7138 ins_pipe(pipe_class_default); 7139 %} 7140 7141 //----------Conditional Move--------------------------------------------------- 7142 7143 // Cmove using isel. 7144 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7145 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7146 predicate(VM_Version::has_isel()); 7147 ins_cost(DEFAULT_COST); 7148 7149 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7150 size(4); 7151 ins_encode %{ 7152 // This is a Power7 instruction for which no machine description 7153 // exists. Anyways, the scheduler should be off on Power7. 7154 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7155 int cc = $cmp$$cmpcode; 7156 __ isel($dst$$Register, $crx$$CondRegister, 7157 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7158 %} 7159 ins_pipe(pipe_class_default); 7160 %} 7161 7162 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7163 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7164 predicate(!VM_Version::has_isel()); 7165 ins_cost(DEFAULT_COST+BRANCH_COST); 7166 7167 ins_variable_size_depending_on_alignment(true); 7168 7169 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7170 // Worst case is branch + move + stop, no stop without scheduler 7171 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7172 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7173 ins_pipe(pipe_class_default); 7174 %} 7175 7176 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7177 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7178 ins_cost(DEFAULT_COST+BRANCH_COST); 7179 7180 ins_variable_size_depending_on_alignment(true); 7181 7182 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7183 // Worst case is branch + move + stop, no stop without scheduler 7184 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7185 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7186 ins_pipe(pipe_class_default); 7187 %} 7188 7189 // Cmove using isel. 7190 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7191 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7192 predicate(VM_Version::has_isel()); 7193 ins_cost(DEFAULT_COST); 7194 7195 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7196 size(4); 7197 ins_encode %{ 7198 // This is a Power7 instruction for which no machine description 7199 // exists. Anyways, the scheduler should be off on Power7. 7200 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7201 int cc = $cmp$$cmpcode; 7202 __ isel($dst$$Register, $crx$$CondRegister, 7203 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7204 %} 7205 ins_pipe(pipe_class_default); 7206 %} 7207 7208 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7209 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7210 predicate(!VM_Version::has_isel()); 7211 ins_cost(DEFAULT_COST+BRANCH_COST); 7212 7213 ins_variable_size_depending_on_alignment(true); 7214 7215 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7216 // Worst case is branch + move + stop, no stop without scheduler. 7217 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7218 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7219 ins_pipe(pipe_class_default); 7220 %} 7221 7222 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7223 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7224 ins_cost(DEFAULT_COST+BRANCH_COST); 7225 7226 ins_variable_size_depending_on_alignment(true); 7227 7228 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7229 // Worst case is branch + move + stop, no stop without scheduler. 7230 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7231 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7232 ins_pipe(pipe_class_default); 7233 %} 7234 7235 // Cmove using isel. 7236 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7237 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7238 predicate(VM_Version::has_isel()); 7239 ins_cost(DEFAULT_COST); 7240 7241 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7242 size(4); 7243 ins_encode %{ 7244 // This is a Power7 instruction for which no machine description 7245 // exists. Anyways, the scheduler should be off on Power7. 7246 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7247 int cc = $cmp$$cmpcode; 7248 __ isel($dst$$Register, $crx$$CondRegister, 7249 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7250 %} 7251 ins_pipe(pipe_class_default); 7252 %} 7253 7254 // Conditional move for RegN. Only cmov(reg, reg). 7255 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7256 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7257 predicate(!VM_Version::has_isel()); 7258 ins_cost(DEFAULT_COST+BRANCH_COST); 7259 7260 ins_variable_size_depending_on_alignment(true); 7261 7262 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7263 // Worst case is branch + move + stop, no stop without scheduler. 7264 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7265 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7266 ins_pipe(pipe_class_default); 7267 %} 7268 7269 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7270 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7271 ins_cost(DEFAULT_COST+BRANCH_COST); 7272 7273 ins_variable_size_depending_on_alignment(true); 7274 7275 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7276 // Worst case is branch + move + stop, no stop without scheduler. 7277 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7278 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7279 ins_pipe(pipe_class_default); 7280 %} 7281 7282 // Cmove using isel. 7283 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7284 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7285 predicate(VM_Version::has_isel()); 7286 ins_cost(DEFAULT_COST); 7287 7288 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7289 size(4); 7290 ins_encode %{ 7291 // This is a Power7 instruction for which no machine description 7292 // exists. Anyways, the scheduler should be off on Power7. 7293 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7294 int cc = $cmp$$cmpcode; 7295 __ isel($dst$$Register, $crx$$CondRegister, 7296 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7297 %} 7298 ins_pipe(pipe_class_default); 7299 %} 7300 7301 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7302 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7303 predicate(!VM_Version::has_isel()); 7304 ins_cost(DEFAULT_COST+BRANCH_COST); 7305 7306 ins_variable_size_depending_on_alignment(true); 7307 7308 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7309 // Worst case is branch + move + stop, no stop without scheduler. 7310 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7311 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7312 ins_pipe(pipe_class_default); 7313 %} 7314 7315 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7316 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7317 ins_cost(DEFAULT_COST+BRANCH_COST); 7318 7319 ins_variable_size_depending_on_alignment(true); 7320 7321 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7322 // Worst case is branch + move + stop, no stop without scheduler. 7323 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7324 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7325 ins_pipe(pipe_class_default); 7326 %} 7327 7328 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7329 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7330 ins_cost(DEFAULT_COST+BRANCH_COST); 7331 7332 ins_variable_size_depending_on_alignment(true); 7333 7334 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7335 // Worst case is branch + move + stop, no stop without scheduler. 7336 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7337 ins_encode %{ 7338 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7339 Label done; 7340 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7341 // Branch if not (cmp crx). 7342 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7343 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7344 // TODO PPC port __ endgroup_if_needed(_size == 12); 7345 __ bind(done); 7346 %} 7347 ins_pipe(pipe_class_default); 7348 %} 7349 7350 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7351 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7352 ins_cost(DEFAULT_COST+BRANCH_COST); 7353 7354 ins_variable_size_depending_on_alignment(true); 7355 7356 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7357 // Worst case is branch + move + stop, no stop without scheduler. 7358 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7359 ins_encode %{ 7360 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7361 Label done; 7362 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7363 // Branch if not (cmp crx). 7364 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7365 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7366 // TODO PPC port __ endgroup_if_needed(_size == 12); 7367 __ bind(done); 7368 %} 7369 ins_pipe(pipe_class_default); 7370 %} 7371 7372 //----------Conditional_store-------------------------------------------------- 7373 // Conditional-store of the updated heap-top. 7374 // Used during allocation of the shared heap. 7375 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7376 7377 // As compareAndSwapL, but return flag register instead of boolean value in 7378 // int register. 7379 // Used by sun/misc/AtomicLongCSImpl.java. 7380 // Mem_ptr must be a memory operand, else this node does not get 7381 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7382 // can be rematerialized which leads to errors. 7383 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7384 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7385 effect(TEMP cr0); 7386 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7387 ins_encode %{ 7388 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7389 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7390 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7391 noreg, NULL, true); 7392 %} 7393 ins_pipe(pipe_class_default); 7394 %} 7395 7396 // As compareAndSwapP, but return flag register instead of boolean value in 7397 // int register. 7398 // This instruction is matched if UseTLAB is off. 7399 // Mem_ptr must be a memory operand, else this node does not get 7400 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7401 // can be rematerialized which leads to errors. 7402 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7403 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7404 ins_cost(2*MEMORY_REF_COST); 7405 7406 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7407 ins_encode %{ 7408 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7409 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7410 %} 7411 ins_pipe(pipe_class_memory); 7412 %} 7413 7414 // Implement LoadPLocked. Must be ordered against changes of the memory location 7415 // by storePConditional. 7416 // Don't know whether this is ever used. 7417 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7418 match(Set dst (LoadPLocked mem)); 7419 ins_cost(2*MEMORY_REF_COST); 7420 7421 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7422 size(4); 7423 ins_encode %{ 7424 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7425 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7426 %} 7427 ins_pipe(pipe_class_memory); 7428 %} 7429 7430 //----------Compare-And-Swap--------------------------------------------------- 7431 7432 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7433 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7434 // matched. 7435 7436 // Strong versions: 7437 7438 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7439 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7440 predicate(VM_Version::has_lqarx()); 7441 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7442 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7443 ins_encode %{ 7444 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7445 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7446 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7447 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7448 $res$$Register, true); 7449 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7450 __ isync(); 7451 } else { 7452 __ sync(); 7453 } 7454 %} 7455 ins_pipe(pipe_class_default); 7456 %} 7457 7458 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7459 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7460 predicate(!VM_Version::has_lqarx()); 7461 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7462 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7463 ins_encode %{ 7464 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7465 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7466 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7467 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7468 $res$$Register, true); 7469 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7470 __ isync(); 7471 } else { 7472 __ sync(); 7473 } 7474 %} 7475 ins_pipe(pipe_class_default); 7476 %} 7477 7478 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7479 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7480 predicate(VM_Version::has_lqarx()); 7481 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7482 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7483 ins_encode %{ 7484 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7485 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7486 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7487 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7488 $res$$Register, true); 7489 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7490 __ isync(); 7491 } else { 7492 __ sync(); 7493 } 7494 %} 7495 ins_pipe(pipe_class_default); 7496 %} 7497 7498 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7499 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7500 predicate(!VM_Version::has_lqarx()); 7501 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7502 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7503 ins_encode %{ 7504 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7505 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7506 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7507 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7508 $res$$Register, true); 7509 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7510 __ isync(); 7511 } else { 7512 __ sync(); 7513 } 7514 %} 7515 ins_pipe(pipe_class_default); 7516 %} 7517 7518 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7519 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7520 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7521 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7522 ins_encode %{ 7523 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7524 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7525 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7526 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7527 $res$$Register, true); 7528 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7529 __ isync(); 7530 } else { 7531 __ sync(); 7532 } 7533 %} 7534 ins_pipe(pipe_class_default); 7535 %} 7536 7537 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7538 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7539 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7540 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7541 ins_encode %{ 7542 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7543 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7544 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7545 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7546 $res$$Register, true); 7547 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7548 __ isync(); 7549 } else { 7550 __ sync(); 7551 } 7552 %} 7553 ins_pipe(pipe_class_default); 7554 %} 7555 7556 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7557 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 7558 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7559 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7560 ins_encode %{ 7561 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7562 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7563 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7564 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7565 $res$$Register, NULL, true); 7566 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7567 __ isync(); 7568 } else { 7569 __ sync(); 7570 } 7571 %} 7572 ins_pipe(pipe_class_default); 7573 %} 7574 7575 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7576 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 7577 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7578 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7579 ins_encode %{ 7580 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7581 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7582 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7583 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7584 $res$$Register, NULL, true); 7585 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7586 __ isync(); 7587 } else { 7588 __ sync(); 7589 } 7590 %} 7591 ins_pipe(pipe_class_default); 7592 %} 7593 7594 // Weak versions: 7595 7596 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7597 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7598 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7599 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7600 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7601 ins_encode %{ 7602 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7603 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7604 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7605 MacroAssembler::MemBarNone, 7606 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7607 %} 7608 ins_pipe(pipe_class_default); 7609 %} 7610 7611 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7612 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7613 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7614 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7615 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7616 ins_encode %{ 7617 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7618 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7619 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7620 MacroAssembler::MemBarNone, 7621 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7622 %} 7623 ins_pipe(pipe_class_default); 7624 %} 7625 7626 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7627 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7628 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7629 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7630 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7631 ins_encode %{ 7632 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7633 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7634 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7635 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7636 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7637 %} 7638 ins_pipe(pipe_class_default); 7639 %} 7640 7641 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7642 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7643 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7644 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7645 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7646 ins_encode %{ 7647 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7648 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7649 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7650 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7651 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7652 %} 7653 ins_pipe(pipe_class_default); 7654 %} 7655 7656 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7657 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7658 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7659 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7660 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7661 ins_encode %{ 7662 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7663 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7664 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7665 MacroAssembler::MemBarNone, 7666 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7667 %} 7668 ins_pipe(pipe_class_default); 7669 %} 7670 7671 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7672 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7673 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7674 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7675 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7676 ins_encode %{ 7677 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7678 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7679 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7680 MacroAssembler::MemBarNone, 7681 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7682 %} 7683 ins_pipe(pipe_class_default); 7684 %} 7685 7686 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7687 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7688 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7689 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7690 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7691 ins_encode %{ 7692 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7693 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7694 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7695 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7696 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7697 %} 7698 ins_pipe(pipe_class_default); 7699 %} 7700 7701 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7702 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7703 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7704 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7705 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7706 ins_encode %{ 7707 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7708 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7709 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7710 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7711 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7712 %} 7713 ins_pipe(pipe_class_default); 7714 %} 7715 7716 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7717 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7718 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7719 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7720 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7721 ins_encode %{ 7722 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7723 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7724 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7725 MacroAssembler::MemBarNone, 7726 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7727 %} 7728 ins_pipe(pipe_class_default); 7729 %} 7730 7731 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7732 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7733 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7734 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7735 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7736 ins_encode %{ 7737 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7738 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7739 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7740 // value is never passed to caller. 7741 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7742 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7743 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7744 %} 7745 ins_pipe(pipe_class_default); 7746 %} 7747 7748 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7749 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7750 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7751 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7752 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7753 ins_encode %{ 7754 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7755 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7756 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7757 MacroAssembler::MemBarNone, 7758 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7759 %} 7760 ins_pipe(pipe_class_default); 7761 %} 7762 7763 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7764 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7765 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7766 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7767 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7768 ins_encode %{ 7769 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7770 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7771 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7772 // value is never passed to caller. 7773 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7774 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7775 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7776 %} 7777 ins_pipe(pipe_class_default); 7778 %} 7779 7780 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7781 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7782 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7783 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7784 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7785 ins_encode %{ 7786 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7787 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7788 // value is never passed to caller. 7789 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7790 MacroAssembler::MemBarNone, 7791 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7792 %} 7793 ins_pipe(pipe_class_default); 7794 %} 7795 7796 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7797 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7798 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7799 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7800 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 7801 ins_encode %{ 7802 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7803 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7804 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7805 // value is never passed to caller. 7806 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7807 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7808 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7809 %} 7810 ins_pipe(pipe_class_default); 7811 %} 7812 7813 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7814 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7815 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7816 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7817 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7818 ins_encode %{ 7819 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7820 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7821 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7822 MacroAssembler::MemBarNone, 7823 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7824 %} 7825 ins_pipe(pipe_class_default); 7826 %} 7827 7828 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7829 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7830 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7831 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7832 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7833 ins_encode %{ 7834 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7835 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7836 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7837 // value is never passed to caller. 7838 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7839 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7840 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7841 %} 7842 ins_pipe(pipe_class_default); 7843 %} 7844 7845 // CompareAndExchange 7846 7847 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7848 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7849 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7850 effect(TEMP_DEF res, TEMP cr0); 7851 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7852 ins_encode %{ 7853 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7854 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7855 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7856 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7857 noreg, true); 7858 %} 7859 ins_pipe(pipe_class_default); 7860 %} 7861 7862 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7863 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7864 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7865 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7866 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7867 ins_encode %{ 7868 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7869 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7870 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7871 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7872 noreg, true); 7873 %} 7874 ins_pipe(pipe_class_default); 7875 %} 7876 7877 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7878 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7879 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7880 effect(TEMP_DEF res, TEMP cr0); 7881 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7882 ins_encode %{ 7883 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7884 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7885 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7886 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7887 noreg, true); 7888 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7889 __ isync(); 7890 } else { 7891 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7892 __ sync(); 7893 } 7894 %} 7895 ins_pipe(pipe_class_default); 7896 %} 7897 7898 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7899 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7900 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7901 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7902 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7903 ins_encode %{ 7904 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7905 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7906 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7907 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7908 noreg, true); 7909 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7910 __ isync(); 7911 } else { 7912 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7913 __ sync(); 7914 } 7915 %} 7916 ins_pipe(pipe_class_default); 7917 %} 7918 7919 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7920 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7921 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7922 effect(TEMP_DEF res, TEMP cr0); 7923 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7924 ins_encode %{ 7925 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7926 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7927 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7928 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7929 noreg, true); 7930 %} 7931 ins_pipe(pipe_class_default); 7932 %} 7933 7934 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7935 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7936 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7937 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7938 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7939 ins_encode %{ 7940 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7941 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7942 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7943 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7944 noreg, true); 7945 %} 7946 ins_pipe(pipe_class_default); 7947 %} 7948 7949 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7950 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7951 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7952 effect(TEMP_DEF res, TEMP cr0); 7953 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7954 ins_encode %{ 7955 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7956 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7957 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7958 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7959 noreg, true); 7960 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7961 __ isync(); 7962 } else { 7963 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7964 __ sync(); 7965 } 7966 %} 7967 ins_pipe(pipe_class_default); 7968 %} 7969 7970 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7971 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7972 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7973 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7974 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7975 ins_encode %{ 7976 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7977 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7978 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7979 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7980 noreg, true); 7981 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7982 __ isync(); 7983 } else { 7984 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7985 __ sync(); 7986 } 7987 %} 7988 ins_pipe(pipe_class_default); 7989 %} 7990 7991 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7992 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 7993 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7994 effect(TEMP_DEF res, TEMP cr0); 7995 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 7996 ins_encode %{ 7997 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7998 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7999 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8000 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8001 noreg, true); 8002 %} 8003 ins_pipe(pipe_class_default); 8004 %} 8005 8006 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8007 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8008 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8009 effect(TEMP_DEF res, TEMP cr0); 8010 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8011 ins_encode %{ 8012 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8013 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8014 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8015 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8016 noreg, true); 8017 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8018 __ isync(); 8019 } else { 8020 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8021 __ sync(); 8022 } 8023 %} 8024 ins_pipe(pipe_class_default); 8025 %} 8026 8027 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8028 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8029 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8030 effect(TEMP_DEF res, TEMP cr0); 8031 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8032 ins_encode %{ 8033 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8034 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8035 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8036 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8037 noreg, true); 8038 %} 8039 ins_pipe(pipe_class_default); 8040 %} 8041 8042 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8043 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8044 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8045 effect(TEMP_DEF res, TEMP cr0); 8046 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8047 ins_encode %{ 8048 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8049 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8050 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8051 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8052 noreg, true); 8053 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8054 __ isync(); 8055 } else { 8056 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8057 __ sync(); 8058 } 8059 %} 8060 ins_pipe(pipe_class_default); 8061 %} 8062 8063 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8064 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8065 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8066 effect(TEMP_DEF res, TEMP cr0); 8067 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8068 ins_encode %{ 8069 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8070 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8071 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8072 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8073 noreg, NULL, true); 8074 %} 8075 ins_pipe(pipe_class_default); 8076 %} 8077 8078 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8079 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8080 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8081 effect(TEMP_DEF res, TEMP cr0); 8082 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8083 ins_encode %{ 8084 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8085 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8086 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8087 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8088 noreg, NULL, true); 8089 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8090 __ isync(); 8091 } else { 8092 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8093 __ sync(); 8094 } 8095 %} 8096 ins_pipe(pipe_class_default); 8097 %} 8098 8099 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8100 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8101 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8102 effect(TEMP_DEF res, TEMP cr0); 8103 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8104 ins_encode %{ 8105 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8106 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8107 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8108 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8109 noreg, NULL, true); 8110 %} 8111 ins_pipe(pipe_class_default); 8112 %} 8113 8114 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8115 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8116 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8117 effect(TEMP_DEF res, TEMP cr0); 8118 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8119 ins_encode %{ 8120 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8121 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8122 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8123 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8124 noreg, NULL, true); 8125 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8126 __ isync(); 8127 } else { 8128 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8129 __ sync(); 8130 } 8131 %} 8132 ins_pipe(pipe_class_default); 8133 %} 8134 8135 // Special RMW 8136 8137 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8138 match(Set res (GetAndAddB mem_ptr src)); 8139 predicate(VM_Version::has_lqarx()); 8140 effect(TEMP_DEF res, TEMP cr0); 8141 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8142 ins_encode %{ 8143 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8144 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8145 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8146 __ isync(); 8147 } else { 8148 __ sync(); 8149 } 8150 %} 8151 ins_pipe(pipe_class_default); 8152 %} 8153 8154 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8155 match(Set res (GetAndAddB mem_ptr src)); 8156 predicate(!VM_Version::has_lqarx()); 8157 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8158 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8159 ins_encode %{ 8160 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8161 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8162 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8163 __ isync(); 8164 } else { 8165 __ sync(); 8166 } 8167 %} 8168 ins_pipe(pipe_class_default); 8169 %} 8170 8171 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8172 match(Set res (GetAndAddS mem_ptr src)); 8173 predicate(VM_Version::has_lqarx()); 8174 effect(TEMP_DEF res, TEMP cr0); 8175 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8176 ins_encode %{ 8177 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8178 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8179 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8180 __ isync(); 8181 } else { 8182 __ sync(); 8183 } 8184 %} 8185 ins_pipe(pipe_class_default); 8186 %} 8187 8188 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8189 match(Set res (GetAndAddS mem_ptr src)); 8190 predicate(!VM_Version::has_lqarx()); 8191 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8192 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8193 ins_encode %{ 8194 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8195 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8196 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8197 __ isync(); 8198 } else { 8199 __ sync(); 8200 } 8201 %} 8202 ins_pipe(pipe_class_default); 8203 %} 8204 8205 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8206 match(Set res (GetAndAddI mem_ptr src)); 8207 effect(TEMP_DEF res, TEMP cr0); 8208 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8209 ins_encode %{ 8210 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8211 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8212 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8213 __ isync(); 8214 } else { 8215 __ sync(); 8216 } 8217 %} 8218 ins_pipe(pipe_class_default); 8219 %} 8220 8221 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8222 match(Set res (GetAndAddL mem_ptr src)); 8223 effect(TEMP_DEF res, TEMP cr0); 8224 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8225 ins_encode %{ 8226 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8227 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8228 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8229 __ isync(); 8230 } else { 8231 __ sync(); 8232 } 8233 %} 8234 ins_pipe(pipe_class_default); 8235 %} 8236 8237 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8238 match(Set res (GetAndSetB mem_ptr src)); 8239 predicate(VM_Version::has_lqarx()); 8240 effect(TEMP_DEF res, TEMP cr0); 8241 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8242 ins_encode %{ 8243 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8244 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8245 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8246 __ isync(); 8247 } else { 8248 __ sync(); 8249 } 8250 %} 8251 ins_pipe(pipe_class_default); 8252 %} 8253 8254 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8255 match(Set res (GetAndSetB mem_ptr src)); 8256 predicate(!VM_Version::has_lqarx()); 8257 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8258 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8259 ins_encode %{ 8260 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8261 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8262 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8263 __ isync(); 8264 } else { 8265 __ sync(); 8266 } 8267 %} 8268 ins_pipe(pipe_class_default); 8269 %} 8270 8271 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8272 match(Set res (GetAndSetS mem_ptr src)); 8273 predicate(VM_Version::has_lqarx()); 8274 effect(TEMP_DEF res, TEMP cr0); 8275 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8276 ins_encode %{ 8277 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8278 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8279 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8280 __ isync(); 8281 } else { 8282 __ sync(); 8283 } 8284 %} 8285 ins_pipe(pipe_class_default); 8286 %} 8287 8288 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8289 match(Set res (GetAndSetS mem_ptr src)); 8290 predicate(!VM_Version::has_lqarx()); 8291 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8292 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8293 ins_encode %{ 8294 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8295 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8296 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8297 __ isync(); 8298 } else { 8299 __ sync(); 8300 } 8301 %} 8302 ins_pipe(pipe_class_default); 8303 %} 8304 8305 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8306 match(Set res (GetAndSetI mem_ptr src)); 8307 effect(TEMP_DEF res, TEMP cr0); 8308 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8309 ins_encode %{ 8310 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8311 MacroAssembler::cmpxchgx_hint_atomic_update()); 8312 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8313 __ isync(); 8314 } else { 8315 __ sync(); 8316 } 8317 %} 8318 ins_pipe(pipe_class_default); 8319 %} 8320 8321 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8322 match(Set res (GetAndSetL mem_ptr src)); 8323 effect(TEMP_DEF res, TEMP cr0); 8324 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8325 ins_encode %{ 8326 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8327 MacroAssembler::cmpxchgx_hint_atomic_update()); 8328 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8329 __ isync(); 8330 } else { 8331 __ sync(); 8332 } 8333 %} 8334 ins_pipe(pipe_class_default); 8335 %} 8336 8337 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8338 match(Set res (GetAndSetP mem_ptr src)); 8339 effect(TEMP_DEF res, TEMP cr0); 8340 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8341 ins_encode %{ 8342 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8343 MacroAssembler::cmpxchgx_hint_atomic_update()); 8344 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8345 __ isync(); 8346 } else { 8347 __ sync(); 8348 } 8349 %} 8350 ins_pipe(pipe_class_default); 8351 %} 8352 8353 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8354 match(Set res (GetAndSetN mem_ptr src)); 8355 effect(TEMP_DEF res, TEMP cr0); 8356 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8357 ins_encode %{ 8358 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8359 MacroAssembler::cmpxchgx_hint_atomic_update()); 8360 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8361 __ isync(); 8362 } else { 8363 __ sync(); 8364 } 8365 %} 8366 ins_pipe(pipe_class_default); 8367 %} 8368 8369 //----------Arithmetic Instructions-------------------------------------------- 8370 // Addition Instructions 8371 8372 // Register Addition 8373 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8374 match(Set dst (AddI src1 src2)); 8375 format %{ "ADD $dst, $src1, $src2" %} 8376 size(4); 8377 ins_encode %{ 8378 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8379 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8380 %} 8381 ins_pipe(pipe_class_default); 8382 %} 8383 8384 // Expand does not work with above instruct. (??) 8385 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8386 // no match-rule 8387 effect(DEF dst, USE src1, USE src2); 8388 format %{ "ADD $dst, $src1, $src2" %} 8389 size(4); 8390 ins_encode %{ 8391 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8392 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8393 %} 8394 ins_pipe(pipe_class_default); 8395 %} 8396 8397 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8398 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8399 ins_cost(DEFAULT_COST*3); 8400 8401 expand %{ 8402 // FIXME: we should do this in the ideal world. 8403 iRegIdst tmp1; 8404 iRegIdst tmp2; 8405 addI_reg_reg(tmp1, src1, src2); 8406 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8407 addI_reg_reg(dst, tmp1, tmp2); 8408 %} 8409 %} 8410 8411 // Immediate Addition 8412 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8413 match(Set dst (AddI src1 src2)); 8414 format %{ "ADDI $dst, $src1, $src2" %} 8415 size(4); 8416 ins_encode %{ 8417 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8418 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8419 %} 8420 ins_pipe(pipe_class_default); 8421 %} 8422 8423 // Immediate Addition with 16-bit shifted operand 8424 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8425 match(Set dst (AddI src1 src2)); 8426 format %{ "ADDIS $dst, $src1, $src2" %} 8427 size(4); 8428 ins_encode %{ 8429 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8430 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8431 %} 8432 ins_pipe(pipe_class_default); 8433 %} 8434 8435 // Long Addition 8436 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8437 match(Set dst (AddL src1 src2)); 8438 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8439 size(4); 8440 ins_encode %{ 8441 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8442 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8443 %} 8444 ins_pipe(pipe_class_default); 8445 %} 8446 8447 // Expand does not work with above instruct. (??) 8448 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8449 // no match-rule 8450 effect(DEF dst, USE src1, USE src2); 8451 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8452 size(4); 8453 ins_encode %{ 8454 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8455 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8456 %} 8457 ins_pipe(pipe_class_default); 8458 %} 8459 8460 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8461 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8462 ins_cost(DEFAULT_COST*3); 8463 8464 expand %{ 8465 // FIXME: we should do this in the ideal world. 8466 iRegLdst tmp1; 8467 iRegLdst tmp2; 8468 addL_reg_reg(tmp1, src1, src2); 8469 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8470 addL_reg_reg(dst, tmp1, tmp2); 8471 %} 8472 %} 8473 8474 // AddL + ConvL2I. 8475 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8476 match(Set dst (ConvL2I (AddL src1 src2))); 8477 8478 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8479 size(4); 8480 ins_encode %{ 8481 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8482 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8483 %} 8484 ins_pipe(pipe_class_default); 8485 %} 8486 8487 // No constant pool entries required. 8488 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8489 match(Set dst (AddL src1 src2)); 8490 8491 format %{ "ADDI $dst, $src1, $src2" %} 8492 size(4); 8493 ins_encode %{ 8494 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8495 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8496 %} 8497 ins_pipe(pipe_class_default); 8498 %} 8499 8500 // Long Immediate Addition with 16-bit shifted operand. 8501 // No constant pool entries required. 8502 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8503 match(Set dst (AddL src1 src2)); 8504 8505 format %{ "ADDIS $dst, $src1, $src2" %} 8506 size(4); 8507 ins_encode %{ 8508 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8509 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8510 %} 8511 ins_pipe(pipe_class_default); 8512 %} 8513 8514 // Pointer Register Addition 8515 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8516 match(Set dst (AddP src1 src2)); 8517 format %{ "ADD $dst, $src1, $src2" %} 8518 size(4); 8519 ins_encode %{ 8520 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8521 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8522 %} 8523 ins_pipe(pipe_class_default); 8524 %} 8525 8526 // Pointer Immediate Addition 8527 // No constant pool entries required. 8528 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8529 match(Set dst (AddP src1 src2)); 8530 8531 format %{ "ADDI $dst, $src1, $src2" %} 8532 size(4); 8533 ins_encode %{ 8534 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8535 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8536 %} 8537 ins_pipe(pipe_class_default); 8538 %} 8539 8540 // Pointer Immediate Addition with 16-bit shifted operand. 8541 // No constant pool entries required. 8542 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8543 match(Set dst (AddP src1 src2)); 8544 8545 format %{ "ADDIS $dst, $src1, $src2" %} 8546 size(4); 8547 ins_encode %{ 8548 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8549 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8550 %} 8551 ins_pipe(pipe_class_default); 8552 %} 8553 8554 //--------------------- 8555 // Subtraction Instructions 8556 8557 // Register Subtraction 8558 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8559 match(Set dst (SubI src1 src2)); 8560 format %{ "SUBF $dst, $src2, $src1" %} 8561 size(4); 8562 ins_encode %{ 8563 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8564 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8565 %} 8566 ins_pipe(pipe_class_default); 8567 %} 8568 8569 // Immediate Subtraction 8570 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 8571 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 8572 8573 // SubI from constant (using subfic). 8574 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 8575 match(Set dst (SubI src1 src2)); 8576 format %{ "SUBI $dst, $src1, $src2" %} 8577 8578 size(4); 8579 ins_encode %{ 8580 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 8581 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 8582 %} 8583 ins_pipe(pipe_class_default); 8584 %} 8585 8586 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 8587 // positive integers and 0xF...F for negative ones. 8588 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 8589 // no match-rule, false predicate 8590 effect(DEF dst, USE src); 8591 predicate(false); 8592 8593 format %{ "SRAWI $dst, $src, #31" %} 8594 size(4); 8595 ins_encode %{ 8596 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 8597 __ srawi($dst$$Register, $src$$Register, 0x1f); 8598 %} 8599 ins_pipe(pipe_class_default); 8600 %} 8601 8602 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 8603 match(Set dst (AbsI src)); 8604 ins_cost(DEFAULT_COST*3); 8605 8606 expand %{ 8607 iRegIdst tmp1; 8608 iRegIdst tmp2; 8609 signmask32I_regI(tmp1, src); 8610 xorI_reg_reg(tmp2, tmp1, src); 8611 subI_reg_reg(dst, tmp2, tmp1); 8612 %} 8613 %} 8614 8615 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 8616 match(Set dst (SubI zero src2)); 8617 format %{ "NEG $dst, $src2" %} 8618 size(4); 8619 ins_encode %{ 8620 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8621 __ neg($dst$$Register, $src2$$Register); 8622 %} 8623 ins_pipe(pipe_class_default); 8624 %} 8625 8626 // Long subtraction 8627 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8628 match(Set dst (SubL src1 src2)); 8629 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 8630 size(4); 8631 ins_encode %{ 8632 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8633 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8634 %} 8635 ins_pipe(pipe_class_default); 8636 %} 8637 8638 // SubL + convL2I. 8639 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8640 match(Set dst (ConvL2I (SubL src1 src2))); 8641 8642 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 8643 size(4); 8644 ins_encode %{ 8645 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8646 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8647 %} 8648 ins_pipe(pipe_class_default); 8649 %} 8650 8651 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8652 // positive longs and 0xF...F for negative ones. 8653 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 8654 // no match-rule, false predicate 8655 effect(DEF dst, USE src); 8656 predicate(false); 8657 8658 format %{ "SRADI $dst, $src, #63" %} 8659 size(4); 8660 ins_encode %{ 8661 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8662 __ sradi($dst$$Register, $src$$Register, 0x3f); 8663 %} 8664 ins_pipe(pipe_class_default); 8665 %} 8666 8667 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8668 // positive longs and 0xF...F for negative ones. 8669 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 8670 // no match-rule, false predicate 8671 effect(DEF dst, USE src); 8672 predicate(false); 8673 8674 format %{ "SRADI $dst, $src, #63" %} 8675 size(4); 8676 ins_encode %{ 8677 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8678 __ sradi($dst$$Register, $src$$Register, 0x3f); 8679 %} 8680 ins_pipe(pipe_class_default); 8681 %} 8682 8683 // Long negation 8684 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 8685 match(Set dst (SubL zero src2)); 8686 format %{ "NEG $dst, $src2 \t// long" %} 8687 size(4); 8688 ins_encode %{ 8689 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8690 __ neg($dst$$Register, $src2$$Register); 8691 %} 8692 ins_pipe(pipe_class_default); 8693 %} 8694 8695 // NegL + ConvL2I. 8696 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 8697 match(Set dst (ConvL2I (SubL zero src2))); 8698 8699 format %{ "NEG $dst, $src2 \t// long + l2i" %} 8700 size(4); 8701 ins_encode %{ 8702 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8703 __ neg($dst$$Register, $src2$$Register); 8704 %} 8705 ins_pipe(pipe_class_default); 8706 %} 8707 8708 // Multiplication Instructions 8709 // Integer Multiplication 8710 8711 // Register Multiplication 8712 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8713 match(Set dst (MulI src1 src2)); 8714 ins_cost(DEFAULT_COST); 8715 8716 format %{ "MULLW $dst, $src1, $src2" %} 8717 size(4); 8718 ins_encode %{ 8719 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 8720 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 8721 %} 8722 ins_pipe(pipe_class_default); 8723 %} 8724 8725 // Immediate Multiplication 8726 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8727 match(Set dst (MulI src1 src2)); 8728 ins_cost(DEFAULT_COST); 8729 8730 format %{ "MULLI $dst, $src1, $src2" %} 8731 size(4); 8732 ins_encode %{ 8733 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8734 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8735 %} 8736 ins_pipe(pipe_class_default); 8737 %} 8738 8739 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8740 match(Set dst (MulL src1 src2)); 8741 ins_cost(DEFAULT_COST); 8742 8743 format %{ "MULLD $dst $src1, $src2 \t// long" %} 8744 size(4); 8745 ins_encode %{ 8746 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 8747 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 8748 %} 8749 ins_pipe(pipe_class_default); 8750 %} 8751 8752 // Multiply high for optimized long division by constant. 8753 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8754 match(Set dst (MulHiL src1 src2)); 8755 ins_cost(DEFAULT_COST); 8756 8757 format %{ "MULHD $dst $src1, $src2 \t// long" %} 8758 size(4); 8759 ins_encode %{ 8760 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 8761 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 8762 %} 8763 ins_pipe(pipe_class_default); 8764 %} 8765 8766 // Immediate Multiplication 8767 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8768 match(Set dst (MulL src1 src2)); 8769 ins_cost(DEFAULT_COST); 8770 8771 format %{ "MULLI $dst, $src1, $src2" %} 8772 size(4); 8773 ins_encode %{ 8774 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8775 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8776 %} 8777 ins_pipe(pipe_class_default); 8778 %} 8779 8780 // Integer Division with Immediate -1: Negate. 8781 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 8782 match(Set dst (DivI src1 src2)); 8783 ins_cost(DEFAULT_COST); 8784 8785 format %{ "NEG $dst, $src1 \t// /-1" %} 8786 size(4); 8787 ins_encode %{ 8788 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8789 __ neg($dst$$Register, $src1$$Register); 8790 %} 8791 ins_pipe(pipe_class_default); 8792 %} 8793 8794 // Integer Division with constant, but not -1. 8795 // We should be able to improve this by checking the type of src2. 8796 // It might well be that src2 is known to be positive. 8797 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8798 match(Set dst (DivI src1 src2)); 8799 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 8800 ins_cost(2*DEFAULT_COST); 8801 8802 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 8803 size(4); 8804 ins_encode %{ 8805 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 8806 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 8807 %} 8808 ins_pipe(pipe_class_default); 8809 %} 8810 8811 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 8812 effect(USE_DEF dst, USE src1, USE crx); 8813 predicate(false); 8814 8815 ins_variable_size_depending_on_alignment(true); 8816 8817 format %{ "CMOVE $dst, neg($src1), $crx" %} 8818 // Worst case is branch + move + stop, no stop without scheduler. 8819 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8820 ins_encode %{ 8821 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8822 Label done; 8823 __ bne($crx$$CondRegister, done); 8824 __ neg($dst$$Register, $src1$$Register); 8825 // TODO PPC port __ endgroup_if_needed(_size == 12); 8826 __ bind(done); 8827 %} 8828 ins_pipe(pipe_class_default); 8829 %} 8830 8831 // Integer Division with Registers not containing constants. 8832 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8833 match(Set dst (DivI src1 src2)); 8834 ins_cost(10*DEFAULT_COST); 8835 8836 expand %{ 8837 immI16 imm %{ (int)-1 %} 8838 flagsReg tmp1; 8839 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8840 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8841 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8842 %} 8843 %} 8844 8845 // Long Division with Immediate -1: Negate. 8846 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 8847 match(Set dst (DivL src1 src2)); 8848 ins_cost(DEFAULT_COST); 8849 8850 format %{ "NEG $dst, $src1 \t// /-1, long" %} 8851 size(4); 8852 ins_encode %{ 8853 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8854 __ neg($dst$$Register, $src1$$Register); 8855 %} 8856 ins_pipe(pipe_class_default); 8857 %} 8858 8859 // Long Division with constant, but not -1. 8860 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8861 match(Set dst (DivL src1 src2)); 8862 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 8863 ins_cost(2*DEFAULT_COST); 8864 8865 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 8866 size(4); 8867 ins_encode %{ 8868 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 8869 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 8870 %} 8871 ins_pipe(pipe_class_default); 8872 %} 8873 8874 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 8875 effect(USE_DEF dst, USE src1, USE crx); 8876 predicate(false); 8877 8878 ins_variable_size_depending_on_alignment(true); 8879 8880 format %{ "CMOVE $dst, neg($src1), $crx" %} 8881 // Worst case is branch + move + stop, no stop without scheduler. 8882 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8883 ins_encode %{ 8884 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8885 Label done; 8886 __ bne($crx$$CondRegister, done); 8887 __ neg($dst$$Register, $src1$$Register); 8888 // TODO PPC port __ endgroup_if_needed(_size == 12); 8889 __ bind(done); 8890 %} 8891 ins_pipe(pipe_class_default); 8892 %} 8893 8894 // Long Division with Registers not containing constants. 8895 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8896 match(Set dst (DivL src1 src2)); 8897 ins_cost(10*DEFAULT_COST); 8898 8899 expand %{ 8900 immL16 imm %{ (int)-1 %} 8901 flagsReg tmp1; 8902 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8903 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8904 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8905 %} 8906 %} 8907 8908 // Integer Remainder with registers. 8909 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8910 match(Set dst (ModI src1 src2)); 8911 ins_cost(10*DEFAULT_COST); 8912 8913 expand %{ 8914 immI16 imm %{ (int)-1 %} 8915 flagsReg tmp1; 8916 iRegIdst tmp2; 8917 iRegIdst tmp3; 8918 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8919 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8920 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8921 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8922 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8923 %} 8924 %} 8925 8926 // Long Remainder with registers 8927 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8928 match(Set dst (ModL src1 src2)); 8929 ins_cost(10*DEFAULT_COST); 8930 8931 expand %{ 8932 immL16 imm %{ (int)-1 %} 8933 flagsReg tmp1; 8934 iRegLdst tmp2; 8935 iRegLdst tmp3; 8936 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8937 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8938 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8939 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8940 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8941 %} 8942 %} 8943 8944 // Integer Shift Instructions 8945 8946 // Register Shift Left 8947 8948 // Clear all but the lowest #mask bits. 8949 // Used to normalize shift amounts in registers. 8950 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 8951 // no match-rule, false predicate 8952 effect(DEF dst, USE src, USE mask); 8953 predicate(false); 8954 8955 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 8956 size(4); 8957 ins_encode %{ 8958 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 8959 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 8960 %} 8961 ins_pipe(pipe_class_default); 8962 %} 8963 8964 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8965 // no match-rule, false predicate 8966 effect(DEF dst, USE src1, USE src2); 8967 predicate(false); 8968 8969 format %{ "SLW $dst, $src1, $src2" %} 8970 size(4); 8971 ins_encode %{ 8972 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 8973 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 8974 %} 8975 ins_pipe(pipe_class_default); 8976 %} 8977 8978 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8979 match(Set dst (LShiftI src1 src2)); 8980 ins_cost(DEFAULT_COST*2); 8981 expand %{ 8982 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 8983 iRegIdst tmpI; 8984 maskI_reg_imm(tmpI, src2, mask); 8985 lShiftI_reg_reg(dst, src1, tmpI); 8986 %} 8987 %} 8988 8989 // Register Shift Left Immediate 8990 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 8991 match(Set dst (LShiftI src1 src2)); 8992 8993 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 8994 size(4); 8995 ins_encode %{ 8996 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 8997 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 8998 %} 8999 ins_pipe(pipe_class_default); 9000 %} 9001 9002 // AndI with negpow2-constant + LShiftI 9003 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9004 match(Set dst (LShiftI (AndI src1 src2) src3)); 9005 predicate(UseRotateAndMaskInstructionsPPC64); 9006 9007 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9008 size(4); 9009 ins_encode %{ 9010 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9011 long src2 = $src2$$constant; 9012 long src3 = $src3$$constant; 9013 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9014 if (maskbits >= 32) { 9015 __ li($dst$$Register, 0); // addi 9016 } else { 9017 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9018 } 9019 %} 9020 ins_pipe(pipe_class_default); 9021 %} 9022 9023 // RShiftI + AndI with negpow2-constant + LShiftI 9024 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9025 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9026 predicate(UseRotateAndMaskInstructionsPPC64); 9027 9028 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9029 size(4); 9030 ins_encode %{ 9031 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9032 long src2 = $src2$$constant; 9033 long src3 = $src3$$constant; 9034 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9035 if (maskbits >= 32) { 9036 __ li($dst$$Register, 0); // addi 9037 } else { 9038 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9039 } 9040 %} 9041 ins_pipe(pipe_class_default); 9042 %} 9043 9044 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9045 // no match-rule, false predicate 9046 effect(DEF dst, USE src1, USE src2); 9047 predicate(false); 9048 9049 format %{ "SLD $dst, $src1, $src2" %} 9050 size(4); 9051 ins_encode %{ 9052 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9053 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9054 %} 9055 ins_pipe(pipe_class_default); 9056 %} 9057 9058 // Register Shift Left 9059 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9060 match(Set dst (LShiftL src1 src2)); 9061 ins_cost(DEFAULT_COST*2); 9062 expand %{ 9063 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9064 iRegIdst tmpI; 9065 maskI_reg_imm(tmpI, src2, mask); 9066 lShiftL_regL_regI(dst, src1, tmpI); 9067 %} 9068 %} 9069 9070 // Register Shift Left Immediate 9071 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9072 match(Set dst (LShiftL src1 src2)); 9073 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9074 size(4); 9075 ins_encode %{ 9076 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9077 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9078 %} 9079 ins_pipe(pipe_class_default); 9080 %} 9081 9082 // If we shift more than 32 bits, we need not convert I2L. 9083 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9084 match(Set dst (LShiftL (ConvI2L src1) src2)); 9085 ins_cost(DEFAULT_COST); 9086 9087 size(4); 9088 format %{ "SLDI $dst, i2l($src1), $src2" %} 9089 ins_encode %{ 9090 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9091 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9092 %} 9093 ins_pipe(pipe_class_default); 9094 %} 9095 9096 // Shift a postivie int to the left. 9097 // Clrlsldi clears the upper 32 bits and shifts. 9098 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9099 match(Set dst (LShiftL (ConvI2L src1) src2)); 9100 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9101 9102 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9103 size(4); 9104 ins_encode %{ 9105 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9106 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9107 %} 9108 ins_pipe(pipe_class_default); 9109 %} 9110 9111 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9112 // no match-rule, false predicate 9113 effect(DEF dst, USE src1, USE src2); 9114 predicate(false); 9115 9116 format %{ "SRAW $dst, $src1, $src2" %} 9117 size(4); 9118 ins_encode %{ 9119 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9120 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9121 %} 9122 ins_pipe(pipe_class_default); 9123 %} 9124 9125 // Register Arithmetic Shift Right 9126 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9127 match(Set dst (RShiftI src1 src2)); 9128 ins_cost(DEFAULT_COST*2); 9129 expand %{ 9130 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9131 iRegIdst tmpI; 9132 maskI_reg_imm(tmpI, src2, mask); 9133 arShiftI_reg_reg(dst, src1, tmpI); 9134 %} 9135 %} 9136 9137 // Register Arithmetic Shift Right Immediate 9138 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9139 match(Set dst (RShiftI src1 src2)); 9140 9141 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9142 size(4); 9143 ins_encode %{ 9144 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9145 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9146 %} 9147 ins_pipe(pipe_class_default); 9148 %} 9149 9150 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9151 // no match-rule, false predicate 9152 effect(DEF dst, USE src1, USE src2); 9153 predicate(false); 9154 9155 format %{ "SRAD $dst, $src1, $src2" %} 9156 size(4); 9157 ins_encode %{ 9158 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9159 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9160 %} 9161 ins_pipe(pipe_class_default); 9162 %} 9163 9164 // Register Shift Right Arithmetic Long 9165 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9166 match(Set dst (RShiftL src1 src2)); 9167 ins_cost(DEFAULT_COST*2); 9168 9169 expand %{ 9170 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9171 iRegIdst tmpI; 9172 maskI_reg_imm(tmpI, src2, mask); 9173 arShiftL_regL_regI(dst, src1, tmpI); 9174 %} 9175 %} 9176 9177 // Register Shift Right Immediate 9178 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9179 match(Set dst (RShiftL src1 src2)); 9180 9181 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9182 size(4); 9183 ins_encode %{ 9184 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9185 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9186 %} 9187 ins_pipe(pipe_class_default); 9188 %} 9189 9190 // RShiftL + ConvL2I 9191 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9192 match(Set dst (ConvL2I (RShiftL src1 src2))); 9193 9194 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9195 size(4); 9196 ins_encode %{ 9197 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9198 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9199 %} 9200 ins_pipe(pipe_class_default); 9201 %} 9202 9203 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9204 // no match-rule, false predicate 9205 effect(DEF dst, USE src1, USE src2); 9206 predicate(false); 9207 9208 format %{ "SRW $dst, $src1, $src2" %} 9209 size(4); 9210 ins_encode %{ 9211 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9212 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9213 %} 9214 ins_pipe(pipe_class_default); 9215 %} 9216 9217 // Register Shift Right 9218 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9219 match(Set dst (URShiftI src1 src2)); 9220 ins_cost(DEFAULT_COST*2); 9221 9222 expand %{ 9223 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9224 iRegIdst tmpI; 9225 maskI_reg_imm(tmpI, src2, mask); 9226 urShiftI_reg_reg(dst, src1, tmpI); 9227 %} 9228 %} 9229 9230 // Register Shift Right Immediate 9231 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9232 match(Set dst (URShiftI src1 src2)); 9233 9234 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9235 size(4); 9236 ins_encode %{ 9237 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9238 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9239 %} 9240 ins_pipe(pipe_class_default); 9241 %} 9242 9243 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9244 // no match-rule, false predicate 9245 effect(DEF dst, USE src1, USE src2); 9246 predicate(false); 9247 9248 format %{ "SRD $dst, $src1, $src2" %} 9249 size(4); 9250 ins_encode %{ 9251 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9252 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9253 %} 9254 ins_pipe(pipe_class_default); 9255 %} 9256 9257 // Register Shift Right 9258 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9259 match(Set dst (URShiftL src1 src2)); 9260 ins_cost(DEFAULT_COST*2); 9261 9262 expand %{ 9263 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9264 iRegIdst tmpI; 9265 maskI_reg_imm(tmpI, src2, mask); 9266 urShiftL_regL_regI(dst, src1, tmpI); 9267 %} 9268 %} 9269 9270 // Register Shift Right Immediate 9271 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9272 match(Set dst (URShiftL src1 src2)); 9273 9274 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9275 size(4); 9276 ins_encode %{ 9277 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9278 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9279 %} 9280 ins_pipe(pipe_class_default); 9281 %} 9282 9283 // URShiftL + ConvL2I. 9284 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9285 match(Set dst (ConvL2I (URShiftL src1 src2))); 9286 9287 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9288 size(4); 9289 ins_encode %{ 9290 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9291 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9292 %} 9293 ins_pipe(pipe_class_default); 9294 %} 9295 9296 // Register Shift Right Immediate with a CastP2X 9297 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9298 match(Set dst (URShiftL (CastP2X src1) src2)); 9299 9300 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9301 size(4); 9302 ins_encode %{ 9303 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9304 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9305 %} 9306 ins_pipe(pipe_class_default); 9307 %} 9308 9309 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9310 match(Set dst (ConvL2I (ConvI2L src))); 9311 9312 format %{ "EXTSW $dst, $src \t// int->int" %} 9313 size(4); 9314 ins_encode %{ 9315 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9316 __ extsw($dst$$Register, $src$$Register); 9317 %} 9318 ins_pipe(pipe_class_default); 9319 %} 9320 9321 //----------Rotate Instructions------------------------------------------------ 9322 9323 // Rotate Left by 8-bit immediate 9324 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9325 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9326 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9327 9328 format %{ "ROTLWI $dst, $src, $lshift" %} 9329 size(4); 9330 ins_encode %{ 9331 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9332 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9333 %} 9334 ins_pipe(pipe_class_default); 9335 %} 9336 9337 // Rotate Right by 8-bit immediate 9338 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9339 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9340 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9341 9342 format %{ "ROTRWI $dst, $rshift" %} 9343 size(4); 9344 ins_encode %{ 9345 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9346 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9347 %} 9348 ins_pipe(pipe_class_default); 9349 %} 9350 9351 //----------Floating Point Arithmetic Instructions----------------------------- 9352 9353 // Add float single precision 9354 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9355 match(Set dst (AddF src1 src2)); 9356 9357 format %{ "FADDS $dst, $src1, $src2" %} 9358 size(4); 9359 ins_encode %{ 9360 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9361 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9362 %} 9363 ins_pipe(pipe_class_default); 9364 %} 9365 9366 // Add float double precision 9367 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9368 match(Set dst (AddD src1 src2)); 9369 9370 format %{ "FADD $dst, $src1, $src2" %} 9371 size(4); 9372 ins_encode %{ 9373 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9374 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9375 %} 9376 ins_pipe(pipe_class_default); 9377 %} 9378 9379 // Sub float single precision 9380 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9381 match(Set dst (SubF src1 src2)); 9382 9383 format %{ "FSUBS $dst, $src1, $src2" %} 9384 size(4); 9385 ins_encode %{ 9386 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9387 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9388 %} 9389 ins_pipe(pipe_class_default); 9390 %} 9391 9392 // Sub float double precision 9393 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9394 match(Set dst (SubD src1 src2)); 9395 format %{ "FSUB $dst, $src1, $src2" %} 9396 size(4); 9397 ins_encode %{ 9398 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9399 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9400 %} 9401 ins_pipe(pipe_class_default); 9402 %} 9403 9404 // Mul float single precision 9405 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9406 match(Set dst (MulF src1 src2)); 9407 format %{ "FMULS $dst, $src1, $src2" %} 9408 size(4); 9409 ins_encode %{ 9410 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9411 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9412 %} 9413 ins_pipe(pipe_class_default); 9414 %} 9415 9416 // Mul float double precision 9417 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9418 match(Set dst (MulD src1 src2)); 9419 format %{ "FMUL $dst, $src1, $src2" %} 9420 size(4); 9421 ins_encode %{ 9422 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9423 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9424 %} 9425 ins_pipe(pipe_class_default); 9426 %} 9427 9428 // Div float single precision 9429 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9430 match(Set dst (DivF src1 src2)); 9431 format %{ "FDIVS $dst, $src1, $src2" %} 9432 size(4); 9433 ins_encode %{ 9434 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9435 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9436 %} 9437 ins_pipe(pipe_class_default); 9438 %} 9439 9440 // Div float double precision 9441 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9442 match(Set dst (DivD src1 src2)); 9443 format %{ "FDIV $dst, $src1, $src2" %} 9444 size(4); 9445 ins_encode %{ 9446 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9447 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9448 %} 9449 ins_pipe(pipe_class_default); 9450 %} 9451 9452 // Absolute float single precision 9453 instruct absF_reg(regF dst, regF src) %{ 9454 match(Set dst (AbsF src)); 9455 format %{ "FABS $dst, $src \t// float" %} 9456 size(4); 9457 ins_encode %{ 9458 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9459 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9460 %} 9461 ins_pipe(pipe_class_default); 9462 %} 9463 9464 // Absolute float double precision 9465 instruct absD_reg(regD dst, regD src) %{ 9466 match(Set dst (AbsD src)); 9467 format %{ "FABS $dst, $src \t// double" %} 9468 size(4); 9469 ins_encode %{ 9470 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9471 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9472 %} 9473 ins_pipe(pipe_class_default); 9474 %} 9475 9476 instruct negF_reg(regF dst, regF src) %{ 9477 match(Set dst (NegF src)); 9478 format %{ "FNEG $dst, $src \t// float" %} 9479 size(4); 9480 ins_encode %{ 9481 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9482 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9483 %} 9484 ins_pipe(pipe_class_default); 9485 %} 9486 9487 instruct negD_reg(regD dst, regD src) %{ 9488 match(Set dst (NegD src)); 9489 format %{ "FNEG $dst, $src \t// double" %} 9490 size(4); 9491 ins_encode %{ 9492 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9493 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9494 %} 9495 ins_pipe(pipe_class_default); 9496 %} 9497 9498 // AbsF + NegF. 9499 instruct negF_absF_reg(regF dst, regF src) %{ 9500 match(Set dst (NegF (AbsF src))); 9501 format %{ "FNABS $dst, $src \t// float" %} 9502 size(4); 9503 ins_encode %{ 9504 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9505 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9506 %} 9507 ins_pipe(pipe_class_default); 9508 %} 9509 9510 // AbsD + NegD. 9511 instruct negD_absD_reg(regD dst, regD src) %{ 9512 match(Set dst (NegD (AbsD src))); 9513 format %{ "FNABS $dst, $src \t// double" %} 9514 size(4); 9515 ins_encode %{ 9516 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9517 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9518 %} 9519 ins_pipe(pipe_class_default); 9520 %} 9521 9522 // VM_Version::has_fsqrt() decides if this node will be used. 9523 // Sqrt float double precision 9524 instruct sqrtD_reg(regD dst, regD src) %{ 9525 match(Set dst (SqrtD src)); 9526 format %{ "FSQRT $dst, $src" %} 9527 size(4); 9528 ins_encode %{ 9529 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 9530 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 9531 %} 9532 ins_pipe(pipe_class_default); 9533 %} 9534 9535 // Single-precision sqrt. 9536 instruct sqrtF_reg(regF dst, regF src) %{ 9537 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 9538 predicate(VM_Version::has_fsqrts()); 9539 ins_cost(DEFAULT_COST); 9540 9541 format %{ "FSQRTS $dst, $src" %} 9542 size(4); 9543 ins_encode %{ 9544 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 9545 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 9546 %} 9547 ins_pipe(pipe_class_default); 9548 %} 9549 9550 instruct roundDouble_nop(regD dst) %{ 9551 match(Set dst (RoundDouble dst)); 9552 ins_cost(0); 9553 9554 format %{ " -- \t// RoundDouble not needed - empty" %} 9555 size(0); 9556 // PPC results are already "rounded" (i.e., normal-format IEEE). 9557 ins_encode( /*empty*/ ); 9558 ins_pipe(pipe_class_default); 9559 %} 9560 9561 instruct roundFloat_nop(regF dst) %{ 9562 match(Set dst (RoundFloat dst)); 9563 ins_cost(0); 9564 9565 format %{ " -- \t// RoundFloat not needed - empty" %} 9566 size(0); 9567 // PPC results are already "rounded" (i.e., normal-format IEEE). 9568 ins_encode( /*empty*/ ); 9569 ins_pipe(pipe_class_default); 9570 %} 9571 9572 9573 // Multiply-Accumulate 9574 // src1 * src2 + src3 9575 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9576 predicate(UseFMA); 9577 match(Set dst (FmaF src3 (Binary src1 src2))); 9578 9579 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 9580 size(4); 9581 ins_encode %{ 9582 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 9583 __ fmadds(as_FloatRegister($dst$$reg), 9584 as_FloatRegister($src1$$reg), 9585 as_FloatRegister($src2$$reg), 9586 as_FloatRegister($src3$$reg)); 9587 %} 9588 ins_pipe(pipe_class_default); 9589 %} 9590 9591 // src1 * src2 + src3 9592 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9593 predicate(UseFMA); 9594 match(Set dst (FmaD src3 (Binary src1 src2))); 9595 9596 format %{ "FMADD $dst, $src1, $src2, $src3" %} 9597 size(4); 9598 ins_encode %{ 9599 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 9600 __ fmadd(as_FloatRegister($dst$$reg), 9601 as_FloatRegister($src1$$reg), 9602 as_FloatRegister($src2$$reg), 9603 as_FloatRegister($src3$$reg)); 9604 %} 9605 ins_pipe(pipe_class_default); 9606 %} 9607 9608 // -src1 * src2 + src3 = -(src1*src2-src3) 9609 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9610 predicate(UseFMA); 9611 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 9612 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 9613 9614 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 9615 size(4); 9616 ins_encode %{ 9617 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 9618 __ fnmsubs(as_FloatRegister($dst$$reg), 9619 as_FloatRegister($src1$$reg), 9620 as_FloatRegister($src2$$reg), 9621 as_FloatRegister($src3$$reg)); 9622 %} 9623 ins_pipe(pipe_class_default); 9624 %} 9625 9626 // -src1 * src2 + src3 = -(src1*src2-src3) 9627 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9628 predicate(UseFMA); 9629 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 9630 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 9631 9632 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 9633 size(4); 9634 ins_encode %{ 9635 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 9636 __ fnmsub(as_FloatRegister($dst$$reg), 9637 as_FloatRegister($src1$$reg), 9638 as_FloatRegister($src2$$reg), 9639 as_FloatRegister($src3$$reg)); 9640 %} 9641 ins_pipe(pipe_class_default); 9642 %} 9643 9644 // -src1 * src2 - src3 = -(src1*src2+src3) 9645 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9646 predicate(UseFMA); 9647 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 9648 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 9649 9650 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 9651 size(4); 9652 ins_encode %{ 9653 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 9654 __ fnmadds(as_FloatRegister($dst$$reg), 9655 as_FloatRegister($src1$$reg), 9656 as_FloatRegister($src2$$reg), 9657 as_FloatRegister($src3$$reg)); 9658 %} 9659 ins_pipe(pipe_class_default); 9660 %} 9661 9662 // -src1 * src2 - src3 = -(src1*src2+src3) 9663 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9664 predicate(UseFMA); 9665 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 9666 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 9667 9668 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 9669 size(4); 9670 ins_encode %{ 9671 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 9672 __ fnmadd(as_FloatRegister($dst$$reg), 9673 as_FloatRegister($src1$$reg), 9674 as_FloatRegister($src2$$reg), 9675 as_FloatRegister($src3$$reg)); 9676 %} 9677 ins_pipe(pipe_class_default); 9678 %} 9679 9680 // src1 * src2 - src3 9681 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9682 predicate(UseFMA); 9683 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 9684 9685 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 9686 size(4); 9687 ins_encode %{ 9688 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 9689 __ fmsubs(as_FloatRegister($dst$$reg), 9690 as_FloatRegister($src1$$reg), 9691 as_FloatRegister($src2$$reg), 9692 as_FloatRegister($src3$$reg)); 9693 %} 9694 ins_pipe(pipe_class_default); 9695 %} 9696 9697 // src1 * src2 - src3 9698 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9699 predicate(UseFMA); 9700 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 9701 9702 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 9703 size(4); 9704 ins_encode %{ 9705 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 9706 __ fmsub(as_FloatRegister($dst$$reg), 9707 as_FloatRegister($src1$$reg), 9708 as_FloatRegister($src2$$reg), 9709 as_FloatRegister($src3$$reg)); 9710 %} 9711 ins_pipe(pipe_class_default); 9712 %} 9713 9714 9715 //----------Logical Instructions----------------------------------------------- 9716 9717 // And Instructions 9718 9719 // Register And 9720 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9721 match(Set dst (AndI src1 src2)); 9722 format %{ "AND $dst, $src1, $src2" %} 9723 size(4); 9724 ins_encode %{ 9725 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9726 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9727 %} 9728 ins_pipe(pipe_class_default); 9729 %} 9730 9731 // Left shifted Immediate And 9732 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 9733 match(Set dst (AndI src1 src2)); 9734 effect(KILL cr0); 9735 format %{ "ANDIS $dst, $src1, $src2.hi" %} 9736 size(4); 9737 ins_encode %{ 9738 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 9739 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 9740 %} 9741 ins_pipe(pipe_class_default); 9742 %} 9743 9744 // Immediate And 9745 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 9746 match(Set dst (AndI src1 src2)); 9747 effect(KILL cr0); 9748 9749 format %{ "ANDI $dst, $src1, $src2" %} 9750 size(4); 9751 ins_encode %{ 9752 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9753 // FIXME: avoid andi_ ? 9754 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9755 %} 9756 ins_pipe(pipe_class_default); 9757 %} 9758 9759 // Immediate And where the immediate is a negative power of 2. 9760 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 9761 match(Set dst (AndI src1 src2)); 9762 format %{ "ANDWI $dst, $src1, $src2" %} 9763 size(4); 9764 ins_encode %{ 9765 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9766 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 9767 %} 9768 ins_pipe(pipe_class_default); 9769 %} 9770 9771 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 9772 match(Set dst (AndI src1 src2)); 9773 format %{ "ANDWI $dst, $src1, $src2" %} 9774 size(4); 9775 ins_encode %{ 9776 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9777 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9778 %} 9779 ins_pipe(pipe_class_default); 9780 %} 9781 9782 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 9783 match(Set dst (AndI src1 src2)); 9784 predicate(UseRotateAndMaskInstructionsPPC64); 9785 format %{ "ANDWI $dst, $src1, $src2" %} 9786 size(4); 9787 ins_encode %{ 9788 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9789 __ rlwinm($dst$$Register, $src1$$Register, 0, 9790 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 9791 %} 9792 ins_pipe(pipe_class_default); 9793 %} 9794 9795 // Register And Long 9796 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9797 match(Set dst (AndL src1 src2)); 9798 ins_cost(DEFAULT_COST); 9799 9800 format %{ "AND $dst, $src1, $src2 \t// long" %} 9801 size(4); 9802 ins_encode %{ 9803 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9804 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9805 %} 9806 ins_pipe(pipe_class_default); 9807 %} 9808 9809 // Immediate And long 9810 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 9811 match(Set dst (AndL src1 src2)); 9812 effect(KILL cr0); 9813 9814 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 9815 size(4); 9816 ins_encode %{ 9817 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9818 // FIXME: avoid andi_ ? 9819 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9820 %} 9821 ins_pipe(pipe_class_default); 9822 %} 9823 9824 // Immediate And Long where the immediate is a negative power of 2. 9825 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 9826 match(Set dst (AndL src1 src2)); 9827 format %{ "ANDDI $dst, $src1, $src2" %} 9828 size(4); 9829 ins_encode %{ 9830 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9831 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 9832 %} 9833 ins_pipe(pipe_class_default); 9834 %} 9835 9836 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9837 match(Set dst (AndL src1 src2)); 9838 format %{ "ANDDI $dst, $src1, $src2" %} 9839 size(4); 9840 ins_encode %{ 9841 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9842 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9843 %} 9844 ins_pipe(pipe_class_default); 9845 %} 9846 9847 // AndL + ConvL2I. 9848 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9849 match(Set dst (ConvL2I (AndL src1 src2))); 9850 ins_cost(DEFAULT_COST); 9851 9852 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 9853 size(4); 9854 ins_encode %{ 9855 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9856 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9857 %} 9858 ins_pipe(pipe_class_default); 9859 %} 9860 9861 // Or Instructions 9862 9863 // Register Or 9864 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9865 match(Set dst (OrI src1 src2)); 9866 format %{ "OR $dst, $src1, $src2" %} 9867 size(4); 9868 ins_encode %{ 9869 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9870 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9871 %} 9872 ins_pipe(pipe_class_default); 9873 %} 9874 9875 // Expand does not work with above instruct. (??) 9876 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9877 // no match-rule 9878 effect(DEF dst, USE src1, USE src2); 9879 format %{ "OR $dst, $src1, $src2" %} 9880 size(4); 9881 ins_encode %{ 9882 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9883 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9884 %} 9885 ins_pipe(pipe_class_default); 9886 %} 9887 9888 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9889 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 9890 ins_cost(DEFAULT_COST*3); 9891 9892 expand %{ 9893 // FIXME: we should do this in the ideal world. 9894 iRegIdst tmp1; 9895 iRegIdst tmp2; 9896 orI_reg_reg(tmp1, src1, src2); 9897 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 9898 orI_reg_reg(dst, tmp1, tmp2); 9899 %} 9900 %} 9901 9902 // Immediate Or 9903 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9904 match(Set dst (OrI src1 src2)); 9905 format %{ "ORI $dst, $src1, $src2" %} 9906 size(4); 9907 ins_encode %{ 9908 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9909 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 9910 %} 9911 ins_pipe(pipe_class_default); 9912 %} 9913 9914 // Register Or Long 9915 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9916 match(Set dst (OrL src1 src2)); 9917 ins_cost(DEFAULT_COST); 9918 9919 size(4); 9920 format %{ "OR $dst, $src1, $src2 \t// long" %} 9921 ins_encode %{ 9922 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9923 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9924 %} 9925 ins_pipe(pipe_class_default); 9926 %} 9927 9928 // OrL + ConvL2I. 9929 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9930 match(Set dst (ConvL2I (OrL src1 src2))); 9931 ins_cost(DEFAULT_COST); 9932 9933 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 9934 size(4); 9935 ins_encode %{ 9936 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9937 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9938 %} 9939 ins_pipe(pipe_class_default); 9940 %} 9941 9942 // Immediate Or long 9943 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 9944 match(Set dst (OrL src1 con)); 9945 ins_cost(DEFAULT_COST); 9946 9947 format %{ "ORI $dst, $src1, $con \t// long" %} 9948 size(4); 9949 ins_encode %{ 9950 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9951 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 9952 %} 9953 ins_pipe(pipe_class_default); 9954 %} 9955 9956 // Xor Instructions 9957 9958 // Register Xor 9959 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9960 match(Set dst (XorI src1 src2)); 9961 format %{ "XOR $dst, $src1, $src2" %} 9962 size(4); 9963 ins_encode %{ 9964 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9965 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9966 %} 9967 ins_pipe(pipe_class_default); 9968 %} 9969 9970 // Expand does not work with above instruct. (??) 9971 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9972 // no match-rule 9973 effect(DEF dst, USE src1, USE src2); 9974 format %{ "XOR $dst, $src1, $src2" %} 9975 size(4); 9976 ins_encode %{ 9977 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9978 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9979 %} 9980 ins_pipe(pipe_class_default); 9981 %} 9982 9983 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9984 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 9985 ins_cost(DEFAULT_COST*3); 9986 9987 expand %{ 9988 // FIXME: we should do this in the ideal world. 9989 iRegIdst tmp1; 9990 iRegIdst tmp2; 9991 xorI_reg_reg(tmp1, src1, src2); 9992 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 9993 xorI_reg_reg(dst, tmp1, tmp2); 9994 %} 9995 %} 9996 9997 // Immediate Xor 9998 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9999 match(Set dst (XorI src1 src2)); 10000 format %{ "XORI $dst, $src1, $src2" %} 10001 size(4); 10002 ins_encode %{ 10003 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10004 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10005 %} 10006 ins_pipe(pipe_class_default); 10007 %} 10008 10009 // Register Xor Long 10010 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10011 match(Set dst (XorL src1 src2)); 10012 ins_cost(DEFAULT_COST); 10013 10014 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10015 size(4); 10016 ins_encode %{ 10017 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10018 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10019 %} 10020 ins_pipe(pipe_class_default); 10021 %} 10022 10023 // XorL + ConvL2I. 10024 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10025 match(Set dst (ConvL2I (XorL src1 src2))); 10026 ins_cost(DEFAULT_COST); 10027 10028 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10029 size(4); 10030 ins_encode %{ 10031 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10032 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10033 %} 10034 ins_pipe(pipe_class_default); 10035 %} 10036 10037 // Immediate Xor Long 10038 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10039 match(Set dst (XorL src1 src2)); 10040 ins_cost(DEFAULT_COST); 10041 10042 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10043 size(4); 10044 ins_encode %{ 10045 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10046 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10047 %} 10048 ins_pipe(pipe_class_default); 10049 %} 10050 10051 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10052 match(Set dst (XorI src1 src2)); 10053 ins_cost(DEFAULT_COST); 10054 10055 format %{ "NOT $dst, $src1 ($src2)" %} 10056 size(4); 10057 ins_encode %{ 10058 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10059 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10060 %} 10061 ins_pipe(pipe_class_default); 10062 %} 10063 10064 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10065 match(Set dst (XorL src1 src2)); 10066 ins_cost(DEFAULT_COST); 10067 10068 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10069 size(4); 10070 ins_encode %{ 10071 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10072 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10073 %} 10074 ins_pipe(pipe_class_default); 10075 %} 10076 10077 // And-complement 10078 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10079 match(Set dst (AndI (XorI src1 src2) src3)); 10080 ins_cost(DEFAULT_COST); 10081 10082 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10083 size(4); 10084 ins_encode( enc_andc(dst, src3, src1) ); 10085 ins_pipe(pipe_class_default); 10086 %} 10087 10088 // And-complement 10089 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10090 // no match-rule, false predicate 10091 effect(DEF dst, USE src1, USE src2); 10092 predicate(false); 10093 10094 format %{ "ANDC $dst, $src1, $src2" %} 10095 size(4); 10096 ins_encode %{ 10097 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10098 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10099 %} 10100 ins_pipe(pipe_class_default); 10101 %} 10102 10103 //----------Moves between int/long and float/double---------------------------- 10104 // 10105 // The following rules move values from int/long registers/stack-locations 10106 // to float/double registers/stack-locations and vice versa, without doing any 10107 // conversions. These rules are used to implement the bit-conversion methods 10108 // of java.lang.Float etc., e.g. 10109 // int floatToIntBits(float value) 10110 // float intBitsToFloat(int bits) 10111 // 10112 // Notes on the implementation on ppc64: 10113 // We only provide rules which move between a register and a stack-location, 10114 // because we always have to go through memory when moving between a float 10115 // register and an integer register. 10116 10117 //---------- Chain stack slots between similar types -------- 10118 10119 // These are needed so that the rules below can match. 10120 10121 // Load integer from stack slot 10122 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10123 match(Set dst src); 10124 ins_cost(MEMORY_REF_COST); 10125 10126 format %{ "LWZ $dst, $src" %} 10127 size(4); 10128 ins_encode( enc_lwz(dst, src) ); 10129 ins_pipe(pipe_class_memory); 10130 %} 10131 10132 // Store integer to stack slot 10133 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10134 match(Set dst src); 10135 ins_cost(MEMORY_REF_COST); 10136 10137 format %{ "STW $src, $dst \t// stk" %} 10138 size(4); 10139 ins_encode( enc_stw(src, dst) ); // rs=rt 10140 ins_pipe(pipe_class_memory); 10141 %} 10142 10143 // Load long from stack slot 10144 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10145 match(Set dst src); 10146 ins_cost(MEMORY_REF_COST); 10147 10148 format %{ "LD $dst, $src \t// long" %} 10149 size(4); 10150 ins_encode( enc_ld(dst, src) ); 10151 ins_pipe(pipe_class_memory); 10152 %} 10153 10154 // Store long to stack slot 10155 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10156 match(Set dst src); 10157 ins_cost(MEMORY_REF_COST); 10158 10159 format %{ "STD $src, $dst \t// long" %} 10160 size(4); 10161 ins_encode( enc_std(src, dst) ); // rs=rt 10162 ins_pipe(pipe_class_memory); 10163 %} 10164 10165 //----------Moves between int and float 10166 10167 // Move float value from float stack-location to integer register. 10168 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10169 match(Set dst (MoveF2I src)); 10170 ins_cost(MEMORY_REF_COST); 10171 10172 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10173 size(4); 10174 ins_encode( enc_lwz(dst, src) ); 10175 ins_pipe(pipe_class_memory); 10176 %} 10177 10178 // Move float value from float register to integer stack-location. 10179 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10180 match(Set dst (MoveF2I src)); 10181 ins_cost(MEMORY_REF_COST); 10182 10183 format %{ "STFS $src, $dst \t// MoveF2I" %} 10184 size(4); 10185 ins_encode( enc_stfs(src, dst) ); 10186 ins_pipe(pipe_class_memory); 10187 %} 10188 10189 // Move integer value from integer stack-location to float register. 10190 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10191 match(Set dst (MoveI2F src)); 10192 ins_cost(MEMORY_REF_COST); 10193 10194 format %{ "LFS $dst, $src \t// MoveI2F" %} 10195 size(4); 10196 ins_encode %{ 10197 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10198 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10199 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10200 %} 10201 ins_pipe(pipe_class_memory); 10202 %} 10203 10204 // Move integer value from integer register to float stack-location. 10205 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10206 match(Set dst (MoveI2F src)); 10207 ins_cost(MEMORY_REF_COST); 10208 10209 format %{ "STW $src, $dst \t// MoveI2F" %} 10210 size(4); 10211 ins_encode( enc_stw(src, dst) ); 10212 ins_pipe(pipe_class_memory); 10213 %} 10214 10215 //----------Moves between long and float 10216 10217 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10218 // no match-rule, false predicate 10219 effect(DEF dst, USE src); 10220 predicate(false); 10221 10222 format %{ "storeD $src, $dst \t// STACK" %} 10223 size(4); 10224 ins_encode( enc_stfd(src, dst) ); 10225 ins_pipe(pipe_class_default); 10226 %} 10227 10228 //----------Moves between long and double 10229 10230 // Move double value from double stack-location to long register. 10231 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10232 match(Set dst (MoveD2L src)); 10233 ins_cost(MEMORY_REF_COST); 10234 size(4); 10235 format %{ "LD $dst, $src \t// MoveD2L" %} 10236 ins_encode( enc_ld(dst, src) ); 10237 ins_pipe(pipe_class_memory); 10238 %} 10239 10240 // Move double value from double register to long stack-location. 10241 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10242 match(Set dst (MoveD2L src)); 10243 effect(DEF dst, USE src); 10244 ins_cost(MEMORY_REF_COST); 10245 10246 format %{ "STFD $src, $dst \t// MoveD2L" %} 10247 size(4); 10248 ins_encode( enc_stfd(src, dst) ); 10249 ins_pipe(pipe_class_memory); 10250 %} 10251 10252 // Move long value from long stack-location to double register. 10253 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10254 match(Set dst (MoveL2D src)); 10255 ins_cost(MEMORY_REF_COST); 10256 10257 format %{ "LFD $dst, $src \t// MoveL2D" %} 10258 size(4); 10259 ins_encode( enc_lfd(dst, src) ); 10260 ins_pipe(pipe_class_memory); 10261 %} 10262 10263 // Move long value from long register to double stack-location. 10264 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10265 match(Set dst (MoveL2D src)); 10266 ins_cost(MEMORY_REF_COST); 10267 10268 format %{ "STD $src, $dst \t// MoveL2D" %} 10269 size(4); 10270 ins_encode( enc_std(src, dst) ); 10271 ins_pipe(pipe_class_memory); 10272 %} 10273 10274 //----------Register Move Instructions----------------------------------------- 10275 10276 // Replicate for Superword 10277 10278 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10279 predicate(false); 10280 effect(DEF dst, USE src); 10281 10282 format %{ "MR $dst, $src \t// replicate " %} 10283 // variable size, 0 or 4. 10284 ins_encode %{ 10285 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10286 __ mr_if_needed($dst$$Register, $src$$Register); 10287 %} 10288 ins_pipe(pipe_class_default); 10289 %} 10290 10291 //----------Cast instructions (Java-level type cast)--------------------------- 10292 10293 // Cast Long to Pointer for unsafe natives. 10294 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10295 match(Set dst (CastX2P src)); 10296 10297 format %{ "MR $dst, $src \t// Long->Ptr" %} 10298 // variable size, 0 or 4. 10299 ins_encode %{ 10300 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10301 __ mr_if_needed($dst$$Register, $src$$Register); 10302 %} 10303 ins_pipe(pipe_class_default); 10304 %} 10305 10306 // Cast Pointer to Long for unsafe natives. 10307 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10308 match(Set dst (CastP2X src)); 10309 10310 format %{ "MR $dst, $src \t// Ptr->Long" %} 10311 // variable size, 0 or 4. 10312 ins_encode %{ 10313 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10314 __ mr_if_needed($dst$$Register, $src$$Register); 10315 %} 10316 ins_pipe(pipe_class_default); 10317 %} 10318 10319 instruct castPP(iRegPdst dst) %{ 10320 match(Set dst (CastPP dst)); 10321 format %{ " -- \t// castPP of $dst" %} 10322 size(0); 10323 ins_encode( /*empty*/ ); 10324 ins_pipe(pipe_class_default); 10325 %} 10326 10327 instruct castII(iRegIdst dst) %{ 10328 match(Set dst (CastII dst)); 10329 format %{ " -- \t// castII of $dst" %} 10330 size(0); 10331 ins_encode( /*empty*/ ); 10332 ins_pipe(pipe_class_default); 10333 %} 10334 10335 instruct checkCastPP(iRegPdst dst) %{ 10336 match(Set dst (CheckCastPP dst)); 10337 format %{ " -- \t// checkcastPP of $dst" %} 10338 size(0); 10339 ins_encode( /*empty*/ ); 10340 ins_pipe(pipe_class_default); 10341 %} 10342 10343 //----------Convert instructions----------------------------------------------- 10344 10345 // Convert to boolean. 10346 10347 // int_to_bool(src) : { 1 if src != 0 10348 // { 0 else 10349 // 10350 // strategy: 10351 // 1) Count leading zeros of 32 bit-value src, 10352 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10353 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10354 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10355 10356 // convI2Bool 10357 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10358 match(Set dst (Conv2B src)); 10359 predicate(UseCountLeadingZerosInstructionsPPC64); 10360 ins_cost(DEFAULT_COST); 10361 10362 expand %{ 10363 immI shiftAmount %{ 0x5 %} 10364 uimmI16 mask %{ 0x1 %} 10365 iRegIdst tmp1; 10366 iRegIdst tmp2; 10367 countLeadingZerosI(tmp1, src); 10368 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10369 xorI_reg_uimm16(dst, tmp2, mask); 10370 %} 10371 %} 10372 10373 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10374 match(Set dst (Conv2B src)); 10375 effect(TEMP crx); 10376 predicate(!UseCountLeadingZerosInstructionsPPC64); 10377 ins_cost(DEFAULT_COST); 10378 10379 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10380 "LI $dst, #0\n\t" 10381 "BEQ $crx, done\n\t" 10382 "LI $dst, #1\n" 10383 "done:" %} 10384 size(16); 10385 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10386 ins_pipe(pipe_class_compare); 10387 %} 10388 10389 // ConvI2B + XorI 10390 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10391 match(Set dst (XorI (Conv2B src) mask)); 10392 predicate(UseCountLeadingZerosInstructionsPPC64); 10393 ins_cost(DEFAULT_COST); 10394 10395 expand %{ 10396 immI shiftAmount %{ 0x5 %} 10397 iRegIdst tmp1; 10398 countLeadingZerosI(tmp1, src); 10399 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10400 %} 10401 %} 10402 10403 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10404 match(Set dst (XorI (Conv2B src) mask)); 10405 effect(TEMP crx); 10406 predicate(!UseCountLeadingZerosInstructionsPPC64); 10407 ins_cost(DEFAULT_COST); 10408 10409 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10410 "LI $dst, #1\n\t" 10411 "BEQ $crx, done\n\t" 10412 "LI $dst, #0\n" 10413 "done:" %} 10414 size(16); 10415 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10416 ins_pipe(pipe_class_compare); 10417 %} 10418 10419 // AndI 0b0..010..0 + ConvI2B 10420 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10421 match(Set dst (Conv2B (AndI src mask))); 10422 predicate(UseRotateAndMaskInstructionsPPC64); 10423 ins_cost(DEFAULT_COST); 10424 10425 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10426 size(4); 10427 ins_encode %{ 10428 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10429 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10430 %} 10431 ins_pipe(pipe_class_default); 10432 %} 10433 10434 // Convert pointer to boolean. 10435 // 10436 // ptr_to_bool(src) : { 1 if src != 0 10437 // { 0 else 10438 // 10439 // strategy: 10440 // 1) Count leading zeros of 64 bit-value src, 10441 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10442 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10443 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10444 10445 // ConvP2B 10446 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10447 match(Set dst (Conv2B src)); 10448 predicate(UseCountLeadingZerosInstructionsPPC64); 10449 ins_cost(DEFAULT_COST); 10450 10451 expand %{ 10452 immI shiftAmount %{ 0x6 %} 10453 uimmI16 mask %{ 0x1 %} 10454 iRegIdst tmp1; 10455 iRegIdst tmp2; 10456 countLeadingZerosP(tmp1, src); 10457 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10458 xorI_reg_uimm16(dst, tmp2, mask); 10459 %} 10460 %} 10461 10462 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10463 match(Set dst (Conv2B src)); 10464 effect(TEMP crx); 10465 predicate(!UseCountLeadingZerosInstructionsPPC64); 10466 ins_cost(DEFAULT_COST); 10467 10468 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10469 "LI $dst, #0\n\t" 10470 "BEQ $crx, done\n\t" 10471 "LI $dst, #1\n" 10472 "done:" %} 10473 size(16); 10474 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10475 ins_pipe(pipe_class_compare); 10476 %} 10477 10478 // ConvP2B + XorI 10479 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10480 match(Set dst (XorI (Conv2B src) mask)); 10481 predicate(UseCountLeadingZerosInstructionsPPC64); 10482 ins_cost(DEFAULT_COST); 10483 10484 expand %{ 10485 immI shiftAmount %{ 0x6 %} 10486 iRegIdst tmp1; 10487 countLeadingZerosP(tmp1, src); 10488 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10489 %} 10490 %} 10491 10492 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10493 match(Set dst (XorI (Conv2B src) mask)); 10494 effect(TEMP crx); 10495 predicate(!UseCountLeadingZerosInstructionsPPC64); 10496 ins_cost(DEFAULT_COST); 10497 10498 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10499 "LI $dst, #1\n\t" 10500 "BEQ $crx, done\n\t" 10501 "LI $dst, #0\n" 10502 "done:" %} 10503 size(16); 10504 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10505 ins_pipe(pipe_class_compare); 10506 %} 10507 10508 // if src1 < src2, return -1 else return 0 10509 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10510 match(Set dst (CmpLTMask src1 src2)); 10511 ins_cost(DEFAULT_COST*4); 10512 10513 expand %{ 10514 iRegLdst src1s; 10515 iRegLdst src2s; 10516 iRegLdst diff; 10517 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10518 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10519 subL_reg_reg(diff, src1s, src2s); 10520 // Need to consider >=33 bit result, therefore we need signmaskL. 10521 signmask64I_regL(dst, diff); 10522 %} 10523 %} 10524 10525 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 10526 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 10527 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 10528 size(4); 10529 ins_encode %{ 10530 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 10531 __ srawi($dst$$Register, $src1$$Register, 0x1f); 10532 %} 10533 ins_pipe(pipe_class_default); 10534 %} 10535 10536 //----------Arithmetic Conversion Instructions--------------------------------- 10537 10538 // Convert to Byte -- nop 10539 // Convert to Short -- nop 10540 10541 // Convert to Int 10542 10543 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 10544 match(Set dst (RShiftI (LShiftI src amount) amount)); 10545 format %{ "EXTSB $dst, $src \t// byte->int" %} 10546 size(4); 10547 ins_encode %{ 10548 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 10549 __ extsb($dst$$Register, $src$$Register); 10550 %} 10551 ins_pipe(pipe_class_default); 10552 %} 10553 10554 // LShiftI 16 + RShiftI 16 converts short to int. 10555 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 10556 match(Set dst (RShiftI (LShiftI src amount) amount)); 10557 format %{ "EXTSH $dst, $src \t// short->int" %} 10558 size(4); 10559 ins_encode %{ 10560 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 10561 __ extsh($dst$$Register, $src$$Register); 10562 %} 10563 ins_pipe(pipe_class_default); 10564 %} 10565 10566 // ConvL2I + ConvI2L: Sign extend int in long register. 10567 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 10568 match(Set dst (ConvI2L (ConvL2I src))); 10569 10570 format %{ "EXTSW $dst, $src \t// long->long" %} 10571 size(4); 10572 ins_encode %{ 10573 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10574 __ extsw($dst$$Register, $src$$Register); 10575 %} 10576 ins_pipe(pipe_class_default); 10577 %} 10578 10579 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 10580 match(Set dst (ConvL2I src)); 10581 format %{ "MR $dst, $src \t// long->int" %} 10582 // variable size, 0 or 4 10583 ins_encode %{ 10584 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10585 __ mr_if_needed($dst$$Register, $src$$Register); 10586 %} 10587 ins_pipe(pipe_class_default); 10588 %} 10589 10590 instruct convD2IRaw_regD(regD dst, regD src) %{ 10591 // no match-rule, false predicate 10592 effect(DEF dst, USE src); 10593 predicate(false); 10594 10595 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 10596 size(4); 10597 ins_encode %{ 10598 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 10599 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10600 %} 10601 ins_pipe(pipe_class_default); 10602 %} 10603 10604 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 10605 // no match-rule, false predicate 10606 effect(DEF dst, USE crx, USE src); 10607 predicate(false); 10608 10609 ins_variable_size_depending_on_alignment(true); 10610 10611 format %{ "cmovI $crx, $dst, $src" %} 10612 // Worst case is branch + move + stop, no stop without scheduler. 10613 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 10614 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10615 ins_pipe(pipe_class_default); 10616 %} 10617 10618 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10619 // no match-rule, false predicate 10620 effect(DEF dst, USE crx, USE mem); 10621 predicate(false); 10622 10623 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 10624 postalloc_expand %{ 10625 // 10626 // replaces 10627 // 10628 // region dst crx mem 10629 // \ | | / 10630 // dst=cmovI_bso_stackSlotL_conLvalue0 10631 // 10632 // with 10633 // 10634 // region dst 10635 // \ / 10636 // dst=loadConI16(0) 10637 // | 10638 // ^ region dst crx mem 10639 // | \ | | / 10640 // dst=cmovI_bso_stackSlotL 10641 // 10642 10643 // Create new nodes. 10644 MachNode *m1 = new loadConI16Node(); 10645 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 10646 10647 // inputs for new nodes 10648 m1->add_req(n_region); 10649 m2->add_req(n_region, n_crx, n_mem); 10650 10651 // precedences for new nodes 10652 m2->add_prec(m1); 10653 10654 // operands for new nodes 10655 m1->_opnds[0] = op_dst; 10656 m1->_opnds[1] = new immI16Oper(0); 10657 10658 m2->_opnds[0] = op_dst; 10659 m2->_opnds[1] = op_crx; 10660 m2->_opnds[2] = op_mem; 10661 10662 // registers for new nodes 10663 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10664 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10665 10666 // Insert new nodes. 10667 nodes->push(m1); 10668 nodes->push(m2); 10669 %} 10670 %} 10671 10672 // Double to Int conversion, NaN is mapped to 0. 10673 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 10674 match(Set dst (ConvD2I src)); 10675 ins_cost(DEFAULT_COST); 10676 10677 expand %{ 10678 regD tmpD; 10679 stackSlotL tmpS; 10680 flagsReg crx; 10681 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10682 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10683 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10684 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10685 %} 10686 %} 10687 10688 instruct convF2IRaw_regF(regF dst, regF src) %{ 10689 // no match-rule, false predicate 10690 effect(DEF dst, USE src); 10691 predicate(false); 10692 10693 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 10694 size(4); 10695 ins_encode %{ 10696 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10697 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10698 %} 10699 ins_pipe(pipe_class_default); 10700 %} 10701 10702 // Float to Int conversion, NaN is mapped to 0. 10703 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 10704 match(Set dst (ConvF2I src)); 10705 ins_cost(DEFAULT_COST); 10706 10707 expand %{ 10708 regF tmpF; 10709 stackSlotL tmpS; 10710 flagsReg crx; 10711 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10712 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10713 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10714 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10715 %} 10716 %} 10717 10718 // Convert to Long 10719 10720 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 10721 match(Set dst (ConvI2L src)); 10722 format %{ "EXTSW $dst, $src \t// int->long" %} 10723 size(4); 10724 ins_encode %{ 10725 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10726 __ extsw($dst$$Register, $src$$Register); 10727 %} 10728 ins_pipe(pipe_class_default); 10729 %} 10730 10731 // Zero-extend: convert unsigned int to long (convUI2L). 10732 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 10733 match(Set dst (AndL (ConvI2L src) mask)); 10734 ins_cost(DEFAULT_COST); 10735 10736 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10737 size(4); 10738 ins_encode %{ 10739 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10740 __ clrldi($dst$$Register, $src$$Register, 32); 10741 %} 10742 ins_pipe(pipe_class_default); 10743 %} 10744 10745 // Zero-extend: convert unsigned int to long in long register. 10746 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 10747 match(Set dst (AndL src mask)); 10748 ins_cost(DEFAULT_COST); 10749 10750 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10751 size(4); 10752 ins_encode %{ 10753 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10754 __ clrldi($dst$$Register, $src$$Register, 32); 10755 %} 10756 ins_pipe(pipe_class_default); 10757 %} 10758 10759 instruct convF2LRaw_regF(regF dst, regF src) %{ 10760 // no match-rule, false predicate 10761 effect(DEF dst, USE src); 10762 predicate(false); 10763 10764 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 10765 size(4); 10766 ins_encode %{ 10767 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10768 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10769 %} 10770 ins_pipe(pipe_class_default); 10771 %} 10772 10773 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 10774 // no match-rule, false predicate 10775 effect(DEF dst, USE crx, USE src); 10776 predicate(false); 10777 10778 ins_variable_size_depending_on_alignment(true); 10779 10780 format %{ "cmovL $crx, $dst, $src" %} 10781 // Worst case is branch + move + stop, no stop without scheduler. 10782 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 10783 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10784 ins_pipe(pipe_class_default); 10785 %} 10786 10787 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10788 // no match-rule, false predicate 10789 effect(DEF dst, USE crx, USE mem); 10790 predicate(false); 10791 10792 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 10793 postalloc_expand %{ 10794 // 10795 // replaces 10796 // 10797 // region dst crx mem 10798 // \ | | / 10799 // dst=cmovL_bso_stackSlotL_conLvalue0 10800 // 10801 // with 10802 // 10803 // region dst 10804 // \ / 10805 // dst=loadConL16(0) 10806 // | 10807 // ^ region dst crx mem 10808 // | \ | | / 10809 // dst=cmovL_bso_stackSlotL 10810 // 10811 10812 // Create new nodes. 10813 MachNode *m1 = new loadConL16Node(); 10814 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 10815 10816 // inputs for new nodes 10817 m1->add_req(n_region); 10818 m2->add_req(n_region, n_crx, n_mem); 10819 m2->add_prec(m1); 10820 10821 // operands for new nodes 10822 m1->_opnds[0] = op_dst; 10823 m1->_opnds[1] = new immL16Oper(0); 10824 m2->_opnds[0] = op_dst; 10825 m2->_opnds[1] = op_crx; 10826 m2->_opnds[2] = op_mem; 10827 10828 // registers for new nodes 10829 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10830 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10831 10832 // Insert new nodes. 10833 nodes->push(m1); 10834 nodes->push(m2); 10835 %} 10836 %} 10837 10838 // Float to Long conversion, NaN is mapped to 0. 10839 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 10840 match(Set dst (ConvF2L src)); 10841 ins_cost(DEFAULT_COST); 10842 10843 expand %{ 10844 regF tmpF; 10845 stackSlotL tmpS; 10846 flagsReg crx; 10847 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10848 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 10849 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10850 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10851 %} 10852 %} 10853 10854 instruct convD2LRaw_regD(regD dst, regD src) %{ 10855 // no match-rule, false predicate 10856 effect(DEF dst, USE src); 10857 predicate(false); 10858 10859 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 10860 size(4); 10861 ins_encode %{ 10862 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10863 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10864 %} 10865 ins_pipe(pipe_class_default); 10866 %} 10867 10868 // Double to Long conversion, NaN is mapped to 0. 10869 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 10870 match(Set dst (ConvD2L src)); 10871 ins_cost(DEFAULT_COST); 10872 10873 expand %{ 10874 regD tmpD; 10875 stackSlotL tmpS; 10876 flagsReg crx; 10877 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10878 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 10879 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10880 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10881 %} 10882 %} 10883 10884 // Convert to Float 10885 10886 // Placed here as needed in expand. 10887 instruct convL2DRaw_regD(regD dst, regD src) %{ 10888 // no match-rule, false predicate 10889 effect(DEF dst, USE src); 10890 predicate(false); 10891 10892 format %{ "FCFID $dst, $src \t// convL2D" %} 10893 size(4); 10894 ins_encode %{ 10895 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10896 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 10897 %} 10898 ins_pipe(pipe_class_default); 10899 %} 10900 10901 // Placed here as needed in expand. 10902 instruct convD2F_reg(regF dst, regD src) %{ 10903 match(Set dst (ConvD2F src)); 10904 format %{ "FRSP $dst, $src \t// convD2F" %} 10905 size(4); 10906 ins_encode %{ 10907 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 10908 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 10909 %} 10910 ins_pipe(pipe_class_default); 10911 %} 10912 10913 // Integer to Float conversion. 10914 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 10915 match(Set dst (ConvI2F src)); 10916 predicate(!VM_Version::has_fcfids()); 10917 ins_cost(DEFAULT_COST); 10918 10919 expand %{ 10920 iRegLdst tmpL; 10921 stackSlotL tmpS; 10922 regD tmpD; 10923 regD tmpD2; 10924 convI2L_reg(tmpL, src); // Sign-extension int to long. 10925 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10926 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10927 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 10928 convD2F_reg(dst, tmpD2); // Convert double to float. 10929 %} 10930 %} 10931 10932 instruct convL2FRaw_regF(regF dst, regD src) %{ 10933 // no match-rule, false predicate 10934 effect(DEF dst, USE src); 10935 predicate(false); 10936 10937 format %{ "FCFIDS $dst, $src \t// convL2F" %} 10938 size(4); 10939 ins_encode %{ 10940 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10941 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 10942 %} 10943 ins_pipe(pipe_class_default); 10944 %} 10945 10946 // Integer to Float conversion. Special version for Power7. 10947 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 10948 match(Set dst (ConvI2F src)); 10949 predicate(VM_Version::has_fcfids()); 10950 ins_cost(DEFAULT_COST); 10951 10952 expand %{ 10953 iRegLdst tmpL; 10954 stackSlotL tmpS; 10955 regD tmpD; 10956 convI2L_reg(tmpL, src); // Sign-extension int to long. 10957 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10958 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10959 convL2FRaw_regF(dst, tmpD); // Convert to float. 10960 %} 10961 %} 10962 10963 // L2F to avoid runtime call. 10964 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 10965 match(Set dst (ConvL2F src)); 10966 predicate(VM_Version::has_fcfids()); 10967 ins_cost(DEFAULT_COST); 10968 10969 expand %{ 10970 stackSlotL tmpS; 10971 regD tmpD; 10972 regL_to_stkL(tmpS, src); // Store long to stack. 10973 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10974 convL2FRaw_regF(dst, tmpD); // Convert to float. 10975 %} 10976 %} 10977 10978 // Moved up as used in expand. 10979 //instruct convD2F_reg(regF dst, regD src) %{%} 10980 10981 // Convert to Double 10982 10983 // Integer to Double conversion. 10984 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 10985 match(Set dst (ConvI2D src)); 10986 ins_cost(DEFAULT_COST); 10987 10988 expand %{ 10989 iRegLdst tmpL; 10990 stackSlotL tmpS; 10991 regD tmpD; 10992 convI2L_reg(tmpL, src); // Sign-extension int to long. 10993 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10994 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10995 convL2DRaw_regD(dst, tmpD); // Convert to double. 10996 %} 10997 %} 10998 10999 // Long to Double conversion 11000 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11001 match(Set dst (ConvL2D src)); 11002 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11003 11004 expand %{ 11005 regD tmpD; 11006 moveL2D_stack_reg(tmpD, src); 11007 convL2DRaw_regD(dst, tmpD); 11008 %} 11009 %} 11010 11011 instruct convF2D_reg(regD dst, regF src) %{ 11012 match(Set dst (ConvF2D src)); 11013 format %{ "FMR $dst, $src \t// float->double" %} 11014 // variable size, 0 or 4 11015 ins_encode %{ 11016 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11017 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11018 %} 11019 ins_pipe(pipe_class_default); 11020 %} 11021 11022 //----------Control Flow Instructions------------------------------------------ 11023 // Compare Instructions 11024 11025 // Compare Integers 11026 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11027 match(Set crx (CmpI src1 src2)); 11028 size(4); 11029 format %{ "CMPW $crx, $src1, $src2" %} 11030 ins_encode %{ 11031 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11032 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11033 %} 11034 ins_pipe(pipe_class_compare); 11035 %} 11036 11037 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11038 match(Set crx (CmpI src1 src2)); 11039 format %{ "CMPWI $crx, $src1, $src2" %} 11040 size(4); 11041 ins_encode %{ 11042 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11043 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11044 %} 11045 ins_pipe(pipe_class_compare); 11046 %} 11047 11048 // (src1 & src2) == 0? 11049 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11050 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11051 // r0 is killed 11052 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11053 size(4); 11054 ins_encode %{ 11055 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11056 __ andi_(R0, $src1$$Register, $src2$$constant); 11057 %} 11058 ins_pipe(pipe_class_compare); 11059 %} 11060 11061 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11062 match(Set crx (CmpL src1 src2)); 11063 format %{ "CMPD $crx, $src1, $src2" %} 11064 size(4); 11065 ins_encode %{ 11066 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11067 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11068 %} 11069 ins_pipe(pipe_class_compare); 11070 %} 11071 11072 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11073 match(Set crx (CmpL src1 src2)); 11074 format %{ "CMPDI $crx, $src1, $src2" %} 11075 size(4); 11076 ins_encode %{ 11077 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11078 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11079 %} 11080 ins_pipe(pipe_class_compare); 11081 %} 11082 11083 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11084 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11085 // r0 is killed 11086 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11087 size(4); 11088 ins_encode %{ 11089 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11090 __ and_(R0, $src1$$Register, $src2$$Register); 11091 %} 11092 ins_pipe(pipe_class_compare); 11093 %} 11094 11095 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11096 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11097 // r0 is killed 11098 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11099 size(4); 11100 ins_encode %{ 11101 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11102 __ andi_(R0, $src1$$Register, $src2$$constant); 11103 %} 11104 ins_pipe(pipe_class_compare); 11105 %} 11106 11107 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11108 // no match-rule, false predicate 11109 effect(DEF dst, USE crx); 11110 predicate(false); 11111 11112 ins_variable_size_depending_on_alignment(true); 11113 11114 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11115 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11116 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16); 11117 ins_encode %{ 11118 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11119 Label done; 11120 // li(Rdst, 0); // equal -> 0 11121 __ beq($crx$$CondRegister, done); 11122 __ li($dst$$Register, 1); // greater -> +1 11123 __ bgt($crx$$CondRegister, done); 11124 __ li($dst$$Register, -1); // unordered or less -> -1 11125 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11126 __ bind(done); 11127 %} 11128 ins_pipe(pipe_class_compare); 11129 %} 11130 11131 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11132 // no match-rule, false predicate 11133 effect(DEF dst, USE crx); 11134 predicate(false); 11135 11136 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11137 postalloc_expand %{ 11138 // 11139 // replaces 11140 // 11141 // region crx 11142 // \ | 11143 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11144 // 11145 // with 11146 // 11147 // region 11148 // \ 11149 // dst=loadConI16(0) 11150 // | 11151 // ^ region crx 11152 // | \ | 11153 // dst=cmovI_conIvalueMinus1_conIvalue1 11154 // 11155 11156 // Create new nodes. 11157 MachNode *m1 = new loadConI16Node(); 11158 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11159 11160 // inputs for new nodes 11161 m1->add_req(n_region); 11162 m2->add_req(n_region, n_crx); 11163 m2->add_prec(m1); 11164 11165 // operands for new nodes 11166 m1->_opnds[0] = op_dst; 11167 m1->_opnds[1] = new immI16Oper(0); 11168 m2->_opnds[0] = op_dst; 11169 m2->_opnds[1] = op_crx; 11170 11171 // registers for new nodes 11172 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11173 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11174 11175 // Insert new nodes. 11176 nodes->push(m1); 11177 nodes->push(m2); 11178 %} 11179 %} 11180 11181 // Manifest a CmpL3 result in an integer register. Very painful. 11182 // This is the test to avoid. 11183 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11184 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11185 match(Set dst (CmpL3 src1 src2)); 11186 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11187 11188 expand %{ 11189 flagsReg tmp1; 11190 cmpL_reg_reg(tmp1, src1, src2); 11191 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11192 %} 11193 %} 11194 11195 // Implicit range checks. 11196 // A range check in the ideal world has one of the following shapes: 11197 // - (If le (CmpU length index)), (IfTrue throw exception) 11198 // - (If lt (CmpU index length)), (IfFalse throw exception) 11199 // 11200 // Match range check 'If le (CmpU length index)'. 11201 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11202 match(If cmp (CmpU src_length index)); 11203 effect(USE labl); 11204 predicate(TrapBasedRangeChecks && 11205 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11206 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11207 (Matcher::branches_to_uncommon_trap(_leaf))); 11208 11209 ins_is_TrapBasedCheckNode(true); 11210 11211 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11212 size(4); 11213 ins_encode %{ 11214 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11215 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11216 __ trap_range_check_le($src_length$$Register, $index$$constant); 11217 } else { 11218 // Both successors are uncommon traps, probability is 0. 11219 // Node got flipped during fixup flow. 11220 assert($cmp$$cmpcode == 0x9, "must be greater"); 11221 __ trap_range_check_g($src_length$$Register, $index$$constant); 11222 } 11223 %} 11224 ins_pipe(pipe_class_trap); 11225 %} 11226 11227 // Match range check 'If lt (CmpU index length)'. 11228 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11229 match(If cmp (CmpU src_index src_length)); 11230 effect(USE labl); 11231 predicate(TrapBasedRangeChecks && 11232 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11233 _leaf->as_If()->_prob >= PROB_ALWAYS && 11234 (Matcher::branches_to_uncommon_trap(_leaf))); 11235 11236 ins_is_TrapBasedCheckNode(true); 11237 11238 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 11239 size(4); 11240 ins_encode %{ 11241 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 11242 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11243 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 11244 } else { 11245 // Both successors are uncommon traps, probability is 0. 11246 // Node got flipped during fixup flow. 11247 assert($cmp$$cmpcode == 0x8, "must be less"); 11248 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 11249 } 11250 %} 11251 ins_pipe(pipe_class_trap); 11252 %} 11253 11254 // Match range check 'If lt (CmpU index length)'. 11255 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 11256 match(If cmp (CmpU src_index length)); 11257 effect(USE labl); 11258 predicate(TrapBasedRangeChecks && 11259 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11260 _leaf->as_If()->_prob >= PROB_ALWAYS && 11261 (Matcher::branches_to_uncommon_trap(_leaf))); 11262 11263 ins_is_TrapBasedCheckNode(true); 11264 11265 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 11266 size(4); 11267 ins_encode %{ 11268 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11269 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11270 __ trap_range_check_ge($src_index$$Register, $length$$constant); 11271 } else { 11272 // Both successors are uncommon traps, probability is 0. 11273 // Node got flipped during fixup flow. 11274 assert($cmp$$cmpcode == 0x8, "must be less"); 11275 __ trap_range_check_l($src_index$$Register, $length$$constant); 11276 } 11277 %} 11278 ins_pipe(pipe_class_trap); 11279 %} 11280 11281 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11282 match(Set crx (CmpU src1 src2)); 11283 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 11284 size(4); 11285 ins_encode %{ 11286 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11287 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11288 %} 11289 ins_pipe(pipe_class_compare); 11290 %} 11291 11292 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 11293 match(Set crx (CmpU src1 src2)); 11294 size(4); 11295 format %{ "CMPLWI $crx, $src1, $src2" %} 11296 ins_encode %{ 11297 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11298 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11299 %} 11300 ins_pipe(pipe_class_compare); 11301 %} 11302 11303 // Implicit zero checks (more implicit null checks). 11304 // No constant pool entries required. 11305 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 11306 match(If cmp (CmpN value zero)); 11307 effect(USE labl); 11308 predicate(TrapBasedNullChecks && 11309 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11310 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11311 Matcher::branches_to_uncommon_trap(_leaf)); 11312 ins_cost(1); 11313 11314 ins_is_TrapBasedCheckNode(true); 11315 11316 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 11317 size(4); 11318 ins_encode %{ 11319 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11320 if ($cmp$$cmpcode == 0xA) { 11321 __ trap_null_check($value$$Register); 11322 } else { 11323 // Both successors are uncommon traps, probability is 0. 11324 // Node got flipped during fixup flow. 11325 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11326 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11327 } 11328 %} 11329 ins_pipe(pipe_class_trap); 11330 %} 11331 11332 // Compare narrow oops. 11333 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 11334 match(Set crx (CmpN src1 src2)); 11335 11336 size(4); 11337 ins_cost(2); 11338 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 11339 ins_encode %{ 11340 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11341 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11342 %} 11343 ins_pipe(pipe_class_compare); 11344 %} 11345 11346 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 11347 match(Set crx (CmpN src1 src2)); 11348 // Make this more expensive than zeroCheckN_iReg_imm0. 11349 ins_cost(2); 11350 11351 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 11352 size(4); 11353 ins_encode %{ 11354 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11355 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11356 %} 11357 ins_pipe(pipe_class_compare); 11358 %} 11359 11360 // Implicit zero checks (more implicit null checks). 11361 // No constant pool entries required. 11362 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 11363 match(If cmp (CmpP value zero)); 11364 effect(USE labl); 11365 predicate(TrapBasedNullChecks && 11366 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11367 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11368 Matcher::branches_to_uncommon_trap(_leaf)); 11369 ins_cost(1); // Should not be cheaper than zeroCheckN. 11370 11371 ins_is_TrapBasedCheckNode(true); 11372 11373 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 11374 size(4); 11375 ins_encode %{ 11376 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11377 if ($cmp$$cmpcode == 0xA) { 11378 __ trap_null_check($value$$Register); 11379 } else { 11380 // Both successors are uncommon traps, probability is 0. 11381 // Node got flipped during fixup flow. 11382 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11383 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11384 } 11385 %} 11386 ins_pipe(pipe_class_trap); 11387 %} 11388 11389 // Compare Pointers 11390 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 11391 match(Set crx (CmpP src1 src2)); 11392 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 11393 size(4); 11394 ins_encode %{ 11395 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11396 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11397 %} 11398 ins_pipe(pipe_class_compare); 11399 %} 11400 11401 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 11402 match(Set crx (CmpP src1 src2)); 11403 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 11404 size(4); 11405 ins_encode %{ 11406 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11407 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 11408 %} 11409 ins_pipe(pipe_class_compare); 11410 %} 11411 11412 // Used in postalloc expand. 11413 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 11414 // This match rule prevents reordering of node before a safepoint. 11415 // This only makes sense if this instructions is used exclusively 11416 // for the expansion of EncodeP! 11417 match(Set crx (CmpP src1 src2)); 11418 predicate(false); 11419 11420 format %{ "CMPDI $crx, $src1, $src2" %} 11421 size(4); 11422 ins_encode %{ 11423 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11424 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11425 %} 11426 ins_pipe(pipe_class_compare); 11427 %} 11428 11429 //----------Float Compares---------------------------------------------------- 11430 11431 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 11432 // Needs matchrule, see cmpDUnordered. 11433 match(Set crx (CmpF src1 src2)); 11434 // no match-rule, false predicate 11435 predicate(false); 11436 11437 format %{ "cmpFUrd $crx, $src1, $src2" %} 11438 size(4); 11439 ins_encode %{ 11440 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11441 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11442 %} 11443 ins_pipe(pipe_class_default); 11444 %} 11445 11446 instruct cmov_bns_less(flagsReg crx) %{ 11447 // no match-rule, false predicate 11448 effect(DEF crx); 11449 predicate(false); 11450 11451 ins_variable_size_depending_on_alignment(true); 11452 11453 format %{ "cmov $crx" %} 11454 // Worst case is branch + move + stop, no stop without scheduler. 11455 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12); 11456 ins_encode %{ 11457 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 11458 Label done; 11459 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 11460 __ li(R0, 0); 11461 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 11462 // TODO PPC port __ endgroup_if_needed(_size == 16); 11463 __ bind(done); 11464 %} 11465 ins_pipe(pipe_class_default); 11466 %} 11467 11468 // Compare floating, generate condition code. 11469 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 11470 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 11471 // 11472 // The following code sequence occurs a lot in mpegaudio: 11473 // 11474 // block BXX: 11475 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 11476 // cmpFUrd CCR6, F11, F9 11477 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 11478 // cmov CCR6 11479 // 8: instruct branchConSched: 11480 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 11481 match(Set crx (CmpF src1 src2)); 11482 ins_cost(DEFAULT_COST+BRANCH_COST); 11483 11484 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 11485 postalloc_expand %{ 11486 // 11487 // replaces 11488 // 11489 // region src1 src2 11490 // \ | | 11491 // crx=cmpF_reg_reg 11492 // 11493 // with 11494 // 11495 // region src1 src2 11496 // \ | | 11497 // crx=cmpFUnordered_reg_reg 11498 // | 11499 // ^ region 11500 // | \ 11501 // crx=cmov_bns_less 11502 // 11503 11504 // Create new nodes. 11505 MachNode *m1 = new cmpFUnordered_reg_regNode(); 11506 MachNode *m2 = new cmov_bns_lessNode(); 11507 11508 // inputs for new nodes 11509 m1->add_req(n_region, n_src1, n_src2); 11510 m2->add_req(n_region); 11511 m2->add_prec(m1); 11512 11513 // operands for new nodes 11514 m1->_opnds[0] = op_crx; 11515 m1->_opnds[1] = op_src1; 11516 m1->_opnds[2] = op_src2; 11517 m2->_opnds[0] = op_crx; 11518 11519 // registers for new nodes 11520 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11521 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11522 11523 // Insert new nodes. 11524 nodes->push(m1); 11525 nodes->push(m2); 11526 %} 11527 %} 11528 11529 // Compare float, generate -1,0,1 11530 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 11531 match(Set dst (CmpF3 src1 src2)); 11532 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11533 11534 expand %{ 11535 flagsReg tmp1; 11536 cmpFUnordered_reg_reg(tmp1, src1, src2); 11537 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11538 %} 11539 %} 11540 11541 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 11542 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 11543 // node right before the conditional move using it. 11544 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 11545 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 11546 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 11547 // conditional move was supposed to be spilled. 11548 match(Set crx (CmpD src1 src2)); 11549 // False predicate, shall not be matched. 11550 predicate(false); 11551 11552 format %{ "cmpFUrd $crx, $src1, $src2" %} 11553 size(4); 11554 ins_encode %{ 11555 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11556 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11557 %} 11558 ins_pipe(pipe_class_default); 11559 %} 11560 11561 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 11562 match(Set crx (CmpD src1 src2)); 11563 ins_cost(DEFAULT_COST+BRANCH_COST); 11564 11565 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 11566 postalloc_expand %{ 11567 // 11568 // replaces 11569 // 11570 // region src1 src2 11571 // \ | | 11572 // crx=cmpD_reg_reg 11573 // 11574 // with 11575 // 11576 // region src1 src2 11577 // \ | | 11578 // crx=cmpDUnordered_reg_reg 11579 // | 11580 // ^ region 11581 // | \ 11582 // crx=cmov_bns_less 11583 // 11584 11585 // create new nodes 11586 MachNode *m1 = new cmpDUnordered_reg_regNode(); 11587 MachNode *m2 = new cmov_bns_lessNode(); 11588 11589 // inputs for new nodes 11590 m1->add_req(n_region, n_src1, n_src2); 11591 m2->add_req(n_region); 11592 m2->add_prec(m1); 11593 11594 // operands for new nodes 11595 m1->_opnds[0] = op_crx; 11596 m1->_opnds[1] = op_src1; 11597 m1->_opnds[2] = op_src2; 11598 m2->_opnds[0] = op_crx; 11599 11600 // registers for new nodes 11601 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11602 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11603 11604 // Insert new nodes. 11605 nodes->push(m1); 11606 nodes->push(m2); 11607 %} 11608 %} 11609 11610 // Compare double, generate -1,0,1 11611 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 11612 match(Set dst (CmpD3 src1 src2)); 11613 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11614 11615 expand %{ 11616 flagsReg tmp1; 11617 cmpDUnordered_reg_reg(tmp1, src1, src2); 11618 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11619 %} 11620 %} 11621 11622 //----------Branches--------------------------------------------------------- 11623 // Jump 11624 11625 // Direct Branch. 11626 instruct branch(label labl) %{ 11627 match(Goto); 11628 effect(USE labl); 11629 ins_cost(BRANCH_COST); 11630 11631 format %{ "B $labl" %} 11632 size(4); 11633 ins_encode %{ 11634 // TODO: PPC port $archOpcode(ppc64Opcode_b); 11635 Label d; // dummy 11636 __ bind(d); 11637 Label* p = $labl$$label; 11638 // `p' is `NULL' when this encoding class is used only to 11639 // determine the size of the encoded instruction. 11640 Label& l = (NULL == p)? d : *(p); 11641 __ b(l); 11642 %} 11643 ins_pipe(pipe_class_default); 11644 %} 11645 11646 // Conditional Near Branch 11647 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11648 // Same match rule as `branchConFar'. 11649 match(If cmp crx); 11650 effect(USE lbl); 11651 ins_cost(BRANCH_COST); 11652 11653 // If set to 1 this indicates that the current instruction is a 11654 // short variant of a long branch. This avoids using this 11655 // instruction in first-pass matching. It will then only be used in 11656 // the `Shorten_branches' pass. 11657 ins_short_branch(1); 11658 11659 format %{ "B$cmp $crx, $lbl" %} 11660 size(4); 11661 ins_encode( enc_bc(crx, cmp, lbl) ); 11662 ins_pipe(pipe_class_default); 11663 %} 11664 11665 // This is for cases when the ppc64 `bc' instruction does not 11666 // reach far enough. So we emit a far branch here, which is more 11667 // expensive. 11668 // 11669 // Conditional Far Branch 11670 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11671 // Same match rule as `branchCon'. 11672 match(If cmp crx); 11673 effect(USE crx, USE lbl); 11674 predicate(!false /* TODO: PPC port HB_Schedule*/); 11675 // Higher cost than `branchCon'. 11676 ins_cost(5*BRANCH_COST); 11677 11678 // This is not a short variant of a branch, but the long variant. 11679 ins_short_branch(0); 11680 11681 format %{ "B_FAR$cmp $crx, $lbl" %} 11682 size(8); 11683 ins_encode( enc_bc_far(crx, cmp, lbl) ); 11684 ins_pipe(pipe_class_default); 11685 %} 11686 11687 // Conditional Branch used with Power6 scheduler (can be far or short). 11688 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11689 // Same match rule as `branchCon'. 11690 match(If cmp crx); 11691 effect(USE crx, USE lbl); 11692 predicate(false /* TODO: PPC port HB_Schedule*/); 11693 // Higher cost than `branchCon'. 11694 ins_cost(5*BRANCH_COST); 11695 11696 // Actually size doesn't depend on alignment but on shortening. 11697 ins_variable_size_depending_on_alignment(true); 11698 // long variant. 11699 ins_short_branch(0); 11700 11701 format %{ "B_FAR$cmp $crx, $lbl" %} 11702 size(8); // worst case 11703 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 11704 ins_pipe(pipe_class_default); 11705 %} 11706 11707 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11708 match(CountedLoopEnd cmp crx); 11709 effect(USE labl); 11710 ins_cost(BRANCH_COST); 11711 11712 // short variant. 11713 ins_short_branch(1); 11714 11715 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 11716 size(4); 11717 ins_encode( enc_bc(crx, cmp, labl) ); 11718 ins_pipe(pipe_class_default); 11719 %} 11720 11721 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11722 match(CountedLoopEnd cmp crx); 11723 effect(USE labl); 11724 predicate(!false /* TODO: PPC port HB_Schedule */); 11725 ins_cost(BRANCH_COST); 11726 11727 // Long variant. 11728 ins_short_branch(0); 11729 11730 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11731 size(8); 11732 ins_encode( enc_bc_far(crx, cmp, labl) ); 11733 ins_pipe(pipe_class_default); 11734 %} 11735 11736 // Conditional Branch used with Power6 scheduler (can be far or short). 11737 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11738 match(CountedLoopEnd cmp crx); 11739 effect(USE labl); 11740 predicate(false /* TODO: PPC port HB_Schedule */); 11741 // Higher cost than `branchCon'. 11742 ins_cost(5*BRANCH_COST); 11743 11744 // Actually size doesn't depend on alignment but on shortening. 11745 ins_variable_size_depending_on_alignment(true); 11746 // Long variant. 11747 ins_short_branch(0); 11748 11749 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11750 size(8); // worst case 11751 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 11752 ins_pipe(pipe_class_default); 11753 %} 11754 11755 // ============================================================================ 11756 // Java runtime operations, intrinsics and other complex operations. 11757 11758 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 11759 // array for an instance of the superklass. Set a hidden internal cache on a 11760 // hit (cache is checked with exposed code in gen_subtype_check()). Return 11761 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 11762 // 11763 // GL TODO: Improve this. 11764 // - result should not be a TEMP 11765 // - Add match rule as on sparc avoiding additional Cmp. 11766 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 11767 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 11768 match(Set result (PartialSubtypeCheck subklass superklass)); 11769 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 11770 ins_cost(DEFAULT_COST*10); 11771 11772 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 11773 ins_encode %{ 11774 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11775 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 11776 $tmp_klass$$Register, NULL, $result$$Register); 11777 %} 11778 ins_pipe(pipe_class_default); 11779 %} 11780 11781 // inlined locking and unlocking 11782 11783 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 11784 match(Set crx (FastLock oop box)); 11785 effect(TEMP tmp1, TEMP tmp2); 11786 predicate(!Compile::current()->use_rtm()); 11787 11788 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 11789 ins_encode %{ 11790 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11791 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11792 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 11793 UseBiasedLocking && !UseOptoBiasInlining); 11794 // If locking was successfull, crx should indicate 'EQ'. 11795 // The compiler generates a branch to the runtime call to 11796 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11797 %} 11798 ins_pipe(pipe_class_compare); 11799 %} 11800 11801 // Separate version for TM. Use bound register for box to enable USE_KILL. 11802 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11803 match(Set crx (FastLock oop box)); 11804 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 11805 predicate(Compile::current()->use_rtm()); 11806 11807 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 11808 ins_encode %{ 11809 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11810 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11811 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11812 /*Biased Locking*/ false, 11813 _rtm_counters, _stack_rtm_counters, 11814 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 11815 /*TM*/ true, ra_->C->profile_rtm()); 11816 // If locking was successfull, crx should indicate 'EQ'. 11817 // The compiler generates a branch to the runtime call to 11818 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11819 %} 11820 ins_pipe(pipe_class_compare); 11821 %} 11822 11823 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11824 match(Set crx (FastUnlock oop box)); 11825 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11826 predicate(!Compile::current()->use_rtm()); 11827 11828 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 11829 ins_encode %{ 11830 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11831 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11832 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11833 UseBiasedLocking && !UseOptoBiasInlining, 11834 false); 11835 // If unlocking was successfull, crx should indicate 'EQ'. 11836 // The compiler generates a branch to the runtime call to 11837 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11838 %} 11839 ins_pipe(pipe_class_compare); 11840 %} 11841 11842 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11843 match(Set crx (FastUnlock oop box)); 11844 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11845 predicate(Compile::current()->use_rtm()); 11846 11847 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 11848 ins_encode %{ 11849 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11850 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11851 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11852 /*Biased Locking*/ false, /*TM*/ true); 11853 // If unlocking was successfull, crx should indicate 'EQ'. 11854 // The compiler generates a branch to the runtime call to 11855 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11856 %} 11857 ins_pipe(pipe_class_compare); 11858 %} 11859 11860 // Align address. 11861 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 11862 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 11863 11864 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 11865 size(4); 11866 ins_encode %{ 11867 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 11868 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 11869 %} 11870 ins_pipe(pipe_class_default); 11871 %} 11872 11873 // Array size computation. 11874 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 11875 match(Set dst (SubL (CastP2X end) (CastP2X start))); 11876 11877 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 11878 size(4); 11879 ins_encode %{ 11880 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 11881 __ subf($dst$$Register, $start$$Register, $end$$Register); 11882 %} 11883 ins_pipe(pipe_class_default); 11884 %} 11885 11886 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 11887 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 11888 match(Set dummy (ClearArray cnt base)); 11889 effect(USE_KILL base, KILL ctr); 11890 ins_cost(2 * MEMORY_REF_COST); 11891 11892 format %{ "ClearArray $cnt, $base" %} 11893 ins_encode %{ 11894 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11895 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 11896 %} 11897 ins_pipe(pipe_class_default); 11898 %} 11899 11900 // Clear-array with constant large array length. 11901 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 11902 match(Set dummy (ClearArray cnt base)); 11903 effect(USE_KILL base, TEMP tmp, KILL ctr); 11904 ins_cost(3 * MEMORY_REF_COST); 11905 11906 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 11907 ins_encode %{ 11908 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11909 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 11910 %} 11911 ins_pipe(pipe_class_default); 11912 %} 11913 11914 // Clear-array with dynamic array length. 11915 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 11916 match(Set dummy (ClearArray cnt base)); 11917 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 11918 ins_cost(4 * MEMORY_REF_COST); 11919 11920 format %{ "ClearArray $cnt, $base" %} 11921 ins_encode %{ 11922 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11923 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 11924 %} 11925 ins_pipe(pipe_class_default); 11926 %} 11927 11928 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11929 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11930 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11931 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11932 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11933 ins_cost(300); 11934 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11935 ins_encode %{ 11936 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11937 __ string_compare($str1$$Register, $str2$$Register, 11938 $cnt1$$Register, $cnt2$$Register, 11939 $tmp$$Register, 11940 $result$$Register, StrIntrinsicNode::LL); 11941 %} 11942 ins_pipe(pipe_class_default); 11943 %} 11944 11945 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11946 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11947 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11948 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11949 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11950 ins_cost(300); 11951 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11952 ins_encode %{ 11953 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11954 __ string_compare($str1$$Register, $str2$$Register, 11955 $cnt1$$Register, $cnt2$$Register, 11956 $tmp$$Register, 11957 $result$$Register, StrIntrinsicNode::UU); 11958 %} 11959 ins_pipe(pipe_class_default); 11960 %} 11961 11962 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11963 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11964 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11965 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11966 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11967 ins_cost(300); 11968 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11969 ins_encode %{ 11970 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11971 __ string_compare($str1$$Register, $str2$$Register, 11972 $cnt1$$Register, $cnt2$$Register, 11973 $tmp$$Register, 11974 $result$$Register, StrIntrinsicNode::LU); 11975 %} 11976 ins_pipe(pipe_class_default); 11977 %} 11978 11979 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11980 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11981 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11982 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11983 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11984 ins_cost(300); 11985 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11986 ins_encode %{ 11987 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11988 __ string_compare($str2$$Register, $str1$$Register, 11989 $cnt2$$Register, $cnt1$$Register, 11990 $tmp$$Register, 11991 $result$$Register, StrIntrinsicNode::UL); 11992 %} 11993 ins_pipe(pipe_class_default); 11994 %} 11995 11996 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 11997 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11998 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 11999 match(Set result (StrEquals (Binary str1 str2) cnt)); 12000 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12001 ins_cost(300); 12002 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12003 ins_encode %{ 12004 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12005 __ array_equals(false, $str1$$Register, $str2$$Register, 12006 $cnt$$Register, $tmp$$Register, 12007 $result$$Register, true /* byte */); 12008 %} 12009 ins_pipe(pipe_class_default); 12010 %} 12011 12012 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12013 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12014 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12015 match(Set result (StrEquals (Binary str1 str2) cnt)); 12016 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12017 ins_cost(300); 12018 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12019 ins_encode %{ 12020 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12021 __ array_equals(false, $str1$$Register, $str2$$Register, 12022 $cnt$$Register, $tmp$$Register, 12023 $result$$Register, false /* byte */); 12024 %} 12025 ins_pipe(pipe_class_default); 12026 %} 12027 12028 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12029 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12030 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12031 match(Set result (AryEq ary1 ary2)); 12032 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12033 ins_cost(300); 12034 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12035 ins_encode %{ 12036 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12037 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12038 $tmp1$$Register, $tmp2$$Register, 12039 $result$$Register, true /* byte */); 12040 %} 12041 ins_pipe(pipe_class_default); 12042 %} 12043 12044 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12045 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12046 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12047 match(Set result (AryEq ary1 ary2)); 12048 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12049 ins_cost(300); 12050 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12051 ins_encode %{ 12052 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12053 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12054 $tmp1$$Register, $tmp2$$Register, 12055 $result$$Register, false /* byte */); 12056 %} 12057 ins_pipe(pipe_class_default); 12058 %} 12059 12060 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12061 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12062 iRegIdst tmp1, iRegIdst tmp2, 12063 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12064 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12065 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12066 // Required for EA: check if it is still a type_array. 12067 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12068 ins_cost(150); 12069 12070 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12071 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12072 12073 ins_encode %{ 12074 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12075 immPOper *needleOper = (immPOper *)$needleImm; 12076 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12077 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12078 jchar chr; 12079 #ifdef VM_LITTLE_ENDIAN 12080 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12081 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12082 #else 12083 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12084 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12085 #endif 12086 __ string_indexof_char($result$$Register, 12087 $haystack$$Register, $haycnt$$Register, 12088 R0, chr, 12089 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12090 %} 12091 ins_pipe(pipe_class_compare); 12092 %} 12093 12094 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12095 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12096 iRegIdst tmp1, iRegIdst tmp2, 12097 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12098 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12099 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12100 // Required for EA: check if it is still a type_array. 12101 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12102 ins_cost(150); 12103 12104 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12105 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12106 12107 ins_encode %{ 12108 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12109 immPOper *needleOper = (immPOper *)$needleImm; 12110 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12111 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12112 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12113 __ string_indexof_char($result$$Register, 12114 $haystack$$Register, $haycnt$$Register, 12115 R0, chr, 12116 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12117 %} 12118 ins_pipe(pipe_class_compare); 12119 %} 12120 12121 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12122 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12123 iRegIdst tmp1, iRegIdst tmp2, 12124 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12125 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12126 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12127 // Required for EA: check if it is still a type_array. 12128 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12129 ins_cost(150); 12130 12131 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12132 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12133 12134 ins_encode %{ 12135 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12136 immPOper *needleOper = (immPOper *)$needleImm; 12137 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12138 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12139 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12140 __ string_indexof_char($result$$Register, 12141 $haystack$$Register, $haycnt$$Register, 12142 R0, chr, 12143 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12144 %} 12145 ins_pipe(pipe_class_compare); 12146 %} 12147 12148 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12149 rscratch2RegP needle, immI_1 needlecntImm, 12150 iRegIdst tmp1, iRegIdst tmp2, 12151 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12152 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12153 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12154 // Required for EA: check if it is still a type_array. 12155 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12156 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12157 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12158 ins_cost(180); 12159 12160 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12161 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12162 ins_encode %{ 12163 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12164 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12165 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12166 guarantee(needle_values, "sanity"); 12167 jchar chr; 12168 #ifdef VM_LITTLE_ENDIAN 12169 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12170 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12171 #else 12172 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12173 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12174 #endif 12175 __ string_indexof_char($result$$Register, 12176 $haystack$$Register, $haycnt$$Register, 12177 R0, chr, 12178 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12179 %} 12180 ins_pipe(pipe_class_compare); 12181 %} 12182 12183 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12184 rscratch2RegP needle, immI_1 needlecntImm, 12185 iRegIdst tmp1, iRegIdst tmp2, 12186 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12187 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12188 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12189 // Required for EA: check if it is still a type_array. 12190 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12191 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12192 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12193 ins_cost(180); 12194 12195 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12196 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12197 ins_encode %{ 12198 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12199 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12200 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12201 guarantee(needle_values, "sanity"); 12202 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12203 __ string_indexof_char($result$$Register, 12204 $haystack$$Register, $haycnt$$Register, 12205 R0, chr, 12206 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12207 %} 12208 ins_pipe(pipe_class_compare); 12209 %} 12210 12211 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12212 rscratch2RegP needle, immI_1 needlecntImm, 12213 iRegIdst tmp1, iRegIdst tmp2, 12214 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12215 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12216 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12217 // Required for EA: check if it is still a type_array. 12218 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12219 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12220 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12221 ins_cost(180); 12222 12223 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12224 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12225 ins_encode %{ 12226 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12227 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12228 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12229 guarantee(needle_values, "sanity"); 12230 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12231 __ string_indexof_char($result$$Register, 12232 $haystack$$Register, $haycnt$$Register, 12233 R0, chr, 12234 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12235 %} 12236 ins_pipe(pipe_class_compare); 12237 %} 12238 12239 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12240 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12241 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12242 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12243 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12244 ins_cost(180); 12245 12246 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 12247 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12248 ins_encode %{ 12249 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12250 __ string_indexof_char($result$$Register, 12251 $haystack$$Register, $haycnt$$Register, 12252 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12253 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12254 %} 12255 ins_pipe(pipe_class_compare); 12256 %} 12257 12258 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12259 iRegPsrc needle, uimmI15 needlecntImm, 12260 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12261 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12262 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12263 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12264 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12265 // Required for EA: check if it is still a type_array. 12266 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12267 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12268 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12269 ins_cost(250); 12270 12271 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12272 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12273 ins_encode %{ 12274 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12275 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12276 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12277 12278 __ string_indexof($result$$Register, 12279 $haystack$$Register, $haycnt$$Register, 12280 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12281 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12282 %} 12283 ins_pipe(pipe_class_compare); 12284 %} 12285 12286 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12287 iRegPsrc needle, uimmI15 needlecntImm, 12288 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12289 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12290 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12291 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12292 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12293 // Required for EA: check if it is still a type_array. 12294 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12295 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12296 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12297 ins_cost(250); 12298 12299 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12300 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12301 ins_encode %{ 12302 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12303 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12304 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12305 12306 __ string_indexof($result$$Register, 12307 $haystack$$Register, $haycnt$$Register, 12308 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12309 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12310 %} 12311 ins_pipe(pipe_class_compare); 12312 %} 12313 12314 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12315 iRegPsrc needle, uimmI15 needlecntImm, 12316 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12317 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12318 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12319 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12320 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12321 // Required for EA: check if it is still a type_array. 12322 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12323 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12324 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12325 ins_cost(250); 12326 12327 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12328 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12329 ins_encode %{ 12330 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12331 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12332 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12333 12334 __ string_indexof($result$$Register, 12335 $haystack$$Register, $haycnt$$Register, 12336 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12337 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12338 %} 12339 ins_pipe(pipe_class_compare); 12340 %} 12341 12342 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12343 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12344 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12345 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12346 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12347 TEMP_DEF result, 12348 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12349 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12350 ins_cost(300); 12351 12352 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12353 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12354 ins_encode %{ 12355 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12356 __ string_indexof($result$$Register, 12357 $haystack$$Register, $haycnt$$Register, 12358 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12359 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12360 %} 12361 ins_pipe(pipe_class_compare); 12362 %} 12363 12364 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12365 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12366 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12367 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12368 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12369 TEMP_DEF result, 12370 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12371 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12372 ins_cost(300); 12373 12374 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12375 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12376 ins_encode %{ 12377 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12378 __ string_indexof($result$$Register, 12379 $haystack$$Register, $haycnt$$Register, 12380 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12381 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12382 %} 12383 ins_pipe(pipe_class_compare); 12384 %} 12385 12386 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12387 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12388 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12389 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12390 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12391 TEMP_DEF result, 12392 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12393 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12394 ins_cost(300); 12395 12396 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12397 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12398 ins_encode %{ 12399 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12400 __ string_indexof($result$$Register, 12401 $haystack$$Register, $haycnt$$Register, 12402 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12403 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12404 %} 12405 ins_pipe(pipe_class_compare); 12406 %} 12407 12408 // char[] to byte[] compression 12409 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12410 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12411 match(Set result (StrCompressedCopy src (Binary dst len))); 12412 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12413 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12414 ins_cost(300); 12415 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12416 ins_encode %{ 12417 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12418 Label Lskip, Ldone; 12419 __ li($result$$Register, 0); 12420 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12421 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 12422 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12423 __ beq(CCR0, Lskip); 12424 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 12425 __ bind(Lskip); 12426 __ mr($result$$Register, $len$$Register); 12427 __ bind(Ldone); 12428 %} 12429 ins_pipe(pipe_class_default); 12430 %} 12431 12432 // byte[] to char[] inflation 12433 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 12434 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12435 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12436 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12437 ins_cost(300); 12438 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12439 ins_encode %{ 12440 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12441 Label Ldone; 12442 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12443 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 12444 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12445 __ beq(CCR0, Ldone); 12446 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 12447 __ bind(Ldone); 12448 %} 12449 ins_pipe(pipe_class_default); 12450 %} 12451 12452 // StringCoding.java intrinsics 12453 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 12454 regCTR ctr, flagsRegCR0 cr0) 12455 %{ 12456 match(Set result (HasNegatives ary1 len)); 12457 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 12458 ins_cost(300); 12459 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 12460 ins_encode %{ 12461 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12462 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 12463 $tmp1$$Register, $tmp2$$Register); 12464 %} 12465 ins_pipe(pipe_class_default); 12466 %} 12467 12468 // encode char[] to byte[] in ISO_8859_1 12469 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12470 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12471 match(Set result (EncodeISOArray src (Binary dst len))); 12472 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12473 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12474 ins_cost(300); 12475 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12476 ins_encode %{ 12477 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12478 Label Lslow, Lfailure1, Lfailure2, Ldone; 12479 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12480 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 12481 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12482 __ beq(CCR0, Ldone); 12483 __ bind(Lslow); 12484 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 12485 __ li($result$$Register, 0); 12486 __ b(Ldone); 12487 12488 __ bind(Lfailure1); 12489 __ mr($result$$Register, $len$$Register); 12490 __ mfctr($tmp1$$Register); 12491 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 12492 __ beq(CCR0, Ldone); 12493 __ b(Lslow); 12494 12495 __ bind(Lfailure2); 12496 __ mfctr($result$$Register); // Remaining characters. 12497 12498 __ bind(Ldone); 12499 __ subf($result$$Register, $result$$Register, $len$$Register); 12500 %} 12501 ins_pipe(pipe_class_default); 12502 %} 12503 12504 12505 //---------- Min/Max Instructions --------------------------------------------- 12506 12507 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12508 match(Set dst (MinI src1 src2)); 12509 ins_cost(DEFAULT_COST*6); 12510 12511 expand %{ 12512 iRegLdst src1s; 12513 iRegLdst src2s; 12514 iRegLdst diff; 12515 iRegLdst sm; 12516 iRegLdst doz; // difference or zero 12517 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12518 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12519 subL_reg_reg(diff, src2s, src1s); 12520 // Need to consider >=33 bit result, therefore we need signmaskL. 12521 signmask64L_regL(sm, diff); 12522 andL_reg_reg(doz, diff, sm); // <=0 12523 addI_regL_regL(dst, doz, src1s); 12524 %} 12525 %} 12526 12527 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12528 match(Set dst (MinI src1 src2)); 12529 effect(KILL cr0); 12530 predicate(VM_Version::has_isel()); 12531 ins_cost(DEFAULT_COST*2); 12532 12533 ins_encode %{ 12534 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12535 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12536 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 12537 %} 12538 ins_pipe(pipe_class_default); 12539 %} 12540 12541 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12542 match(Set dst (MaxI src1 src2)); 12543 ins_cost(DEFAULT_COST*6); 12544 12545 expand %{ 12546 iRegLdst src1s; 12547 iRegLdst src2s; 12548 iRegLdst diff; 12549 iRegLdst sm; 12550 iRegLdst doz; // difference or zero 12551 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12552 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12553 subL_reg_reg(diff, src2s, src1s); 12554 // Need to consider >=33 bit result, therefore we need signmaskL. 12555 signmask64L_regL(sm, diff); 12556 andcL_reg_reg(doz, diff, sm); // >=0 12557 addI_regL_regL(dst, doz, src1s); 12558 %} 12559 %} 12560 12561 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12562 match(Set dst (MaxI src1 src2)); 12563 effect(KILL cr0); 12564 predicate(VM_Version::has_isel()); 12565 ins_cost(DEFAULT_COST*2); 12566 12567 ins_encode %{ 12568 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12569 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12570 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 12571 %} 12572 ins_pipe(pipe_class_default); 12573 %} 12574 12575 //---------- Population Count Instructions ------------------------------------ 12576 12577 // Popcnt for Power7. 12578 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 12579 match(Set dst (PopCountI src)); 12580 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12581 ins_cost(DEFAULT_COST); 12582 12583 format %{ "POPCNTW $dst, $src" %} 12584 size(4); 12585 ins_encode %{ 12586 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12587 __ popcntw($dst$$Register, $src$$Register); 12588 %} 12589 ins_pipe(pipe_class_default); 12590 %} 12591 12592 // Popcnt for Power7. 12593 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 12594 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12595 match(Set dst (PopCountL src)); 12596 ins_cost(DEFAULT_COST); 12597 12598 format %{ "POPCNTD $dst, $src" %} 12599 size(4); 12600 ins_encode %{ 12601 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12602 __ popcntd($dst$$Register, $src$$Register); 12603 %} 12604 ins_pipe(pipe_class_default); 12605 %} 12606 12607 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 12608 match(Set dst (CountLeadingZerosI src)); 12609 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12610 ins_cost(DEFAULT_COST); 12611 12612 format %{ "CNTLZW $dst, $src" %} 12613 size(4); 12614 ins_encode %{ 12615 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 12616 __ cntlzw($dst$$Register, $src$$Register); 12617 %} 12618 ins_pipe(pipe_class_default); 12619 %} 12620 12621 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 12622 match(Set dst (CountLeadingZerosL src)); 12623 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12624 ins_cost(DEFAULT_COST); 12625 12626 format %{ "CNTLZD $dst, $src" %} 12627 size(4); 12628 ins_encode %{ 12629 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12630 __ cntlzd($dst$$Register, $src$$Register); 12631 %} 12632 ins_pipe(pipe_class_default); 12633 %} 12634 12635 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 12636 // no match-rule, false predicate 12637 effect(DEF dst, USE src); 12638 predicate(false); 12639 12640 format %{ "CNTLZD $dst, $src" %} 12641 size(4); 12642 ins_encode %{ 12643 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12644 __ cntlzd($dst$$Register, $src$$Register); 12645 %} 12646 ins_pipe(pipe_class_default); 12647 %} 12648 12649 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 12650 match(Set dst (CountTrailingZerosI src)); 12651 predicate(UseCountLeadingZerosInstructionsPPC64); 12652 ins_cost(DEFAULT_COST); 12653 12654 expand %{ 12655 immI16 imm1 %{ (int)-1 %} 12656 immI16 imm2 %{ (int)32 %} 12657 immI_minus1 m1 %{ -1 %} 12658 iRegIdst tmpI1; 12659 iRegIdst tmpI2; 12660 iRegIdst tmpI3; 12661 addI_reg_imm16(tmpI1, src, imm1); 12662 andcI_reg_reg(tmpI2, src, m1, tmpI1); 12663 countLeadingZerosI(tmpI3, tmpI2); 12664 subI_imm16_reg(dst, imm2, tmpI3); 12665 %} 12666 %} 12667 12668 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 12669 match(Set dst (CountTrailingZerosL src)); 12670 predicate(UseCountLeadingZerosInstructionsPPC64); 12671 ins_cost(DEFAULT_COST); 12672 12673 expand %{ 12674 immL16 imm1 %{ (long)-1 %} 12675 immI16 imm2 %{ (int)64 %} 12676 iRegLdst tmpL1; 12677 iRegLdst tmpL2; 12678 iRegIdst tmpL3; 12679 addL_reg_imm16(tmpL1, src, imm1); 12680 andcL_reg_reg(tmpL2, tmpL1, src); 12681 countLeadingZerosL(tmpL3, tmpL2); 12682 subI_imm16_reg(dst, imm2, tmpL3); 12683 %} 12684 %} 12685 12686 // Expand nodes for byte_reverse_int. 12687 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12688 effect(DEF dst, USE src, USE pos, USE shift); 12689 predicate(false); 12690 12691 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12692 size(4); 12693 ins_encode %{ 12694 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12695 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12696 %} 12697 ins_pipe(pipe_class_default); 12698 %} 12699 12700 // As insrwi_a, but with USE_DEF. 12701 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12702 effect(USE_DEF dst, USE src, USE pos, USE shift); 12703 predicate(false); 12704 12705 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12706 size(4); 12707 ins_encode %{ 12708 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12709 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12710 %} 12711 ins_pipe(pipe_class_default); 12712 %} 12713 12714 // Just slightly faster than java implementation. 12715 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 12716 match(Set dst (ReverseBytesI src)); 12717 predicate(UseCountLeadingZerosInstructionsPPC64); 12718 ins_cost(DEFAULT_COST); 12719 12720 expand %{ 12721 immI16 imm24 %{ (int) 24 %} 12722 immI16 imm16 %{ (int) 16 %} 12723 immI16 imm8 %{ (int) 8 %} 12724 immI16 imm4 %{ (int) 4 %} 12725 immI16 imm0 %{ (int) 0 %} 12726 iRegLdst tmpI1; 12727 iRegLdst tmpI2; 12728 iRegLdst tmpI3; 12729 12730 urShiftI_reg_imm(tmpI1, src, imm24); 12731 insrwi_a(dst, tmpI1, imm24, imm8); 12732 urShiftI_reg_imm(tmpI2, src, imm16); 12733 insrwi(dst, tmpI2, imm8, imm16); 12734 urShiftI_reg_imm(tmpI3, src, imm8); 12735 insrwi(dst, tmpI3, imm8, imm8); 12736 insrwi(dst, src, imm0, imm8); 12737 %} 12738 %} 12739 12740 //---------- Replicate Vector Instructions ------------------------------------ 12741 12742 // Insrdi does replicate if src == dst. 12743 instruct repl32(iRegLdst dst) %{ 12744 predicate(false); 12745 effect(USE_DEF dst); 12746 12747 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 12748 size(4); 12749 ins_encode %{ 12750 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12751 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 12752 %} 12753 ins_pipe(pipe_class_default); 12754 %} 12755 12756 // Insrdi does replicate if src == dst. 12757 instruct repl48(iRegLdst dst) %{ 12758 predicate(false); 12759 effect(USE_DEF dst); 12760 12761 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 12762 size(4); 12763 ins_encode %{ 12764 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12765 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 12766 %} 12767 ins_pipe(pipe_class_default); 12768 %} 12769 12770 // Insrdi does replicate if src == dst. 12771 instruct repl56(iRegLdst dst) %{ 12772 predicate(false); 12773 effect(USE_DEF dst); 12774 12775 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 12776 size(4); 12777 ins_encode %{ 12778 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12779 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 12780 %} 12781 ins_pipe(pipe_class_default); 12782 %} 12783 12784 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12785 match(Set dst (ReplicateB src)); 12786 predicate(n->as_Vector()->length() == 8); 12787 expand %{ 12788 moveReg(dst, src); 12789 repl56(dst); 12790 repl48(dst); 12791 repl32(dst); 12792 %} 12793 %} 12794 12795 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 12796 match(Set dst (ReplicateB zero)); 12797 predicate(n->as_Vector()->length() == 8); 12798 format %{ "LI $dst, #0 \t// replicate8B" %} 12799 size(4); 12800 ins_encode %{ 12801 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12802 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12803 %} 12804 ins_pipe(pipe_class_default); 12805 %} 12806 12807 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12808 match(Set dst (ReplicateB src)); 12809 predicate(n->as_Vector()->length() == 8); 12810 format %{ "LI $dst, #-1 \t// replicate8B" %} 12811 size(4); 12812 ins_encode %{ 12813 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12814 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12815 %} 12816 ins_pipe(pipe_class_default); 12817 %} 12818 12819 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12820 match(Set dst (ReplicateS src)); 12821 predicate(n->as_Vector()->length() == 4); 12822 expand %{ 12823 moveReg(dst, src); 12824 repl48(dst); 12825 repl32(dst); 12826 %} 12827 %} 12828 12829 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 12830 match(Set dst (ReplicateS zero)); 12831 predicate(n->as_Vector()->length() == 4); 12832 format %{ "LI $dst, #0 \t// replicate4C" %} 12833 size(4); 12834 ins_encode %{ 12835 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12836 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12837 %} 12838 ins_pipe(pipe_class_default); 12839 %} 12840 12841 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12842 match(Set dst (ReplicateS src)); 12843 predicate(n->as_Vector()->length() == 4); 12844 format %{ "LI $dst, -1 \t// replicate4C" %} 12845 size(4); 12846 ins_encode %{ 12847 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12848 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12849 %} 12850 ins_pipe(pipe_class_default); 12851 %} 12852 12853 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12854 match(Set dst (ReplicateI src)); 12855 predicate(n->as_Vector()->length() == 2); 12856 ins_cost(2 * DEFAULT_COST); 12857 expand %{ 12858 moveReg(dst, src); 12859 repl32(dst); 12860 %} 12861 %} 12862 12863 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 12864 match(Set dst (ReplicateI zero)); 12865 predicate(n->as_Vector()->length() == 2); 12866 format %{ "LI $dst, #0 \t// replicate4C" %} 12867 size(4); 12868 ins_encode %{ 12869 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12870 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12871 %} 12872 ins_pipe(pipe_class_default); 12873 %} 12874 12875 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12876 match(Set dst (ReplicateI src)); 12877 predicate(n->as_Vector()->length() == 2); 12878 format %{ "LI $dst, -1 \t// replicate4C" %} 12879 size(4); 12880 ins_encode %{ 12881 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12882 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12883 %} 12884 ins_pipe(pipe_class_default); 12885 %} 12886 12887 // Move float to int register via stack, replicate. 12888 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 12889 match(Set dst (ReplicateF src)); 12890 predicate(n->as_Vector()->length() == 2); 12891 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 12892 expand %{ 12893 stackSlotL tmpS; 12894 iRegIdst tmpI; 12895 moveF2I_reg_stack(tmpS, src); // Move float to stack. 12896 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 12897 moveReg(dst, tmpI); // Move int to long reg. 12898 repl32(dst); // Replicate bitpattern. 12899 %} 12900 %} 12901 12902 // Replicate scalar constant to packed float values in Double register 12903 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 12904 match(Set dst (ReplicateF src)); 12905 predicate(n->as_Vector()->length() == 2); 12906 ins_cost(5 * DEFAULT_COST); 12907 12908 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 12909 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 12910 %} 12911 12912 // Replicate scalar zero constant to packed float values in Double register 12913 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 12914 match(Set dst (ReplicateF zero)); 12915 predicate(n->as_Vector()->length() == 2); 12916 12917 format %{ "LI $dst, #0 \t// replicate2F" %} 12918 ins_encode %{ 12919 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12920 __ li($dst$$Register, 0x0); 12921 %} 12922 ins_pipe(pipe_class_default); 12923 %} 12924 12925 12926 //----------Overflow Math Instructions----------------------------------------- 12927 12928 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 12929 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 12930 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 12931 12932 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12933 match(Set cr0 (OverflowAddL op1 op2)); 12934 12935 format %{ "add_ $op1, $op2\t# overflow check long" %} 12936 ins_encode %{ 12937 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12938 __ li(R0, 0); 12939 __ mtxer(R0); // clear XER.SO 12940 __ addo_(R0, $op1$$Register, $op2$$Register); 12941 %} 12942 ins_pipe(pipe_class_default); 12943 %} 12944 12945 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12946 match(Set cr0 (OverflowSubL op1 op2)); 12947 12948 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 12949 ins_encode %{ 12950 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12951 __ li(R0, 0); 12952 __ mtxer(R0); // clear XER.SO 12953 __ subfo_(R0, $op2$$Register, $op1$$Register); 12954 %} 12955 ins_pipe(pipe_class_default); 12956 %} 12957 12958 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 12959 match(Set cr0 (OverflowSubL zero op2)); 12960 12961 format %{ "nego_ R0, $op2\t# overflow check long" %} 12962 ins_encode %{ 12963 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12964 __ li(R0, 0); 12965 __ mtxer(R0); // clear XER.SO 12966 __ nego_(R0, $op2$$Register); 12967 %} 12968 ins_pipe(pipe_class_default); 12969 %} 12970 12971 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12972 match(Set cr0 (OverflowMulL op1 op2)); 12973 12974 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 12975 ins_encode %{ 12976 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12977 __ li(R0, 0); 12978 __ mtxer(R0); // clear XER.SO 12979 __ mulldo_(R0, $op1$$Register, $op2$$Register); 12980 %} 12981 ins_pipe(pipe_class_default); 12982 %} 12983 12984 12985 // ============================================================================ 12986 // Safepoint Instruction 12987 12988 instruct safePoint_poll(iRegPdst poll) %{ 12989 match(SafePoint poll); 12990 predicate(LoadPollAddressFromThread); 12991 12992 // It caused problems to add the effect that r0 is killed, but this 12993 // effect no longer needs to be mentioned, since r0 is not contained 12994 // in a reg_class. 12995 12996 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 12997 size(4); 12998 ins_encode( enc_poll(0x0, poll) ); 12999 ins_pipe(pipe_class_default); 13000 %} 13001 13002 // Safepoint without per-thread support. Load address of page to poll 13003 // as constant. 13004 // Rscratch2RegP is R12. 13005 // LoadConPollAddr node is added in pd_post_matching_hook(). It must be 13006 // a seperate node so that the oop map is at the right location. 13007 instruct safePoint_poll_conPollAddr(rscratch2RegP poll) %{ 13008 match(SafePoint poll); 13009 predicate(!LoadPollAddressFromThread); 13010 13011 // It caused problems to add the effect that r0 is killed, but this 13012 // effect no longer needs to be mentioned, since r0 is not contained 13013 // in a reg_class. 13014 13015 format %{ "LD R0, #0, R12 \t// Safepoint poll for GC" %} 13016 ins_encode( enc_poll(0x0, poll) ); 13017 ins_pipe(pipe_class_default); 13018 %} 13019 13020 // ============================================================================ 13021 // Call Instructions 13022 13023 // Call Java Static Instruction 13024 13025 // Schedulable version of call static node. 13026 instruct CallStaticJavaDirect(method meth) %{ 13027 match(CallStaticJava); 13028 effect(USE meth); 13029 ins_cost(CALL_COST); 13030 13031 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 13032 13033 format %{ "CALL,static $meth \t// ==> " %} 13034 size(4); 13035 ins_encode( enc_java_static_call(meth) ); 13036 ins_pipe(pipe_class_call); 13037 %} 13038 13039 // Call Java Dynamic Instruction 13040 13041 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 13042 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 13043 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 13044 // The call destination must still be placed in the constant pool. 13045 instruct CallDynamicJavaDirectSched(method meth) %{ 13046 match(CallDynamicJava); // To get all the data fields we need ... 13047 effect(USE meth); 13048 predicate(false); // ... but never match. 13049 13050 ins_field_load_ic_hi_node(loadConL_hiNode*); 13051 ins_field_load_ic_node(loadConLNode*); 13052 ins_num_consts(1 /* 1 patchable constant: call destination */); 13053 13054 format %{ "BL \t// dynamic $meth ==> " %} 13055 size(4); 13056 ins_encode( enc_java_dynamic_call_sched(meth) ); 13057 ins_pipe(pipe_class_call); 13058 %} 13059 13060 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 13061 // We use postalloc expanded calls if we use inline caches 13062 // and do not update method data. 13063 // 13064 // This instruction has two constants: inline cache (IC) and call destination. 13065 // Loading the inline cache will be postalloc expanded, thus leaving a call with 13066 // one constant. 13067 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 13068 match(CallDynamicJava); 13069 effect(USE meth); 13070 predicate(UseInlineCaches); 13071 ins_cost(CALL_COST); 13072 13073 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 13074 13075 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 13076 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 13077 %} 13078 13079 // Compound version of call dynamic java 13080 // We use postalloc expanded calls if we use inline caches 13081 // and do not update method data. 13082 instruct CallDynamicJavaDirect(method meth) %{ 13083 match(CallDynamicJava); 13084 effect(USE meth); 13085 predicate(!UseInlineCaches); 13086 ins_cost(CALL_COST); 13087 13088 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 13089 ins_num_consts(4); 13090 13091 format %{ "CALL,dynamic $meth \t// ==> " %} 13092 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 13093 ins_pipe(pipe_class_call); 13094 %} 13095 13096 // Call Runtime Instruction 13097 13098 instruct CallRuntimeDirect(method meth) %{ 13099 match(CallRuntime); 13100 effect(USE meth); 13101 ins_cost(CALL_COST); 13102 13103 // Enc_java_to_runtime_call needs up to 3 constants: call target, 13104 // env for callee, C-toc. 13105 ins_num_consts(3); 13106 13107 format %{ "CALL,runtime" %} 13108 ins_encode( enc_java_to_runtime_call(meth) ); 13109 ins_pipe(pipe_class_call); 13110 %} 13111 13112 // Call Leaf 13113 13114 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 13115 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 13116 effect(DEF dst, USE src); 13117 13118 ins_num_consts(1); 13119 13120 format %{ "MTCTR $src" %} 13121 size(4); 13122 ins_encode( enc_leaf_call_mtctr(src) ); 13123 ins_pipe(pipe_class_default); 13124 %} 13125 13126 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 13127 instruct CallLeafDirect(method meth) %{ 13128 match(CallLeaf); // To get the data all the data fields we need ... 13129 effect(USE meth); 13130 predicate(false); // but never match. 13131 13132 format %{ "BCTRL \t// leaf call $meth ==> " %} 13133 size(4); 13134 ins_encode %{ 13135 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 13136 __ bctrl(); 13137 %} 13138 ins_pipe(pipe_class_call); 13139 %} 13140 13141 // postalloc expand of CallLeafDirect. 13142 // Load adress to call from TOC, then bl to it. 13143 instruct CallLeafDirect_Ex(method meth) %{ 13144 match(CallLeaf); 13145 effect(USE meth); 13146 ins_cost(CALL_COST); 13147 13148 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 13149 // env for callee, C-toc. 13150 ins_num_consts(3); 13151 13152 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 13153 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 13154 %} 13155 13156 // Call runtime without safepoint - same as CallLeaf. 13157 // postalloc expand of CallLeafNoFPDirect. 13158 // Load adress to call from TOC, then bl to it. 13159 instruct CallLeafNoFPDirect_Ex(method meth) %{ 13160 match(CallLeafNoFP); 13161 effect(USE meth); 13162 ins_cost(CALL_COST); 13163 13164 // Enc_java_to_runtime_call needs up to 3 constants: call target, 13165 // env for callee, C-toc. 13166 ins_num_consts(3); 13167 13168 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 13169 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 13170 %} 13171 13172 // Tail Call; Jump from runtime stub to Java code. 13173 // Also known as an 'interprocedural jump'. 13174 // Target of jump will eventually return to caller. 13175 // TailJump below removes the return address. 13176 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 13177 match(TailCall jump_target method_oop); 13178 ins_cost(CALL_COST); 13179 13180 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 13181 "BCTR \t// tail call" %} 13182 size(8); 13183 ins_encode %{ 13184 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13185 __ mtctr($jump_target$$Register); 13186 __ bctr(); 13187 %} 13188 ins_pipe(pipe_class_call); 13189 %} 13190 13191 // Return Instruction 13192 instruct Ret() %{ 13193 match(Return); 13194 format %{ "BLR \t// branch to link register" %} 13195 size(4); 13196 ins_encode %{ 13197 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 13198 // LR is restored in MachEpilogNode. Just do the RET here. 13199 __ blr(); 13200 %} 13201 ins_pipe(pipe_class_default); 13202 %} 13203 13204 // Tail Jump; remove the return address; jump to target. 13205 // TailCall above leaves the return address around. 13206 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 13207 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 13208 // "restore" before this instruction (in Epilogue), we need to materialize it 13209 // in %i0. 13210 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 13211 match(TailJump jump_target ex_oop); 13212 ins_cost(CALL_COST); 13213 13214 format %{ "LD R4_ARG2 = LR\n\t" 13215 "MTCTR $jump_target\n\t" 13216 "BCTR \t// TailJump, exception oop: $ex_oop" %} 13217 size(12); 13218 ins_encode %{ 13219 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13220 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 13221 __ mtctr($jump_target$$Register); 13222 __ bctr(); 13223 %} 13224 ins_pipe(pipe_class_call); 13225 %} 13226 13227 // Create exception oop: created by stack-crawling runtime code. 13228 // Created exception is now available to this handler, and is setup 13229 // just prior to jumping to this handler. No code emitted. 13230 instruct CreateException(rarg1RegP ex_oop) %{ 13231 match(Set ex_oop (CreateEx)); 13232 ins_cost(0); 13233 13234 format %{ " -- \t// exception oop; no code emitted" %} 13235 size(0); 13236 ins_encode( /*empty*/ ); 13237 ins_pipe(pipe_class_default); 13238 %} 13239 13240 // Rethrow exception: The exception oop will come in the first 13241 // argument position. Then JUMP (not call) to the rethrow stub code. 13242 instruct RethrowException() %{ 13243 match(Rethrow); 13244 ins_cost(CALL_COST); 13245 13246 format %{ "Jmp rethrow_stub" %} 13247 ins_encode %{ 13248 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13249 cbuf.set_insts_mark(); 13250 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 13251 %} 13252 ins_pipe(pipe_class_call); 13253 %} 13254 13255 // Die now. 13256 instruct ShouldNotReachHere() %{ 13257 match(Halt); 13258 ins_cost(CALL_COST); 13259 13260 format %{ "ShouldNotReachHere" %} 13261 size(4); 13262 ins_encode %{ 13263 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 13264 __ trap_should_not_reach_here(); 13265 %} 13266 ins_pipe(pipe_class_default); 13267 %} 13268 13269 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 13270 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 13271 // Get a DEF on threadRegP, no costs, no encoding, use 13272 // 'ins_should_rematerialize(true)' to avoid spilling. 13273 instruct tlsLoadP(threadRegP dst) %{ 13274 match(Set dst (ThreadLocal)); 13275 ins_cost(0); 13276 13277 ins_should_rematerialize(true); 13278 13279 format %{ " -- \t// $dst=Thread::current(), empty" %} 13280 size(0); 13281 ins_encode( /*empty*/ ); 13282 ins_pipe(pipe_class_empty); 13283 %} 13284 13285 //---Some PPC specific nodes--------------------------------------------------- 13286 13287 // Stop a group. 13288 instruct endGroup() %{ 13289 ins_cost(0); 13290 13291 ins_is_nop(true); 13292 13293 format %{ "End Bundle (ori r1, r1, 0)" %} 13294 size(4); 13295 ins_encode %{ 13296 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 13297 __ endgroup(); 13298 %} 13299 ins_pipe(pipe_class_default); 13300 %} 13301 13302 // Nop instructions 13303 13304 instruct fxNop() %{ 13305 ins_cost(0); 13306 13307 ins_is_nop(true); 13308 13309 format %{ "fxNop" %} 13310 size(4); 13311 ins_encode %{ 13312 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13313 __ nop(); 13314 %} 13315 ins_pipe(pipe_class_default); 13316 %} 13317 13318 instruct fpNop0() %{ 13319 ins_cost(0); 13320 13321 ins_is_nop(true); 13322 13323 format %{ "fpNop0" %} 13324 size(4); 13325 ins_encode %{ 13326 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13327 __ fpnop0(); 13328 %} 13329 ins_pipe(pipe_class_default); 13330 %} 13331 13332 instruct fpNop1() %{ 13333 ins_cost(0); 13334 13335 ins_is_nop(true); 13336 13337 format %{ "fpNop1" %} 13338 size(4); 13339 ins_encode %{ 13340 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13341 __ fpnop1(); 13342 %} 13343 ins_pipe(pipe_class_default); 13344 %} 13345 13346 instruct brNop0() %{ 13347 ins_cost(0); 13348 size(4); 13349 format %{ "brNop0" %} 13350 ins_encode %{ 13351 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13352 __ brnop0(); 13353 %} 13354 ins_is_nop(true); 13355 ins_pipe(pipe_class_default); 13356 %} 13357 13358 instruct brNop1() %{ 13359 ins_cost(0); 13360 13361 ins_is_nop(true); 13362 13363 format %{ "brNop1" %} 13364 size(4); 13365 ins_encode %{ 13366 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13367 __ brnop1(); 13368 %} 13369 ins_pipe(pipe_class_default); 13370 %} 13371 13372 instruct brNop2() %{ 13373 ins_cost(0); 13374 13375 ins_is_nop(true); 13376 13377 format %{ "brNop2" %} 13378 size(4); 13379 ins_encode %{ 13380 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13381 __ brnop2(); 13382 %} 13383 ins_pipe(pipe_class_default); 13384 %} 13385 13386 //----------PEEPHOLE RULES----------------------------------------------------- 13387 // These must follow all instruction definitions as they use the names 13388 // defined in the instructions definitions. 13389 // 13390 // peepmatch ( root_instr_name [preceeding_instruction]* ); 13391 // 13392 // peepconstraint %{ 13393 // (instruction_number.operand_name relational_op instruction_number.operand_name 13394 // [, ...] ); 13395 // // instruction numbers are zero-based using left to right order in peepmatch 13396 // 13397 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 13398 // // provide an instruction_number.operand_name for each operand that appears 13399 // // in the replacement instruction's match rule 13400 // 13401 // ---------VM FLAGS--------------------------------------------------------- 13402 // 13403 // All peephole optimizations can be turned off using -XX:-OptoPeephole 13404 // 13405 // Each peephole rule is given an identifying number starting with zero and 13406 // increasing by one in the order seen by the parser. An individual peephole 13407 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 13408 // on the command-line. 13409 // 13410 // ---------CURRENT LIMITATIONS---------------------------------------------- 13411 // 13412 // Only match adjacent instructions in same basic block 13413 // Only equality constraints 13414 // Only constraints between operands, not (0.dest_reg == EAX_enc) 13415 // Only one replacement instruction 13416 // 13417 // ---------EXAMPLE---------------------------------------------------------- 13418 // 13419 // // pertinent parts of existing instructions in architecture description 13420 // instruct movI(eRegI dst, eRegI src) %{ 13421 // match(Set dst (CopyI src)); 13422 // %} 13423 // 13424 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 13425 // match(Set dst (AddI dst src)); 13426 // effect(KILL cr); 13427 // %} 13428 // 13429 // // Change (inc mov) to lea 13430 // peephole %{ 13431 // // increment preceeded by register-register move 13432 // peepmatch ( incI_eReg movI ); 13433 // // require that the destination register of the increment 13434 // // match the destination register of the move 13435 // peepconstraint ( 0.dst == 1.dst ); 13436 // // construct a replacement instruction that sets 13437 // // the destination to ( move's source register + one ) 13438 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13439 // %} 13440 // 13441 // Implementation no longer uses movX instructions since 13442 // machine-independent system no longer uses CopyX nodes. 13443 // 13444 // peephole %{ 13445 // peepmatch ( incI_eReg movI ); 13446 // peepconstraint ( 0.dst == 1.dst ); 13447 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13448 // %} 13449 // 13450 // peephole %{ 13451 // peepmatch ( decI_eReg movI ); 13452 // peepconstraint ( 0.dst == 1.dst ); 13453 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13454 // %} 13455 // 13456 // peephole %{ 13457 // peepmatch ( addI_eReg_imm movI ); 13458 // peepconstraint ( 0.dst == 1.dst ); 13459 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13460 // %} 13461 // 13462 // peephole %{ 13463 // peepmatch ( addP_eReg_imm movP ); 13464 // peepconstraint ( 0.dst == 1.dst ); 13465 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 13466 // %} 13467 13468 // // Change load of spilled value to only a spill 13469 // instruct storeI(memory mem, eRegI src) %{ 13470 // match(Set mem (StoreI mem src)); 13471 // %} 13472 // 13473 // instruct loadI(eRegI dst, memory mem) %{ 13474 // match(Set dst (LoadI mem)); 13475 // %} 13476 // 13477 peephole %{ 13478 peepmatch ( loadI storeI ); 13479 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13480 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 13481 %} 13482 13483 peephole %{ 13484 peepmatch ( loadL storeL ); 13485 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13486 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 13487 %} 13488 13489 peephole %{ 13490 peepmatch ( loadP storeP ); 13491 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 13492 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 13493 %} 13494 13495 //----------SMARTSPILL RULES--------------------------------------------------- 13496 // These must follow all instruction definitions as they use the names 13497 // defined in the instructions definitions.