1 // 2 // Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2022 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 // Vector-Scalar Registers 259 // ---------------------------- 260 // 1st 32 VSRs are aliases for the FPRs which are already defined above. 261 reg_def VSR0 ( SOC, SOC, Op_VecX, 0, VMRegImpl::Bad()); 262 reg_def VSR1 ( SOC, SOC, Op_VecX, 1, VMRegImpl::Bad()); 263 reg_def VSR2 ( SOC, SOC, Op_VecX, 2, VMRegImpl::Bad()); 264 reg_def VSR3 ( SOC, SOC, Op_VecX, 3, VMRegImpl::Bad()); 265 reg_def VSR4 ( SOC, SOC, Op_VecX, 4, VMRegImpl::Bad()); 266 reg_def VSR5 ( SOC, SOC, Op_VecX, 5, VMRegImpl::Bad()); 267 reg_def VSR6 ( SOC, SOC, Op_VecX, 6, VMRegImpl::Bad()); 268 reg_def VSR7 ( SOC, SOC, Op_VecX, 7, VMRegImpl::Bad()); 269 reg_def VSR8 ( SOC, SOC, Op_VecX, 8, VMRegImpl::Bad()); 270 reg_def VSR9 ( SOC, SOC, Op_VecX, 9, VMRegImpl::Bad()); 271 reg_def VSR10 ( SOC, SOC, Op_VecX, 10, VMRegImpl::Bad()); 272 reg_def VSR11 ( SOC, SOC, Op_VecX, 11, VMRegImpl::Bad()); 273 reg_def VSR12 ( SOC, SOC, Op_VecX, 12, VMRegImpl::Bad()); 274 reg_def VSR13 ( SOC, SOC, Op_VecX, 13, VMRegImpl::Bad()); 275 reg_def VSR14 ( SOC, SOE, Op_VecX, 14, VMRegImpl::Bad()); 276 reg_def VSR15 ( SOC, SOE, Op_VecX, 15, VMRegImpl::Bad()); 277 reg_def VSR16 ( SOC, SOE, Op_VecX, 16, VMRegImpl::Bad()); 278 reg_def VSR17 ( SOC, SOE, Op_VecX, 17, VMRegImpl::Bad()); 279 reg_def VSR18 ( SOC, SOE, Op_VecX, 18, VMRegImpl::Bad()); 280 reg_def VSR19 ( SOC, SOE, Op_VecX, 19, VMRegImpl::Bad()); 281 reg_def VSR20 ( SOC, SOE, Op_VecX, 20, VMRegImpl::Bad()); 282 reg_def VSR21 ( SOC, SOE, Op_VecX, 21, VMRegImpl::Bad()); 283 reg_def VSR22 ( SOC, SOE, Op_VecX, 22, VMRegImpl::Bad()); 284 reg_def VSR23 ( SOC, SOE, Op_VecX, 23, VMRegImpl::Bad()); 285 reg_def VSR24 ( SOC, SOE, Op_VecX, 24, VMRegImpl::Bad()); 286 reg_def VSR25 ( SOC, SOE, Op_VecX, 25, VMRegImpl::Bad()); 287 reg_def VSR26 ( SOC, SOE, Op_VecX, 26, VMRegImpl::Bad()); 288 reg_def VSR27 ( SOC, SOE, Op_VecX, 27, VMRegImpl::Bad()); 289 reg_def VSR28 ( SOC, SOE, Op_VecX, 28, VMRegImpl::Bad()); 290 reg_def VSR29 ( SOC, SOE, Op_VecX, 29, VMRegImpl::Bad()); 291 reg_def VSR30 ( SOC, SOE, Op_VecX, 30, VMRegImpl::Bad()); 292 reg_def VSR31 ( SOC, SOE, Op_VecX, 31, VMRegImpl::Bad()); 293 // 2nd 32 VSRs are aliases for the VRs which are only defined here. 294 reg_def VSR32 ( SOC, SOC, Op_VecX, 32, VSR32->as_VMReg()); 295 reg_def VSR33 ( SOC, SOC, Op_VecX, 33, VSR33->as_VMReg()); 296 reg_def VSR34 ( SOC, SOC, Op_VecX, 34, VSR34->as_VMReg()); 297 reg_def VSR35 ( SOC, SOC, Op_VecX, 35, VSR35->as_VMReg()); 298 reg_def VSR36 ( SOC, SOC, Op_VecX, 36, VSR36->as_VMReg()); 299 reg_def VSR37 ( SOC, SOC, Op_VecX, 37, VSR37->as_VMReg()); 300 reg_def VSR38 ( SOC, SOC, Op_VecX, 38, VSR38->as_VMReg()); 301 reg_def VSR39 ( SOC, SOC, Op_VecX, 39, VSR39->as_VMReg()); 302 reg_def VSR40 ( SOC, SOC, Op_VecX, 40, VSR40->as_VMReg()); 303 reg_def VSR41 ( SOC, SOC, Op_VecX, 41, VSR41->as_VMReg()); 304 reg_def VSR42 ( SOC, SOC, Op_VecX, 42, VSR42->as_VMReg()); 305 reg_def VSR43 ( SOC, SOC, Op_VecX, 43, VSR43->as_VMReg()); 306 reg_def VSR44 ( SOC, SOC, Op_VecX, 44, VSR44->as_VMReg()); 307 reg_def VSR45 ( SOC, SOC, Op_VecX, 45, VSR45->as_VMReg()); 308 reg_def VSR46 ( SOC, SOC, Op_VecX, 46, VSR46->as_VMReg()); 309 reg_def VSR47 ( SOC, SOC, Op_VecX, 47, VSR47->as_VMReg()); 310 reg_def VSR48 ( SOC, SOC, Op_VecX, 48, VSR48->as_VMReg()); 311 reg_def VSR49 ( SOC, SOC, Op_VecX, 49, VSR49->as_VMReg()); 312 reg_def VSR50 ( SOC, SOC, Op_VecX, 50, VSR50->as_VMReg()); 313 reg_def VSR51 ( SOC, SOC, Op_VecX, 51, VSR51->as_VMReg()); 314 reg_def VSR52 ( SOC, SOE, Op_VecX, 52, VSR52->as_VMReg()); 315 reg_def VSR53 ( SOC, SOE, Op_VecX, 53, VSR53->as_VMReg()); 316 reg_def VSR54 ( SOC, SOE, Op_VecX, 54, VSR54->as_VMReg()); 317 reg_def VSR55 ( SOC, SOE, Op_VecX, 55, VSR55->as_VMReg()); 318 reg_def VSR56 ( SOC, SOE, Op_VecX, 56, VSR56->as_VMReg()); 319 reg_def VSR57 ( SOC, SOE, Op_VecX, 57, VSR57->as_VMReg()); 320 reg_def VSR58 ( SOC, SOE, Op_VecX, 58, VSR58->as_VMReg()); 321 reg_def VSR59 ( SOC, SOE, Op_VecX, 59, VSR59->as_VMReg()); 322 reg_def VSR60 ( SOC, SOE, Op_VecX, 60, VSR60->as_VMReg()); 323 reg_def VSR61 ( SOC, SOE, Op_VecX, 61, VSR61->as_VMReg()); 324 reg_def VSR62 ( SOC, SOE, Op_VecX, 62, VSR62->as_VMReg()); 325 reg_def VSR63 ( SOC, SOE, Op_VecX, 63, VSR63->as_VMReg()); 326 327 // ---------------------------- 328 // Specify priority of register selection within phases of register 329 // allocation. Highest priority is first. A useful heuristic is to 330 // give registers a low priority when they are required by machine 331 // instructions, like EAX and EDX on I486, and choose no-save registers 332 // before save-on-call, & save-on-call before save-on-entry. Registers 333 // which participate in fixed calling sequences should come last. 334 // Registers which are used as pairs must fall on an even boundary. 335 336 // It's worth about 1% on SPEC geomean to get this right. 337 338 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 339 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 340 // R3_num. Therefore, R3_num may not be (and in reality is not) 341 // the same as R3->encoding()! Furthermore, we cannot make any 342 // assumptions on ordering, e.g. R3_num may be less than R2_num. 343 // Additionally, the function 344 // static enum RC rc_class(OptoReg::Name reg ) 345 // maps a given <register>_num value to its chunk type (except for flags) 346 // and its current implementation relies on chunk0 and chunk1 having a 347 // size of 64 each. 348 349 // If you change this allocation class, please have a look at the 350 // default values for the parameters RoundRobinIntegerRegIntervalStart 351 // and RoundRobinFloatRegIntervalStart 352 353 alloc_class chunk0 ( 354 // Chunk0 contains *all* 64 integer registers halves. 355 356 // "non-volatile" registers 357 R14, R14_H, 358 R15, R15_H, 359 R17, R17_H, 360 R18, R18_H, 361 R19, R19_H, 362 R20, R20_H, 363 R21, R21_H, 364 R22, R22_H, 365 R23, R23_H, 366 R24, R24_H, 367 R25, R25_H, 368 R26, R26_H, 369 R27, R27_H, 370 R28, R28_H, 371 R29, R29_H, 372 R30, R30_H, 373 R31, R31_H, 374 375 // scratch/special registers 376 R11, R11_H, 377 R12, R12_H, 378 379 // argument registers 380 R10, R10_H, 381 R9, R9_H, 382 R8, R8_H, 383 R7, R7_H, 384 R6, R6_H, 385 R5, R5_H, 386 R4, R4_H, 387 R3, R3_H, 388 389 // special registers, not available for allocation 390 R16, R16_H, // R16_thread 391 R13, R13_H, // system thread id 392 R2, R2_H, // may be used for TOC 393 R1, R1_H, // SP 394 R0, R0_H // R0 (scratch) 395 ); 396 397 // If you change this allocation class, please have a look at the 398 // default values for the parameters RoundRobinIntegerRegIntervalStart 399 // and RoundRobinFloatRegIntervalStart 400 401 alloc_class chunk1 ( 402 // Chunk1 contains *all* 64 floating-point registers halves. 403 404 // scratch register 405 F0, F0_H, 406 407 // argument registers 408 F13, F13_H, 409 F12, F12_H, 410 F11, F11_H, 411 F10, F10_H, 412 F9, F9_H, 413 F8, F8_H, 414 F7, F7_H, 415 F6, F6_H, 416 F5, F5_H, 417 F4, F4_H, 418 F3, F3_H, 419 F2, F2_H, 420 F1, F1_H, 421 422 // non-volatile registers 423 F14, F14_H, 424 F15, F15_H, 425 F16, F16_H, 426 F17, F17_H, 427 F18, F18_H, 428 F19, F19_H, 429 F20, F20_H, 430 F21, F21_H, 431 F22, F22_H, 432 F23, F23_H, 433 F24, F24_H, 434 F25, F25_H, 435 F26, F26_H, 436 F27, F27_H, 437 F28, F28_H, 438 F29, F29_H, 439 F30, F30_H, 440 F31, F31_H 441 ); 442 443 alloc_class chunk2 ( 444 // Chunk2 contains *all* 8 condition code registers. 445 446 CCR0, 447 CCR1, 448 CCR2, 449 CCR3, 450 CCR4, 451 CCR5, 452 CCR6, 453 CCR7 454 ); 455 456 alloc_class chunk3 ( 457 VSR0, 458 VSR1, 459 VSR2, 460 VSR3, 461 VSR4, 462 VSR5, 463 VSR6, 464 VSR7, 465 VSR8, 466 VSR9, 467 VSR10, 468 VSR11, 469 VSR12, 470 VSR13, 471 VSR14, 472 VSR15, 473 VSR16, 474 VSR17, 475 VSR18, 476 VSR19, 477 VSR20, 478 VSR21, 479 VSR22, 480 VSR23, 481 VSR24, 482 VSR25, 483 VSR26, 484 VSR27, 485 VSR28, 486 VSR29, 487 VSR30, 488 VSR31, 489 VSR32, 490 VSR33, 491 VSR34, 492 VSR35, 493 VSR36, 494 VSR37, 495 VSR38, 496 VSR39, 497 VSR40, 498 VSR41, 499 VSR42, 500 VSR43, 501 VSR44, 502 VSR45, 503 VSR46, 504 VSR47, 505 VSR48, 506 VSR49, 507 VSR50, 508 VSR51, 509 VSR52, 510 VSR53, 511 VSR54, 512 VSR55, 513 VSR56, 514 VSR57, 515 VSR58, 516 VSR59, 517 VSR60, 518 VSR61, 519 VSR62, 520 VSR63 521 ); 522 523 alloc_class chunk4 ( 524 // special registers 525 // These registers are not allocated, but used for nodes generated by postalloc expand. 526 SR_XER, 527 SR_LR, 528 SR_CTR, 529 SR_VRSAVE, 530 SR_SPEFSCR, 531 SR_PPR 532 ); 533 534 //-------Architecture Description Register Classes----------------------- 535 536 // Several register classes are automatically defined based upon 537 // information in this architecture description. 538 539 // 1) reg_class inline_cache_reg ( as defined in frame section ) 540 // 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 541 // 542 543 // ---------------------------- 544 // 32 Bit Register Classes 545 // ---------------------------- 546 547 // We specify registers twice, once as read/write, and once read-only. 548 // We use the read-only registers for source operands. With this, we 549 // can include preset read only registers in this class, as a hard-coded 550 // '0'-register. (We used to simulate this on ppc.) 551 552 // 32 bit registers that can be read and written i.e. these registers 553 // can be dest (or src) of normal instructions. 554 reg_class bits32_reg_rw( 555 /*R0*/ // R0 556 /*R1*/ // SP 557 R2, // TOC 558 R3, 559 R4, 560 R5, 561 R6, 562 R7, 563 R8, 564 R9, 565 R10, 566 R11, 567 R12, 568 /*R13*/ // system thread id 569 R14, 570 R15, 571 /*R16*/ // R16_thread 572 R17, 573 R18, 574 R19, 575 R20, 576 R21, 577 R22, 578 R23, 579 R24, 580 R25, 581 R26, 582 R27, 583 R28, 584 /*R29,*/ // global TOC 585 R30, 586 R31 587 ); 588 589 // 32 bit registers that can only be read i.e. these registers can 590 // only be src of all instructions. 591 reg_class bits32_reg_ro( 592 /*R0*/ // R0 593 /*R1*/ // SP 594 R2 // TOC 595 R3, 596 R4, 597 R5, 598 R6, 599 R7, 600 R8, 601 R9, 602 R10, 603 R11, 604 R12, 605 /*R13*/ // system thread id 606 R14, 607 R15, 608 /*R16*/ // R16_thread 609 R17, 610 R18, 611 R19, 612 R20, 613 R21, 614 R22, 615 R23, 616 R24, 617 R25, 618 R26, 619 R27, 620 R28, 621 /*R29,*/ 622 R30, 623 R31 624 ); 625 626 reg_class rscratch1_bits32_reg(R11); 627 reg_class rscratch2_bits32_reg(R12); 628 reg_class rarg1_bits32_reg(R3); 629 reg_class rarg2_bits32_reg(R4); 630 reg_class rarg3_bits32_reg(R5); 631 reg_class rarg4_bits32_reg(R6); 632 633 // ---------------------------- 634 // 64 Bit Register Classes 635 // ---------------------------- 636 // 64-bit build means 64-bit pointers means hi/lo pairs 637 638 reg_class rscratch1_bits64_reg(R11_H, R11); 639 reg_class rscratch2_bits64_reg(R12_H, R12); 640 reg_class rarg1_bits64_reg(R3_H, R3); 641 reg_class rarg2_bits64_reg(R4_H, R4); 642 reg_class rarg3_bits64_reg(R5_H, R5); 643 reg_class rarg4_bits64_reg(R6_H, R6); 644 // Thread register, 'written' by tlsLoadP, see there. 645 reg_class thread_bits64_reg(R16_H, R16); 646 647 reg_class r19_bits64_reg(R19_H, R19); 648 649 // 64 bit registers that can be read and written i.e. these registers 650 // can be dest (or src) of normal instructions. 651 reg_class bits64_reg_rw( 652 /*R0_H, R0*/ // R0 653 /*R1_H, R1*/ // SP 654 R2_H, R2, // TOC 655 R3_H, R3, 656 R4_H, R4, 657 R5_H, R5, 658 R6_H, R6, 659 R7_H, R7, 660 R8_H, R8, 661 R9_H, R9, 662 R10_H, R10, 663 R11_H, R11, 664 R12_H, R12, 665 /*R13_H, R13*/ // system thread id 666 R14_H, R14, 667 R15_H, R15, 668 /*R16_H, R16*/ // R16_thread 669 R17_H, R17, 670 R18_H, R18, 671 R19_H, R19, 672 R20_H, R20, 673 R21_H, R21, 674 R22_H, R22, 675 R23_H, R23, 676 R24_H, R24, 677 R25_H, R25, 678 R26_H, R26, 679 R27_H, R27, 680 R28_H, R28, 681 /*R29_H, R29,*/ 682 R30_H, R30, 683 R31_H, R31 684 ); 685 686 // 64 bit registers used excluding r2, r11 and r12 687 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses 688 // r2, r11 and r12 internally. 689 reg_class bits64_reg_leaf_call( 690 /*R0_H, R0*/ // R0 691 /*R1_H, R1*/ // SP 692 /*R2_H, R2*/ // TOC 693 R3_H, R3, 694 R4_H, R4, 695 R5_H, R5, 696 R6_H, R6, 697 R7_H, R7, 698 R8_H, R8, 699 R9_H, R9, 700 R10_H, R10, 701 /*R11_H, R11*/ 702 /*R12_H, R12*/ 703 /*R13_H, R13*/ // system thread id 704 R14_H, R14, 705 R15_H, R15, 706 /*R16_H, R16*/ // R16_thread 707 R17_H, R17, 708 R18_H, R18, 709 R19_H, R19, 710 R20_H, R20, 711 R21_H, R21, 712 R22_H, R22, 713 R23_H, R23, 714 R24_H, R24, 715 R25_H, R25, 716 R26_H, R26, 717 R27_H, R27, 718 R28_H, R28, 719 /*R29_H, R29,*/ 720 R30_H, R30, 721 R31_H, R31 722 ); 723 724 // Used to hold the TOC to avoid collisions with expanded DynamicCall 725 // which uses r19 as inline cache internally and expanded LeafCall which uses 726 // r2, r11 and r12 internally. 727 reg_class bits64_constant_table_base( 728 /*R0_H, R0*/ // R0 729 /*R1_H, R1*/ // SP 730 /*R2_H, R2*/ // TOC 731 R3_H, R3, 732 R4_H, R4, 733 R5_H, R5, 734 R6_H, R6, 735 R7_H, R7, 736 R8_H, R8, 737 R9_H, R9, 738 R10_H, R10, 739 /*R11_H, R11*/ 740 /*R12_H, R12*/ 741 /*R13_H, R13*/ // system thread id 742 R14_H, R14, 743 R15_H, R15, 744 /*R16_H, R16*/ // R16_thread 745 R17_H, R17, 746 R18_H, R18, 747 /*R19_H, R19*/ 748 R20_H, R20, 749 R21_H, R21, 750 R22_H, R22, 751 R23_H, R23, 752 R24_H, R24, 753 R25_H, R25, 754 R26_H, R26, 755 R27_H, R27, 756 R28_H, R28, 757 /*R29_H, R29,*/ 758 R30_H, R30, 759 R31_H, R31 760 ); 761 762 // 64 bit registers that can only be read i.e. these registers can 763 // only be src of all instructions. 764 reg_class bits64_reg_ro( 765 /*R0_H, R0*/ // R0 766 R1_H, R1, 767 R2_H, R2, // TOC 768 R3_H, R3, 769 R4_H, R4, 770 R5_H, R5, 771 R6_H, R6, 772 R7_H, R7, 773 R8_H, R8, 774 R9_H, R9, 775 R10_H, R10, 776 R11_H, R11, 777 R12_H, R12, 778 /*R13_H, R13*/ // system thread id 779 R14_H, R14, 780 R15_H, R15, 781 R16_H, R16, // R16_thread 782 R17_H, R17, 783 R18_H, R18, 784 R19_H, R19, 785 R20_H, R20, 786 R21_H, R21, 787 R22_H, R22, 788 R23_H, R23, 789 R24_H, R24, 790 R25_H, R25, 791 R26_H, R26, 792 R27_H, R27, 793 R28_H, R28, 794 /*R29_H, R29,*/ // TODO: let allocator handle TOC!! 795 R30_H, R30, 796 R31_H, R31 797 ); 798 799 800 // ---------------------------- 801 // Special Class for Condition Code Flags Register 802 803 reg_class int_flags( 804 /*CCR0*/ // scratch 805 /*CCR1*/ // scratch 806 /*CCR2*/ // nv! 807 /*CCR3*/ // nv! 808 /*CCR4*/ // nv! 809 CCR5, 810 CCR6, 811 CCR7 812 ); 813 814 reg_class int_flags_ro( 815 CCR0, 816 CCR1, 817 CCR2, 818 CCR3, 819 CCR4, 820 CCR5, 821 CCR6, 822 CCR7 823 ); 824 825 reg_class int_flags_CR0(CCR0); 826 reg_class int_flags_CR1(CCR1); 827 reg_class int_flags_CR6(CCR6); 828 reg_class ctr_reg(SR_CTR); 829 830 // ---------------------------- 831 // Float Register Classes 832 // ---------------------------- 833 834 reg_class flt_reg( 835 F0, 836 F1, 837 F2, 838 F3, 839 F4, 840 F5, 841 F6, 842 F7, 843 F8, 844 F9, 845 F10, 846 F11, 847 F12, 848 F13, 849 F14, // nv! 850 F15, // nv! 851 F16, // nv! 852 F17, // nv! 853 F18, // nv! 854 F19, // nv! 855 F20, // nv! 856 F21, // nv! 857 F22, // nv! 858 F23, // nv! 859 F24, // nv! 860 F25, // nv! 861 F26, // nv! 862 F27, // nv! 863 F28, // nv! 864 F29, // nv! 865 F30, // nv! 866 F31 // nv! 867 ); 868 869 // Double precision float registers have virtual `high halves' that 870 // are needed by the allocator. 871 reg_class dbl_reg( 872 F0, F0_H, 873 F1, F1_H, 874 F2, F2_H, 875 F3, F3_H, 876 F4, F4_H, 877 F5, F5_H, 878 F6, F6_H, 879 F7, F7_H, 880 F8, F8_H, 881 F9, F9_H, 882 F10, F10_H, 883 F11, F11_H, 884 F12, F12_H, 885 F13, F13_H, 886 F14, F14_H, // nv! 887 F15, F15_H, // nv! 888 F16, F16_H, // nv! 889 F17, F17_H, // nv! 890 F18, F18_H, // nv! 891 F19, F19_H, // nv! 892 F20, F20_H, // nv! 893 F21, F21_H, // nv! 894 F22, F22_H, // nv! 895 F23, F23_H, // nv! 896 F24, F24_H, // nv! 897 F25, F25_H, // nv! 898 F26, F26_H, // nv! 899 F27, F27_H, // nv! 900 F28, F28_H, // nv! 901 F29, F29_H, // nv! 902 F30, F30_H, // nv! 903 F31, F31_H // nv! 904 ); 905 906 // ---------------------------- 907 // Vector-Scalar Register Class 908 // ---------------------------- 909 910 reg_class vs_reg( 911 // Attention: Only these ones are saved & restored at safepoint by RegisterSaver. 912 VSR32, 913 VSR33, 914 VSR34, 915 VSR35, 916 VSR36, 917 VSR37, 918 VSR38, 919 VSR39, 920 VSR40, 921 VSR41, 922 VSR42, 923 VSR43, 924 VSR44, 925 VSR45, 926 VSR46, 927 VSR47, 928 VSR48, 929 VSR49, 930 VSR50, 931 VSR51 932 // VSR52-VSR63 // nv! 933 ); 934 935 %} 936 937 //----------DEFINITION BLOCK--------------------------------------------------- 938 // Define name --> value mappings to inform the ADLC of an integer valued name 939 // Current support includes integer values in the range [0, 0x7FFFFFFF] 940 // Format: 941 // int_def <name> ( <int_value>, <expression>); 942 // Generated Code in ad_<arch>.hpp 943 // #define <name> (<expression>) 944 // // value == <int_value> 945 // Generated code in ad_<arch>.cpp adlc_verification() 946 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 947 // 948 definitions %{ 949 // The default cost (of an ALU instruction). 950 int_def DEFAULT_COST_LOW ( 30, 30); 951 int_def DEFAULT_COST ( 100, 100); 952 int_def HUGE_COST (1000000, 1000000); 953 954 // Memory refs 955 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 956 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 957 958 // Branches are even more expensive. 959 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 960 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 961 %} 962 963 964 //----------SOURCE BLOCK------------------------------------------------------- 965 // This is a block of C++ code which provides values, functions, and 966 // definitions necessary in the rest of the architecture description. 967 source_hpp %{ 968 // Header information of the source block. 969 // Method declarations/definitions which are used outside 970 // the ad-scope can conveniently be defined here. 971 // 972 // To keep related declarations/definitions/uses close together, 973 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 974 975 #include "opto/convertnode.hpp" 976 977 // Returns true if Node n is followed by a MemBar node that 978 // will do an acquire. If so, this node must not do the acquire 979 // operation. 980 bool followed_by_acquire(const Node *n); 981 %} 982 983 source %{ 984 985 #include "opto/c2_CodeStubs.hpp" 986 #include "oops/klass.inline.hpp" 987 988 void PhaseOutput::pd_perform_mach_node_analysis() { 989 } 990 991 int MachNode::pd_alignment_required() const { 992 return 1; 993 } 994 995 int MachNode::compute_padding(int current_offset) const { 996 return 0; 997 } 998 999 // Should the matcher clone input 'm' of node 'n'? 1000 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { 1001 return false; 1002 } 1003 1004 // Should the Matcher clone shifts on addressing modes, expecting them 1005 // to be subsumed into complex addressing expressions or compute them 1006 // into registers? 1007 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 1008 return clone_base_plus_offset_address(m, mstack, address_visited); 1009 } 1010 1011 // Optimize load-acquire. 1012 // 1013 // Check if acquire is unnecessary due to following operation that does 1014 // acquire anyways. 1015 // Walk the pattern: 1016 // 1017 // n: Load.acq 1018 // | 1019 // MemBarAcquire 1020 // | | 1021 // Proj(ctrl) Proj(mem) 1022 // | | 1023 // MemBarRelease/Volatile 1024 // 1025 bool followed_by_acquire(const Node *load) { 1026 assert(load->is_Load(), "So far implemented only for loads."); 1027 1028 // Find MemBarAcquire. 1029 const Node *mba = NULL; 1030 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 1031 const Node *out = load->fast_out(i); 1032 if (out->Opcode() == Op_MemBarAcquire) { 1033 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 1034 mba = out; 1035 break; 1036 } 1037 } 1038 if (!mba) return false; 1039 1040 // Find following MemBar node. 1041 // 1042 // The following node must be reachable by control AND memory 1043 // edge to assure no other operations are in between the two nodes. 1044 // 1045 // So first get the Proj node, mem_proj, to use it to iterate forward. 1046 Node *mem_proj = NULL; 1047 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 1048 mem_proj = mba->fast_out(i); // Runs out of bounds and asserts if Proj not found. 1049 assert(mem_proj->is_Proj(), "only projections here"); 1050 ProjNode *proj = mem_proj->as_Proj(); 1051 if (proj->_con == TypeFunc::Memory && 1052 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 1053 break; 1054 } 1055 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 1056 1057 // Search MemBar behind Proj. If there are other memory operations 1058 // behind the Proj we lost. 1059 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 1060 Node *x = mem_proj->fast_out(j); 1061 // Proj might have an edge to a store or load node which precedes the membar. 1062 if (x->is_Mem()) return false; 1063 1064 // On PPC64 release and volatile are implemented by an instruction 1065 // that also has acquire semantics. I.e. there is no need for an 1066 // acquire before these. 1067 int xop = x->Opcode(); 1068 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 1069 // Make sure we're not missing Call/Phi/MergeMem by checking 1070 // control edges. The control edge must directly lead back 1071 // to the MemBarAcquire 1072 Node *ctrl_proj = x->in(0); 1073 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 1074 return true; 1075 } 1076 } 1077 } 1078 1079 return false; 1080 } 1081 1082 #define __ _masm. 1083 1084 // Tertiary op of a LoadP or StoreP encoding. 1085 #define REGP_OP true 1086 1087 // **************************************************************************** 1088 1089 // REQUIRED FUNCTIONALITY 1090 1091 // !!!!! Special hack to get all type of calls to specify the byte offset 1092 // from the start of the call to the point where the return address 1093 // will point. 1094 1095 // PPC port: Removed use of lazy constant construct. 1096 1097 int MachCallStaticJavaNode::ret_addr_offset() { 1098 // It's only a single branch-and-link instruction. 1099 return 4; 1100 } 1101 1102 int MachCallDynamicJavaNode::ret_addr_offset() { 1103 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 1104 // postalloc expanded calls if we use inline caches and do not update method data. 1105 if (UseInlineCaches) return 4; 1106 1107 int vtable_index = this->_vtable_index; 1108 if (vtable_index < 0) { 1109 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 1110 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 1111 return 12; 1112 } else { 1113 return 24 + MacroAssembler::instr_size_for_decode_klass_not_null(); 1114 } 1115 } 1116 1117 int MachCallRuntimeNode::ret_addr_offset() { 1118 if (rule() == CallRuntimeDirect_rule) { 1119 // CallRuntimeDirectNode uses call_c. 1120 #if defined(ABI_ELFv2) 1121 return 28; 1122 #else 1123 return 40; 1124 #endif 1125 } 1126 assert(rule() == CallLeafDirect_rule, "unexpected node with rule %u", rule()); 1127 // CallLeafDirectNode uses bl. 1128 return 4; 1129 } 1130 1131 int MachCallNativeNode::ret_addr_offset() { 1132 Unimplemented(); 1133 return -1; 1134 } 1135 1136 //============================================================================= 1137 1138 // condition code conversions 1139 1140 static int cc_to_boint(int cc) { 1141 return Assembler::bcondCRbiIs0 | (cc & 8); 1142 } 1143 1144 static int cc_to_inverse_boint(int cc) { 1145 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 1146 } 1147 1148 static int cc_to_biint(int cc, int flags_reg) { 1149 return (flags_reg << 2) | (cc & 3); 1150 } 1151 1152 //============================================================================= 1153 1154 // Compute padding required for nodes which need alignment. The padding 1155 // is the number of bytes (not instructions) which will be inserted before 1156 // the instruction. The padding must match the size of a NOP instruction. 1157 1158 // Add nop if a prefixed (two-word) instruction is going to cross a 64-byte boundary. 1159 // (See Section 1.6 of Power ISA Version 3.1) 1160 static int compute_prefix_padding(int current_offset) { 1161 assert(PowerArchitecturePPC64 >= 10 && (CodeEntryAlignment & 63) == 0, 1162 "Code buffer must be aligned to a multiple of 64 bytes"); 1163 if (is_aligned(current_offset + BytesPerInstWord, 64)) { 1164 return BytesPerInstWord; 1165 } 1166 return 0; 1167 } 1168 1169 int loadConI32Node::compute_padding(int current_offset) const { 1170 return compute_prefix_padding(current_offset); 1171 } 1172 1173 int loadConL34Node::compute_padding(int current_offset) const { 1174 return compute_prefix_padding(current_offset); 1175 } 1176 1177 int addI_reg_imm32Node::compute_padding(int current_offset) const { 1178 return compute_prefix_padding(current_offset); 1179 } 1180 1181 int addL_reg_imm34Node::compute_padding(int current_offset) const { 1182 return compute_prefix_padding(current_offset); 1183 } 1184 1185 int addP_reg_imm34Node::compute_padding(int current_offset) const { 1186 return compute_prefix_padding(current_offset); 1187 } 1188 1189 int cmprb_Whitespace_reg_reg_prefixedNode::compute_padding(int current_offset) const { 1190 return compute_prefix_padding(current_offset); 1191 } 1192 1193 1194 //============================================================================= 1195 1196 // Emit an interrupt that is caught by the debugger (for debugging compiler). 1197 void emit_break(CodeBuffer &cbuf) { 1198 C2_MacroAssembler _masm(&cbuf); 1199 __ illtrap(); 1200 } 1201 1202 #ifndef PRODUCT 1203 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1204 st->print("BREAKPOINT"); 1205 } 1206 #endif 1207 1208 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1209 emit_break(cbuf); 1210 } 1211 1212 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1213 return MachNode::size(ra_); 1214 } 1215 1216 //============================================================================= 1217 1218 void emit_nop(CodeBuffer &cbuf) { 1219 C2_MacroAssembler _masm(&cbuf); 1220 __ nop(); 1221 } 1222 1223 static inline void emit_long(CodeBuffer &cbuf, int value) { 1224 *((int*)(cbuf.insts_end())) = value; 1225 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1226 } 1227 1228 //============================================================================= 1229 1230 %} // interrupt source 1231 1232 source_hpp %{ // Header information of the source block. 1233 1234 //-------------------------------------------------------------- 1235 //---< Used for optimization in Compile::Shorten_branches >--- 1236 //-------------------------------------------------------------- 1237 1238 class C2_MacroAssembler; 1239 1240 class CallStubImpl { 1241 1242 public: 1243 1244 // Emit call stub, compiled java to interpreter. 1245 static void emit_trampoline_stub(C2_MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1246 1247 // Size of call trampoline stub. 1248 // This doesn't need to be accurate to the byte, but it 1249 // must be larger than or equal to the real size of the stub. 1250 static uint size_call_trampoline() { 1251 return MacroAssembler::trampoline_stub_size; 1252 } 1253 1254 // number of relocations needed by a call trampoline stub 1255 static uint reloc_call_trampoline() { 1256 return 5; 1257 } 1258 1259 }; 1260 1261 %} // end source_hpp 1262 1263 source %{ 1264 1265 // Emit a trampoline stub for a call to a target which is too far away. 1266 // 1267 // code sequences: 1268 // 1269 // call-site: 1270 // branch-and-link to <destination> or <trampoline stub> 1271 // 1272 // Related trampoline stub for this call-site in the stub section: 1273 // load the call target from the constant pool 1274 // branch via CTR (LR/link still points to the call-site above) 1275 1276 void CallStubImpl::emit_trampoline_stub(C2_MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1277 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1278 if (stub == NULL) { 1279 ciEnv::current()->record_out_of_memory_failure(); 1280 } 1281 } 1282 1283 //============================================================================= 1284 1285 // Emit an inline branch-and-link call and a related trampoline stub. 1286 // 1287 // code sequences: 1288 // 1289 // call-site: 1290 // branch-and-link to <destination> or <trampoline stub> 1291 // 1292 // Related trampoline stub for this call-site in the stub section: 1293 // load the call target from the constant pool 1294 // branch via CTR (LR/link still points to the call-site above) 1295 // 1296 1297 typedef struct { 1298 int insts_call_instruction_offset; 1299 int ret_addr_offset; 1300 } EmitCallOffsets; 1301 1302 // Emit a branch-and-link instruction that branches to a trampoline. 1303 // - Remember the offset of the branch-and-link instruction. 1304 // - Add a relocation at the branch-and-link instruction. 1305 // - Emit a branch-and-link. 1306 // - Remember the return pc offset. 1307 EmitCallOffsets emit_call_with_trampoline_stub(C2_MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1308 EmitCallOffsets offsets = { -1, -1 }; 1309 const int start_offset = __ offset(); 1310 offsets.insts_call_instruction_offset = __ offset(); 1311 1312 // No entry point given, use the current pc. 1313 if (entry_point == NULL) entry_point = __ pc(); 1314 1315 // Put the entry point as a constant into the constant pool. 1316 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1317 if (entry_point_toc_addr == NULL) { 1318 ciEnv::current()->record_out_of_memory_failure(); 1319 return offsets; 1320 } 1321 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1322 1323 // Emit the trampoline stub which will be related to the branch-and-link below. 1324 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1325 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1326 __ relocate(rtype); 1327 1328 // Note: At this point we do not have the address of the trampoline 1329 // stub, and the entry point might be too far away for bl, so __ pc() 1330 // serves as dummy and the bl will be patched later. 1331 __ bl((address) __ pc()); 1332 1333 offsets.ret_addr_offset = __ offset() - start_offset; 1334 1335 return offsets; 1336 } 1337 1338 //============================================================================= 1339 1340 // Factory for creating loadConL* nodes for large/small constant pool. 1341 1342 static inline jlong replicate_immF(float con) { 1343 // Replicate float con 2 times and pack into vector. 1344 int val = *((int*)&con); 1345 jlong lval = val; 1346 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1347 return lval; 1348 } 1349 1350 //============================================================================= 1351 1352 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1353 int ConstantTable::calculate_table_base_offset() const { 1354 return 0; // absolute addressing, no offset 1355 } 1356 1357 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1358 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1359 iRegPdstOper *op_dst = new iRegPdstOper(); 1360 MachNode *m1 = new loadToc_hiNode(); 1361 MachNode *m2 = new loadToc_loNode(); 1362 1363 m1->add_req(NULL); 1364 m2->add_req(NULL, m1); 1365 m1->_opnds[0] = op_dst; 1366 m2->_opnds[0] = op_dst; 1367 m2->_opnds[1] = op_dst; 1368 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1369 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1370 nodes->push(m1); 1371 nodes->push(m2); 1372 } 1373 1374 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1375 // Is postalloc expanded. 1376 ShouldNotReachHere(); 1377 } 1378 1379 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1380 return 0; 1381 } 1382 1383 #ifndef PRODUCT 1384 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1385 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1386 } 1387 #endif 1388 1389 //============================================================================= 1390 1391 #ifndef PRODUCT 1392 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1393 Compile* C = ra_->C; 1394 const long framesize = C->output()->frame_slots() << LogBytesPerInt; 1395 1396 st->print("PROLOG\n\t"); 1397 if (C->output()->need_stack_bang(framesize)) { 1398 st->print("stack_overflow_check\n\t"); 1399 } 1400 1401 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1402 st->print("save return pc\n\t"); 1403 st->print("push frame %ld\n\t", -framesize); 1404 } 1405 1406 if (C->stub_function() == NULL) { 1407 st->print("nmethod entry barrier\n\t"); 1408 } 1409 } 1410 #endif 1411 1412 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1413 Compile* C = ra_->C; 1414 C2_MacroAssembler _masm(&cbuf); 1415 1416 const long framesize = C->output()->frame_size_in_bytes(); 1417 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1418 1419 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1420 1421 const Register return_pc = R20; // Must match return_addr() in frame section. 1422 const Register callers_sp = R21; 1423 const Register push_frame_temp = R22; 1424 const Register toc_temp = R23; 1425 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1426 1427 if (method_is_frameless) { 1428 // Add nop at beginning of all frameless methods to prevent any 1429 // oop instructions from getting overwritten by make_not_entrant 1430 // (patching attempt would fail). 1431 __ nop(); 1432 } else { 1433 // Get return pc. 1434 __ mflr(return_pc); 1435 } 1436 1437 if (C->clinit_barrier_on_entry()) { 1438 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1439 1440 Label L_skip_barrier; 1441 Register klass = toc_temp; 1442 1443 // Notify OOP recorder (don't need the relocation) 1444 AddressLiteral md = __ constant_metadata_address(C->method()->holder()->constant_encoding()); 1445 __ load_const_optimized(klass, md.value(), R0); 1446 __ clinit_barrier(klass, R16_thread, &L_skip_barrier /*L_fast_path*/); 1447 1448 __ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub(), R0); 1449 __ mtctr(klass); 1450 __ bctr(); 1451 1452 __ bind(L_skip_barrier); 1453 } 1454 1455 // Calls to C2R adapters often do not accept exceptional returns. 1456 // We require that their callers must bang for them. But be 1457 // careful, because some VM calls (such as call site linkage) can 1458 // use several kilobytes of stack. But the stack safety zone should 1459 // account for that. See bugs 4446381, 4468289, 4497237. 1460 1461 int bangsize = C->output()->bang_size_in_bytes(); 1462 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1463 if (C->output()->need_stack_bang(bangsize)) { 1464 // Unfortunately we cannot use the function provided in 1465 // assembler.cpp as we have to emulate the pipes. So I had to 1466 // insert the code of generate_stack_overflow_check(), see 1467 // assembler.cpp for some illuminative comments. 1468 const int page_size = os::vm_page_size(); 1469 int bang_end = StackOverflow::stack_shadow_zone_size(); 1470 1471 // This is how far the previous frame's stack banging extended. 1472 const int bang_end_safe = bang_end; 1473 1474 if (bangsize > page_size) { 1475 bang_end += bangsize; 1476 } 1477 1478 int bang_offset = bang_end_safe; 1479 1480 while (bang_offset <= bang_end) { 1481 // Need at least one stack bang at end of shadow zone. 1482 1483 // Again I had to copy code, this time from assembler_ppc.cpp, 1484 // bang_stack_with_offset - see there for comments. 1485 1486 // Stack grows down, caller passes positive offset. 1487 assert(bang_offset > 0, "must bang with positive offset"); 1488 1489 long stdoffset = -bang_offset; 1490 1491 if (Assembler::is_simm(stdoffset, 16)) { 1492 // Signed 16 bit offset, a simple std is ok. 1493 if (UseLoadInstructionsForStackBangingPPC64) { 1494 __ ld(R0, (int)(signed short)stdoffset, R1_SP); 1495 } else { 1496 __ std(R0, (int)(signed short)stdoffset, R1_SP); 1497 } 1498 } else if (Assembler::is_simm(stdoffset, 31)) { 1499 // Use largeoffset calculations for addis & ld/std. 1500 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1501 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1502 1503 Register tmp = R11; 1504 __ addis(tmp, R1_SP, hi); 1505 if (UseLoadInstructionsForStackBangingPPC64) { 1506 __ ld(R0, lo, tmp); 1507 } else { 1508 __ std(R0, lo, tmp); 1509 } 1510 } else { 1511 ShouldNotReachHere(); 1512 } 1513 1514 bang_offset += page_size; 1515 } 1516 // R11 trashed 1517 } // C->output()->need_stack_bang(framesize) 1518 1519 unsigned int bytes = (unsigned int)framesize; 1520 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1521 ciMethod *currMethod = C->method(); 1522 1523 if (!method_is_frameless) { 1524 // Get callers sp. 1525 __ mr(callers_sp, R1_SP); 1526 1527 // Push method's frame, modifies SP. 1528 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1529 // The ABI is already accounted for in 'framesize' via the 1530 // 'out_preserve' area. 1531 Register tmp = push_frame_temp; 1532 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1533 if (Assembler::is_simm(-offset, 16)) { 1534 __ stdu(R1_SP, -offset, R1_SP); 1535 } else { 1536 long x = -offset; 1537 // Had to insert load_const(tmp, -offset). 1538 __ lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1539 __ ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1540 __ sldi(tmp, tmp, 32); 1541 __ oris(tmp, tmp, (x & 0xffff0000) >> 16); 1542 __ ori( tmp, tmp, (x & 0x0000ffff)); 1543 1544 __ stdux(R1_SP, R1_SP, tmp); 1545 } 1546 } 1547 #if 0 // TODO: PPC port 1548 // For testing large constant pools, emit a lot of constants to constant pool. 1549 // "Randomize" const_size. 1550 if (ConstantsALot) { 1551 const int num_consts = const_size(); 1552 for (int i = 0; i < num_consts; i++) { 1553 __ long_constant(0xB0B5B00BBABE); 1554 } 1555 } 1556 #endif 1557 if (!method_is_frameless) { 1558 // Save return pc. 1559 __ std(return_pc, _abi0(lr), callers_sp); 1560 } 1561 1562 if (C->stub_function() == NULL) { 1563 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); 1564 bs->nmethod_entry_barrier(&_masm, push_frame_temp); 1565 } 1566 1567 C->output()->set_frame_complete(cbuf.insts_size()); 1568 } 1569 1570 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1571 // Variable size. determine dynamically. 1572 return MachNode::size(ra_); 1573 } 1574 1575 int MachPrologNode::reloc() const { 1576 // Return number of relocatable values contained in this instruction. 1577 return 1; // 1 reloc entry for load_const(toc). 1578 } 1579 1580 //============================================================================= 1581 1582 #ifndef PRODUCT 1583 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1584 Compile* C = ra_->C; 1585 1586 st->print("EPILOG\n\t"); 1587 st->print("restore return pc\n\t"); 1588 st->print("pop frame\n\t"); 1589 1590 if (do_polling() && C->is_method_compilation()) { 1591 st->print("safepoint poll\n\t"); 1592 } 1593 } 1594 #endif 1595 1596 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1597 Compile* C = ra_->C; 1598 C2_MacroAssembler _masm(&cbuf); 1599 1600 const long framesize = ((long)C->output()->frame_slots()) << LogBytesPerInt; 1601 assert(framesize >= 0, "negative frame-size?"); 1602 1603 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1604 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1605 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1606 const Register temp = R12; 1607 1608 if (!method_is_frameless) { 1609 // Restore return pc relative to callers' sp. 1610 __ ld(return_pc, ((int)framesize) + _abi0(lr), R1_SP); 1611 // Move return pc to LR. 1612 __ mtlr(return_pc); 1613 // Pop frame (fixed frame-size). 1614 __ addi(R1_SP, R1_SP, (int)framesize); 1615 } 1616 1617 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1618 __ reserved_stack_check(return_pc); 1619 } 1620 1621 if (method_needs_polling) { 1622 Label dummy_label; 1623 Label* code_stub = &dummy_label; 1624 if (!UseSIGTRAP && !C->output()->in_scratch_emit_size()) { 1625 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 1626 C->output()->add_stub(stub); 1627 code_stub = &stub->entry(); 1628 __ relocate(relocInfo::poll_return_type); 1629 } 1630 __ safepoint_poll(*code_stub, temp, true /* at_return */, true /* in_nmethod */); 1631 } 1632 } 1633 1634 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1635 // Variable size. Determine dynamically. 1636 return MachNode::size(ra_); 1637 } 1638 1639 int MachEpilogNode::reloc() const { 1640 // Return number of relocatable values contained in this instruction. 1641 return 1; // 1 for load_from_polling_page. 1642 } 1643 1644 const Pipeline * MachEpilogNode::pipeline() const { 1645 return MachNode::pipeline_class(); 1646 } 1647 1648 // ============================================================================= 1649 1650 // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or 1651 // rc_stack. 1652 enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack }; 1653 1654 static enum RC rc_class(OptoReg::Name reg) { 1655 // Return the register class for the given register. The given register 1656 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1657 // enumeration in adGlobals_ppc.hpp. 1658 1659 if (reg == OptoReg::Bad) return rc_bad; 1660 1661 // We have 64 integer register halves, starting at index 0. 1662 if (reg < 64) return rc_int; 1663 1664 // We have 64 floating-point register halves, starting at index 64. 1665 if (reg < 64+64) return rc_float; 1666 1667 // We have 64 vector-scalar registers, starting at index 128. 1668 if (reg < 64+64+64) return rc_vs; 1669 1670 // Between float regs & stack are the flags regs. 1671 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1672 1673 return rc_stack; 1674 } 1675 1676 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1677 bool do_print, Compile* C, outputStream *st) { 1678 1679 assert(opcode == Assembler::LD_OPCODE || 1680 opcode == Assembler::STD_OPCODE || 1681 opcode == Assembler::LWZ_OPCODE || 1682 opcode == Assembler::STW_OPCODE || 1683 opcode == Assembler::LFD_OPCODE || 1684 opcode == Assembler::STFD_OPCODE || 1685 opcode == Assembler::LFS_OPCODE || 1686 opcode == Assembler::STFS_OPCODE, 1687 "opcode not supported"); 1688 1689 if (cbuf) { 1690 int d = 1691 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1692 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1693 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1694 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1695 } 1696 #ifndef PRODUCT 1697 else if (do_print) { 1698 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1699 op_str, 1700 Matcher::regName[reg], 1701 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1702 } 1703 #endif 1704 return 4; // size 1705 } 1706 1707 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1708 Compile* C = ra_->C; 1709 1710 // Get registers to move. 1711 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1712 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1713 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1714 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1715 1716 enum RC src_hi_rc = rc_class(src_hi); 1717 enum RC src_lo_rc = rc_class(src_lo); 1718 enum RC dst_hi_rc = rc_class(dst_hi); 1719 enum RC dst_lo_rc = rc_class(dst_lo); 1720 1721 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1722 if (src_hi != OptoReg::Bad) 1723 assert((src_lo&1)==0 && src_lo+1==src_hi && 1724 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1725 "expected aligned-adjacent pairs"); 1726 // Generate spill code! 1727 int size = 0; 1728 1729 if (src_lo == dst_lo && src_hi == dst_hi) 1730 return size; // Self copy, no move. 1731 1732 if (bottom_type()->isa_vect() != NULL && ideal_reg() == Op_VecX) { 1733 // Memory->Memory Spill. 1734 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1735 int src_offset = ra_->reg2offset(src_lo); 1736 int dst_offset = ra_->reg2offset(dst_lo); 1737 if (cbuf) { 1738 C2_MacroAssembler _masm(cbuf); 1739 __ ld(R0, src_offset, R1_SP); 1740 __ std(R0, dst_offset, R1_SP); 1741 __ ld(R0, src_offset+8, R1_SP); 1742 __ std(R0, dst_offset+8, R1_SP); 1743 } 1744 size += 16; 1745 } 1746 // VectorSRegister->Memory Spill. 1747 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) { 1748 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1749 int dst_offset = ra_->reg2offset(dst_lo); 1750 if (cbuf) { 1751 C2_MacroAssembler _masm(cbuf); 1752 __ addi(R0, R1_SP, dst_offset); 1753 __ stxvd2x(Rsrc, R0); 1754 } 1755 size += 8; 1756 } 1757 // Memory->VectorSRegister Spill. 1758 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) { 1759 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1760 int src_offset = ra_->reg2offset(src_lo); 1761 if (cbuf) { 1762 C2_MacroAssembler _masm(cbuf); 1763 __ addi(R0, R1_SP, src_offset); 1764 __ lxvd2x(Rdst, R0); 1765 } 1766 size += 8; 1767 } 1768 // VectorSRegister->VectorSRegister. 1769 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) { 1770 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1771 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1772 if (cbuf) { 1773 C2_MacroAssembler _masm(cbuf); 1774 __ xxlor(Rdst, Rsrc, Rsrc); 1775 } 1776 size += 4; 1777 } 1778 else { 1779 ShouldNotReachHere(); // No VSR spill. 1780 } 1781 return size; 1782 } 1783 1784 // -------------------------------------- 1785 // Memory->Memory Spill. Use R0 to hold the value. 1786 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1787 int src_offset = ra_->reg2offset(src_lo); 1788 int dst_offset = ra_->reg2offset(dst_lo); 1789 if (src_hi != OptoReg::Bad) { 1790 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1791 "expected same type of move for high parts"); 1792 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1793 if (!cbuf && !do_size) st->print("\n\t"); 1794 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1795 } else { 1796 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1797 if (!cbuf && !do_size) st->print("\n\t"); 1798 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1799 } 1800 return size; 1801 } 1802 1803 // -------------------------------------- 1804 // Check for float->int copy; requires a trip through memory. 1805 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1806 Unimplemented(); 1807 } 1808 1809 // -------------------------------------- 1810 // Check for integer reg-reg copy. 1811 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1812 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1813 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1814 size = (Rsrc != Rdst) ? 4 : 0; 1815 1816 if (cbuf) { 1817 C2_MacroAssembler _masm(cbuf); 1818 if (size) { 1819 __ mr(Rdst, Rsrc); 1820 } 1821 } 1822 #ifndef PRODUCT 1823 else if (!do_size) { 1824 if (size) { 1825 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1826 } else { 1827 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1828 } 1829 } 1830 #endif 1831 return size; 1832 } 1833 1834 // Check for integer store. 1835 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1836 int dst_offset = ra_->reg2offset(dst_lo); 1837 if (src_hi != OptoReg::Bad) { 1838 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1839 "expected same type of move for high parts"); 1840 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1841 } else { 1842 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1843 } 1844 return size; 1845 } 1846 1847 // Check for integer load. 1848 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1849 int src_offset = ra_->reg2offset(src_lo); 1850 if (src_hi != OptoReg::Bad) { 1851 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1852 "expected same type of move for high parts"); 1853 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1854 } else { 1855 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1856 } 1857 return size; 1858 } 1859 1860 // Check for float reg-reg copy. 1861 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1862 if (cbuf) { 1863 C2_MacroAssembler _masm(cbuf); 1864 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1865 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1866 __ fmr(Rdst, Rsrc); 1867 } 1868 #ifndef PRODUCT 1869 else if (!do_size) { 1870 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1871 } 1872 #endif 1873 return 4; 1874 } 1875 1876 // Check for float store. 1877 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1878 int dst_offset = ra_->reg2offset(dst_lo); 1879 if (src_hi != OptoReg::Bad) { 1880 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1881 "expected same type of move for high parts"); 1882 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1883 } else { 1884 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1885 } 1886 return size; 1887 } 1888 1889 // Check for float load. 1890 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1891 int src_offset = ra_->reg2offset(src_lo); 1892 if (src_hi != OptoReg::Bad) { 1893 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1894 "expected same type of move for high parts"); 1895 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1896 } else { 1897 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1898 } 1899 return size; 1900 } 1901 1902 // -------------------------------------------------------------------- 1903 // Check for hi bits still needing moving. Only happens for misaligned 1904 // arguments to native calls. 1905 if (src_hi == dst_hi) 1906 return size; // Self copy; no move. 1907 1908 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1909 ShouldNotReachHere(); // Unimplemented 1910 return 0; 1911 } 1912 1913 #ifndef PRODUCT 1914 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1915 if (!ra_) 1916 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1917 else 1918 implementation(NULL, ra_, false, st); 1919 } 1920 #endif 1921 1922 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1923 implementation(&cbuf, ra_, false, NULL); 1924 } 1925 1926 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1927 return implementation(NULL, ra_, true, NULL); 1928 } 1929 1930 #ifndef PRODUCT 1931 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1932 st->print("NOP \t// %d nops to pad for loops or prefixed instructions.", _count); 1933 } 1934 #endif 1935 1936 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 1937 C2_MacroAssembler _masm(&cbuf); 1938 // _count contains the number of nops needed for padding. 1939 for (int i = 0; i < _count; i++) { 1940 __ nop(); 1941 } 1942 } 1943 1944 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 1945 return _count * 4; 1946 } 1947 1948 #ifndef PRODUCT 1949 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1950 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1951 char reg_str[128]; 1952 ra_->dump_register(this, reg_str); 1953 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 1954 } 1955 #endif 1956 1957 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1958 C2_MacroAssembler _masm(&cbuf); 1959 1960 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1961 int reg = ra_->get_encode(this); 1962 1963 if (Assembler::is_simm(offset, 16)) { 1964 __ addi(as_Register(reg), R1, offset); 1965 } else { 1966 ShouldNotReachHere(); 1967 } 1968 } 1969 1970 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1971 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1972 return 4; 1973 } 1974 1975 #ifndef PRODUCT 1976 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1977 st->print_cr("---- MachUEPNode ----"); 1978 st->print_cr("..."); 1979 } 1980 #endif 1981 1982 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1983 // This is the unverified entry point. 1984 C2_MacroAssembler _masm(&cbuf); 1985 1986 // Inline_cache contains a klass. 1987 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 1988 Register receiver_klass = R12_scratch2; // tmp 1989 1990 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 1991 assert(R11_scratch1 == R11, "need prologue scratch register"); 1992 1993 // Check for NULL argument if we don't have implicit null checks. 1994 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 1995 if (TrapBasedNullChecks) { 1996 __ trap_null_check(R3_ARG1); 1997 } else { 1998 Label valid; 1999 __ cmpdi(CCR0, R3_ARG1, 0); 2000 __ bne_predict_taken(CCR0, valid); 2001 // We have a null argument, branch to ic_miss_stub. 2002 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2003 relocInfo::runtime_call_type); 2004 __ bind(valid); 2005 } 2006 } 2007 // Assume argument is not NULL, load klass from receiver. 2008 __ load_klass(receiver_klass, R3_ARG1); 2009 2010 if (TrapBasedICMissChecks) { 2011 __ trap_ic_miss_check(receiver_klass, ic_klass); 2012 } else { 2013 Label valid; 2014 __ cmpd(CCR0, receiver_klass, ic_klass); 2015 __ beq_predict_taken(CCR0, valid); 2016 // We have an unexpected klass, branch to ic_miss_stub. 2017 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2018 relocInfo::runtime_call_type); 2019 __ bind(valid); 2020 } 2021 2022 // Argument is valid and klass is as expected, continue. 2023 } 2024 2025 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2026 // Variable size. Determine dynamically. 2027 return MachNode::size(ra_); 2028 } 2029 2030 //============================================================================= 2031 2032 %} // interrupt source 2033 2034 source_hpp %{ // Header information of the source block. 2035 2036 class HandlerImpl { 2037 2038 public: 2039 2040 static int emit_exception_handler(CodeBuffer &cbuf); 2041 static int emit_deopt_handler(CodeBuffer& cbuf); 2042 2043 static uint size_exception_handler() { 2044 // The exception_handler is a b64_patchable. 2045 return MacroAssembler::b64_patchable_size; 2046 } 2047 2048 static uint size_deopt_handler() { 2049 // The deopt_handler is a bl64_patchable. 2050 return MacroAssembler::bl64_patchable_size; 2051 } 2052 2053 }; 2054 2055 class Node::PD { 2056 public: 2057 enum NodeFlags { 2058 _last_flag = Node::_last_flag 2059 }; 2060 }; 2061 2062 %} // end source_hpp 2063 2064 source %{ 2065 2066 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2067 C2_MacroAssembler _masm(&cbuf); 2068 2069 address base = __ start_a_stub(size_exception_handler()); 2070 if (base == NULL) return 0; // CodeBuffer::expand failed 2071 2072 int offset = __ offset(); 2073 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2074 relocInfo::runtime_call_type); 2075 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2076 __ end_a_stub(); 2077 2078 return offset; 2079 } 2080 2081 // The deopt_handler is like the exception handler, but it calls to 2082 // the deoptimization blob instead of jumping to the exception blob. 2083 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2084 C2_MacroAssembler _masm(&cbuf); 2085 2086 address base = __ start_a_stub(size_deopt_handler()); 2087 if (base == NULL) return 0; // CodeBuffer::expand failed 2088 2089 int offset = __ offset(); 2090 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2091 relocInfo::runtime_call_type); 2092 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2093 __ end_a_stub(); 2094 2095 return offset; 2096 } 2097 2098 //============================================================================= 2099 2100 // Use a frame slots bias for frameless methods if accessing the stack. 2101 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2102 if (as_Register(reg_enc) == R1_SP) { 2103 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2104 } 2105 return 0; 2106 } 2107 2108 const bool Matcher::match_rule_supported(int opcode) { 2109 if (!has_match_rule(opcode)) { 2110 return false; // no match rule present 2111 } 2112 2113 switch (opcode) { 2114 case Op_SqrtD: 2115 return VM_Version::has_fsqrt(); 2116 case Op_RoundDoubleMode: 2117 return VM_Version::has_vsx(); 2118 case Op_CountLeadingZerosI: 2119 case Op_CountLeadingZerosL: 2120 return UseCountLeadingZerosInstructionsPPC64; 2121 case Op_CountTrailingZerosI: 2122 case Op_CountTrailingZerosL: 2123 return (UseCountLeadingZerosInstructionsPPC64 || UseCountTrailingZerosInstructionsPPC64); 2124 case Op_PopCountI: 2125 case Op_PopCountL: 2126 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2127 2128 case Op_AddVB: 2129 case Op_AddVS: 2130 case Op_AddVI: 2131 case Op_AddVF: 2132 case Op_AddVD: 2133 case Op_SubVB: 2134 case Op_SubVS: 2135 case Op_SubVI: 2136 case Op_SubVF: 2137 case Op_SubVD: 2138 case Op_MulVS: 2139 case Op_MulVF: 2140 case Op_MulVD: 2141 case Op_DivVF: 2142 case Op_DivVD: 2143 case Op_AbsVF: 2144 case Op_AbsVD: 2145 case Op_NegVF: 2146 case Op_NegVD: 2147 case Op_SqrtVF: 2148 case Op_SqrtVD: 2149 case Op_AddVL: 2150 case Op_SubVL: 2151 case Op_MulVI: 2152 case Op_RoundDoubleModeV: 2153 return SuperwordUseVSX; 2154 case Op_PopCountVI: 2155 return (SuperwordUseVSX && UsePopCountInstruction); 2156 case Op_FmaVF: 2157 case Op_FmaVD: 2158 return (SuperwordUseVSX && UseFMA); 2159 2160 case Op_Digit: 2161 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isDigit); 2162 case Op_LowerCase: 2163 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isLowerCase); 2164 case Op_UpperCase: 2165 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isUpperCase); 2166 case Op_Whitespace: 2167 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isWhitespace); 2168 2169 case Op_CacheWB: 2170 case Op_CacheWBPreSync: 2171 case Op_CacheWBPostSync: 2172 return VM_Version::supports_data_cache_line_flush(); 2173 } 2174 2175 return true; // Per default match rules are supported. 2176 } 2177 2178 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { 2179 if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) { 2180 return false; 2181 } 2182 return true; // Per default match rules are supported. 2183 } 2184 2185 const RegMask* Matcher::predicate_reg_mask(void) { 2186 return NULL; 2187 } 2188 2189 const TypeVect* Matcher::predicate_reg_type(const Type* elemTy, int length) { 2190 return NULL; 2191 } 2192 2193 // Vector calling convention not yet implemented. 2194 const bool Matcher::supports_vector_calling_convention(void) { 2195 return false; 2196 } 2197 2198 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 2199 Unimplemented(); 2200 return OptoRegPair(0, 0); 2201 } 2202 2203 const int Matcher::float_pressure(int default_pressure_threshold) { 2204 return default_pressure_threshold; 2205 } 2206 2207 // Vector width in bytes. 2208 const int Matcher::vector_width_in_bytes(BasicType bt) { 2209 if (SuperwordUseVSX) { 2210 assert(MaxVectorSize == 16, ""); 2211 return 16; 2212 } else { 2213 assert(MaxVectorSize == 8, ""); 2214 return 8; 2215 } 2216 } 2217 2218 // Vector ideal reg. 2219 const uint Matcher::vector_ideal_reg(int size) { 2220 if (SuperwordUseVSX) { 2221 assert(MaxVectorSize == 16 && size == 16, ""); 2222 return Op_VecX; 2223 } else { 2224 assert(MaxVectorSize == 8 && size == 8, ""); 2225 return Op_RegL; 2226 } 2227 } 2228 2229 // Limits on vector size (number of elements) loaded into vector. 2230 const int Matcher::max_vector_size(const BasicType bt) { 2231 assert(is_java_primitive(bt), "only primitive type vectors"); 2232 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2233 } 2234 2235 const int Matcher::min_vector_size(const BasicType bt) { 2236 return max_vector_size(bt); // Same as max. 2237 } 2238 2239 const int Matcher::scalable_vector_reg_size(const BasicType bt) { 2240 return -1; 2241 } 2242 2243 // RETURNS: whether this branch offset is short enough that a short 2244 // branch can be used. 2245 // 2246 // If the platform does not provide any short branch variants, then 2247 // this method should return `false' for offset 0. 2248 // 2249 // `Compile::Fill_buffer' will decide on basis of this information 2250 // whether to do the pass `Compile::Shorten_branches' at all. 2251 // 2252 // And `Compile::Shorten_branches' will decide on basis of this 2253 // information whether to replace particular branch sites by short 2254 // ones. 2255 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2256 // Is the offset within the range of a ppc64 pc relative branch? 2257 bool b; 2258 2259 const int safety_zone = 3 * BytesPerInstWord; 2260 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2261 29 - 16 + 1 + 2); 2262 return b; 2263 } 2264 2265 /* TODO: PPC port 2266 // Make a new machine dependent decode node (with its operands). 2267 MachTypeNode *Matcher::make_decode_node() { 2268 assert(CompressedOops::base() == NULL && CompressedOops::shift() == 0, 2269 "This method is only implemented for unscaled cOops mode so far"); 2270 MachTypeNode *decode = new decodeN_unscaledNode(); 2271 decode->set_opnd_array(0, new iRegPdstOper()); 2272 decode->set_opnd_array(1, new iRegNsrcOper()); 2273 return decode; 2274 } 2275 */ 2276 2277 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { 2278 ShouldNotReachHere(); // generic vector operands not supported 2279 return NULL; 2280 } 2281 2282 bool Matcher::is_generic_reg2reg_move(MachNode* m) { 2283 ShouldNotReachHere(); // generic vector operands not supported 2284 return false; 2285 } 2286 2287 bool Matcher::is_generic_vector(MachOper* opnd) { 2288 ShouldNotReachHere(); // generic vector operands not supported 2289 return false; 2290 } 2291 2292 // Constants for c2c and c calling conventions. 2293 2294 const MachRegisterNumbers iarg_reg[8] = { 2295 R3_num, R4_num, R5_num, R6_num, 2296 R7_num, R8_num, R9_num, R10_num 2297 }; 2298 2299 const MachRegisterNumbers farg_reg[13] = { 2300 F1_num, F2_num, F3_num, F4_num, 2301 F5_num, F6_num, F7_num, F8_num, 2302 F9_num, F10_num, F11_num, F12_num, 2303 F13_num 2304 }; 2305 2306 const MachRegisterNumbers vsarg_reg[64] = { 2307 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2308 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2309 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2310 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2311 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2312 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2313 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2314 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2315 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2316 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2317 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2318 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2319 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2320 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2321 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2322 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2323 }; 2324 2325 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2326 2327 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2328 2329 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2330 2331 // Return whether or not this register is ever used as an argument. This 2332 // function is used on startup to build the trampoline stubs in generateOptoStub. 2333 // Registers not mentioned will be killed by the VM call in the trampoline, and 2334 // arguments in those registers not be available to the callee. 2335 bool Matcher::can_be_java_arg(int reg) { 2336 // We return true for all registers contained in iarg_reg[] and 2337 // farg_reg[] and their virtual halves. 2338 // We must include the virtual halves in order to get STDs and LDs 2339 // instead of STWs and LWs in the trampoline stubs. 2340 2341 if ( reg == R3_num || reg == R3_H_num 2342 || reg == R4_num || reg == R4_H_num 2343 || reg == R5_num || reg == R5_H_num 2344 || reg == R6_num || reg == R6_H_num 2345 || reg == R7_num || reg == R7_H_num 2346 || reg == R8_num || reg == R8_H_num 2347 || reg == R9_num || reg == R9_H_num 2348 || reg == R10_num || reg == R10_H_num) 2349 return true; 2350 2351 if ( reg == F1_num || reg == F1_H_num 2352 || reg == F2_num || reg == F2_H_num 2353 || reg == F3_num || reg == F3_H_num 2354 || reg == F4_num || reg == F4_H_num 2355 || reg == F5_num || reg == F5_H_num 2356 || reg == F6_num || reg == F6_H_num 2357 || reg == F7_num || reg == F7_H_num 2358 || reg == F8_num || reg == F8_H_num 2359 || reg == F9_num || reg == F9_H_num 2360 || reg == F10_num || reg == F10_H_num 2361 || reg == F11_num || reg == F11_H_num 2362 || reg == F12_num || reg == F12_H_num 2363 || reg == F13_num || reg == F13_H_num) 2364 return true; 2365 2366 return false; 2367 } 2368 2369 bool Matcher::is_spillable_arg(int reg) { 2370 return can_be_java_arg(reg); 2371 } 2372 2373 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2374 return false; 2375 } 2376 2377 // Register for DIVI projection of divmodI. 2378 RegMask Matcher::divI_proj_mask() { 2379 ShouldNotReachHere(); 2380 return RegMask(); 2381 } 2382 2383 // Register for MODI projection of divmodI. 2384 RegMask Matcher::modI_proj_mask() { 2385 ShouldNotReachHere(); 2386 return RegMask(); 2387 } 2388 2389 // Register for DIVL projection of divmodL. 2390 RegMask Matcher::divL_proj_mask() { 2391 ShouldNotReachHere(); 2392 return RegMask(); 2393 } 2394 2395 // Register for MODL projection of divmodL. 2396 RegMask Matcher::modL_proj_mask() { 2397 ShouldNotReachHere(); 2398 return RegMask(); 2399 } 2400 2401 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2402 return RegMask(); 2403 } 2404 2405 %} 2406 2407 //----------ENCODING BLOCK----------------------------------------------------- 2408 // This block specifies the encoding classes used by the compiler to output 2409 // byte streams. Encoding classes are parameterized macros used by 2410 // Machine Instruction Nodes in order to generate the bit encoding of the 2411 // instruction. Operands specify their base encoding interface with the 2412 // interface keyword. There are currently supported four interfaces, 2413 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2414 // operand to generate a function which returns its register number when 2415 // queried. CONST_INTER causes an operand to generate a function which 2416 // returns the value of the constant when queried. MEMORY_INTER causes an 2417 // operand to generate four functions which return the Base Register, the 2418 // Index Register, the Scale Value, and the Offset Value of the operand when 2419 // queried. COND_INTER causes an operand to generate six functions which 2420 // return the encoding code (ie - encoding bits for the instruction) 2421 // associated with each basic boolean condition for a conditional instruction. 2422 // 2423 // Instructions specify two basic values for encoding. Again, a function 2424 // is available to check if the constant displacement is an oop. They use the 2425 // ins_encode keyword to specify their encoding classes (which must be 2426 // a sequence of enc_class names, and their parameters, specified in 2427 // the encoding block), and they use the 2428 // opcode keyword to specify, in order, their primary, secondary, and 2429 // tertiary opcode. Only the opcode sections which a particular instruction 2430 // needs for encoding need to be specified. 2431 encode %{ 2432 enc_class enc_unimplemented %{ 2433 C2_MacroAssembler _masm(&cbuf); 2434 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2435 %} 2436 2437 enc_class enc_untested %{ 2438 #ifdef ASSERT 2439 C2_MacroAssembler _masm(&cbuf); 2440 __ untested("Untested mach node encoding in AD file."); 2441 #else 2442 #endif 2443 %} 2444 2445 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2446 C2_MacroAssembler _masm(&cbuf); 2447 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2448 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2449 %} 2450 2451 // Load acquire. 2452 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2453 C2_MacroAssembler _masm(&cbuf); 2454 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2455 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2456 __ twi_0($dst$$Register); 2457 __ isync(); 2458 %} 2459 2460 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2461 2462 C2_MacroAssembler _masm(&cbuf); 2463 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2464 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2465 %} 2466 2467 // Load acquire. 2468 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2469 2470 C2_MacroAssembler _masm(&cbuf); 2471 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2472 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2473 __ twi_0($dst$$Register); 2474 __ isync(); 2475 %} 2476 2477 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2478 2479 C2_MacroAssembler _masm(&cbuf); 2480 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2481 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2482 %} 2483 2484 // Load acquire. 2485 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2486 2487 C2_MacroAssembler _masm(&cbuf); 2488 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2489 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2490 __ twi_0($dst$$Register); 2491 __ isync(); 2492 %} 2493 2494 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2495 C2_MacroAssembler _masm(&cbuf); 2496 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2497 // Operand 'ds' requires 4-alignment. 2498 assert((Idisp & 0x3) == 0, "unaligned offset"); 2499 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2500 %} 2501 2502 // Load acquire. 2503 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2504 C2_MacroAssembler _masm(&cbuf); 2505 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2506 // Operand 'ds' requires 4-alignment. 2507 assert((Idisp & 0x3) == 0, "unaligned offset"); 2508 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2509 __ twi_0($dst$$Register); 2510 __ isync(); 2511 %} 2512 2513 enc_class enc_lfd(RegF dst, memory mem) %{ 2514 C2_MacroAssembler _masm(&cbuf); 2515 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2516 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2517 %} 2518 2519 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2520 2521 C2_MacroAssembler _masm(&cbuf); 2522 int toc_offset = 0; 2523 2524 address const_toc_addr; 2525 // Create a non-oop constant, no relocation needed. 2526 // If it is an IC, it has a virtual_call_Relocation. 2527 const_toc_addr = __ long_constant((jlong)$src$$constant); 2528 if (const_toc_addr == NULL) { 2529 ciEnv::current()->record_out_of_memory_failure(); 2530 return; 2531 } 2532 2533 // Get the constant's TOC offset. 2534 toc_offset = __ offset_to_method_toc(const_toc_addr); 2535 2536 // Keep the current instruction offset in mind. 2537 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2538 2539 __ ld($dst$$Register, toc_offset, $toc$$Register); 2540 %} 2541 2542 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2543 2544 C2_MacroAssembler _masm(&cbuf); 2545 2546 if (!ra_->C->output()->in_scratch_emit_size()) { 2547 address const_toc_addr; 2548 // Create a non-oop constant, no relocation needed. 2549 // If it is an IC, it has a virtual_call_Relocation. 2550 const_toc_addr = __ long_constant((jlong)$src$$constant); 2551 if (const_toc_addr == NULL) { 2552 ciEnv::current()->record_out_of_memory_failure(); 2553 return; 2554 } 2555 2556 // Get the constant's TOC offset. 2557 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2558 // Store the toc offset of the constant. 2559 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2560 2561 // Also keep the current instruction offset in mind. 2562 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2563 } 2564 2565 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2566 %} 2567 2568 %} // encode 2569 2570 source %{ 2571 2572 typedef struct { 2573 loadConL_hiNode *_large_hi; 2574 loadConL_loNode *_large_lo; 2575 loadConLNode *_small; 2576 MachNode *_last; 2577 } loadConLNodesTuple; 2578 2579 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2580 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2581 loadConLNodesTuple nodes; 2582 2583 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2584 if (large_constant_pool) { 2585 // Create new nodes. 2586 loadConL_hiNode *m1 = new loadConL_hiNode(); 2587 loadConL_loNode *m2 = new loadConL_loNode(); 2588 2589 // inputs for new nodes 2590 m1->add_req(NULL, toc); 2591 m2->add_req(NULL, m1); 2592 2593 // operands for new nodes 2594 m1->_opnds[0] = new iRegLdstOper(); // dst 2595 m1->_opnds[1] = immSrc; // src 2596 m1->_opnds[2] = new iRegPdstOper(); // toc 2597 m2->_opnds[0] = new iRegLdstOper(); // dst 2598 m2->_opnds[1] = immSrc; // src 2599 m2->_opnds[2] = new iRegLdstOper(); // base 2600 2601 // Initialize ins_attrib TOC fields. 2602 m1->_const_toc_offset = -1; 2603 m2->_const_toc_offset_hi_node = m1; 2604 2605 // Initialize ins_attrib instruction offset. 2606 m1->_cbuf_insts_offset = -1; 2607 2608 // register allocation for new nodes 2609 ra_->set_pair(m1->_idx, reg_second, reg_first); 2610 ra_->set_pair(m2->_idx, reg_second, reg_first); 2611 2612 // Create result. 2613 nodes._large_hi = m1; 2614 nodes._large_lo = m2; 2615 nodes._small = NULL; 2616 nodes._last = nodes._large_lo; 2617 assert(m2->bottom_type()->isa_long(), "must be long"); 2618 } else { 2619 loadConLNode *m2 = new loadConLNode(); 2620 2621 // inputs for new nodes 2622 m2->add_req(NULL, toc); 2623 2624 // operands for new nodes 2625 m2->_opnds[0] = new iRegLdstOper(); // dst 2626 m2->_opnds[1] = immSrc; // src 2627 m2->_opnds[2] = new iRegPdstOper(); // toc 2628 2629 // Initialize ins_attrib instruction offset. 2630 m2->_cbuf_insts_offset = -1; 2631 2632 // register allocation for new nodes 2633 ra_->set_pair(m2->_idx, reg_second, reg_first); 2634 2635 // Create result. 2636 nodes._large_hi = NULL; 2637 nodes._large_lo = NULL; 2638 nodes._small = m2; 2639 nodes._last = nodes._small; 2640 assert(m2->bottom_type()->isa_long(), "must be long"); 2641 } 2642 2643 return nodes; 2644 } 2645 2646 typedef struct { 2647 loadConL_hiNode *_large_hi; 2648 loadConL_loNode *_large_lo; 2649 mtvsrdNode *_moved; 2650 xxspltdNode *_replicated; 2651 loadConLNode *_small; 2652 MachNode *_last; 2653 } loadConLReplicatedNodesTuple; 2654 2655 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2656 vecXOper *dst, immI_0Oper *zero, 2657 OptoReg::Name reg_second, OptoReg::Name reg_first, 2658 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2659 loadConLReplicatedNodesTuple nodes; 2660 2661 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2662 if (large_constant_pool) { 2663 // Create new nodes. 2664 loadConL_hiNode *m1 = new loadConL_hiNode(); 2665 loadConL_loNode *m2 = new loadConL_loNode(); 2666 mtvsrdNode *m3 = new mtvsrdNode(); 2667 xxspltdNode *m4 = new xxspltdNode(); 2668 2669 // inputs for new nodes 2670 m1->add_req(NULL, toc); 2671 m2->add_req(NULL, m1); 2672 m3->add_req(NULL, m2); 2673 m4->add_req(NULL, m3); 2674 2675 // operands for new nodes 2676 m1->_opnds[0] = new iRegLdstOper(); // dst 2677 m1->_opnds[1] = immSrc; // src 2678 m1->_opnds[2] = new iRegPdstOper(); // toc 2679 2680 m2->_opnds[0] = new iRegLdstOper(); // dst 2681 m2->_opnds[1] = immSrc; // src 2682 m2->_opnds[2] = new iRegLdstOper(); // base 2683 2684 m3->_opnds[0] = new vecXOper(); // dst 2685 m3->_opnds[1] = new iRegLdstOper(); // src 2686 2687 m4->_opnds[0] = new vecXOper(); // dst 2688 m4->_opnds[1] = new vecXOper(); // src 2689 m4->_opnds[2] = zero; 2690 2691 // Initialize ins_attrib TOC fields. 2692 m1->_const_toc_offset = -1; 2693 m2->_const_toc_offset_hi_node = m1; 2694 2695 // Initialize ins_attrib instruction offset. 2696 m1->_cbuf_insts_offset = -1; 2697 2698 // register allocation for new nodes 2699 ra_->set_pair(m1->_idx, reg_second, reg_first); 2700 ra_->set_pair(m2->_idx, reg_second, reg_first); 2701 ra_->set1(m3->_idx, reg_second); 2702 ra_->set2(m3->_idx, reg_vec_first); 2703 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2704 2705 // Create result. 2706 nodes._large_hi = m1; 2707 nodes._large_lo = m2; 2708 nodes._moved = m3; 2709 nodes._replicated = m4; 2710 nodes._small = NULL; 2711 nodes._last = nodes._replicated; 2712 assert(m2->bottom_type()->isa_long(), "must be long"); 2713 } else { 2714 loadConLNode *m2 = new loadConLNode(); 2715 mtvsrdNode *m3 = new mtvsrdNode(); 2716 xxspltdNode *m4 = new xxspltdNode(); 2717 2718 // inputs for new nodes 2719 m2->add_req(NULL, toc); 2720 2721 // operands for new nodes 2722 m2->_opnds[0] = new iRegLdstOper(); // dst 2723 m2->_opnds[1] = immSrc; // src 2724 m2->_opnds[2] = new iRegPdstOper(); // toc 2725 2726 m3->_opnds[0] = new vecXOper(); // dst 2727 m3->_opnds[1] = new iRegLdstOper(); // src 2728 2729 m4->_opnds[0] = new vecXOper(); // dst 2730 m4->_opnds[1] = new vecXOper(); // src 2731 m4->_opnds[2] = zero; 2732 2733 // Initialize ins_attrib instruction offset. 2734 m2->_cbuf_insts_offset = -1; 2735 ra_->set1(m3->_idx, reg_second); 2736 ra_->set2(m3->_idx, reg_vec_first); 2737 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2738 2739 // register allocation for new nodes 2740 ra_->set_pair(m2->_idx, reg_second, reg_first); 2741 2742 // Create result. 2743 nodes._large_hi = NULL; 2744 nodes._large_lo = NULL; 2745 nodes._small = m2; 2746 nodes._moved = m3; 2747 nodes._replicated = m4; 2748 nodes._last = nodes._replicated; 2749 assert(m2->bottom_type()->isa_long(), "must be long"); 2750 } 2751 2752 return nodes; 2753 } 2754 2755 %} // source 2756 2757 encode %{ 2758 // Postalloc expand emitter for loading a long constant from the method's TOC. 2759 // Enc_class needed as consttanttablebase is not supported by postalloc 2760 // expand. 2761 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2762 // Create new nodes. 2763 loadConLNodesTuple loadConLNodes = 2764 loadConLNodesTuple_create(ra_, n_toc, op_src, 2765 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2766 2767 // Push new nodes. 2768 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2769 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2770 2771 // some asserts 2772 assert(nodes->length() >= 1, "must have created at least 1 node"); 2773 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2774 %} 2775 2776 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2777 2778 C2_MacroAssembler _masm(&cbuf); 2779 int toc_offset = 0; 2780 2781 intptr_t val = $src$$constant; 2782 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2783 address const_toc_addr; 2784 if (constant_reloc == relocInfo::oop_type) { 2785 // Create an oop constant and a corresponding relocation. 2786 AddressLiteral a = __ allocate_oop_address((jobject)val); 2787 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2788 __ relocate(a.rspec()); 2789 } else if (constant_reloc == relocInfo::metadata_type) { 2790 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2791 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2792 __ relocate(a.rspec()); 2793 } else { 2794 // Create a non-oop constant, no relocation needed. 2795 const_toc_addr = __ long_constant((jlong)$src$$constant); 2796 } 2797 2798 if (const_toc_addr == NULL) { 2799 ciEnv::current()->record_out_of_memory_failure(); 2800 return; 2801 } 2802 // Get the constant's TOC offset. 2803 toc_offset = __ offset_to_method_toc(const_toc_addr); 2804 2805 __ ld($dst$$Register, toc_offset, $toc$$Register); 2806 %} 2807 2808 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2809 2810 C2_MacroAssembler _masm(&cbuf); 2811 if (!ra_->C->output()->in_scratch_emit_size()) { 2812 intptr_t val = $src$$constant; 2813 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2814 address const_toc_addr; 2815 if (constant_reloc == relocInfo::oop_type) { 2816 // Create an oop constant and a corresponding relocation. 2817 AddressLiteral a = __ allocate_oop_address((jobject)val); 2818 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2819 __ relocate(a.rspec()); 2820 } else if (constant_reloc == relocInfo::metadata_type) { 2821 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2822 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2823 __ relocate(a.rspec()); 2824 } else { // non-oop pointers, e.g. card mark base, heap top 2825 // Create a non-oop constant, no relocation needed. 2826 const_toc_addr = __ long_constant((jlong)$src$$constant); 2827 } 2828 2829 if (const_toc_addr == NULL) { 2830 ciEnv::current()->record_out_of_memory_failure(); 2831 return; 2832 } 2833 // Get the constant's TOC offset. 2834 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2835 // Store the toc offset of the constant. 2836 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 2837 } 2838 2839 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2840 %} 2841 2842 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 2843 // Enc_class needed as consttanttablebase is not supported by postalloc 2844 // expand. 2845 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 2846 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2847 if (large_constant_pool) { 2848 // Create new nodes. 2849 loadConP_hiNode *m1 = new loadConP_hiNode(); 2850 loadConP_loNode *m2 = new loadConP_loNode(); 2851 2852 // inputs for new nodes 2853 m1->add_req(NULL, n_toc); 2854 m2->add_req(NULL, m1); 2855 2856 // operands for new nodes 2857 m1->_opnds[0] = new iRegPdstOper(); // dst 2858 m1->_opnds[1] = op_src; // src 2859 m1->_opnds[2] = new iRegPdstOper(); // toc 2860 m2->_opnds[0] = new iRegPdstOper(); // dst 2861 m2->_opnds[1] = op_src; // src 2862 m2->_opnds[2] = new iRegLdstOper(); // base 2863 2864 // Initialize ins_attrib TOC fields. 2865 m1->_const_toc_offset = -1; 2866 m2->_const_toc_offset_hi_node = m1; 2867 2868 // Register allocation for new nodes. 2869 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2870 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2871 2872 nodes->push(m1); 2873 nodes->push(m2); 2874 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2875 } else { 2876 loadConPNode *m2 = new loadConPNode(); 2877 2878 // inputs for new nodes 2879 m2->add_req(NULL, n_toc); 2880 2881 // operands for new nodes 2882 m2->_opnds[0] = new iRegPdstOper(); // dst 2883 m2->_opnds[1] = op_src; // src 2884 m2->_opnds[2] = new iRegPdstOper(); // toc 2885 2886 // Register allocation for new nodes. 2887 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2888 2889 nodes->push(m2); 2890 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2891 } 2892 %} 2893 2894 // Enc_class needed as consttanttablebase is not supported by postalloc 2895 // expand. 2896 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 2897 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2898 2899 MachNode *m2; 2900 if (large_constant_pool) { 2901 m2 = new loadConFCompNode(); 2902 } else { 2903 m2 = new loadConFNode(); 2904 } 2905 // inputs for new nodes 2906 m2->add_req(NULL, n_toc); 2907 2908 // operands for new nodes 2909 m2->_opnds[0] = op_dst; 2910 m2->_opnds[1] = op_src; 2911 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2912 2913 // register allocation for new nodes 2914 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2915 nodes->push(m2); 2916 %} 2917 2918 // Enc_class needed as consttanttablebase is not supported by postalloc 2919 // expand. 2920 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 2921 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2922 2923 MachNode *m2; 2924 if (large_constant_pool) { 2925 m2 = new loadConDCompNode(); 2926 } else { 2927 m2 = new loadConDNode(); 2928 } 2929 // inputs for new nodes 2930 m2->add_req(NULL, n_toc); 2931 2932 // operands for new nodes 2933 m2->_opnds[0] = op_dst; 2934 m2->_opnds[1] = op_src; 2935 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2936 2937 // register allocation for new nodes 2938 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2939 nodes->push(m2); 2940 %} 2941 2942 enc_class enc_stw(iRegIsrc src, memory mem) %{ 2943 C2_MacroAssembler _masm(&cbuf); 2944 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2945 __ stw($src$$Register, Idisp, $mem$$base$$Register); 2946 %} 2947 2948 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 2949 C2_MacroAssembler _masm(&cbuf); 2950 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2951 // Operand 'ds' requires 4-alignment. 2952 assert((Idisp & 0x3) == 0, "unaligned offset"); 2953 __ std($src$$Register, Idisp, $mem$$base$$Register); 2954 %} 2955 2956 enc_class enc_stfs(RegF src, memory mem) %{ 2957 C2_MacroAssembler _masm(&cbuf); 2958 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2959 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 2960 %} 2961 2962 enc_class enc_stfd(RegF src, memory mem) %{ 2963 C2_MacroAssembler _masm(&cbuf); 2964 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2965 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 2966 %} 2967 2968 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 2969 2970 if (VM_Version::has_isel()) { 2971 // use isel instruction with Power 7 2972 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2973 encodeP_subNode *n_sub_base = new encodeP_subNode(); 2974 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2975 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 2976 2977 n_compare->add_req(n_region, n_src); 2978 n_compare->_opnds[0] = op_crx; 2979 n_compare->_opnds[1] = op_src; 2980 n_compare->_opnds[2] = new immL16Oper(0); 2981 2982 n_sub_base->add_req(n_region, n_src); 2983 n_sub_base->_opnds[0] = op_dst; 2984 n_sub_base->_opnds[1] = op_src; 2985 n_sub_base->_bottom_type = _bottom_type; 2986 2987 n_shift->add_req(n_region, n_sub_base); 2988 n_shift->_opnds[0] = op_dst; 2989 n_shift->_opnds[1] = op_dst; 2990 n_shift->_bottom_type = _bottom_type; 2991 2992 n_cond_set->add_req(n_region, n_compare, n_shift); 2993 n_cond_set->_opnds[0] = op_dst; 2994 n_cond_set->_opnds[1] = op_crx; 2995 n_cond_set->_opnds[2] = op_dst; 2996 n_cond_set->_bottom_type = _bottom_type; 2997 2998 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2999 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3000 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3001 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3002 3003 nodes->push(n_compare); 3004 nodes->push(n_sub_base); 3005 nodes->push(n_shift); 3006 nodes->push(n_cond_set); 3007 3008 } else { 3009 // before Power 7 3010 moveRegNode *n_move = new moveRegNode(); 3011 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3012 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3013 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3014 3015 n_move->add_req(n_region, n_src); 3016 n_move->_opnds[0] = op_dst; 3017 n_move->_opnds[1] = op_src; 3018 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3019 3020 n_compare->add_req(n_region, n_src); 3021 n_compare->add_prec(n_move); 3022 3023 n_compare->_opnds[0] = op_crx; 3024 n_compare->_opnds[1] = op_src; 3025 n_compare->_opnds[2] = new immL16Oper(0); 3026 3027 n_sub_base->add_req(n_region, n_compare, n_src); 3028 n_sub_base->_opnds[0] = op_dst; 3029 n_sub_base->_opnds[1] = op_crx; 3030 n_sub_base->_opnds[2] = op_src; 3031 n_sub_base->_bottom_type = _bottom_type; 3032 3033 n_shift->add_req(n_region, n_sub_base); 3034 n_shift->_opnds[0] = op_dst; 3035 n_shift->_opnds[1] = op_dst; 3036 n_shift->_bottom_type = _bottom_type; 3037 3038 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3039 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3040 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3041 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3042 3043 nodes->push(n_move); 3044 nodes->push(n_compare); 3045 nodes->push(n_sub_base); 3046 nodes->push(n_shift); 3047 } 3048 3049 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3050 %} 3051 3052 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3053 3054 encodeP_subNode *n1 = new encodeP_subNode(); 3055 n1->add_req(n_region, n_src); 3056 n1->_opnds[0] = op_dst; 3057 n1->_opnds[1] = op_src; 3058 n1->_bottom_type = _bottom_type; 3059 3060 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3061 n2->add_req(n_region, n1); 3062 n2->_opnds[0] = op_dst; 3063 n2->_opnds[1] = op_dst; 3064 n2->_bottom_type = _bottom_type; 3065 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3066 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3067 3068 nodes->push(n1); 3069 nodes->push(n2); 3070 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3071 %} 3072 3073 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3074 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3075 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3076 3077 n_compare->add_req(n_region, n_src); 3078 n_compare->_opnds[0] = op_crx; 3079 n_compare->_opnds[1] = op_src; 3080 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3081 3082 n_shift->add_req(n_region, n_src); 3083 n_shift->_opnds[0] = op_dst; 3084 n_shift->_opnds[1] = op_src; 3085 n_shift->_bottom_type = _bottom_type; 3086 3087 if (VM_Version::has_isel()) { 3088 // use isel instruction with Power 7 3089 3090 decodeN_addNode *n_add_base = new decodeN_addNode(); 3091 n_add_base->add_req(n_region, n_shift); 3092 n_add_base->_opnds[0] = op_dst; 3093 n_add_base->_opnds[1] = op_dst; 3094 n_add_base->_bottom_type = _bottom_type; 3095 3096 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3097 n_cond_set->add_req(n_region, n_compare, n_add_base); 3098 n_cond_set->_opnds[0] = op_dst; 3099 n_cond_set->_opnds[1] = op_crx; 3100 n_cond_set->_opnds[2] = op_dst; 3101 n_cond_set->_bottom_type = _bottom_type; 3102 3103 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3104 ra_->set_oop(n_cond_set, true); 3105 3106 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3107 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3108 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3109 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3110 3111 nodes->push(n_compare); 3112 nodes->push(n_shift); 3113 nodes->push(n_add_base); 3114 nodes->push(n_cond_set); 3115 3116 } else { 3117 // before Power 7 3118 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3119 3120 n_add_base->add_req(n_region, n_compare, n_shift); 3121 n_add_base->_opnds[0] = op_dst; 3122 n_add_base->_opnds[1] = op_crx; 3123 n_add_base->_opnds[2] = op_dst; 3124 n_add_base->_bottom_type = _bottom_type; 3125 3126 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3127 ra_->set_oop(n_add_base, true); 3128 3129 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3130 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3131 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3132 3133 nodes->push(n_compare); 3134 nodes->push(n_shift); 3135 nodes->push(n_add_base); 3136 } 3137 %} 3138 3139 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3140 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3141 n1->add_req(n_region, n_src); 3142 n1->_opnds[0] = op_dst; 3143 n1->_opnds[1] = op_src; 3144 n1->_bottom_type = _bottom_type; 3145 3146 decodeN_addNode *n2 = new decodeN_addNode(); 3147 n2->add_req(n_region, n1); 3148 n2->_opnds[0] = op_dst; 3149 n2->_opnds[1] = op_dst; 3150 n2->_bottom_type = _bottom_type; 3151 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3152 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3153 3154 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3155 ra_->set_oop(n2, true); 3156 3157 nodes->push(n1); 3158 nodes->push(n2); 3159 %} 3160 3161 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3162 3163 C2_MacroAssembler _masm(&cbuf); 3164 int cc = $cmp$$cmpcode; 3165 int flags_reg = $crx$$reg; 3166 Label done; 3167 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3168 // Branch if not (cmp crx). 3169 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3170 __ mr($dst$$Register, $src$$Register); 3171 __ bind(done); 3172 %} 3173 3174 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3175 3176 C2_MacroAssembler _masm(&cbuf); 3177 Label done; 3178 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3179 // Branch if not (cmp crx). 3180 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3181 __ li($dst$$Register, $src$$constant); 3182 __ bind(done); 3183 %} 3184 3185 // This enc_class is needed so that scheduler gets proper 3186 // input mapping for latency computation. 3187 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3188 C2_MacroAssembler _masm(&cbuf); 3189 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3190 %} 3191 3192 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3193 3194 C2_MacroAssembler _masm(&cbuf); 3195 3196 Label done; 3197 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3198 __ li($dst$$Register, $zero$$constant); 3199 __ beq($crx$$CondRegister, done); 3200 __ li($dst$$Register, $notzero$$constant); 3201 __ bind(done); 3202 %} 3203 3204 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3205 3206 C2_MacroAssembler _masm(&cbuf); 3207 3208 Label done; 3209 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3210 __ li($dst$$Register, $zero$$constant); 3211 __ beq($crx$$CondRegister, done); 3212 __ li($dst$$Register, $notzero$$constant); 3213 __ bind(done); 3214 %} 3215 3216 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3217 3218 C2_MacroAssembler _masm(&cbuf); 3219 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3220 Label done; 3221 __ bso($crx$$CondRegister, done); 3222 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3223 __ bind(done); 3224 %} 3225 3226 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3227 3228 C2_MacroAssembler _masm(&cbuf); 3229 Label done; 3230 __ bso($crx$$CondRegister, done); 3231 __ mffprd($dst$$Register, $src$$FloatRegister); 3232 __ bind(done); 3233 %} 3234 3235 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3236 3237 C2_MacroAssembler _masm(&cbuf); 3238 Label d; // dummy 3239 __ bind(d); 3240 Label* p = ($lbl$$label); 3241 // `p' is `NULL' when this encoding class is used only to 3242 // determine the size of the encoded instruction. 3243 Label& l = (NULL == p)? d : *(p); 3244 int cc = $cmp$$cmpcode; 3245 int flags_reg = $crx$$reg; 3246 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3247 int bhint = Assembler::bhintNoHint; 3248 3249 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3250 if (_prob <= PROB_NEVER) { 3251 bhint = Assembler::bhintIsNotTaken; 3252 } else if (_prob >= PROB_ALWAYS) { 3253 bhint = Assembler::bhintIsTaken; 3254 } 3255 } 3256 3257 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3258 cc_to_biint(cc, flags_reg), 3259 l); 3260 %} 3261 3262 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3263 // The scheduler doesn't know about branch shortening, so we set the opcode 3264 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3265 3266 C2_MacroAssembler _masm(&cbuf); 3267 Label d; // dummy 3268 __ bind(d); 3269 Label* p = ($lbl$$label); 3270 // `p' is `NULL' when this encoding class is used only to 3271 // determine the size of the encoded instruction. 3272 Label& l = (NULL == p)? d : *(p); 3273 int cc = $cmp$$cmpcode; 3274 int flags_reg = $crx$$reg; 3275 int bhint = Assembler::bhintNoHint; 3276 3277 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3278 if (_prob <= PROB_NEVER) { 3279 bhint = Assembler::bhintIsNotTaken; 3280 } else if (_prob >= PROB_ALWAYS) { 3281 bhint = Assembler::bhintIsTaken; 3282 } 3283 } 3284 3285 // Tell the conditional far branch to optimize itself when being relocated. 3286 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3287 cc_to_biint(cc, flags_reg), 3288 l, 3289 MacroAssembler::bc_far_optimize_on_relocate); 3290 %} 3291 3292 // Postalloc expand emitter for loading a replicatef float constant from 3293 // the method's TOC. 3294 // Enc_class needed as consttanttablebase is not supported by postalloc 3295 // expand. 3296 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3297 // Create new nodes. 3298 3299 // Make an operand with the bit pattern to load as float. 3300 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3301 3302 loadConLNodesTuple loadConLNodes = 3303 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3304 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3305 3306 // Push new nodes. 3307 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3308 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3309 3310 assert(nodes->length() >= 1, "must have created at least 1 node"); 3311 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3312 %} 3313 3314 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3315 // Create new nodes. 3316 3317 // Make an operand with the bit pattern to load as float. 3318 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3319 immI_0Oper *op_zero = new immI_0Oper(0); 3320 3321 loadConLReplicatedNodesTuple loadConLNodes = 3322 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3323 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3324 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3325 3326 // Push new nodes. 3327 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3328 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3329 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3330 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3331 3332 assert(nodes->length() >= 1, "must have created at least 1 node"); 3333 %} 3334 3335 // This enc_class is needed so that scheduler gets proper 3336 // input mapping for latency computation. 3337 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3338 // Fake operand dst needed for PPC scheduler. 3339 assert($dst$$constant == 0x0, "dst must be 0x0"); 3340 3341 C2_MacroAssembler _masm(&cbuf); 3342 // Mark the code position where the load from the safepoint 3343 // polling page was emitted as relocInfo::poll_type. 3344 __ relocate(relocInfo::poll_type); 3345 __ load_from_polling_page($poll$$Register); 3346 %} 3347 3348 // A Java static call or a runtime call. 3349 // 3350 // Branch-and-link relative to a trampoline. 3351 // The trampoline loads the target address and does a long branch to there. 3352 // In case we call java, the trampoline branches to a interpreter_stub 3353 // which loads the inline cache and the real call target from the constant pool. 3354 // 3355 // This basically looks like this: 3356 // 3357 // >>>> consts -+ -+ 3358 // | |- offset1 3359 // [call target1] | <-+ 3360 // [IC cache] |- offset2 3361 // [call target2] <--+ 3362 // 3363 // <<<< consts 3364 // >>>> insts 3365 // 3366 // bl offset16 -+ -+ ??? // How many bits available? 3367 // | | 3368 // <<<< insts | | 3369 // >>>> stubs | | 3370 // | |- trampoline_stub_Reloc 3371 // trampoline stub: | <-+ 3372 // r2 = toc | 3373 // r2 = [r2 + offset1] | // Load call target1 from const section 3374 // mtctr r2 | 3375 // bctr |- static_stub_Reloc 3376 // comp_to_interp_stub: <---+ 3377 // r1 = toc 3378 // ICreg = [r1 + IC_offset] // Load IC from const section 3379 // r1 = [r1 + offset2] // Load call target2 from const section 3380 // mtctr r1 3381 // bctr 3382 // 3383 // <<<< stubs 3384 // 3385 // The call instruction in the code either 3386 // - Branches directly to a compiled method if the offset is encodable in instruction. 3387 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3388 // - Branches to the compiled_to_interp stub if the target is interpreted. 3389 // 3390 // Further there are three relocations from the loads to the constants in 3391 // the constant section. 3392 // 3393 // Usage of r1 and r2 in the stubs allows to distinguish them. 3394 enc_class enc_java_static_call(method meth) %{ 3395 3396 C2_MacroAssembler _masm(&cbuf); 3397 address entry_point = (address)$meth$$method; 3398 3399 if (!_method) { 3400 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3401 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3402 } else { 3403 // Remember the offset not the address. 3404 const int start_offset = __ offset(); 3405 3406 // The trampoline stub. 3407 // No entry point given, use the current pc. 3408 // Make sure branch fits into 3409 if (entry_point == 0) entry_point = __ pc(); 3410 3411 // Put the entry point as a constant into the constant pool. 3412 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3413 if (entry_point_toc_addr == NULL) { 3414 ciEnv::current()->record_out_of_memory_failure(); 3415 return; 3416 } 3417 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3418 3419 // Emit the trampoline stub which will be related to the branch-and-link below. 3420 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3421 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3422 int method_index = resolved_method_index(cbuf); 3423 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3424 : static_call_Relocation::spec(method_index)); 3425 3426 // The real call. 3427 // Note: At this point we do not have the address of the trampoline 3428 // stub, and the entry point might be too far away for bl, so __ pc() 3429 // serves as dummy and the bl will be patched later. 3430 cbuf.set_insts_mark(); 3431 __ bl(__ pc()); // Emits a relocation. 3432 3433 // The stub for call to interpreter. 3434 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3435 if (stub == NULL) { 3436 ciEnv::current()->record_failure("CodeCache is full"); 3437 return; 3438 } 3439 } 3440 %} 3441 3442 // Second node of expanded dynamic call - the call. 3443 enc_class enc_java_dynamic_call_sched(method meth) %{ 3444 3445 C2_MacroAssembler _masm(&cbuf); 3446 3447 if (!ra_->C->output()->in_scratch_emit_size()) { 3448 // Create a call trampoline stub for the given method. 3449 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3450 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3451 if (entry_point_const == NULL) { 3452 ciEnv::current()->record_out_of_memory_failure(); 3453 return; 3454 } 3455 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3456 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3457 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3458 3459 // Build relocation at call site with ic position as data. 3460 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3461 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3462 "must have one, but can't have both"); 3463 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3464 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3465 "must contain instruction offset"); 3466 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3467 ? _load_ic_hi_node->_cbuf_insts_offset 3468 : _load_ic_node->_cbuf_insts_offset; 3469 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3470 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3471 "should be load from TOC"); 3472 int method_index = resolved_method_index(cbuf); 3473 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3474 } 3475 3476 // At this point I do not have the address of the trampoline stub, 3477 // and the entry point might be too far away for bl. Pc() serves 3478 // as dummy and bl will be patched later. 3479 __ bl((address) __ pc()); 3480 %} 3481 3482 // postalloc expand emitter for virtual calls. 3483 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3484 3485 // Create the nodes for loading the IC from the TOC. 3486 loadConLNodesTuple loadConLNodes_IC = 3487 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3488 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3489 3490 // Create the call node. 3491 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3492 call->_method_handle_invoke = _method_handle_invoke; 3493 call->_vtable_index = _vtable_index; 3494 call->_method = _method; 3495 call->_optimized_virtual = _optimized_virtual; 3496 call->_tf = _tf; 3497 call->_entry_point = _entry_point; 3498 call->_cnt = _cnt; 3499 call->_guaranteed_safepoint = true; 3500 call->_oop_map = _oop_map; 3501 call->_jvms = _jvms; 3502 call->_jvmadj = _jvmadj; 3503 call->_in_rms = _in_rms; 3504 call->_nesting = _nesting; 3505 call->_override_symbolic_info = _override_symbolic_info; 3506 3507 // New call needs all inputs of old call. 3508 // Req... 3509 for (uint i = 0; i < req(); ++i) { 3510 // The expanded node does not need toc any more. 3511 // Add the inline cache constant here instead. This expresses the 3512 // register of the inline cache must be live at the call. 3513 // Else we would have to adapt JVMState by -1. 3514 if (i == mach_constant_base_node_input()) { 3515 call->add_req(loadConLNodes_IC._last); 3516 } else { 3517 call->add_req(in(i)); 3518 } 3519 } 3520 // ...as well as prec 3521 for (uint i = req(); i < len(); ++i) { 3522 call->add_prec(in(i)); 3523 } 3524 3525 // Remember nodes loading the inline cache into r19. 3526 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3527 call->_load_ic_node = loadConLNodes_IC._small; 3528 3529 // Operands for new nodes. 3530 call->_opnds[0] = _opnds[0]; 3531 call->_opnds[1] = _opnds[1]; 3532 3533 // Only the inline cache is associated with a register. 3534 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3535 3536 // Push new nodes. 3537 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3538 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3539 nodes->push(call); 3540 %} 3541 3542 // Compound version of call dynamic 3543 // Toc is only passed so that it can be used in ins_encode statement. 3544 // In the code we have to use $constanttablebase. 3545 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3546 C2_MacroAssembler _masm(&cbuf); 3547 int start_offset = __ offset(); 3548 3549 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3550 3551 int vtable_index = this->_vtable_index; 3552 if (vtable_index < 0) { 3553 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3554 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3555 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3556 3557 // Virtual call relocation will point to ic load. 3558 address virtual_call_meta_addr = __ pc(); 3559 // Load a clear inline cache. 3560 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3561 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3562 if (!success) { 3563 ciEnv::current()->record_out_of_memory_failure(); 3564 return; 3565 } 3566 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3567 // to determine who we intended to call. 3568 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3569 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3570 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3571 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset); 3572 } else { 3573 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3574 // Go thru the vtable. Get receiver klass. Receiver already 3575 // checked for non-null. If we'll go thru a C2I adapter, the 3576 // interpreter expects method in R19_method. 3577 3578 __ load_klass(R11_scratch1, R3); 3579 3580 int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index * vtableEntry::size_in_bytes(); 3581 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3582 __ li(R19_method, v_off); 3583 __ ldx(R19_method/*method*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3584 // NOTE: for vtable dispatches, the vtable entry will never be 3585 // null. However it may very well end up in handle_wrong_method 3586 // if the method is abstract for the particular class. 3587 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3588 // Call target. Either compiled code or C2I adapter. 3589 __ mtctr(R11_scratch1); 3590 __ bctrl(); 3591 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3592 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset); 3593 } 3594 %} 3595 3596 // a runtime call 3597 enc_class enc_java_to_runtime_call (method meth) %{ 3598 3599 C2_MacroAssembler _masm(&cbuf); 3600 const address start_pc = __ pc(); 3601 3602 #if defined(ABI_ELFv2) 3603 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3604 __ call_c(entry, relocInfo::runtime_call_type); 3605 #else 3606 // The function we're going to call. 3607 FunctionDescriptor fdtemp; 3608 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3609 3610 Register Rtoc = R12_scratch2; 3611 // Calculate the method's TOC. 3612 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3613 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3614 // pool entries; call_c_using_toc will optimize the call. 3615 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3616 if (!success) { 3617 ciEnv::current()->record_out_of_memory_failure(); 3618 return; 3619 } 3620 #endif 3621 3622 // Check the ret_addr_offset. 3623 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3624 "Fix constant in ret_addr_offset()"); 3625 %} 3626 3627 // Move to ctr for leaf call. 3628 // This enc_class is needed so that scheduler gets proper 3629 // input mapping for latency computation. 3630 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3631 C2_MacroAssembler _masm(&cbuf); 3632 __ mtctr($src$$Register); 3633 %} 3634 3635 // Postalloc expand emitter for runtime leaf calls. 3636 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3637 loadConLNodesTuple loadConLNodes_Entry; 3638 #if defined(ABI_ELFv2) 3639 jlong entry_address = (jlong) this->entry_point(); 3640 assert(entry_address, "need address here"); 3641 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3642 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3643 #else 3644 // Get the struct that describes the function we are about to call. 3645 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3646 assert(fd, "need fd here"); 3647 jlong entry_address = (jlong) fd->entry(); 3648 // new nodes 3649 loadConLNodesTuple loadConLNodes_Env; 3650 loadConLNodesTuple loadConLNodes_Toc; 3651 3652 // Create nodes and operands for loading the entry point. 3653 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3654 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3655 3656 3657 // Create nodes and operands for loading the env pointer. 3658 if (fd->env() != NULL) { 3659 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3660 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3661 } else { 3662 loadConLNodes_Env._large_hi = NULL; 3663 loadConLNodes_Env._large_lo = NULL; 3664 loadConLNodes_Env._small = NULL; 3665 loadConLNodes_Env._last = new loadConL16Node(); 3666 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3667 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3668 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3669 } 3670 3671 // Create nodes and operands for loading the Toc point. 3672 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3673 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3674 #endif // ABI_ELFv2 3675 // mtctr node 3676 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3677 3678 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3679 mtctr->add_req(0, loadConLNodes_Entry._last); 3680 3681 mtctr->_opnds[0] = new iRegLdstOper(); 3682 mtctr->_opnds[1] = new iRegLdstOper(); 3683 3684 // call node 3685 MachCallLeafNode *call = new CallLeafDirectNode(); 3686 3687 call->_opnds[0] = _opnds[0]; 3688 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3689 3690 // Make the new call node look like the old one. 3691 call->_name = _name; 3692 call->_tf = _tf; 3693 call->_entry_point = _entry_point; 3694 call->_cnt = _cnt; 3695 call->_guaranteed_safepoint = false; 3696 call->_oop_map = _oop_map; 3697 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3698 call->_jvms = NULL; 3699 call->_jvmadj = _jvmadj; 3700 call->_in_rms = _in_rms; 3701 call->_nesting = _nesting; 3702 3703 // New call needs all inputs of old call. 3704 // Req... 3705 for (uint i = 0; i < req(); ++i) { 3706 if (i != mach_constant_base_node_input()) { 3707 call->add_req(in(i)); 3708 } 3709 } 3710 3711 // These must be reqired edges, as the registers are live up to 3712 // the call. Else the constants are handled as kills. 3713 call->add_req(mtctr); 3714 #if !defined(ABI_ELFv2) 3715 call->add_req(loadConLNodes_Env._last); 3716 call->add_req(loadConLNodes_Toc._last); 3717 #endif 3718 3719 // ...as well as prec 3720 for (uint i = req(); i < len(); ++i) { 3721 call->add_prec(in(i)); 3722 } 3723 3724 // registers 3725 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 3726 3727 // Insert the new nodes. 3728 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 3729 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 3730 #if !defined(ABI_ELFv2) 3731 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 3732 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 3733 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 3734 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 3735 #endif 3736 nodes->push(mtctr); 3737 nodes->push(call); 3738 %} 3739 %} 3740 3741 //----------FRAME-------------------------------------------------------------- 3742 // Definition of frame structure and management information. 3743 3744 frame %{ 3745 // These two registers define part of the calling convention between 3746 // compiled code and the interpreter. 3747 3748 // Inline Cache Register or method for I2C. 3749 inline_cache_reg(R19); // R19_method 3750 3751 // Optional: name the operand used by cisc-spilling to access 3752 // [stack_pointer + offset]. 3753 cisc_spilling_operand_name(indOffset); 3754 3755 // Number of stack slots consumed by a Monitor enter. 3756 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 3757 3758 // Compiled code's Frame Pointer. 3759 frame_pointer(R1); // R1_SP 3760 3761 // Interpreter stores its frame pointer in a register which is 3762 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 3763 // interpreted java to compiled java. 3764 // 3765 // R14_state holds pointer to caller's cInterpreter. 3766 interpreter_frame_pointer(R14); // R14_state 3767 3768 stack_alignment(frame::alignment_in_bytes); 3769 3770 // Number of outgoing stack slots killed above the 3771 // out_preserve_stack_slots for calls to C. Supports the var-args 3772 // backing area for register parms. 3773 // 3774 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 3775 3776 // The after-PROLOG location of the return address. Location of 3777 // return address specifies a type (REG or STACK) and a number 3778 // representing the register number (i.e. - use a register name) or 3779 // stack slot. 3780 // 3781 // A: Link register is stored in stack slot ... 3782 // M: ... but it's in the caller's frame according to PPC-64 ABI. 3783 // J: Therefore, we make sure that the link register is also in R11_scratch1 3784 // at the end of the prolog. 3785 // B: We use R20, now. 3786 //return_addr(REG R20); 3787 3788 // G: After reading the comments made by all the luminaries on their 3789 // failure to tell the compiler where the return address really is, 3790 // I hardly dare to try myself. However, I'm convinced it's in slot 3791 // 4 what apparently works and saves us some spills. 3792 return_addr(STACK 4); 3793 3794 // Location of native (C/C++) and interpreter return values. This 3795 // is specified to be the same as Java. In the 32-bit VM, long 3796 // values are actually returned from native calls in O0:O1 and 3797 // returned to the interpreter in I0:I1. The copying to and from 3798 // the register pairs is done by the appropriate call and epilog 3799 // opcodes. This simplifies the register allocator. 3800 c_return_value %{ 3801 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3802 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0), 3803 "only return normal values"); 3804 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3805 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3806 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3807 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3808 %} 3809 3810 // Location of compiled Java return values. Same as C 3811 return_value %{ 3812 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3813 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0), 3814 "only return normal values"); 3815 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3816 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3817 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3818 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3819 %} 3820 %} 3821 3822 3823 //----------ATTRIBUTES--------------------------------------------------------- 3824 3825 //----------Operand Attributes------------------------------------------------- 3826 op_attrib op_cost(1); // Required cost attribute. 3827 3828 //----------Instruction Attributes--------------------------------------------- 3829 3830 // Cost attribute. required. 3831 ins_attrib ins_cost(DEFAULT_COST); 3832 3833 // Is this instruction a non-matching short branch variant of some 3834 // long branch? Not required. 3835 ins_attrib ins_short_branch(0); 3836 3837 ins_attrib ins_is_TrapBasedCheckNode(true); 3838 3839 // Number of constants. 3840 // This instruction uses the given number of constants 3841 // (optional attribute). 3842 // This is needed to determine in time whether the constant pool will 3843 // exceed 4000 entries. Before postalloc_expand the overall number of constants 3844 // is determined. It's also used to compute the constant pool size 3845 // in Output(). 3846 ins_attrib ins_num_consts(0); 3847 3848 // Required alignment attribute (must be a power of 2) specifies the 3849 // alignment that some part of the instruction (not necessarily the 3850 // start) requires. If > 1, a compute_padding() function must be 3851 // provided for the instruction. 3852 ins_attrib ins_alignment(1); 3853 3854 // Enforce/prohibit rematerializations. 3855 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 3856 // then rematerialization of that instruction is prohibited and the 3857 // instruction's value will be spilled if necessary. 3858 // Causes that MachNode::rematerialize() returns false. 3859 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 3860 // then rematerialization should be enforced and a copy of the instruction 3861 // should be inserted if possible; rematerialization is not guaranteed. 3862 // Note: this may result in rematerializations in front of every use. 3863 // Causes that MachNode::rematerialize() can return true. 3864 // (optional attribute) 3865 ins_attrib ins_cannot_rematerialize(false); 3866 ins_attrib ins_should_rematerialize(false); 3867 3868 // Instruction has variable size depending on alignment. 3869 ins_attrib ins_variable_size_depending_on_alignment(false); 3870 3871 // Instruction is a nop. 3872 ins_attrib ins_is_nop(false); 3873 3874 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 3875 ins_attrib ins_use_mach_if_fast_lock_node(false); 3876 3877 // Field for the toc offset of a constant. 3878 // 3879 // This is needed if the toc offset is not encodable as an immediate in 3880 // the PPC load instruction. If so, the upper (hi) bits of the offset are 3881 // added to the toc, and from this a load with immediate is performed. 3882 // With postalloc expand, we get two nodes that require the same offset 3883 // but which don't know about each other. The offset is only known 3884 // when the constant is added to the constant pool during emitting. 3885 // It is generated in the 'hi'-node adding the upper bits, and saved 3886 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 3887 // the offset from there when it gets encoded. 3888 ins_attrib ins_field_const_toc_offset(0); 3889 ins_attrib ins_field_const_toc_offset_hi_node(0); 3890 3891 // A field that can hold the instructions offset in the code buffer. 3892 // Set in the nodes emitter. 3893 ins_attrib ins_field_cbuf_insts_offset(-1); 3894 3895 // Fields for referencing a call's load-IC-node. 3896 // If the toc offset can not be encoded as an immediate in a load, we 3897 // use two nodes. 3898 ins_attrib ins_field_load_ic_hi_node(0); 3899 ins_attrib ins_field_load_ic_node(0); 3900 3901 //----------OPERANDS----------------------------------------------------------- 3902 // Operand definitions must precede instruction definitions for correct 3903 // parsing in the ADLC because operands constitute user defined types 3904 // which are used in instruction definitions. 3905 // 3906 // Formats are generated automatically for constants and base registers. 3907 3908 operand vecX() %{ 3909 constraint(ALLOC_IN_RC(vs_reg)); 3910 match(VecX); 3911 3912 format %{ %} 3913 interface(REG_INTER); 3914 %} 3915 3916 //----------Simple Operands---------------------------------------------------- 3917 // Immediate Operands 3918 3919 // Integer Immediate: 32-bit 3920 operand immI() %{ 3921 match(ConI); 3922 op_cost(40); 3923 format %{ %} 3924 interface(CONST_INTER); 3925 %} 3926 3927 operand immI8() %{ 3928 predicate(Assembler::is_simm(n->get_int(), 8)); 3929 op_cost(0); 3930 match(ConI); 3931 format %{ %} 3932 interface(CONST_INTER); 3933 %} 3934 3935 // Integer Immediate: 16-bit 3936 operand immI16() %{ 3937 predicate(Assembler::is_simm(n->get_int(), 16)); 3938 op_cost(0); 3939 match(ConI); 3940 format %{ %} 3941 interface(CONST_INTER); 3942 %} 3943 3944 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 3945 operand immIhi16() %{ 3946 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 3947 match(ConI); 3948 op_cost(0); 3949 format %{ %} 3950 interface(CONST_INTER); 3951 %} 3952 3953 // Integer Immediate: 32-bit immediate for prefixed addi and load/store. 3954 operand immI32() %{ 3955 predicate(PowerArchitecturePPC64 >= 10); 3956 op_cost(0); 3957 match(ConI); 3958 format %{ %} 3959 interface(CONST_INTER); 3960 %} 3961 3962 operand immInegpow2() %{ 3963 predicate(is_power_of_2(-(juint)(n->get_int()))); 3964 match(ConI); 3965 op_cost(0); 3966 format %{ %} 3967 interface(CONST_INTER); 3968 %} 3969 3970 operand immIpow2minus1() %{ 3971 predicate(is_power_of_2((juint)(n->get_int()) + 1u)); 3972 match(ConI); 3973 op_cost(0); 3974 format %{ %} 3975 interface(CONST_INTER); 3976 %} 3977 3978 operand immIpowerOf2() %{ 3979 predicate(is_power_of_2((juint)(n->get_int()))); 3980 match(ConI); 3981 op_cost(0); 3982 format %{ %} 3983 interface(CONST_INTER); 3984 %} 3985 3986 // Unsigned Integer Immediate: the values 0-31 3987 operand uimmI5() %{ 3988 predicate(Assembler::is_uimm(n->get_int(), 5)); 3989 match(ConI); 3990 op_cost(0); 3991 format %{ %} 3992 interface(CONST_INTER); 3993 %} 3994 3995 // Unsigned Integer Immediate: 6-bit 3996 operand uimmI6() %{ 3997 predicate(Assembler::is_uimm(n->get_int(), 6)); 3998 match(ConI); 3999 op_cost(0); 4000 format %{ %} 4001 interface(CONST_INTER); 4002 %} 4003 4004 // Unsigned Integer Immediate: 6-bit int, greater than 32 4005 operand uimmI6_ge32() %{ 4006 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4007 match(ConI); 4008 op_cost(0); 4009 format %{ %} 4010 interface(CONST_INTER); 4011 %} 4012 4013 // Unsigned Integer Immediate: 15-bit 4014 operand uimmI15() %{ 4015 predicate(Assembler::is_uimm(n->get_int(), 15)); 4016 match(ConI); 4017 op_cost(0); 4018 format %{ %} 4019 interface(CONST_INTER); 4020 %} 4021 4022 // Unsigned Integer Immediate: 16-bit 4023 operand uimmI16() %{ 4024 predicate(Assembler::is_uimm(n->get_int(), 16)); 4025 match(ConI); 4026 op_cost(0); 4027 format %{ %} 4028 interface(CONST_INTER); 4029 %} 4030 4031 // constant 'int 0'. 4032 operand immI_0() %{ 4033 predicate(n->get_int() == 0); 4034 match(ConI); 4035 op_cost(0); 4036 format %{ %} 4037 interface(CONST_INTER); 4038 %} 4039 4040 // constant 'int 1'. 4041 operand immI_1() %{ 4042 predicate(n->get_int() == 1); 4043 match(ConI); 4044 op_cost(0); 4045 format %{ %} 4046 interface(CONST_INTER); 4047 %} 4048 4049 // constant 'int -1'. 4050 operand immI_minus1() %{ 4051 predicate(n->get_int() == -1); 4052 match(ConI); 4053 op_cost(0); 4054 format %{ %} 4055 interface(CONST_INTER); 4056 %} 4057 4058 // int value 16. 4059 operand immI_16() %{ 4060 predicate(n->get_int() == 16); 4061 match(ConI); 4062 op_cost(0); 4063 format %{ %} 4064 interface(CONST_INTER); 4065 %} 4066 4067 // int value 24. 4068 operand immI_24() %{ 4069 predicate(n->get_int() == 24); 4070 match(ConI); 4071 op_cost(0); 4072 format %{ %} 4073 interface(CONST_INTER); 4074 %} 4075 4076 // Compressed oops constants 4077 // Pointer Immediate 4078 operand immN() %{ 4079 match(ConN); 4080 4081 op_cost(10); 4082 format %{ %} 4083 interface(CONST_INTER); 4084 %} 4085 4086 // NULL Pointer Immediate 4087 operand immN_0() %{ 4088 predicate(n->get_narrowcon() == 0); 4089 match(ConN); 4090 4091 op_cost(0); 4092 format %{ %} 4093 interface(CONST_INTER); 4094 %} 4095 4096 // Compressed klass constants 4097 operand immNKlass() %{ 4098 match(ConNKlass); 4099 4100 op_cost(0); 4101 format %{ %} 4102 interface(CONST_INTER); 4103 %} 4104 4105 // This operand can be used to avoid matching of an instruct 4106 // with chain rule. 4107 operand immNKlass_NM() %{ 4108 match(ConNKlass); 4109 predicate(false); 4110 op_cost(0); 4111 format %{ %} 4112 interface(CONST_INTER); 4113 %} 4114 4115 // Pointer Immediate: 64-bit 4116 operand immP() %{ 4117 match(ConP); 4118 op_cost(0); 4119 format %{ %} 4120 interface(CONST_INTER); 4121 %} 4122 4123 // Operand to avoid match of loadConP. 4124 // This operand can be used to avoid matching of an instruct 4125 // with chain rule. 4126 operand immP_NM() %{ 4127 match(ConP); 4128 predicate(false); 4129 op_cost(0); 4130 format %{ %} 4131 interface(CONST_INTER); 4132 %} 4133 4134 // costant 'pointer 0'. 4135 operand immP_0() %{ 4136 predicate(n->get_ptr() == 0); 4137 match(ConP); 4138 op_cost(0); 4139 format %{ %} 4140 interface(CONST_INTER); 4141 %} 4142 4143 // pointer 0x0 or 0x1 4144 operand immP_0or1() %{ 4145 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4146 match(ConP); 4147 op_cost(0); 4148 format %{ %} 4149 interface(CONST_INTER); 4150 %} 4151 4152 operand immL() %{ 4153 match(ConL); 4154 op_cost(40); 4155 format %{ %} 4156 interface(CONST_INTER); 4157 %} 4158 4159 operand immLmax30() %{ 4160 predicate((n->get_long() <= 30)); 4161 match(ConL); 4162 op_cost(0); 4163 format %{ %} 4164 interface(CONST_INTER); 4165 %} 4166 4167 // Long Immediate: 16-bit 4168 operand immL16() %{ 4169 predicate(Assembler::is_simm(n->get_long(), 16)); 4170 match(ConL); 4171 op_cost(0); 4172 format %{ %} 4173 interface(CONST_INTER); 4174 %} 4175 4176 // Long Immediate: 16-bit, 4-aligned 4177 operand immL16Alg4() %{ 4178 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4179 match(ConL); 4180 op_cost(0); 4181 format %{ %} 4182 interface(CONST_INTER); 4183 %} 4184 4185 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4186 operand immL32hi16() %{ 4187 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4188 match(ConL); 4189 op_cost(0); 4190 format %{ %} 4191 interface(CONST_INTER); 4192 %} 4193 4194 // Long Immediate: 32-bit 4195 operand immL32() %{ 4196 predicate(Assembler::is_simm(n->get_long(), 32)); 4197 match(ConL); 4198 op_cost(0); 4199 format %{ %} 4200 interface(CONST_INTER); 4201 %} 4202 4203 // Long Immediate: 34-bit, immediate field in prefixed addi and load/store. 4204 operand immL34() %{ 4205 predicate(PowerArchitecturePPC64 >= 10 && Assembler::is_simm(n->get_long(), 34)); 4206 match(ConL); 4207 op_cost(0); 4208 format %{ %} 4209 interface(CONST_INTER); 4210 %} 4211 4212 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4213 operand immLhighest16() %{ 4214 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4215 match(ConL); 4216 op_cost(0); 4217 format %{ %} 4218 interface(CONST_INTER); 4219 %} 4220 4221 operand immLnegpow2() %{ 4222 predicate(is_power_of_2(-(julong)(n->get_long()))); 4223 match(ConL); 4224 op_cost(0); 4225 format %{ %} 4226 interface(CONST_INTER); 4227 %} 4228 4229 operand immLpow2minus1() %{ 4230 predicate(is_power_of_2((julong)(n->get_long()) + 1ull)); 4231 match(ConL); 4232 op_cost(0); 4233 format %{ %} 4234 interface(CONST_INTER); 4235 %} 4236 4237 // constant 'long 0'. 4238 operand immL_0() %{ 4239 predicate(n->get_long() == 0L); 4240 match(ConL); 4241 op_cost(0); 4242 format %{ %} 4243 interface(CONST_INTER); 4244 %} 4245 4246 // constat ' long -1'. 4247 operand immL_minus1() %{ 4248 predicate(n->get_long() == -1L); 4249 match(ConL); 4250 op_cost(0); 4251 format %{ %} 4252 interface(CONST_INTER); 4253 %} 4254 4255 // Long Immediate: low 32-bit mask 4256 operand immL_32bits() %{ 4257 predicate(n->get_long() == 0xFFFFFFFFL); 4258 match(ConL); 4259 op_cost(0); 4260 format %{ %} 4261 interface(CONST_INTER); 4262 %} 4263 4264 // Unsigned Long Immediate: 16-bit 4265 operand uimmL16() %{ 4266 predicate(Assembler::is_uimm(n->get_long(), 16)); 4267 match(ConL); 4268 op_cost(0); 4269 format %{ %} 4270 interface(CONST_INTER); 4271 %} 4272 4273 // Float Immediate 4274 operand immF() %{ 4275 match(ConF); 4276 op_cost(40); 4277 format %{ %} 4278 interface(CONST_INTER); 4279 %} 4280 4281 // Float Immediate: +0.0f. 4282 operand immF_0() %{ 4283 predicate(jint_cast(n->getf()) == 0); 4284 match(ConF); 4285 4286 op_cost(0); 4287 format %{ %} 4288 interface(CONST_INTER); 4289 %} 4290 4291 // Double Immediate 4292 operand immD() %{ 4293 match(ConD); 4294 op_cost(40); 4295 format %{ %} 4296 interface(CONST_INTER); 4297 %} 4298 4299 // Double Immediate: +0.0d. 4300 operand immD_0() %{ 4301 predicate(jlong_cast(n->getd()) == 0); 4302 match(ConD); 4303 4304 op_cost(0); 4305 format %{ %} 4306 interface(CONST_INTER); 4307 %} 4308 4309 // Integer Register Operands 4310 // Integer Destination Register 4311 // See definition of reg_class bits32_reg_rw. 4312 operand iRegIdst() %{ 4313 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4314 match(RegI); 4315 match(rscratch1RegI); 4316 match(rscratch2RegI); 4317 match(rarg1RegI); 4318 match(rarg2RegI); 4319 match(rarg3RegI); 4320 match(rarg4RegI); 4321 format %{ %} 4322 interface(REG_INTER); 4323 %} 4324 4325 // Integer Source Register 4326 // See definition of reg_class bits32_reg_ro. 4327 operand iRegIsrc() %{ 4328 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4329 match(RegI); 4330 match(rscratch1RegI); 4331 match(rscratch2RegI); 4332 match(rarg1RegI); 4333 match(rarg2RegI); 4334 match(rarg3RegI); 4335 match(rarg4RegI); 4336 format %{ %} 4337 interface(REG_INTER); 4338 %} 4339 4340 operand rscratch1RegI() %{ 4341 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4342 match(iRegIdst); 4343 format %{ %} 4344 interface(REG_INTER); 4345 %} 4346 4347 operand rscratch2RegI() %{ 4348 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4349 match(iRegIdst); 4350 format %{ %} 4351 interface(REG_INTER); 4352 %} 4353 4354 operand rarg1RegI() %{ 4355 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4356 match(iRegIdst); 4357 format %{ %} 4358 interface(REG_INTER); 4359 %} 4360 4361 operand rarg2RegI() %{ 4362 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4363 match(iRegIdst); 4364 format %{ %} 4365 interface(REG_INTER); 4366 %} 4367 4368 operand rarg3RegI() %{ 4369 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4370 match(iRegIdst); 4371 format %{ %} 4372 interface(REG_INTER); 4373 %} 4374 4375 operand rarg4RegI() %{ 4376 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4377 match(iRegIdst); 4378 format %{ %} 4379 interface(REG_INTER); 4380 %} 4381 4382 operand rarg1RegL() %{ 4383 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4384 match(iRegLdst); 4385 format %{ %} 4386 interface(REG_INTER); 4387 %} 4388 4389 operand rarg2RegL() %{ 4390 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4391 match(iRegLdst); 4392 format %{ %} 4393 interface(REG_INTER); 4394 %} 4395 4396 operand rarg3RegL() %{ 4397 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4398 match(iRegLdst); 4399 format %{ %} 4400 interface(REG_INTER); 4401 %} 4402 4403 operand rarg4RegL() %{ 4404 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4405 match(iRegLdst); 4406 format %{ %} 4407 interface(REG_INTER); 4408 %} 4409 4410 // Pointer Destination Register 4411 // See definition of reg_class bits64_reg_rw. 4412 operand iRegPdst() %{ 4413 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4414 match(RegP); 4415 match(rscratch1RegP); 4416 match(rscratch2RegP); 4417 match(rarg1RegP); 4418 match(rarg2RegP); 4419 match(rarg3RegP); 4420 match(rarg4RegP); 4421 format %{ %} 4422 interface(REG_INTER); 4423 %} 4424 4425 // Pointer Destination Register 4426 // Operand not using r11 and r12 (killed in epilog). 4427 operand iRegPdstNoScratch() %{ 4428 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4429 match(RegP); 4430 match(rarg1RegP); 4431 match(rarg2RegP); 4432 match(rarg3RegP); 4433 match(rarg4RegP); 4434 format %{ %} 4435 interface(REG_INTER); 4436 %} 4437 4438 // Pointer Source Register 4439 // See definition of reg_class bits64_reg_ro. 4440 operand iRegPsrc() %{ 4441 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4442 match(RegP); 4443 match(iRegPdst); 4444 match(rscratch1RegP); 4445 match(rscratch2RegP); 4446 match(rarg1RegP); 4447 match(rarg2RegP); 4448 match(rarg3RegP); 4449 match(rarg4RegP); 4450 match(threadRegP); 4451 format %{ %} 4452 interface(REG_INTER); 4453 %} 4454 4455 // Thread operand. 4456 operand threadRegP() %{ 4457 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4458 match(iRegPdst); 4459 format %{ "R16" %} 4460 interface(REG_INTER); 4461 %} 4462 4463 operand rscratch1RegP() %{ 4464 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4465 match(iRegPdst); 4466 format %{ "R11" %} 4467 interface(REG_INTER); 4468 %} 4469 4470 operand rscratch2RegP() %{ 4471 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4472 match(iRegPdst); 4473 format %{ %} 4474 interface(REG_INTER); 4475 %} 4476 4477 operand rarg1RegP() %{ 4478 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4479 match(iRegPdst); 4480 format %{ %} 4481 interface(REG_INTER); 4482 %} 4483 4484 operand rarg2RegP() %{ 4485 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4486 match(iRegPdst); 4487 format %{ %} 4488 interface(REG_INTER); 4489 %} 4490 4491 operand rarg3RegP() %{ 4492 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4493 match(iRegPdst); 4494 format %{ %} 4495 interface(REG_INTER); 4496 %} 4497 4498 operand rarg4RegP() %{ 4499 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4500 match(iRegPdst); 4501 format %{ %} 4502 interface(REG_INTER); 4503 %} 4504 4505 operand iRegNsrc() %{ 4506 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4507 match(RegN); 4508 match(iRegNdst); 4509 4510 format %{ %} 4511 interface(REG_INTER); 4512 %} 4513 4514 operand iRegNdst() %{ 4515 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4516 match(RegN); 4517 4518 format %{ %} 4519 interface(REG_INTER); 4520 %} 4521 4522 // Long Destination Register 4523 // See definition of reg_class bits64_reg_rw. 4524 operand iRegLdst() %{ 4525 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4526 match(RegL); 4527 match(rscratch1RegL); 4528 match(rscratch2RegL); 4529 format %{ %} 4530 interface(REG_INTER); 4531 %} 4532 4533 // Long Source Register 4534 // See definition of reg_class bits64_reg_ro. 4535 operand iRegLsrc() %{ 4536 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4537 match(RegL); 4538 match(iRegLdst); 4539 match(rscratch1RegL); 4540 match(rscratch2RegL); 4541 format %{ %} 4542 interface(REG_INTER); 4543 %} 4544 4545 // Special operand for ConvL2I. 4546 operand iRegL2Isrc(iRegLsrc reg) %{ 4547 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4548 match(ConvL2I reg); 4549 format %{ "ConvL2I($reg)" %} 4550 interface(REG_INTER) 4551 %} 4552 4553 operand rscratch1RegL() %{ 4554 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4555 match(RegL); 4556 format %{ %} 4557 interface(REG_INTER); 4558 %} 4559 4560 operand rscratch2RegL() %{ 4561 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4562 match(RegL); 4563 format %{ %} 4564 interface(REG_INTER); 4565 %} 4566 4567 // Condition Code Flag Registers 4568 operand flagsReg() %{ 4569 constraint(ALLOC_IN_RC(int_flags)); 4570 match(RegFlags); 4571 format %{ %} 4572 interface(REG_INTER); 4573 %} 4574 4575 operand flagsRegSrc() %{ 4576 constraint(ALLOC_IN_RC(int_flags_ro)); 4577 match(RegFlags); 4578 match(flagsReg); 4579 match(flagsRegCR0); 4580 format %{ %} 4581 interface(REG_INTER); 4582 %} 4583 4584 // Condition Code Flag Register CR0 4585 operand flagsRegCR0() %{ 4586 constraint(ALLOC_IN_RC(int_flags_CR0)); 4587 match(RegFlags); 4588 format %{ "CR0" %} 4589 interface(REG_INTER); 4590 %} 4591 4592 operand flagsRegCR1() %{ 4593 constraint(ALLOC_IN_RC(int_flags_CR1)); 4594 match(RegFlags); 4595 format %{ "CR1" %} 4596 interface(REG_INTER); 4597 %} 4598 4599 operand flagsRegCR6() %{ 4600 constraint(ALLOC_IN_RC(int_flags_CR6)); 4601 match(RegFlags); 4602 format %{ "CR6" %} 4603 interface(REG_INTER); 4604 %} 4605 4606 operand regCTR() %{ 4607 constraint(ALLOC_IN_RC(ctr_reg)); 4608 // RegFlags should work. Introducing a RegSpecial type would cause a 4609 // lot of changes. 4610 match(RegFlags); 4611 format %{"SR_CTR" %} 4612 interface(REG_INTER); 4613 %} 4614 4615 operand regD() %{ 4616 constraint(ALLOC_IN_RC(dbl_reg)); 4617 match(RegD); 4618 format %{ %} 4619 interface(REG_INTER); 4620 %} 4621 4622 operand regF() %{ 4623 constraint(ALLOC_IN_RC(flt_reg)); 4624 match(RegF); 4625 format %{ %} 4626 interface(REG_INTER); 4627 %} 4628 4629 // Special Registers 4630 4631 // Method Register 4632 operand inline_cache_regP(iRegPdst reg) %{ 4633 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4634 match(reg); 4635 format %{ %} 4636 interface(REG_INTER); 4637 %} 4638 4639 // Operands to remove register moves in unscaled mode. 4640 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4641 operand iRegP2N(iRegPsrc reg) %{ 4642 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0); 4643 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4644 match(EncodeP reg); 4645 format %{ "$reg" %} 4646 interface(REG_INTER) 4647 %} 4648 4649 operand iRegN2P(iRegNsrc reg) %{ 4650 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4651 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4652 match(DecodeN reg); 4653 format %{ "$reg" %} 4654 interface(REG_INTER) 4655 %} 4656 4657 operand iRegN2P_klass(iRegNsrc reg) %{ 4658 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 4659 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4660 match(DecodeNKlass reg); 4661 format %{ "$reg" %} 4662 interface(REG_INTER) 4663 %} 4664 4665 //----------Complex Operands--------------------------------------------------- 4666 // Indirect Memory Reference 4667 operand indirect(iRegPsrc reg) %{ 4668 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4669 match(reg); 4670 op_cost(100); 4671 format %{ "[$reg]" %} 4672 interface(MEMORY_INTER) %{ 4673 base($reg); 4674 index(0x0); 4675 scale(0x0); 4676 disp(0x0); 4677 %} 4678 %} 4679 4680 // Indirect with Offset 4681 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 4682 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4683 match(AddP reg offset); 4684 op_cost(100); 4685 format %{ "[$reg + $offset]" %} 4686 interface(MEMORY_INTER) %{ 4687 base($reg); 4688 index(0x0); 4689 scale(0x0); 4690 disp($offset); 4691 %} 4692 %} 4693 4694 // Indirect with 4-aligned Offset 4695 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 4696 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4697 match(AddP reg offset); 4698 op_cost(100); 4699 format %{ "[$reg + $offset]" %} 4700 interface(MEMORY_INTER) %{ 4701 base($reg); 4702 index(0x0); 4703 scale(0x0); 4704 disp($offset); 4705 %} 4706 %} 4707 4708 //----------Complex Operands for Compressed OOPs------------------------------- 4709 // Compressed OOPs with narrow_oop_shift == 0. 4710 4711 // Indirect Memory Reference, compressed OOP 4712 operand indirectNarrow(iRegNsrc reg) %{ 4713 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4714 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4715 match(DecodeN reg); 4716 op_cost(100); 4717 format %{ "[$reg]" %} 4718 interface(MEMORY_INTER) %{ 4719 base($reg); 4720 index(0x0); 4721 scale(0x0); 4722 disp(0x0); 4723 %} 4724 %} 4725 4726 operand indirectNarrow_klass(iRegNsrc reg) %{ 4727 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 4728 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4729 match(DecodeNKlass reg); 4730 op_cost(100); 4731 format %{ "[$reg]" %} 4732 interface(MEMORY_INTER) %{ 4733 base($reg); 4734 index(0x0); 4735 scale(0x0); 4736 disp(0x0); 4737 %} 4738 %} 4739 4740 // Indirect with Offset, compressed OOP 4741 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 4742 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4743 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4744 match(AddP (DecodeN reg) offset); 4745 op_cost(100); 4746 format %{ "[$reg + $offset]" %} 4747 interface(MEMORY_INTER) %{ 4748 base($reg); 4749 index(0x0); 4750 scale(0x0); 4751 disp($offset); 4752 %} 4753 %} 4754 4755 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 4756 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 4757 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4758 match(AddP (DecodeNKlass reg) offset); 4759 op_cost(100); 4760 format %{ "[$reg + $offset]" %} 4761 interface(MEMORY_INTER) %{ 4762 base($reg); 4763 index(0x0); 4764 scale(0x0); 4765 disp($offset); 4766 %} 4767 %} 4768 4769 // Indirect with 4-aligned Offset, compressed OOP 4770 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 4771 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4772 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4773 match(AddP (DecodeN reg) offset); 4774 op_cost(100); 4775 format %{ "[$reg + $offset]" %} 4776 interface(MEMORY_INTER) %{ 4777 base($reg); 4778 index(0x0); 4779 scale(0x0); 4780 disp($offset); 4781 %} 4782 %} 4783 4784 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 4785 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 4786 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4787 match(AddP (DecodeNKlass reg) offset); 4788 op_cost(100); 4789 format %{ "[$reg + $offset]" %} 4790 interface(MEMORY_INTER) %{ 4791 base($reg); 4792 index(0x0); 4793 scale(0x0); 4794 disp($offset); 4795 %} 4796 %} 4797 4798 //----------Special Memory Operands-------------------------------------------- 4799 // Stack Slot Operand 4800 // 4801 // This operand is used for loading and storing temporary values on 4802 // the stack where a match requires a value to flow through memory. 4803 operand stackSlotI(sRegI reg) %{ 4804 constraint(ALLOC_IN_RC(stack_slots)); 4805 op_cost(100); 4806 //match(RegI); 4807 format %{ "[sp+$reg]" %} 4808 interface(MEMORY_INTER) %{ 4809 base(0x1); // R1_SP 4810 index(0x0); 4811 scale(0x0); 4812 disp($reg); // Stack Offset 4813 %} 4814 %} 4815 4816 operand stackSlotL(sRegL reg) %{ 4817 constraint(ALLOC_IN_RC(stack_slots)); 4818 op_cost(100); 4819 //match(RegL); 4820 format %{ "[sp+$reg]" %} 4821 interface(MEMORY_INTER) %{ 4822 base(0x1); // R1_SP 4823 index(0x0); 4824 scale(0x0); 4825 disp($reg); // Stack Offset 4826 %} 4827 %} 4828 4829 operand stackSlotP(sRegP reg) %{ 4830 constraint(ALLOC_IN_RC(stack_slots)); 4831 op_cost(100); 4832 //match(RegP); 4833 format %{ "[sp+$reg]" %} 4834 interface(MEMORY_INTER) %{ 4835 base(0x1); // R1_SP 4836 index(0x0); 4837 scale(0x0); 4838 disp($reg); // Stack Offset 4839 %} 4840 %} 4841 4842 operand stackSlotF(sRegF reg) %{ 4843 constraint(ALLOC_IN_RC(stack_slots)); 4844 op_cost(100); 4845 //match(RegF); 4846 format %{ "[sp+$reg]" %} 4847 interface(MEMORY_INTER) %{ 4848 base(0x1); // R1_SP 4849 index(0x0); 4850 scale(0x0); 4851 disp($reg); // Stack Offset 4852 %} 4853 %} 4854 4855 operand stackSlotD(sRegD reg) %{ 4856 constraint(ALLOC_IN_RC(stack_slots)); 4857 op_cost(100); 4858 //match(RegD); 4859 format %{ "[sp+$reg]" %} 4860 interface(MEMORY_INTER) %{ 4861 base(0x1); // R1_SP 4862 index(0x0); 4863 scale(0x0); 4864 disp($reg); // Stack Offset 4865 %} 4866 %} 4867 4868 // Operands for expressing Control Flow 4869 // NOTE: Label is a predefined operand which should not be redefined in 4870 // the AD file. It is generically handled within the ADLC. 4871 4872 //----------Conditional Branch Operands---------------------------------------- 4873 // Comparison Op 4874 // 4875 // This is the operation of the comparison, and is limited to the 4876 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 4877 // (!=). 4878 // 4879 // Other attributes of the comparison, such as unsignedness, are specified 4880 // by the comparison instruction that sets a condition code flags register. 4881 // That result is represented by a flags operand whose subtype is appropriate 4882 // to the unsignedness (etc.) of the comparison. 4883 // 4884 // Later, the instruction which matches both the Comparison Op (a Bool) and 4885 // the flags (produced by the Cmp) specifies the coding of the comparison op 4886 // by matching a specific subtype of Bool operand below. 4887 4888 // When used for floating point comparisons: unordered same as less. 4889 operand cmpOp() %{ 4890 match(Bool); 4891 format %{ "" %} 4892 interface(COND_INTER) %{ 4893 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 4894 // BO & BI 4895 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 4896 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 4897 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 4898 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 4899 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 4900 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 4901 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 4902 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 4903 %} 4904 %} 4905 4906 //----------OPERAND CLASSES---------------------------------------------------- 4907 // Operand Classes are groups of operands that are used to simplify 4908 // instruction definitions by not requiring the AD writer to specify 4909 // seperate instructions for every form of operand when the 4910 // instruction accepts multiple operand types with the same basic 4911 // encoding and format. The classic case of this is memory operands. 4912 // Indirect is not included since its use is limited to Compare & Swap. 4913 4914 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 4915 // Memory operand where offsets are 4-aligned. Required for ld, std. 4916 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 4917 opclass indirectMemory(indirect, indirectNarrow); 4918 4919 // Special opclass for I and ConvL2I. 4920 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 4921 4922 // Operand classes to match encode and decode. iRegN_P2N is only used 4923 // for storeN. I have never seen an encode node elsewhere. 4924 opclass iRegN_P2N(iRegNsrc, iRegP2N); 4925 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 4926 4927 //----------PIPELINE----------------------------------------------------------- 4928 4929 pipeline %{ 4930 4931 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 4932 // J. Res. & Dev., No. 1, Jan. 2002. 4933 4934 //----------ATTRIBUTES--------------------------------------------------------- 4935 attributes %{ 4936 4937 // Power4 instructions are of fixed length. 4938 fixed_size_instructions; 4939 4940 // TODO: if `bundle' means number of instructions fetched 4941 // per cycle, this is 8. If `bundle' means Power4 `group', that is 4942 // max instructions issued per cycle, this is 5. 4943 max_instructions_per_bundle = 8; 4944 4945 // A Power4 instruction is 4 bytes long. 4946 instruction_unit_size = 4; 4947 4948 // The Power4 processor fetches 64 bytes... 4949 instruction_fetch_unit_size = 64; 4950 4951 // ...in one line 4952 instruction_fetch_units = 1 4953 4954 // Unused, list one so that array generated by adlc is not empty. 4955 // Aix compiler chokes if _nop_count = 0. 4956 nops(fxNop); 4957 %} 4958 4959 //----------RESOURCES---------------------------------------------------------- 4960 // Resources are the functional units available to the machine 4961 resources( 4962 PPC_BR, // branch unit 4963 PPC_CR, // condition unit 4964 PPC_FX1, // integer arithmetic unit 1 4965 PPC_FX2, // integer arithmetic unit 2 4966 PPC_LDST1, // load/store unit 1 4967 PPC_LDST2, // load/store unit 2 4968 PPC_FP1, // float arithmetic unit 1 4969 PPC_FP2, // float arithmetic unit 2 4970 PPC_LDST = PPC_LDST1 | PPC_LDST2, 4971 PPC_FX = PPC_FX1 | PPC_FX2, 4972 PPC_FP = PPC_FP1 | PPC_FP2 4973 ); 4974 4975 //----------PIPELINE DESCRIPTION----------------------------------------------- 4976 // Pipeline Description specifies the stages in the machine's pipeline 4977 pipe_desc( 4978 // Power4 longest pipeline path 4979 PPC_IF, // instruction fetch 4980 PPC_IC, 4981 //PPC_BP, // branch prediction 4982 PPC_D0, // decode 4983 PPC_D1, // decode 4984 PPC_D2, // decode 4985 PPC_D3, // decode 4986 PPC_Xfer1, 4987 PPC_GD, // group definition 4988 PPC_MP, // map 4989 PPC_ISS, // issue 4990 PPC_RF, // resource fetch 4991 PPC_EX1, // execute (all units) 4992 PPC_EX2, // execute (FP, LDST) 4993 PPC_EX3, // execute (FP, LDST) 4994 PPC_EX4, // execute (FP) 4995 PPC_EX5, // execute (FP) 4996 PPC_EX6, // execute (FP) 4997 PPC_WB, // write back 4998 PPC_Xfer2, 4999 PPC_CP 5000 ); 5001 5002 //----------PIPELINE CLASSES--------------------------------------------------- 5003 // Pipeline Classes describe the stages in which input and output are 5004 // referenced by the hardware pipeline. 5005 5006 // Simple pipeline classes. 5007 5008 // Default pipeline class. 5009 pipe_class pipe_class_default() %{ 5010 single_instruction; 5011 fixed_latency(2); 5012 %} 5013 5014 // Pipeline class for empty instructions. 5015 pipe_class pipe_class_empty() %{ 5016 single_instruction; 5017 fixed_latency(0); 5018 %} 5019 5020 // Pipeline class for compares. 5021 pipe_class pipe_class_compare() %{ 5022 single_instruction; 5023 fixed_latency(16); 5024 %} 5025 5026 // Pipeline class for traps. 5027 pipe_class pipe_class_trap() %{ 5028 single_instruction; 5029 fixed_latency(100); 5030 %} 5031 5032 // Pipeline class for memory operations. 5033 pipe_class pipe_class_memory() %{ 5034 single_instruction; 5035 fixed_latency(16); 5036 %} 5037 5038 // Pipeline class for call. 5039 pipe_class pipe_class_call() %{ 5040 single_instruction; 5041 fixed_latency(100); 5042 %} 5043 5044 // Define the class for the Nop node. 5045 define %{ 5046 MachNop = pipe_class_default; 5047 %} 5048 5049 %} 5050 5051 //----------INSTRUCTIONS------------------------------------------------------- 5052 5053 // Naming of instructions: 5054 // opA_operB / opA_operB_operC: 5055 // Operation 'op' with one or two source operands 'oper'. Result 5056 // type is A, source operand types are B and C. 5057 // Iff A == B == C, B and C are left out. 5058 // 5059 // The instructions are ordered according to the following scheme: 5060 // - loads 5061 // - load constants 5062 // - prefetch 5063 // - store 5064 // - encode/decode 5065 // - membar 5066 // - conditional moves 5067 // - compare & swap 5068 // - arithmetic and logic operations 5069 // * int: Add, Sub, Mul, Div, Mod 5070 // * int: lShift, arShift, urShift, rot 5071 // * float: Add, Sub, Mul, Div 5072 // * and, or, xor ... 5073 // - register moves: float <-> int, reg <-> stack, repl 5074 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5075 // - conv (low level type cast requiring bit changes (sign extend etc) 5076 // - compares, range & zero checks. 5077 // - branches 5078 // - complex operations, intrinsics, min, max, replicate 5079 // - lock 5080 // - Calls 5081 // 5082 // If there are similar instructions with different types they are sorted: 5083 // int before float 5084 // small before big 5085 // signed before unsigned 5086 // e.g., loadS before loadUS before loadI before loadF. 5087 5088 5089 //----------Load/Store Instructions-------------------------------------------- 5090 5091 //----------Load Instructions-------------------------------------------------- 5092 5093 // Converts byte to int. 5094 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5095 // reuses the 'amount' operand, but adlc expects that operand specification 5096 // and operands in match rule are equivalent. 5097 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5098 effect(DEF dst, USE src); 5099 format %{ "EXTSB $dst, $src \t// byte->int" %} 5100 size(4); 5101 ins_encode %{ 5102 __ extsb($dst$$Register, $src$$Register); 5103 %} 5104 ins_pipe(pipe_class_default); 5105 %} 5106 5107 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5108 // match-rule, false predicate 5109 match(Set dst (LoadB mem)); 5110 predicate(false); 5111 5112 format %{ "LBZ $dst, $mem" %} 5113 size(4); 5114 ins_encode( enc_lbz(dst, mem) ); 5115 ins_pipe(pipe_class_memory); 5116 %} 5117 5118 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5119 // match-rule, false predicate 5120 match(Set dst (LoadB mem)); 5121 predicate(false); 5122 5123 format %{ "LBZ $dst, $mem\n\t" 5124 "TWI $dst\n\t" 5125 "ISYNC" %} 5126 size(12); 5127 ins_encode( enc_lbz_ac(dst, mem) ); 5128 ins_pipe(pipe_class_memory); 5129 %} 5130 5131 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5132 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5133 match(Set dst (LoadB mem)); 5134 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5135 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5136 expand %{ 5137 iRegIdst tmp; 5138 loadUB_indirect(tmp, mem); 5139 convB2I_reg_2(dst, tmp); 5140 %} 5141 %} 5142 5143 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5144 match(Set dst (LoadB mem)); 5145 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5146 expand %{ 5147 iRegIdst tmp; 5148 loadUB_indirect_ac(tmp, mem); 5149 convB2I_reg_2(dst, tmp); 5150 %} 5151 %} 5152 5153 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5154 // match-rule, false predicate 5155 match(Set dst (LoadB mem)); 5156 predicate(false); 5157 5158 format %{ "LBZ $dst, $mem" %} 5159 size(4); 5160 ins_encode( enc_lbz(dst, mem) ); 5161 ins_pipe(pipe_class_memory); 5162 %} 5163 5164 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5165 // match-rule, false predicate 5166 match(Set dst (LoadB mem)); 5167 predicate(false); 5168 5169 format %{ "LBZ $dst, $mem\n\t" 5170 "TWI $dst\n\t" 5171 "ISYNC" %} 5172 size(12); 5173 ins_encode( enc_lbz_ac(dst, mem) ); 5174 ins_pipe(pipe_class_memory); 5175 %} 5176 5177 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5178 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5179 match(Set dst (LoadB mem)); 5180 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5181 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5182 5183 expand %{ 5184 iRegIdst tmp; 5185 loadUB_indOffset16(tmp, mem); 5186 convB2I_reg_2(dst, tmp); 5187 %} 5188 %} 5189 5190 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5191 match(Set dst (LoadB mem)); 5192 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5193 5194 expand %{ 5195 iRegIdst tmp; 5196 loadUB_indOffset16_ac(tmp, mem); 5197 convB2I_reg_2(dst, tmp); 5198 %} 5199 %} 5200 5201 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5202 instruct loadUB(iRegIdst dst, memory mem) %{ 5203 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5204 match(Set dst (LoadUB mem)); 5205 ins_cost(MEMORY_REF_COST); 5206 5207 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5208 size(4); 5209 ins_encode( enc_lbz(dst, mem) ); 5210 ins_pipe(pipe_class_memory); 5211 %} 5212 5213 // Load Unsigned Byte (8bit UNsigned) acquire. 5214 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5215 match(Set dst (LoadUB mem)); 5216 ins_cost(3*MEMORY_REF_COST); 5217 5218 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5219 "TWI $dst\n\t" 5220 "ISYNC" %} 5221 size(12); 5222 ins_encode( enc_lbz_ac(dst, mem) ); 5223 ins_pipe(pipe_class_memory); 5224 %} 5225 5226 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5227 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5228 match(Set dst (ConvI2L (LoadUB mem))); 5229 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5230 ins_cost(MEMORY_REF_COST); 5231 5232 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5233 size(4); 5234 ins_encode( enc_lbz(dst, mem) ); 5235 ins_pipe(pipe_class_memory); 5236 %} 5237 5238 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5239 match(Set dst (ConvI2L (LoadUB mem))); 5240 ins_cost(3*MEMORY_REF_COST); 5241 5242 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5243 "TWI $dst\n\t" 5244 "ISYNC" %} 5245 size(12); 5246 ins_encode( enc_lbz_ac(dst, mem) ); 5247 ins_pipe(pipe_class_memory); 5248 %} 5249 5250 // Load Short (16bit signed) 5251 instruct loadS(iRegIdst dst, memory mem) %{ 5252 match(Set dst (LoadS mem)); 5253 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5254 ins_cost(MEMORY_REF_COST); 5255 5256 format %{ "LHA $dst, $mem" %} 5257 size(4); 5258 ins_encode %{ 5259 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5260 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5261 %} 5262 ins_pipe(pipe_class_memory); 5263 %} 5264 5265 // Load Short (16bit signed) acquire. 5266 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5267 match(Set dst (LoadS mem)); 5268 ins_cost(3*MEMORY_REF_COST); 5269 5270 format %{ "LHA $dst, $mem\t acquire\n\t" 5271 "TWI $dst\n\t" 5272 "ISYNC" %} 5273 size(12); 5274 ins_encode %{ 5275 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5276 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5277 __ twi_0($dst$$Register); 5278 __ isync(); 5279 %} 5280 ins_pipe(pipe_class_memory); 5281 %} 5282 5283 // Load Char (16bit unsigned) 5284 instruct loadUS(iRegIdst dst, memory mem) %{ 5285 match(Set dst (LoadUS mem)); 5286 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5287 ins_cost(MEMORY_REF_COST); 5288 5289 format %{ "LHZ $dst, $mem" %} 5290 size(4); 5291 ins_encode( enc_lhz(dst, mem) ); 5292 ins_pipe(pipe_class_memory); 5293 %} 5294 5295 // Load Char (16bit unsigned) acquire. 5296 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5297 match(Set dst (LoadUS mem)); 5298 ins_cost(3*MEMORY_REF_COST); 5299 5300 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5301 "TWI $dst\n\t" 5302 "ISYNC" %} 5303 size(12); 5304 ins_encode( enc_lhz_ac(dst, mem) ); 5305 ins_pipe(pipe_class_memory); 5306 %} 5307 5308 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5309 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5310 match(Set dst (ConvI2L (LoadUS mem))); 5311 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5312 ins_cost(MEMORY_REF_COST); 5313 5314 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5315 size(4); 5316 ins_encode( enc_lhz(dst, mem) ); 5317 ins_pipe(pipe_class_memory); 5318 %} 5319 5320 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5321 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5322 match(Set dst (ConvI2L (LoadUS mem))); 5323 ins_cost(3*MEMORY_REF_COST); 5324 5325 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5326 "TWI $dst\n\t" 5327 "ISYNC" %} 5328 size(12); 5329 ins_encode( enc_lhz_ac(dst, mem) ); 5330 ins_pipe(pipe_class_memory); 5331 %} 5332 5333 // Load Integer. 5334 instruct loadI(iRegIdst dst, memory mem) %{ 5335 match(Set dst (LoadI mem)); 5336 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5337 ins_cost(MEMORY_REF_COST); 5338 5339 format %{ "LWZ $dst, $mem" %} 5340 size(4); 5341 ins_encode( enc_lwz(dst, mem) ); 5342 ins_pipe(pipe_class_memory); 5343 %} 5344 5345 // Load Integer acquire. 5346 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5347 match(Set dst (LoadI mem)); 5348 ins_cost(3*MEMORY_REF_COST); 5349 5350 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5351 "TWI $dst\n\t" 5352 "ISYNC" %} 5353 size(12); 5354 ins_encode( enc_lwz_ac(dst, mem) ); 5355 ins_pipe(pipe_class_memory); 5356 %} 5357 5358 // Match loading integer and casting it to unsigned int in 5359 // long register. 5360 // LoadI + ConvI2L + AndL 0xffffffff. 5361 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5362 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5363 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5364 ins_cost(MEMORY_REF_COST); 5365 5366 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5367 size(4); 5368 ins_encode( enc_lwz(dst, mem) ); 5369 ins_pipe(pipe_class_memory); 5370 %} 5371 5372 // Match loading integer and casting it to long. 5373 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5374 match(Set dst (ConvI2L (LoadI mem))); 5375 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5376 ins_cost(MEMORY_REF_COST); 5377 5378 format %{ "LWA $dst, $mem \t// loadI2L" %} 5379 size(4); 5380 ins_encode %{ 5381 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5382 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5383 %} 5384 ins_pipe(pipe_class_memory); 5385 %} 5386 5387 // Match loading integer and casting it to long - acquire. 5388 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5389 match(Set dst (ConvI2L (LoadI mem))); 5390 ins_cost(3*MEMORY_REF_COST); 5391 5392 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5393 "TWI $dst\n\t" 5394 "ISYNC" %} 5395 size(12); 5396 ins_encode %{ 5397 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5398 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5399 __ twi_0($dst$$Register); 5400 __ isync(); 5401 %} 5402 ins_pipe(pipe_class_memory); 5403 %} 5404 5405 // Load Long - aligned 5406 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5407 match(Set dst (LoadL mem)); 5408 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5409 ins_cost(MEMORY_REF_COST); 5410 5411 format %{ "LD $dst, $mem \t// long" %} 5412 size(4); 5413 ins_encode( enc_ld(dst, mem) ); 5414 ins_pipe(pipe_class_memory); 5415 %} 5416 5417 // Load Long - aligned acquire. 5418 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5419 match(Set dst (LoadL mem)); 5420 ins_cost(3*MEMORY_REF_COST); 5421 5422 format %{ "LD $dst, $mem \t// long acquire\n\t" 5423 "TWI $dst\n\t" 5424 "ISYNC" %} 5425 size(12); 5426 ins_encode( enc_ld_ac(dst, mem) ); 5427 ins_pipe(pipe_class_memory); 5428 %} 5429 5430 // Load Long - UNaligned 5431 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5432 match(Set dst (LoadL_unaligned mem)); 5433 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5434 ins_cost(MEMORY_REF_COST); 5435 5436 format %{ "LD $dst, $mem \t// unaligned long" %} 5437 size(4); 5438 ins_encode( enc_ld(dst, mem) ); 5439 ins_pipe(pipe_class_memory); 5440 %} 5441 5442 // Load nodes for superwords 5443 5444 // Load Aligned Packed Byte 5445 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5446 predicate(n->as_LoadVector()->memory_size() == 8); 5447 match(Set dst (LoadVector mem)); 5448 ins_cost(MEMORY_REF_COST); 5449 5450 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5451 size(4); 5452 ins_encode( enc_ld(dst, mem) ); 5453 ins_pipe(pipe_class_memory); 5454 %} 5455 5456 // Load Aligned Packed Byte 5457 instruct loadV16(vecX dst, indirect mem) %{ 5458 predicate(n->as_LoadVector()->memory_size() == 16); 5459 match(Set dst (LoadVector mem)); 5460 ins_cost(MEMORY_REF_COST); 5461 5462 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5463 size(4); 5464 ins_encode %{ 5465 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5466 %} 5467 ins_pipe(pipe_class_default); 5468 %} 5469 5470 // Load Range, range = array length (=jint) 5471 instruct loadRange(iRegIdst dst, memory mem) %{ 5472 match(Set dst (LoadRange mem)); 5473 ins_cost(MEMORY_REF_COST); 5474 5475 format %{ "LWZ $dst, $mem \t// range" %} 5476 size(4); 5477 ins_encode( enc_lwz(dst, mem) ); 5478 ins_pipe(pipe_class_memory); 5479 %} 5480 5481 // Load Compressed Pointer 5482 instruct loadN(iRegNdst dst, memory mem) %{ 5483 match(Set dst (LoadN mem)); 5484 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5485 ins_cost(MEMORY_REF_COST); 5486 5487 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5488 size(4); 5489 ins_encode( enc_lwz(dst, mem) ); 5490 ins_pipe(pipe_class_memory); 5491 %} 5492 5493 // Load Compressed Pointer acquire. 5494 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5495 match(Set dst (LoadN mem)); 5496 ins_cost(3*MEMORY_REF_COST); 5497 5498 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5499 "TWI $dst\n\t" 5500 "ISYNC" %} 5501 size(12); 5502 ins_encode( enc_lwz_ac(dst, mem) ); 5503 ins_pipe(pipe_class_memory); 5504 %} 5505 5506 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5507 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5508 match(Set dst (DecodeN (LoadN mem))); 5509 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0); 5510 ins_cost(MEMORY_REF_COST); 5511 5512 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5513 size(4); 5514 ins_encode( enc_lwz(dst, mem) ); 5515 ins_pipe(pipe_class_memory); 5516 %} 5517 5518 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5519 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5520 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0 && 5521 _kids[0]->_leaf->as_Load()->is_unordered()); 5522 ins_cost(MEMORY_REF_COST); 5523 5524 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5525 size(4); 5526 ins_encode( enc_lwz(dst, mem) ); 5527 ins_pipe(pipe_class_memory); 5528 %} 5529 5530 // Load Pointer 5531 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5532 match(Set dst (LoadP mem)); 5533 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0); 5534 ins_cost(MEMORY_REF_COST); 5535 5536 format %{ "LD $dst, $mem \t// ptr" %} 5537 size(4); 5538 ins_encode( enc_ld(dst, mem) ); 5539 ins_pipe(pipe_class_memory); 5540 %} 5541 5542 // Load Pointer acquire. 5543 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5544 match(Set dst (LoadP mem)); 5545 ins_cost(3*MEMORY_REF_COST); 5546 5547 predicate(n->as_Load()->barrier_data() == 0); 5548 5549 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5550 "TWI $dst\n\t" 5551 "ISYNC" %} 5552 size(12); 5553 ins_encode( enc_ld_ac(dst, mem) ); 5554 ins_pipe(pipe_class_memory); 5555 %} 5556 5557 // LoadP + CastP2L 5558 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5559 match(Set dst (CastP2X (LoadP mem))); 5560 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && _kids[0]->_leaf->as_Load()->barrier_data() == 0); 5561 ins_cost(MEMORY_REF_COST); 5562 5563 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5564 size(4); 5565 ins_encode( enc_ld(dst, mem) ); 5566 ins_pipe(pipe_class_memory); 5567 %} 5568 5569 // Load compressed klass pointer. 5570 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5571 match(Set dst (LoadNKlass mem)); 5572 ins_cost(MEMORY_REF_COST); 5573 5574 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5575 size(4); 5576 ins_encode( enc_lwz(dst, mem) ); 5577 ins_pipe(pipe_class_memory); 5578 %} 5579 5580 // Load Klass Pointer 5581 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5582 match(Set dst (LoadKlass mem)); 5583 ins_cost(MEMORY_REF_COST); 5584 5585 format %{ "LD $dst, $mem \t// klass ptr" %} 5586 size(4); 5587 ins_encode( enc_ld(dst, mem) ); 5588 ins_pipe(pipe_class_memory); 5589 %} 5590 5591 // Load Float 5592 instruct loadF(regF dst, memory mem) %{ 5593 match(Set dst (LoadF mem)); 5594 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5595 ins_cost(MEMORY_REF_COST); 5596 5597 format %{ "LFS $dst, $mem" %} 5598 size(4); 5599 ins_encode %{ 5600 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5601 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5602 %} 5603 ins_pipe(pipe_class_memory); 5604 %} 5605 5606 // Load Float acquire. 5607 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5608 match(Set dst (LoadF mem)); 5609 effect(TEMP cr0); 5610 ins_cost(3*MEMORY_REF_COST); 5611 5612 format %{ "LFS $dst, $mem \t// acquire\n\t" 5613 "FCMPU cr0, $dst, $dst\n\t" 5614 "BNE cr0, next\n" 5615 "next:\n\t" 5616 "ISYNC" %} 5617 size(16); 5618 ins_encode %{ 5619 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5620 Label next; 5621 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5622 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5623 __ bne(CCR0, next); 5624 __ bind(next); 5625 __ isync(); 5626 %} 5627 ins_pipe(pipe_class_memory); 5628 %} 5629 5630 // Load Double - aligned 5631 instruct loadD(regD dst, memory mem) %{ 5632 match(Set dst (LoadD mem)); 5633 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5634 ins_cost(MEMORY_REF_COST); 5635 5636 format %{ "LFD $dst, $mem" %} 5637 size(4); 5638 ins_encode( enc_lfd(dst, mem) ); 5639 ins_pipe(pipe_class_memory); 5640 %} 5641 5642 // Load Double - aligned acquire. 5643 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5644 match(Set dst (LoadD mem)); 5645 effect(TEMP cr0); 5646 ins_cost(3*MEMORY_REF_COST); 5647 5648 format %{ "LFD $dst, $mem \t// acquire\n\t" 5649 "FCMPU cr0, $dst, $dst\n\t" 5650 "BNE cr0, next\n" 5651 "next:\n\t" 5652 "ISYNC" %} 5653 size(16); 5654 ins_encode %{ 5655 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5656 Label next; 5657 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5658 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5659 __ bne(CCR0, next); 5660 __ bind(next); 5661 __ isync(); 5662 %} 5663 ins_pipe(pipe_class_memory); 5664 %} 5665 5666 // Load Double - UNaligned 5667 instruct loadD_unaligned(regD dst, memory mem) %{ 5668 match(Set dst (LoadD_unaligned mem)); 5669 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5670 ins_cost(MEMORY_REF_COST); 5671 5672 format %{ "LFD $dst, $mem" %} 5673 size(4); 5674 ins_encode( enc_lfd(dst, mem) ); 5675 ins_pipe(pipe_class_memory); 5676 %} 5677 5678 //----------Constants-------------------------------------------------------- 5679 5680 // Load MachConstantTableBase: add hi offset to global toc. 5681 // TODO: Handle hidden register r29 in bundler! 5682 instruct loadToc_hi(iRegLdst dst) %{ 5683 effect(DEF dst); 5684 ins_cost(DEFAULT_COST); 5685 5686 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 5687 size(4); 5688 ins_encode %{ 5689 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 5690 %} 5691 ins_pipe(pipe_class_default); 5692 %} 5693 5694 // Load MachConstantTableBase: add lo offset to global toc. 5695 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 5696 effect(DEF dst, USE src); 5697 ins_cost(DEFAULT_COST); 5698 5699 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 5700 size(4); 5701 ins_encode %{ 5702 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 5703 %} 5704 ins_pipe(pipe_class_default); 5705 %} 5706 5707 // Load 16-bit integer constant 0xssss???? 5708 instruct loadConI16(iRegIdst dst, immI16 src) %{ 5709 match(Set dst src); 5710 5711 format %{ "LI $dst, $src" %} 5712 size(4); 5713 ins_encode %{ 5714 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 5715 %} 5716 ins_pipe(pipe_class_default); 5717 %} 5718 5719 // Load integer constant 0x????0000 5720 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 5721 match(Set dst src); 5722 ins_cost(DEFAULT_COST); 5723 5724 format %{ "LIS $dst, $src.hi" %} 5725 size(4); 5726 ins_encode %{ 5727 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 5728 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5729 %} 5730 ins_pipe(pipe_class_default); 5731 %} 5732 5733 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 5734 // and sign extended), this adds the low 16 bits. 5735 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 5736 // no match-rule, false predicate 5737 effect(DEF dst, USE src1, USE src2); 5738 predicate(false); 5739 5740 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 5741 size(4); 5742 ins_encode %{ 5743 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5744 %} 5745 ins_pipe(pipe_class_default); 5746 %} 5747 5748 instruct loadConI32(iRegIdst dst, immI32 src) %{ 5749 match(Set dst src); 5750 // This macro is valid only in Power 10 and up, but adding the following predicate here 5751 // caused a build error, so we comment it out for now. 5752 // predicate(PowerArchitecturePPC64 >= 10); 5753 ins_cost(DEFAULT_COST+1); 5754 5755 format %{ "PLI $dst, $src" %} 5756 size(8); 5757 ins_encode %{ 5758 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 5759 __ pli($dst$$Register, $src$$constant); 5760 %} 5761 ins_pipe(pipe_class_default); 5762 ins_alignment(2); 5763 %} 5764 5765 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 5766 match(Set dst src); 5767 ins_cost(DEFAULT_COST*2); 5768 5769 expand %{ 5770 // Would like to use $src$$constant. 5771 immI16 srcLo %{ _opnds[1]->constant() %} 5772 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5773 immIhi16 srcHi %{ _opnds[1]->constant() %} 5774 iRegIdst tmpI; 5775 loadConIhi16(tmpI, srcHi); 5776 loadConI32_lo16(dst, tmpI, srcLo); 5777 %} 5778 %} 5779 5780 // No constant pool entries required. 5781 instruct loadConL16(iRegLdst dst, immL16 src) %{ 5782 match(Set dst src); 5783 5784 format %{ "LI $dst, $src \t// long" %} 5785 size(4); 5786 ins_encode %{ 5787 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 5788 %} 5789 ins_pipe(pipe_class_default); 5790 %} 5791 5792 // Load long constant 0xssssssss????0000 5793 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 5794 match(Set dst src); 5795 ins_cost(DEFAULT_COST); 5796 5797 format %{ "LIS $dst, $src.hi \t// long" %} 5798 size(4); 5799 ins_encode %{ 5800 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5801 %} 5802 ins_pipe(pipe_class_default); 5803 %} 5804 5805 // To load a 32 bit constant: merge lower 16 bits into already loaded 5806 // high 16 bits. 5807 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 5808 // no match-rule, false predicate 5809 effect(DEF dst, USE src1, USE src2); 5810 predicate(false); 5811 5812 format %{ "ORI $dst, $src1, $src2.lo" %} 5813 size(4); 5814 ins_encode %{ 5815 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5816 %} 5817 ins_pipe(pipe_class_default); 5818 %} 5819 5820 // Load 32-bit long constant 5821 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 5822 match(Set dst src); 5823 ins_cost(DEFAULT_COST*2); 5824 5825 expand %{ 5826 // Would like to use $src$$constant. 5827 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 5828 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5829 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 5830 iRegLdst tmpL; 5831 loadConL32hi16(tmpL, srcHi); 5832 loadConL32_lo16(dst, tmpL, srcLo); 5833 %} 5834 %} 5835 5836 // Load 34-bit long constant using prefixed addi. No constant pool entries required. 5837 instruct loadConL34(iRegLdst dst, immL34 src) %{ 5838 match(Set dst src); 5839 // This macro is valid only in Power 10 and up, but adding the following predicate here 5840 // caused a build error, so we comment it out for now. 5841 // predicate(PowerArchitecturePPC64 >= 10); 5842 ins_cost(DEFAULT_COST+1); 5843 5844 format %{ "PLI $dst, $src \t// long" %} 5845 size(8); 5846 ins_encode %{ 5847 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 5848 __ pli($dst$$Register, $src$$constant); 5849 %} 5850 ins_pipe(pipe_class_default); 5851 ins_alignment(2); 5852 %} 5853 5854 // Load long constant 0x????000000000000. 5855 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 5856 match(Set dst src); 5857 ins_cost(DEFAULT_COST); 5858 5859 expand %{ 5860 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 5861 immI shift32 %{ 32 %} 5862 iRegLdst tmpL; 5863 loadConL32hi16(tmpL, srcHi); 5864 lshiftL_regL_immI(dst, tmpL, shift32); 5865 %} 5866 %} 5867 5868 // Expand node for constant pool load: small offset. 5869 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 5870 effect(DEF dst, USE src, USE toc); 5871 ins_cost(MEMORY_REF_COST); 5872 5873 ins_num_consts(1); 5874 // Needed so that CallDynamicJavaDirect can compute the address of this 5875 // instruction for relocation. 5876 ins_field_cbuf_insts_offset(int); 5877 5878 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 5879 size(4); 5880 ins_encode( enc_load_long_constL(dst, src, toc) ); 5881 ins_pipe(pipe_class_memory); 5882 %} 5883 5884 // Expand node for constant pool load: large offset. 5885 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 5886 effect(DEF dst, USE src, USE toc); 5887 predicate(false); 5888 5889 ins_num_consts(1); 5890 ins_field_const_toc_offset(int); 5891 // Needed so that CallDynamicJavaDirect can compute the address of this 5892 // instruction for relocation. 5893 ins_field_cbuf_insts_offset(int); 5894 5895 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 5896 size(4); 5897 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 5898 ins_pipe(pipe_class_default); 5899 %} 5900 5901 // Expand node for constant pool load: large offset. 5902 // No constant pool entries required. 5903 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 5904 effect(DEF dst, USE src, USE base); 5905 predicate(false); 5906 5907 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 5908 5909 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 5910 size(4); 5911 ins_encode %{ 5912 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 5913 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 5914 %} 5915 ins_pipe(pipe_class_memory); 5916 %} 5917 5918 // Load long constant from constant table. Expand in case of 5919 // offset > 16 bit is needed. 5920 // Adlc adds toc node MachConstantTableBase. 5921 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 5922 match(Set dst src); 5923 ins_cost(MEMORY_REF_COST); 5924 5925 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 5926 // We can not inline the enc_class for the expand as that does not support constanttablebase. 5927 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 5928 %} 5929 5930 // Load NULL as compressed oop. 5931 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 5932 match(Set dst src); 5933 ins_cost(DEFAULT_COST); 5934 5935 format %{ "LI $dst, $src \t// compressed ptr" %} 5936 size(4); 5937 ins_encode %{ 5938 __ li($dst$$Register, 0); 5939 %} 5940 ins_pipe(pipe_class_default); 5941 %} 5942 5943 // Load hi part of compressed oop constant. 5944 instruct loadConN_hi(iRegNdst dst, immN src) %{ 5945 effect(DEF dst, USE src); 5946 ins_cost(DEFAULT_COST); 5947 5948 format %{ "LIS $dst, $src \t// narrow oop hi" %} 5949 size(4); 5950 ins_encode %{ 5951 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 5952 %} 5953 ins_pipe(pipe_class_default); 5954 %} 5955 5956 // Add lo part of compressed oop constant to already loaded hi part. 5957 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 5958 effect(DEF dst, USE src1, USE src2); 5959 ins_cost(DEFAULT_COST); 5960 5961 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 5962 size(4); 5963 ins_encode %{ 5964 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5965 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 5966 RelocationHolder rspec = oop_Relocation::spec(oop_index); 5967 __ relocate(rspec, 1); 5968 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 5969 %} 5970 ins_pipe(pipe_class_default); 5971 %} 5972 5973 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 5974 effect(DEF dst, USE src, USE shift, USE mask_begin); 5975 5976 size(4); 5977 ins_encode %{ 5978 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 5979 %} 5980 ins_pipe(pipe_class_default); 5981 %} 5982 5983 // Needed to postalloc expand loadConN: ConN is loaded as ConI 5984 // leaving the upper 32 bits with sign-extension bits. 5985 // This clears these bits: dst = src & 0xFFFFFFFF. 5986 // TODO: Eventually call this maskN_regN_FFFFFFFF. 5987 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 5988 effect(DEF dst, USE src); 5989 predicate(false); 5990 5991 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 5992 size(4); 5993 ins_encode %{ 5994 __ clrldi($dst$$Register, $src$$Register, 0x20); 5995 %} 5996 ins_pipe(pipe_class_default); 5997 %} 5998 5999 // Optimize DecodeN for disjoint base. 6000 // Load base of compressed oops into a register 6001 instruct loadBase(iRegLdst dst) %{ 6002 effect(DEF dst); 6003 6004 format %{ "LoadConst $dst, heapbase" %} 6005 ins_encode %{ 6006 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0); 6007 %} 6008 ins_pipe(pipe_class_default); 6009 %} 6010 6011 // Loading ConN must be postalloc expanded so that edges between 6012 // the nodes are safe. They may not interfere with a safepoint. 6013 // GL TODO: This needs three instructions: better put this into the constant pool. 6014 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6015 match(Set dst src); 6016 ins_cost(DEFAULT_COST*2); 6017 6018 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6019 postalloc_expand %{ 6020 MachNode *m1 = new loadConN_hiNode(); 6021 MachNode *m2 = new loadConN_loNode(); 6022 MachNode *m3 = new clearMs32bNode(); 6023 m1->add_req(NULL); 6024 m2->add_req(NULL, m1); 6025 m3->add_req(NULL, m2); 6026 m1->_opnds[0] = op_dst; 6027 m1->_opnds[1] = op_src; 6028 m2->_opnds[0] = op_dst; 6029 m2->_opnds[1] = op_dst; 6030 m2->_opnds[2] = op_src; 6031 m3->_opnds[0] = op_dst; 6032 m3->_opnds[1] = op_dst; 6033 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6034 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6035 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6036 nodes->push(m1); 6037 nodes->push(m2); 6038 nodes->push(m3); 6039 %} 6040 %} 6041 6042 // We have seen a safepoint between the hi and lo parts, and this node was handled 6043 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6044 // not a narrow oop. 6045 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6046 match(Set dst src); 6047 effect(DEF dst, USE src); 6048 ins_cost(DEFAULT_COST); 6049 6050 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6051 size(4); 6052 ins_encode %{ 6053 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant); 6054 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6055 %} 6056 ins_pipe(pipe_class_default); 6057 %} 6058 6059 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6060 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6061 match(Set dst src1); 6062 effect(TEMP src2); 6063 ins_cost(DEFAULT_COST); 6064 6065 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6066 size(4); 6067 ins_encode %{ 6068 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6069 %} 6070 ins_pipe(pipe_class_default); 6071 %} 6072 6073 // This needs a match rule so that build_oop_map knows this is 6074 // not a narrow oop. 6075 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6076 match(Set dst src1); 6077 effect(TEMP src2); 6078 ins_cost(DEFAULT_COST); 6079 6080 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6081 size(4); 6082 ins_encode %{ 6083 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src1$$constant); 6084 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6085 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6086 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6087 6088 __ relocate(rspec, 1); 6089 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6090 %} 6091 ins_pipe(pipe_class_default); 6092 %} 6093 6094 // Loading ConNKlass must be postalloc expanded so that edges between 6095 // the nodes are safe. They may not interfere with a safepoint. 6096 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6097 match(Set dst src); 6098 ins_cost(DEFAULT_COST*2); 6099 6100 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6101 postalloc_expand %{ 6102 // Load high bits into register. Sign extended. 6103 MachNode *m1 = new loadConNKlass_hiNode(); 6104 m1->add_req(NULL); 6105 m1->_opnds[0] = op_dst; 6106 m1->_opnds[1] = op_src; 6107 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6108 nodes->push(m1); 6109 6110 MachNode *m2 = m1; 6111 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) { 6112 // Value might be 1-extended. Mask out these bits. 6113 m2 = new loadConNKlass_maskNode(); 6114 m2->add_req(NULL, m1); 6115 m2->_opnds[0] = op_dst; 6116 m2->_opnds[1] = op_src; 6117 m2->_opnds[2] = op_dst; 6118 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6119 nodes->push(m2); 6120 } 6121 6122 MachNode *m3 = new loadConNKlass_loNode(); 6123 m3->add_req(NULL, m2); 6124 m3->_opnds[0] = op_dst; 6125 m3->_opnds[1] = op_src; 6126 m3->_opnds[2] = op_dst; 6127 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6128 nodes->push(m3); 6129 %} 6130 %} 6131 6132 // 0x1 is used in object initialization (initial object header). 6133 // No constant pool entries required. 6134 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6135 match(Set dst src); 6136 6137 format %{ "LI $dst, $src \t// ptr" %} 6138 size(4); 6139 ins_encode %{ 6140 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6141 %} 6142 ins_pipe(pipe_class_default); 6143 %} 6144 6145 // Expand node for constant pool load: small offset. 6146 // The match rule is needed to generate the correct bottom_type(), 6147 // however this node should never match. The use of predicate is not 6148 // possible since ADLC forbids predicates for chain rules. The higher 6149 // costs do not prevent matching in this case. For that reason the 6150 // operand immP_NM with predicate(false) is used. 6151 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6152 match(Set dst src); 6153 effect(TEMP toc); 6154 6155 ins_num_consts(1); 6156 6157 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6158 size(4); 6159 ins_encode( enc_load_long_constP(dst, src, toc) ); 6160 ins_pipe(pipe_class_memory); 6161 %} 6162 6163 // Expand node for constant pool load: large offset. 6164 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6165 effect(DEF dst, USE src, USE toc); 6166 predicate(false); 6167 6168 ins_num_consts(1); 6169 ins_field_const_toc_offset(int); 6170 6171 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6172 size(4); 6173 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6174 ins_pipe(pipe_class_default); 6175 %} 6176 6177 // Expand node for constant pool load: large offset. 6178 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6179 match(Set dst src); 6180 effect(TEMP base); 6181 6182 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6183 6184 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6185 size(4); 6186 ins_encode %{ 6187 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6188 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6189 %} 6190 ins_pipe(pipe_class_memory); 6191 %} 6192 6193 // Load pointer constant from constant table. Expand in case an 6194 // offset > 16 bit is needed. 6195 // Adlc adds toc node MachConstantTableBase. 6196 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6197 match(Set dst src); 6198 ins_cost(MEMORY_REF_COST); 6199 6200 // This rule does not use "expand" because then 6201 // the result type is not known to be an Oop. An ADLC 6202 // enhancement will be needed to make that work - not worth it! 6203 6204 // If this instruction rematerializes, it prolongs the live range 6205 // of the toc node, causing illegal graphs. 6206 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6207 ins_cannot_rematerialize(true); 6208 6209 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6210 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6211 %} 6212 6213 // Expand node for constant pool load: small offset. 6214 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6215 effect(DEF dst, USE src, USE toc); 6216 ins_cost(MEMORY_REF_COST); 6217 6218 ins_num_consts(1); 6219 6220 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6221 size(4); 6222 ins_encode %{ 6223 address float_address = __ float_constant($src$$constant); 6224 if (float_address == NULL) { 6225 ciEnv::current()->record_out_of_memory_failure(); 6226 return; 6227 } 6228 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6229 %} 6230 ins_pipe(pipe_class_memory); 6231 %} 6232 6233 // Expand node for constant pool load: large offset. 6234 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6235 effect(DEF dst, USE src, USE toc); 6236 ins_cost(MEMORY_REF_COST); 6237 6238 ins_num_consts(1); 6239 6240 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6241 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6242 "ADDIS $toc, $toc, -offset_hi"%} 6243 size(12); 6244 ins_encode %{ 6245 FloatRegister Rdst = $dst$$FloatRegister; 6246 Register Rtoc = $toc$$Register; 6247 address float_address = __ float_constant($src$$constant); 6248 if (float_address == NULL) { 6249 ciEnv::current()->record_out_of_memory_failure(); 6250 return; 6251 } 6252 int offset = __ offset_to_method_toc(float_address); 6253 int hi = (offset + (1<<15))>>16; 6254 int lo = offset - hi * (1<<16); 6255 6256 __ addis(Rtoc, Rtoc, hi); 6257 __ lfs(Rdst, lo, Rtoc); 6258 __ addis(Rtoc, Rtoc, -hi); 6259 %} 6260 ins_pipe(pipe_class_memory); 6261 %} 6262 6263 // Adlc adds toc node MachConstantTableBase. 6264 instruct loadConF_Ex(regF dst, immF src) %{ 6265 match(Set dst src); 6266 ins_cost(MEMORY_REF_COST); 6267 6268 // See loadConP. 6269 ins_cannot_rematerialize(true); 6270 6271 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6272 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6273 %} 6274 6275 // Expand node for constant pool load: small offset. 6276 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6277 effect(DEF dst, USE src, USE toc); 6278 ins_cost(MEMORY_REF_COST); 6279 6280 ins_num_consts(1); 6281 6282 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6283 size(4); 6284 ins_encode %{ 6285 address float_address = __ double_constant($src$$constant); 6286 if (float_address == NULL) { 6287 ciEnv::current()->record_out_of_memory_failure(); 6288 return; 6289 } 6290 int offset = __ offset_to_method_toc(float_address); 6291 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6292 %} 6293 ins_pipe(pipe_class_memory); 6294 %} 6295 6296 // Expand node for constant pool load: large offset. 6297 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6298 effect(DEF dst, USE src, USE toc); 6299 ins_cost(MEMORY_REF_COST); 6300 6301 ins_num_consts(1); 6302 6303 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6304 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6305 "ADDIS $toc, $toc, -offset_hi" %} 6306 size(12); 6307 ins_encode %{ 6308 FloatRegister Rdst = $dst$$FloatRegister; 6309 Register Rtoc = $toc$$Register; 6310 address float_address = __ double_constant($src$$constant); 6311 if (float_address == NULL) { 6312 ciEnv::current()->record_out_of_memory_failure(); 6313 return; 6314 } 6315 int offset = __ offset_to_method_toc(float_address); 6316 int hi = (offset + (1<<15))>>16; 6317 int lo = offset - hi * (1<<16); 6318 6319 __ addis(Rtoc, Rtoc, hi); 6320 __ lfd(Rdst, lo, Rtoc); 6321 __ addis(Rtoc, Rtoc, -hi); 6322 %} 6323 ins_pipe(pipe_class_memory); 6324 %} 6325 6326 // Adlc adds toc node MachConstantTableBase. 6327 instruct loadConD_Ex(regD dst, immD src) %{ 6328 match(Set dst src); 6329 ins_cost(MEMORY_REF_COST); 6330 6331 // See loadConP. 6332 ins_cannot_rematerialize(true); 6333 6334 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6335 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6336 %} 6337 6338 // Prefetch instructions. 6339 // Must be safe to execute with invalid address (cannot fault). 6340 6341 // Special prefetch versions which use the dcbz instruction. 6342 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6343 match(PrefetchAllocation (AddP mem src)); 6344 predicate(AllocatePrefetchStyle == 3); 6345 ins_cost(MEMORY_REF_COST); 6346 6347 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6348 size(4); 6349 ins_encode %{ 6350 __ dcbz($src$$Register, $mem$$base$$Register); 6351 %} 6352 ins_pipe(pipe_class_memory); 6353 %} 6354 6355 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6356 match(PrefetchAllocation mem); 6357 predicate(AllocatePrefetchStyle == 3); 6358 ins_cost(MEMORY_REF_COST); 6359 6360 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6361 size(4); 6362 ins_encode %{ 6363 __ dcbz($mem$$base$$Register); 6364 %} 6365 ins_pipe(pipe_class_memory); 6366 %} 6367 6368 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6369 match(PrefetchAllocation (AddP mem src)); 6370 predicate(AllocatePrefetchStyle != 3); 6371 ins_cost(MEMORY_REF_COST); 6372 6373 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6374 size(4); 6375 ins_encode %{ 6376 __ dcbtst($src$$Register, $mem$$base$$Register); 6377 %} 6378 ins_pipe(pipe_class_memory); 6379 %} 6380 6381 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6382 match(PrefetchAllocation mem); 6383 predicate(AllocatePrefetchStyle != 3); 6384 ins_cost(MEMORY_REF_COST); 6385 6386 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6387 size(4); 6388 ins_encode %{ 6389 __ dcbtst($mem$$base$$Register); 6390 %} 6391 ins_pipe(pipe_class_memory); 6392 %} 6393 6394 //----------Store Instructions------------------------------------------------- 6395 6396 // Store Byte 6397 instruct storeB(memory mem, iRegIsrc src) %{ 6398 match(Set mem (StoreB mem src)); 6399 ins_cost(MEMORY_REF_COST); 6400 6401 format %{ "STB $src, $mem \t// byte" %} 6402 size(4); 6403 ins_encode %{ 6404 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6405 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6406 %} 6407 ins_pipe(pipe_class_memory); 6408 %} 6409 6410 // Store Char/Short 6411 instruct storeC(memory mem, iRegIsrc src) %{ 6412 match(Set mem (StoreC mem src)); 6413 ins_cost(MEMORY_REF_COST); 6414 6415 format %{ "STH $src, $mem \t// short" %} 6416 size(4); 6417 ins_encode %{ 6418 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6419 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6420 %} 6421 ins_pipe(pipe_class_memory); 6422 %} 6423 6424 // Store Integer 6425 instruct storeI(memory mem, iRegIsrc src) %{ 6426 match(Set mem (StoreI mem src)); 6427 ins_cost(MEMORY_REF_COST); 6428 6429 format %{ "STW $src, $mem" %} 6430 size(4); 6431 ins_encode( enc_stw(src, mem) ); 6432 ins_pipe(pipe_class_memory); 6433 %} 6434 6435 // ConvL2I + StoreI. 6436 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6437 match(Set mem (StoreI mem (ConvL2I src))); 6438 ins_cost(MEMORY_REF_COST); 6439 6440 format %{ "STW l2i($src), $mem" %} 6441 size(4); 6442 ins_encode( enc_stw(src, mem) ); 6443 ins_pipe(pipe_class_memory); 6444 %} 6445 6446 // Store Long 6447 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6448 match(Set mem (StoreL mem src)); 6449 ins_cost(MEMORY_REF_COST); 6450 6451 format %{ "STD $src, $mem \t// long" %} 6452 size(4); 6453 ins_encode( enc_std(src, mem) ); 6454 ins_pipe(pipe_class_memory); 6455 %} 6456 6457 // Store super word nodes. 6458 6459 // Store Aligned Packed Byte long register to memory 6460 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6461 predicate(n->as_StoreVector()->memory_size() == 8); 6462 match(Set mem (StoreVector mem src)); 6463 ins_cost(MEMORY_REF_COST); 6464 6465 format %{ "STD $mem, $src \t// packed8B" %} 6466 size(4); 6467 ins_encode( enc_std(src, mem) ); 6468 ins_pipe(pipe_class_memory); 6469 %} 6470 6471 // Store Packed Byte long register to memory 6472 instruct storeV16(indirect mem, vecX src) %{ 6473 predicate(n->as_StoreVector()->memory_size() == 16); 6474 match(Set mem (StoreVector mem src)); 6475 ins_cost(MEMORY_REF_COST); 6476 6477 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6478 size(4); 6479 ins_encode %{ 6480 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6481 %} 6482 ins_pipe(pipe_class_default); 6483 %} 6484 6485 // Reinterpret: only one vector size used: either L or X 6486 instruct reinterpretL(iRegLdst dst) %{ 6487 match(Set dst (VectorReinterpret dst)); 6488 ins_cost(0); 6489 format %{ "reinterpret $dst" %} 6490 ins_encode( /*empty*/ ); 6491 ins_pipe(pipe_class_empty); 6492 %} 6493 6494 instruct reinterpretX(vecX dst) %{ 6495 match(Set dst (VectorReinterpret dst)); 6496 ins_cost(0); 6497 format %{ "reinterpret $dst" %} 6498 ins_encode( /*empty*/ ); 6499 ins_pipe(pipe_class_empty); 6500 %} 6501 6502 // Store Compressed Oop 6503 instruct storeN(memory dst, iRegN_P2N src) %{ 6504 match(Set dst (StoreN dst src)); 6505 ins_cost(MEMORY_REF_COST); 6506 6507 format %{ "STW $src, $dst \t// compressed oop" %} 6508 size(4); 6509 ins_encode( enc_stw(src, dst) ); 6510 ins_pipe(pipe_class_memory); 6511 %} 6512 6513 // Store Compressed KLass 6514 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6515 match(Set dst (StoreNKlass dst src)); 6516 ins_cost(MEMORY_REF_COST); 6517 6518 format %{ "STW $src, $dst \t// compressed klass" %} 6519 size(4); 6520 ins_encode( enc_stw(src, dst) ); 6521 ins_pipe(pipe_class_memory); 6522 %} 6523 6524 // Store Pointer 6525 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6526 match(Set dst (StoreP dst src)); 6527 ins_cost(MEMORY_REF_COST); 6528 6529 format %{ "STD $src, $dst \t// ptr" %} 6530 size(4); 6531 ins_encode( enc_std(src, dst) ); 6532 ins_pipe(pipe_class_memory); 6533 %} 6534 6535 // Store Float 6536 instruct storeF(memory mem, regF src) %{ 6537 match(Set mem (StoreF mem src)); 6538 ins_cost(MEMORY_REF_COST); 6539 6540 format %{ "STFS $src, $mem" %} 6541 size(4); 6542 ins_encode( enc_stfs(src, mem) ); 6543 ins_pipe(pipe_class_memory); 6544 %} 6545 6546 // Store Double 6547 instruct storeD(memory mem, regD src) %{ 6548 match(Set mem (StoreD mem src)); 6549 ins_cost(MEMORY_REF_COST); 6550 6551 format %{ "STFD $src, $mem" %} 6552 size(4); 6553 ins_encode( enc_stfd(src, mem) ); 6554 ins_pipe(pipe_class_memory); 6555 %} 6556 6557 //----------Store Instructions With Zeros-------------------------------------- 6558 6559 instruct storeCM(memory mem, immI_0 zero) %{ 6560 match(Set mem (StoreCM mem zero)); 6561 ins_cost(MEMORY_REF_COST); 6562 6563 format %{ "STB #0, $mem \t// CMS card-mark byte store" %} 6564 size(8); 6565 ins_encode %{ 6566 __ li(R0, 0); 6567 // No release barrier: Oops are allowed to get visible after marking. 6568 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6569 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6570 %} 6571 ins_pipe(pipe_class_memory); 6572 %} 6573 6574 // Convert oop pointer into compressed form. 6575 6576 // Nodes for postalloc expand. 6577 6578 // Shift node for expand. 6579 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6580 // The match rule is needed to make it a 'MachTypeNode'! 6581 match(Set dst (EncodeP src)); 6582 predicate(false); 6583 6584 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6585 size(4); 6586 ins_encode %{ 6587 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 6588 %} 6589 ins_pipe(pipe_class_default); 6590 %} 6591 6592 // Add node for expand. 6593 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6594 // The match rule is needed to make it a 'MachTypeNode'! 6595 match(Set dst (EncodeP src)); 6596 predicate(false); 6597 6598 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6599 ins_encode %{ 6600 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 6601 %} 6602 ins_pipe(pipe_class_default); 6603 %} 6604 6605 // Conditional sub base. 6606 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6607 // The match rule is needed to make it a 'MachTypeNode'! 6608 match(Set dst (EncodeP (Binary crx src1))); 6609 predicate(false); 6610 6611 format %{ "BEQ $crx, done\n\t" 6612 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6613 "done:" %} 6614 ins_encode %{ 6615 Label done; 6616 __ beq($crx$$CondRegister, done); 6617 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0); 6618 __ bind(done); 6619 %} 6620 ins_pipe(pipe_class_default); 6621 %} 6622 6623 // Power 7 can use isel instruction 6624 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6625 // The match rule is needed to make it a 'MachTypeNode'! 6626 match(Set dst (EncodeP (Binary crx src1))); 6627 predicate(false); 6628 6629 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6630 size(4); 6631 ins_encode %{ 6632 // This is a Power7 instruction for which no machine description exists. 6633 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6634 %} 6635 ins_pipe(pipe_class_default); 6636 %} 6637 6638 // Disjoint narrow oop base. 6639 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6640 match(Set dst (EncodeP src)); 6641 predicate(CompressedOops::base_disjoint()); 6642 6643 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6644 size(4); 6645 ins_encode %{ 6646 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32); 6647 %} 6648 ins_pipe(pipe_class_default); 6649 %} 6650 6651 // shift != 0, base != 0 6652 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6653 match(Set dst (EncodeP src)); 6654 effect(TEMP crx); 6655 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6656 CompressedOops::shift() != 0 && 6657 CompressedOops::base_overlaps()); 6658 6659 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 6660 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 6661 %} 6662 6663 // shift != 0, base != 0 6664 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 6665 match(Set dst (EncodeP src)); 6666 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 6667 CompressedOops::shift() != 0 && 6668 CompressedOops::base_overlaps()); 6669 6670 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 6671 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 6672 %} 6673 6674 // shift != 0, base == 0 6675 // TODO: This is the same as encodeP_shift. Merge! 6676 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 6677 match(Set dst (EncodeP src)); 6678 predicate(CompressedOops::shift() != 0 && 6679 CompressedOops::base() ==0); 6680 6681 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 6682 size(4); 6683 ins_encode %{ 6684 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 6685 %} 6686 ins_pipe(pipe_class_default); 6687 %} 6688 6689 // Compressed OOPs with narrow_oop_shift == 0. 6690 // shift == 0, base == 0 6691 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 6692 match(Set dst (EncodeP src)); 6693 predicate(CompressedOops::shift() == 0); 6694 6695 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 6696 // variable size, 0 or 4. 6697 ins_encode %{ 6698 __ mr_if_needed($dst$$Register, $src$$Register); 6699 %} 6700 ins_pipe(pipe_class_default); 6701 %} 6702 6703 // Decode nodes. 6704 6705 // Shift node for expand. 6706 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 6707 // The match rule is needed to make it a 'MachTypeNode'! 6708 match(Set dst (DecodeN src)); 6709 predicate(false); 6710 6711 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 6712 size(4); 6713 ins_encode %{ 6714 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 6715 %} 6716 ins_pipe(pipe_class_default); 6717 %} 6718 6719 // Add node for expand. 6720 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 6721 // The match rule is needed to make it a 'MachTypeNode'! 6722 match(Set dst (DecodeN src)); 6723 predicate(false); 6724 6725 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 6726 ins_encode %{ 6727 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 6728 %} 6729 ins_pipe(pipe_class_default); 6730 %} 6731 6732 // conditianal add base for expand 6733 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 6734 // The match rule is needed to make it a 'MachTypeNode'! 6735 // NOTICE that the rule is nonsense - we just have to make sure that: 6736 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6737 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6738 match(Set dst (DecodeN (Binary crx src))); 6739 predicate(false); 6740 6741 format %{ "BEQ $crx, done\n\t" 6742 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 6743 "done:" %} 6744 ins_encode %{ 6745 Label done; 6746 __ beq($crx$$CondRegister, done); 6747 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 6748 __ bind(done); 6749 %} 6750 ins_pipe(pipe_class_default); 6751 %} 6752 6753 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6754 // The match rule is needed to make it a 'MachTypeNode'! 6755 // NOTICE that the rule is nonsense - we just have to make sure that: 6756 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6757 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6758 match(Set dst (DecodeN (Binary crx src1))); 6759 predicate(false); 6760 6761 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 6762 size(4); 6763 ins_encode %{ 6764 // This is a Power7 instruction for which no machine description exists. 6765 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6766 %} 6767 ins_pipe(pipe_class_default); 6768 %} 6769 6770 // shift != 0, base != 0 6771 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6772 match(Set dst (DecodeN src)); 6773 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6774 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6775 CompressedOops::shift() != 0 && 6776 CompressedOops::base() != 0); 6777 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 6778 effect(TEMP crx); 6779 6780 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 6781 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 6782 %} 6783 6784 // shift != 0, base == 0 6785 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 6786 match(Set dst (DecodeN src)); 6787 predicate(CompressedOops::shift() != 0 && 6788 CompressedOops::base() == 0); 6789 6790 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 6791 size(4); 6792 ins_encode %{ 6793 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 6794 %} 6795 ins_pipe(pipe_class_default); 6796 %} 6797 6798 // Optimize DecodeN for disjoint base. 6799 // Shift narrow oop and or it into register that already contains the heap base. 6800 // Base == dst must hold, and is assured by construction in postaloc_expand. 6801 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 6802 match(Set dst (DecodeN src)); 6803 effect(TEMP base); 6804 predicate(false); 6805 6806 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 6807 size(4); 6808 ins_encode %{ 6809 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift()); 6810 %} 6811 ins_pipe(pipe_class_default); 6812 %} 6813 6814 // Optimize DecodeN for disjoint base. 6815 // This node requires only one cycle on the critical path. 6816 // We must postalloc_expand as we can not express use_def effects where 6817 // the used register is L and the def'ed register P. 6818 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 6819 match(Set dst (DecodeN src)); 6820 effect(TEMP_DEF dst); 6821 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6822 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6823 CompressedOops::base_disjoint()); 6824 ins_cost(DEFAULT_COST); 6825 6826 format %{ "MOV $dst, heapbase \t\n" 6827 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 6828 postalloc_expand %{ 6829 loadBaseNode *n1 = new loadBaseNode(); 6830 n1->add_req(NULL); 6831 n1->_opnds[0] = op_dst; 6832 6833 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6834 n2->add_req(n_region, n_src, n1); 6835 n2->_opnds[0] = op_dst; 6836 n2->_opnds[1] = op_src; 6837 n2->_opnds[2] = op_dst; 6838 n2->_bottom_type = _bottom_type; 6839 6840 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 6841 ra_->set_oop(n2, true); 6842 6843 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6844 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6845 6846 nodes->push(n1); 6847 nodes->push(n2); 6848 %} 6849 %} 6850 6851 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6852 match(Set dst (DecodeN src)); 6853 effect(TEMP_DEF dst, TEMP crx); 6854 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6855 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6856 CompressedOops::base_disjoint() && VM_Version::has_isel()); 6857 ins_cost(3 * DEFAULT_COST); 6858 6859 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 6860 postalloc_expand %{ 6861 loadBaseNode *n1 = new loadBaseNode(); 6862 n1->add_req(NULL); 6863 n1->_opnds[0] = op_dst; 6864 6865 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 6866 n_compare->add_req(n_region, n_src); 6867 n_compare->_opnds[0] = op_crx; 6868 n_compare->_opnds[1] = op_src; 6869 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 6870 6871 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6872 n2->add_req(n_region, n_src, n1); 6873 n2->_opnds[0] = op_dst; 6874 n2->_opnds[1] = op_src; 6875 n2->_opnds[2] = op_dst; 6876 n2->_bottom_type = _bottom_type; 6877 6878 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 6879 n_cond_set->add_req(n_region, n_compare, n2); 6880 n_cond_set->_opnds[0] = op_dst; 6881 n_cond_set->_opnds[1] = op_crx; 6882 n_cond_set->_opnds[2] = op_dst; 6883 n_cond_set->_bottom_type = _bottom_type; 6884 6885 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 6886 ra_->set_oop(n_cond_set, true); 6887 6888 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6889 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 6890 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6891 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6892 6893 nodes->push(n1); 6894 nodes->push(n_compare); 6895 nodes->push(n2); 6896 nodes->push(n_cond_set); 6897 %} 6898 %} 6899 6900 // src != 0, shift != 0, base != 0 6901 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 6902 match(Set dst (DecodeN src)); 6903 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6904 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6905 CompressedOops::shift() != 0 && 6906 CompressedOops::base() != 0); 6907 ins_cost(2 * DEFAULT_COST); 6908 6909 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 6910 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 6911 %} 6912 6913 // Compressed OOPs with narrow_oop_shift == 0. 6914 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 6915 match(Set dst (DecodeN src)); 6916 predicate(CompressedOops::shift() == 0); 6917 ins_cost(DEFAULT_COST); 6918 6919 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 6920 // variable size, 0 or 4. 6921 ins_encode %{ 6922 __ mr_if_needed($dst$$Register, $src$$Register); 6923 %} 6924 ins_pipe(pipe_class_default); 6925 %} 6926 6927 // Convert compressed oop into int for vectors alignment masking. 6928 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 6929 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6930 predicate(CompressedOops::shift() == 0); 6931 ins_cost(DEFAULT_COST); 6932 6933 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 6934 // variable size, 0 or 4. 6935 ins_encode %{ 6936 __ mr_if_needed($dst$$Register, $src$$Register); 6937 %} 6938 ins_pipe(pipe_class_default); 6939 %} 6940 6941 // Convert klass pointer into compressed form. 6942 6943 // Nodes for postalloc expand. 6944 6945 // Shift node for expand. 6946 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 6947 // The match rule is needed to make it a 'MachTypeNode'! 6948 match(Set dst (EncodePKlass src)); 6949 predicate(false); 6950 6951 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6952 size(4); 6953 ins_encode %{ 6954 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 6955 %} 6956 ins_pipe(pipe_class_default); 6957 %} 6958 6959 // Add node for expand. 6960 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6961 // The match rule is needed to make it a 'MachTypeNode'! 6962 match(Set dst (EncodePKlass (Binary base src))); 6963 predicate(false); 6964 6965 format %{ "SUB $dst, $base, $src \t// encode" %} 6966 size(4); 6967 ins_encode %{ 6968 __ subf($dst$$Register, $base$$Register, $src$$Register); 6969 %} 6970 ins_pipe(pipe_class_default); 6971 %} 6972 6973 // Disjoint narrow oop base. 6974 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6975 match(Set dst (EncodePKlass src)); 6976 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/); 6977 6978 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6979 size(4); 6980 ins_encode %{ 6981 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32); 6982 %} 6983 ins_pipe(pipe_class_default); 6984 %} 6985 6986 // shift != 0, base != 0 6987 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 6988 match(Set dst (EncodePKlass (Binary base src))); 6989 predicate(false); 6990 6991 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6992 postalloc_expand %{ 6993 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 6994 n1->add_req(n_region, n_base, n_src); 6995 n1->_opnds[0] = op_dst; 6996 n1->_opnds[1] = op_base; 6997 n1->_opnds[2] = op_src; 6998 n1->_bottom_type = _bottom_type; 6999 7000 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7001 n2->add_req(n_region, n1); 7002 n2->_opnds[0] = op_dst; 7003 n2->_opnds[1] = op_dst; 7004 n2->_bottom_type = _bottom_type; 7005 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7006 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7007 7008 nodes->push(n1); 7009 nodes->push(n2); 7010 %} 7011 %} 7012 7013 // shift != 0, base != 0 7014 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7015 match(Set dst (EncodePKlass src)); 7016 //predicate(CompressedKlassPointers::shift() != 0 && 7017 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/); 7018 7019 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7020 ins_cost(DEFAULT_COST*2); // Don't count constant. 7021 expand %{ 7022 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %} 7023 iRegLdst base; 7024 loadConL_Ex(base, baseImm); 7025 encodePKlass_not_null_Ex(dst, base, src); 7026 %} 7027 %} 7028 7029 // Decode nodes. 7030 7031 // Shift node for expand. 7032 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7033 // The match rule is needed to make it a 'MachTypeNode'! 7034 match(Set dst (DecodeNKlass src)); 7035 predicate(false); 7036 7037 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7038 size(4); 7039 ins_encode %{ 7040 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 7041 %} 7042 ins_pipe(pipe_class_default); 7043 %} 7044 7045 // Add node for expand. 7046 7047 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7048 // The match rule is needed to make it a 'MachTypeNode'! 7049 match(Set dst (DecodeNKlass (Binary base src))); 7050 predicate(false); 7051 7052 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7053 size(4); 7054 ins_encode %{ 7055 __ add($dst$$Register, $base$$Register, $src$$Register); 7056 %} 7057 ins_pipe(pipe_class_default); 7058 %} 7059 7060 // src != 0, shift != 0, base != 0 7061 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7062 match(Set dst (DecodeNKlass (Binary base src))); 7063 //effect(kill src); // We need a register for the immediate result after shifting. 7064 predicate(false); 7065 7066 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7067 postalloc_expand %{ 7068 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7069 n1->add_req(n_region, n_base, n_src); 7070 n1->_opnds[0] = op_dst; 7071 n1->_opnds[1] = op_base; 7072 n1->_opnds[2] = op_src; 7073 n1->_bottom_type = _bottom_type; 7074 7075 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7076 n2->add_req(n_region, n1); 7077 n2->_opnds[0] = op_dst; 7078 n2->_opnds[1] = op_dst; 7079 n2->_bottom_type = _bottom_type; 7080 7081 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7082 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7083 7084 nodes->push(n1); 7085 nodes->push(n2); 7086 %} 7087 %} 7088 7089 // src != 0, shift != 0, base != 0 7090 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7091 match(Set dst (DecodeNKlass src)); 7092 // predicate(CompressedKlassPointers::shift() != 0 && 7093 // CompressedKlassPointers::base() != 0); 7094 7095 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7096 7097 ins_cost(DEFAULT_COST*2); // Don't count constant. 7098 expand %{ 7099 // We add first, then we shift. Like this, we can get along with one register less. 7100 // But we have to load the base pre-shifted. 7101 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %} 7102 iRegLdst base; 7103 loadConL_Ex(base, baseImm); 7104 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7105 %} 7106 %} 7107 7108 //----------MemBar Instructions----------------------------------------------- 7109 // Memory barrier flavors 7110 7111 instruct membar_acquire() %{ 7112 match(LoadFence); 7113 ins_cost(4*MEMORY_REF_COST); 7114 7115 format %{ "MEMBAR-acquire" %} 7116 size(4); 7117 ins_encode %{ 7118 __ acquire(); 7119 %} 7120 ins_pipe(pipe_class_default); 7121 %} 7122 7123 instruct unnecessary_membar_acquire() %{ 7124 match(MemBarAcquire); 7125 ins_cost(0); 7126 7127 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7128 size(0); 7129 ins_encode( /*empty*/ ); 7130 ins_pipe(pipe_class_default); 7131 %} 7132 7133 instruct membar_acquire_lock() %{ 7134 match(MemBarAcquireLock); 7135 ins_cost(0); 7136 7137 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7138 size(0); 7139 ins_encode( /*empty*/ ); 7140 ins_pipe(pipe_class_default); 7141 %} 7142 7143 instruct membar_release() %{ 7144 match(MemBarRelease); 7145 match(StoreFence); 7146 ins_cost(4*MEMORY_REF_COST); 7147 7148 format %{ "MEMBAR-release" %} 7149 size(4); 7150 ins_encode %{ 7151 __ release(); 7152 %} 7153 ins_pipe(pipe_class_default); 7154 %} 7155 7156 instruct membar_storestore() %{ 7157 match(MemBarStoreStore); 7158 match(StoreStoreFence); 7159 ins_cost(4*MEMORY_REF_COST); 7160 7161 format %{ "MEMBAR-store-store" %} 7162 size(4); 7163 ins_encode %{ 7164 __ membar(Assembler::StoreStore); 7165 %} 7166 ins_pipe(pipe_class_default); 7167 %} 7168 7169 instruct membar_release_lock() %{ 7170 match(MemBarReleaseLock); 7171 ins_cost(0); 7172 7173 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7174 size(0); 7175 ins_encode( /*empty*/ ); 7176 ins_pipe(pipe_class_default); 7177 %} 7178 7179 instruct membar_volatile() %{ 7180 match(MemBarVolatile); 7181 ins_cost(4*MEMORY_REF_COST); 7182 7183 format %{ "MEMBAR-volatile" %} 7184 size(4); 7185 ins_encode %{ 7186 __ fence(); 7187 %} 7188 ins_pipe(pipe_class_default); 7189 %} 7190 7191 // This optimization is wrong on PPC. The following pattern is not supported: 7192 // MemBarVolatile 7193 // ^ ^ 7194 // | | 7195 // CtrlProj MemProj 7196 // ^ ^ 7197 // | | 7198 // | Load 7199 // | 7200 // MemBarVolatile 7201 // 7202 // The first MemBarVolatile could get optimized out! According to 7203 // Vladimir, this pattern can not occur on Oracle platforms. 7204 // However, it does occur on PPC64 (because of membars in 7205 // inline_unsafe_load_store). 7206 // 7207 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7208 // Don't forget to look at the implementation of post_store_load_barrier again, 7209 // we did other fixes in that method. 7210 //instruct unnecessary_membar_volatile() %{ 7211 // match(MemBarVolatile); 7212 // predicate(Matcher::post_store_load_barrier(n)); 7213 // ins_cost(0); 7214 // 7215 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7216 // size(0); 7217 // ins_encode( /*empty*/ ); 7218 // ins_pipe(pipe_class_default); 7219 //%} 7220 7221 instruct membar_CPUOrder() %{ 7222 match(MemBarCPUOrder); 7223 ins_cost(0); 7224 7225 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7226 size(0); 7227 ins_encode( /*empty*/ ); 7228 ins_pipe(pipe_class_default); 7229 %} 7230 7231 //----------Conditional Move--------------------------------------------------- 7232 7233 // Cmove using isel. 7234 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7235 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7236 predicate(VM_Version::has_isel()); 7237 ins_cost(DEFAULT_COST); 7238 7239 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7240 size(4); 7241 ins_encode %{ 7242 // This is a Power7 instruction for which no machine description 7243 // exists. Anyways, the scheduler should be off on Power7. 7244 int cc = $cmp$$cmpcode; 7245 __ isel($dst$$Register, $crx$$CondRegister, 7246 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7247 %} 7248 ins_pipe(pipe_class_default); 7249 %} 7250 7251 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7252 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7253 predicate(!VM_Version::has_isel()); 7254 ins_cost(DEFAULT_COST+BRANCH_COST); 7255 7256 ins_variable_size_depending_on_alignment(true); 7257 7258 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7259 // Worst case is branch + move + stop, no stop without scheduler 7260 size(8); 7261 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7262 ins_pipe(pipe_class_default); 7263 %} 7264 7265 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7266 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7267 ins_cost(DEFAULT_COST+BRANCH_COST); 7268 7269 ins_variable_size_depending_on_alignment(true); 7270 7271 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7272 // Worst case is branch + move + stop, no stop without scheduler 7273 size(8); 7274 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7275 ins_pipe(pipe_class_default); 7276 %} 7277 7278 // Cmove using isel. 7279 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7280 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7281 predicate(VM_Version::has_isel()); 7282 ins_cost(DEFAULT_COST); 7283 7284 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7285 size(4); 7286 ins_encode %{ 7287 // This is a Power7 instruction for which no machine description 7288 // exists. Anyways, the scheduler should be off on Power7. 7289 int cc = $cmp$$cmpcode; 7290 __ isel($dst$$Register, $crx$$CondRegister, 7291 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7292 %} 7293 ins_pipe(pipe_class_default); 7294 %} 7295 7296 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7297 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7298 predicate(!VM_Version::has_isel()); 7299 ins_cost(DEFAULT_COST+BRANCH_COST); 7300 7301 ins_variable_size_depending_on_alignment(true); 7302 7303 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7304 // Worst case is branch + move + stop, no stop without scheduler. 7305 size(8); 7306 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7307 ins_pipe(pipe_class_default); 7308 %} 7309 7310 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7311 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7312 ins_cost(DEFAULT_COST+BRANCH_COST); 7313 7314 ins_variable_size_depending_on_alignment(true); 7315 7316 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7317 // Worst case is branch + move + stop, no stop without scheduler. 7318 size(8); 7319 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7320 ins_pipe(pipe_class_default); 7321 %} 7322 7323 // Cmove using isel. 7324 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7325 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7326 predicate(VM_Version::has_isel()); 7327 ins_cost(DEFAULT_COST); 7328 7329 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7330 size(4); 7331 ins_encode %{ 7332 // This is a Power7 instruction for which no machine description 7333 // exists. Anyways, the scheduler should be off on Power7. 7334 int cc = $cmp$$cmpcode; 7335 __ isel($dst$$Register, $crx$$CondRegister, 7336 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7337 %} 7338 ins_pipe(pipe_class_default); 7339 %} 7340 7341 // Conditional move for RegN. Only cmov(reg, reg). 7342 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7343 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7344 predicate(!VM_Version::has_isel()); 7345 ins_cost(DEFAULT_COST+BRANCH_COST); 7346 7347 ins_variable_size_depending_on_alignment(true); 7348 7349 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7350 // Worst case is branch + move + stop, no stop without scheduler. 7351 size(8); 7352 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7353 ins_pipe(pipe_class_default); 7354 %} 7355 7356 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7357 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7358 ins_cost(DEFAULT_COST+BRANCH_COST); 7359 7360 ins_variable_size_depending_on_alignment(true); 7361 7362 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7363 // Worst case is branch + move + stop, no stop without scheduler. 7364 size(8); 7365 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7366 ins_pipe(pipe_class_default); 7367 %} 7368 7369 // Cmove using isel. 7370 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7371 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7372 predicate(VM_Version::has_isel()); 7373 ins_cost(DEFAULT_COST); 7374 7375 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7376 size(4); 7377 ins_encode %{ 7378 // This is a Power7 instruction for which no machine description 7379 // exists. Anyways, the scheduler should be off on Power7. 7380 int cc = $cmp$$cmpcode; 7381 __ isel($dst$$Register, $crx$$CondRegister, 7382 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7383 %} 7384 ins_pipe(pipe_class_default); 7385 %} 7386 7387 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7388 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7389 predicate(!VM_Version::has_isel()); 7390 ins_cost(DEFAULT_COST+BRANCH_COST); 7391 7392 ins_variable_size_depending_on_alignment(true); 7393 7394 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7395 // Worst case is branch + move + stop, no stop without scheduler. 7396 size(8); 7397 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7398 ins_pipe(pipe_class_default); 7399 %} 7400 7401 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7402 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7403 ins_cost(DEFAULT_COST+BRANCH_COST); 7404 7405 ins_variable_size_depending_on_alignment(true); 7406 7407 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7408 // Worst case is branch + move + stop, no stop without scheduler. 7409 size(8); 7410 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7411 ins_pipe(pipe_class_default); 7412 %} 7413 7414 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7415 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7416 ins_cost(DEFAULT_COST+BRANCH_COST); 7417 7418 ins_variable_size_depending_on_alignment(true); 7419 7420 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7421 // Worst case is branch + move + stop, no stop without scheduler. 7422 size(8); 7423 ins_encode %{ 7424 Label done; 7425 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7426 // Branch if not (cmp crx). 7427 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7428 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7429 __ bind(done); 7430 %} 7431 ins_pipe(pipe_class_default); 7432 %} 7433 7434 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7435 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7436 ins_cost(DEFAULT_COST+BRANCH_COST); 7437 7438 ins_variable_size_depending_on_alignment(true); 7439 7440 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7441 // Worst case is branch + move + stop, no stop without scheduler. 7442 size(8); 7443 ins_encode %{ 7444 Label done; 7445 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7446 // Branch if not (cmp crx). 7447 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7448 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7449 __ bind(done); 7450 %} 7451 ins_pipe(pipe_class_default); 7452 %} 7453 7454 //----------Conditional_store-------------------------------------------------- 7455 // Conditional-store of the updated heap-top. 7456 // Used during allocation of the shared heap. 7457 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7458 7459 // As compareAndSwapL, but return flag register instead of boolean value in 7460 // int register. 7461 // Used by sun/misc/AtomicLongCSImpl.java. 7462 // Mem_ptr must be a memory operand, else this node does not get 7463 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7464 // can be rematerialized which leads to errors. 7465 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7466 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7467 effect(TEMP cr0); 7468 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7469 ins_encode %{ 7470 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7471 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7472 noreg, NULL, true); 7473 %} 7474 ins_pipe(pipe_class_default); 7475 %} 7476 7477 // As compareAndSwapP, but return flag register instead of boolean value in 7478 // int register. 7479 // This instruction is matched if UseTLAB is off. 7480 // Mem_ptr must be a memory operand, else this node does not get 7481 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7482 // can be rematerialized which leads to errors. 7483 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7484 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7485 ins_cost(2*MEMORY_REF_COST); 7486 predicate(n->as_LoadStore()->barrier_data() == 0); 7487 7488 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7489 ins_encode %{ 7490 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7491 %} 7492 ins_pipe(pipe_class_memory); 7493 %} 7494 7495 // Implement LoadPLocked. Must be ordered against changes of the memory location 7496 // by storePConditional. 7497 // Don't know whether this is ever used. 7498 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7499 match(Set dst (LoadPLocked mem)); 7500 ins_cost(2*MEMORY_REF_COST); 7501 7502 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7503 size(4); 7504 ins_encode %{ 7505 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7506 %} 7507 ins_pipe(pipe_class_memory); 7508 %} 7509 7510 //----------Compare-And-Swap--------------------------------------------------- 7511 7512 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7513 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7514 // matched. 7515 7516 // Strong versions: 7517 7518 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7519 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7520 predicate(VM_Version::has_lqarx()); 7521 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7522 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7523 ins_encode %{ 7524 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7525 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 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 compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7538 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7539 predicate(!VM_Version::has_lqarx()); 7540 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7541 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7542 ins_encode %{ 7543 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7544 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$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 compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7557 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7558 predicate(VM_Version::has_lqarx()); 7559 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7560 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7561 ins_encode %{ 7562 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7563 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7564 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7565 $res$$Register, 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 compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7576 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7577 predicate(!VM_Version::has_lqarx()); 7578 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7579 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7580 ins_encode %{ 7581 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7582 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7583 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7584 $res$$Register, 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 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7595 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7596 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7597 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7598 ins_encode %{ 7599 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7600 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7601 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7602 $res$$Register, true); 7603 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7604 __ isync(); 7605 } else { 7606 __ sync(); 7607 } 7608 %} 7609 ins_pipe(pipe_class_default); 7610 %} 7611 7612 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7613 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7614 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7615 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7616 ins_encode %{ 7617 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7618 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7619 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7620 $res$$Register, true); 7621 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7622 __ isync(); 7623 } else { 7624 __ sync(); 7625 } 7626 %} 7627 ins_pipe(pipe_class_default); 7628 %} 7629 7630 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7631 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 7632 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7633 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7634 ins_encode %{ 7635 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7636 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7637 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7638 $res$$Register, NULL, true); 7639 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7640 __ isync(); 7641 } else { 7642 __ sync(); 7643 } 7644 %} 7645 ins_pipe(pipe_class_default); 7646 %} 7647 7648 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7649 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 7650 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7651 predicate(n->as_LoadStore()->barrier_data() == 0); 7652 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7653 ins_encode %{ 7654 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7655 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7656 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7657 $res$$Register, NULL, true); 7658 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7659 __ isync(); 7660 } else { 7661 __ sync(); 7662 } 7663 %} 7664 ins_pipe(pipe_class_default); 7665 %} 7666 7667 // Weak versions: 7668 7669 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7670 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7671 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7672 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7673 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7674 ins_encode %{ 7675 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7676 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7677 MacroAssembler::MemBarNone, 7678 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7679 %} 7680 ins_pipe(pipe_class_default); 7681 %} 7682 7683 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7684 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7685 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7686 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7687 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7688 ins_encode %{ 7689 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7690 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7691 MacroAssembler::MemBarNone, 7692 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7693 %} 7694 ins_pipe(pipe_class_default); 7695 %} 7696 7697 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7698 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7699 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7700 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7701 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7702 ins_encode %{ 7703 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7704 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7705 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7706 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7707 %} 7708 ins_pipe(pipe_class_default); 7709 %} 7710 7711 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7712 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7713 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7714 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7715 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7716 ins_encode %{ 7717 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7718 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7719 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7720 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7721 %} 7722 ins_pipe(pipe_class_default); 7723 %} 7724 7725 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7726 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7727 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7728 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7729 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7730 ins_encode %{ 7731 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7732 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7733 MacroAssembler::MemBarNone, 7734 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7735 %} 7736 ins_pipe(pipe_class_default); 7737 %} 7738 7739 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7740 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7741 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7742 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7743 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7744 ins_encode %{ 7745 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7746 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7747 MacroAssembler::MemBarNone, 7748 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7749 %} 7750 ins_pipe(pipe_class_default); 7751 %} 7752 7753 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7754 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7755 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7756 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7757 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7758 ins_encode %{ 7759 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7760 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7761 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7762 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7763 %} 7764 ins_pipe(pipe_class_default); 7765 %} 7766 7767 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7768 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7769 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7770 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7771 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7772 ins_encode %{ 7773 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7774 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7775 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7776 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7777 %} 7778 ins_pipe(pipe_class_default); 7779 %} 7780 7781 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7782 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7783 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7784 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7785 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7786 ins_encode %{ 7787 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7788 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7789 MacroAssembler::MemBarNone, 7790 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7791 %} 7792 ins_pipe(pipe_class_default); 7793 %} 7794 7795 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7796 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7797 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7798 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7799 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7800 ins_encode %{ 7801 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7802 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7803 // value is never passed to caller. 7804 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7805 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7806 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7807 %} 7808 ins_pipe(pipe_class_default); 7809 %} 7810 7811 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7812 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7813 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7814 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7815 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7816 ins_encode %{ 7817 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7818 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7819 MacroAssembler::MemBarNone, 7820 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7821 %} 7822 ins_pipe(pipe_class_default); 7823 %} 7824 7825 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7826 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7827 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7828 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7829 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7830 ins_encode %{ 7831 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7832 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7833 // value is never passed to caller. 7834 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7835 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7836 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7837 %} 7838 ins_pipe(pipe_class_default); 7839 %} 7840 7841 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7842 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7843 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7844 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7845 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7846 ins_encode %{ 7847 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7848 // value is never passed to caller. 7849 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7850 MacroAssembler::MemBarNone, 7851 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7852 %} 7853 ins_pipe(pipe_class_default); 7854 %} 7855 7856 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7857 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7858 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7859 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7860 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 7861 ins_encode %{ 7862 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7863 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7864 // value is never passed to caller. 7865 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7866 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7867 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7868 %} 7869 ins_pipe(pipe_class_default); 7870 %} 7871 7872 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7873 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7874 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0); 7875 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7876 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7877 ins_encode %{ 7878 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7879 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7880 MacroAssembler::MemBarNone, 7881 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7882 %} 7883 ins_pipe(pipe_class_default); 7884 %} 7885 7886 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7887 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7888 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0); 7889 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7890 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7891 ins_encode %{ 7892 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7893 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7894 // value is never passed to caller. 7895 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7896 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7897 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7898 %} 7899 ins_pipe(pipe_class_default); 7900 %} 7901 7902 // CompareAndExchange 7903 7904 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7905 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7906 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7907 effect(TEMP_DEF res, TEMP cr0); 7908 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7909 ins_encode %{ 7910 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7911 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7912 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7913 noreg, true); 7914 %} 7915 ins_pipe(pipe_class_default); 7916 %} 7917 7918 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7919 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7920 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7921 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7922 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7923 ins_encode %{ 7924 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7925 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7926 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7927 noreg, true); 7928 %} 7929 ins_pipe(pipe_class_default); 7930 %} 7931 7932 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7933 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7934 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7935 effect(TEMP_DEF res, TEMP cr0); 7936 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7937 ins_encode %{ 7938 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7939 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7940 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7941 noreg, true); 7942 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7943 __ isync(); 7944 } else { 7945 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7946 __ sync(); 7947 } 7948 %} 7949 ins_pipe(pipe_class_default); 7950 %} 7951 7952 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7953 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7954 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7955 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7956 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7957 ins_encode %{ 7958 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7959 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7960 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7961 noreg, true); 7962 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7963 __ isync(); 7964 } else { 7965 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7966 __ sync(); 7967 } 7968 %} 7969 ins_pipe(pipe_class_default); 7970 %} 7971 7972 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7973 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7974 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7975 effect(TEMP_DEF res, TEMP cr0); 7976 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7977 ins_encode %{ 7978 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7979 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7980 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7981 noreg, true); 7982 %} 7983 ins_pipe(pipe_class_default); 7984 %} 7985 7986 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7987 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7988 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7989 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7990 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7991 ins_encode %{ 7992 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7993 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7994 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7995 noreg, true); 7996 %} 7997 ins_pipe(pipe_class_default); 7998 %} 7999 8000 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8001 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8002 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8003 effect(TEMP_DEF res, TEMP cr0); 8004 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8005 ins_encode %{ 8006 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8007 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8008 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8009 noreg, true); 8010 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8011 __ isync(); 8012 } else { 8013 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8014 __ sync(); 8015 } 8016 %} 8017 ins_pipe(pipe_class_default); 8018 %} 8019 8020 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8021 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8022 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8023 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8024 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8025 ins_encode %{ 8026 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8027 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8028 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8029 noreg, true); 8030 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8031 __ isync(); 8032 } else { 8033 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8034 __ sync(); 8035 } 8036 %} 8037 ins_pipe(pipe_class_default); 8038 %} 8039 8040 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8041 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8042 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8043 effect(TEMP_DEF res, TEMP cr0); 8044 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8045 ins_encode %{ 8046 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8047 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8048 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8049 noreg, true); 8050 %} 8051 ins_pipe(pipe_class_default); 8052 %} 8053 8054 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8055 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8056 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8057 effect(TEMP_DEF res, TEMP cr0); 8058 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8059 ins_encode %{ 8060 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8061 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8062 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8063 noreg, true); 8064 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8065 __ isync(); 8066 } else { 8067 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8068 __ sync(); 8069 } 8070 %} 8071 ins_pipe(pipe_class_default); 8072 %} 8073 8074 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8075 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8076 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8077 effect(TEMP_DEF res, TEMP cr0); 8078 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8079 ins_encode %{ 8080 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8081 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8082 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8083 noreg, true); 8084 %} 8085 ins_pipe(pipe_class_default); 8086 %} 8087 8088 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8089 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8090 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8091 effect(TEMP_DEF res, TEMP cr0); 8092 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8093 ins_encode %{ 8094 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8095 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8096 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8097 noreg, true); 8098 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8099 __ isync(); 8100 } else { 8101 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8102 __ sync(); 8103 } 8104 %} 8105 ins_pipe(pipe_class_default); 8106 %} 8107 8108 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8109 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8110 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8111 effect(TEMP_DEF res, TEMP cr0); 8112 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8113 ins_encode %{ 8114 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8115 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8116 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8117 noreg, NULL, true); 8118 %} 8119 ins_pipe(pipe_class_default); 8120 %} 8121 8122 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8123 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8124 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8125 effect(TEMP_DEF res, TEMP cr0); 8126 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8127 ins_encode %{ 8128 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8129 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8130 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8131 noreg, NULL, true); 8132 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8133 __ isync(); 8134 } else { 8135 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8136 __ sync(); 8137 } 8138 %} 8139 ins_pipe(pipe_class_default); 8140 %} 8141 8142 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8143 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8144 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) 8145 && n->as_LoadStore()->barrier_data() == 0); 8146 effect(TEMP_DEF res, TEMP cr0); 8147 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8148 ins_encode %{ 8149 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8150 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8151 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8152 noreg, NULL, true); 8153 %} 8154 ins_pipe(pipe_class_default); 8155 %} 8156 8157 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8158 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8159 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) 8160 && n->as_LoadStore()->barrier_data() == 0); 8161 effect(TEMP_DEF res, TEMP cr0); 8162 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8163 ins_encode %{ 8164 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8165 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8166 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8167 noreg, NULL, true); 8168 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8169 __ isync(); 8170 } else { 8171 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8172 __ sync(); 8173 } 8174 %} 8175 ins_pipe(pipe_class_default); 8176 %} 8177 8178 // Special RMW 8179 8180 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8181 match(Set res (GetAndAddB mem_ptr src)); 8182 predicate(VM_Version::has_lqarx()); 8183 effect(TEMP_DEF res, TEMP cr0); 8184 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8185 ins_encode %{ 8186 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8187 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8188 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8189 __ isync(); 8190 } else { 8191 __ sync(); 8192 } 8193 %} 8194 ins_pipe(pipe_class_default); 8195 %} 8196 8197 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8198 match(Set res (GetAndAddB mem_ptr src)); 8199 predicate(!VM_Version::has_lqarx()); 8200 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8201 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8202 ins_encode %{ 8203 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8204 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8205 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8206 __ isync(); 8207 } else { 8208 __ sync(); 8209 } 8210 %} 8211 ins_pipe(pipe_class_default); 8212 %} 8213 8214 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8215 match(Set res (GetAndAddS mem_ptr src)); 8216 predicate(VM_Version::has_lqarx()); 8217 effect(TEMP_DEF res, TEMP cr0); 8218 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8219 ins_encode %{ 8220 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8221 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8222 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8223 __ isync(); 8224 } else { 8225 __ sync(); 8226 } 8227 %} 8228 ins_pipe(pipe_class_default); 8229 %} 8230 8231 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8232 match(Set res (GetAndAddS mem_ptr src)); 8233 predicate(!VM_Version::has_lqarx()); 8234 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8235 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8236 ins_encode %{ 8237 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8238 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8239 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8240 __ isync(); 8241 } else { 8242 __ sync(); 8243 } 8244 %} 8245 ins_pipe(pipe_class_default); 8246 %} 8247 8248 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8249 match(Set res (GetAndAddI mem_ptr src)); 8250 effect(TEMP_DEF res, TEMP cr0); 8251 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8252 ins_encode %{ 8253 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8254 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8255 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8256 __ isync(); 8257 } else { 8258 __ sync(); 8259 } 8260 %} 8261 ins_pipe(pipe_class_default); 8262 %} 8263 8264 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8265 match(Set res (GetAndAddL mem_ptr src)); 8266 effect(TEMP_DEF res, TEMP cr0); 8267 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8268 ins_encode %{ 8269 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8270 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8271 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8272 __ isync(); 8273 } else { 8274 __ sync(); 8275 } 8276 %} 8277 ins_pipe(pipe_class_default); 8278 %} 8279 8280 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8281 match(Set res (GetAndSetB mem_ptr src)); 8282 predicate(VM_Version::has_lqarx()); 8283 effect(TEMP_DEF res, TEMP cr0); 8284 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8285 ins_encode %{ 8286 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8287 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8288 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8289 __ isync(); 8290 } else { 8291 __ sync(); 8292 } 8293 %} 8294 ins_pipe(pipe_class_default); 8295 %} 8296 8297 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8298 match(Set res (GetAndSetB mem_ptr src)); 8299 predicate(!VM_Version::has_lqarx()); 8300 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8301 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8302 ins_encode %{ 8303 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8304 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8305 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8306 __ isync(); 8307 } else { 8308 __ sync(); 8309 } 8310 %} 8311 ins_pipe(pipe_class_default); 8312 %} 8313 8314 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8315 match(Set res (GetAndSetS mem_ptr src)); 8316 predicate(VM_Version::has_lqarx()); 8317 effect(TEMP_DEF res, TEMP cr0); 8318 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8319 ins_encode %{ 8320 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8321 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8322 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8323 __ isync(); 8324 } else { 8325 __ sync(); 8326 } 8327 %} 8328 ins_pipe(pipe_class_default); 8329 %} 8330 8331 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8332 match(Set res (GetAndSetS mem_ptr src)); 8333 predicate(!VM_Version::has_lqarx()); 8334 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8335 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8336 ins_encode %{ 8337 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8338 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8339 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8340 __ isync(); 8341 } else { 8342 __ sync(); 8343 } 8344 %} 8345 ins_pipe(pipe_class_default); 8346 %} 8347 8348 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8349 match(Set res (GetAndSetI mem_ptr src)); 8350 effect(TEMP_DEF res, TEMP cr0); 8351 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8352 ins_encode %{ 8353 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8354 MacroAssembler::cmpxchgx_hint_atomic_update()); 8355 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8356 __ isync(); 8357 } else { 8358 __ sync(); 8359 } 8360 %} 8361 ins_pipe(pipe_class_default); 8362 %} 8363 8364 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8365 match(Set res (GetAndSetL mem_ptr src)); 8366 effect(TEMP_DEF res, TEMP cr0); 8367 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8368 ins_encode %{ 8369 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8370 MacroAssembler::cmpxchgx_hint_atomic_update()); 8371 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8372 __ isync(); 8373 } else { 8374 __ sync(); 8375 } 8376 %} 8377 ins_pipe(pipe_class_default); 8378 %} 8379 8380 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8381 match(Set res (GetAndSetP mem_ptr src)); 8382 predicate(n->as_LoadStore()->barrier_data() == 0); 8383 effect(TEMP_DEF res, TEMP cr0); 8384 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8385 ins_encode %{ 8386 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8387 MacroAssembler::cmpxchgx_hint_atomic_update()); 8388 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8389 __ isync(); 8390 } else { 8391 __ sync(); 8392 } 8393 %} 8394 ins_pipe(pipe_class_default); 8395 %} 8396 8397 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8398 match(Set res (GetAndSetN mem_ptr src)); 8399 effect(TEMP_DEF res, TEMP cr0); 8400 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8401 ins_encode %{ 8402 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8403 MacroAssembler::cmpxchgx_hint_atomic_update()); 8404 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8405 __ isync(); 8406 } else { 8407 __ sync(); 8408 } 8409 %} 8410 ins_pipe(pipe_class_default); 8411 %} 8412 8413 //----------Arithmetic Instructions-------------------------------------------- 8414 // Addition Instructions 8415 8416 // Register Addition 8417 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8418 match(Set dst (AddI src1 src2)); 8419 format %{ "ADD $dst, $src1, $src2" %} 8420 size(4); 8421 ins_encode %{ 8422 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8423 %} 8424 ins_pipe(pipe_class_default); 8425 %} 8426 8427 // Expand does not work with above instruct. (??) 8428 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8429 // no match-rule 8430 effect(DEF dst, USE src1, USE src2); 8431 format %{ "ADD $dst, $src1, $src2" %} 8432 size(4); 8433 ins_encode %{ 8434 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8435 %} 8436 ins_pipe(pipe_class_default); 8437 %} 8438 8439 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8440 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8441 ins_cost(DEFAULT_COST*3); 8442 8443 expand %{ 8444 // FIXME: we should do this in the ideal world. 8445 iRegIdst tmp1; 8446 iRegIdst tmp2; 8447 addI_reg_reg(tmp1, src1, src2); 8448 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8449 addI_reg_reg(dst, tmp1, tmp2); 8450 %} 8451 %} 8452 8453 // Immediate Addition 8454 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8455 match(Set dst (AddI src1 src2)); 8456 format %{ "ADDI $dst, $src1, $src2" %} 8457 size(4); 8458 ins_encode %{ 8459 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8460 %} 8461 ins_pipe(pipe_class_default); 8462 %} 8463 8464 // Immediate Addition with 16-bit shifted operand 8465 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8466 match(Set dst (AddI src1 src2)); 8467 format %{ "ADDIS $dst, $src1, $src2" %} 8468 size(4); 8469 ins_encode %{ 8470 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8471 %} 8472 ins_pipe(pipe_class_default); 8473 %} 8474 8475 // Immediate Addition using prefixed addi 8476 instruct addI_reg_imm32(iRegIdst dst, iRegIsrc src1, immI32 src2) %{ 8477 match(Set dst (AddI src1 src2)); 8478 predicate(PowerArchitecturePPC64 >= 10); 8479 ins_cost(DEFAULT_COST+1); 8480 format %{ "PADDI $dst, $src1, $src2" %} 8481 size(8); 8482 ins_encode %{ 8483 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 8484 __ paddi($dst$$Register, $src1$$Register, $src2$$constant); 8485 %} 8486 ins_pipe(pipe_class_default); 8487 ins_alignment(2); 8488 %} 8489 8490 // Long Addition 8491 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8492 match(Set dst (AddL src1 src2)); 8493 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8494 size(4); 8495 ins_encode %{ 8496 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8497 %} 8498 ins_pipe(pipe_class_default); 8499 %} 8500 8501 // Expand does not work with above instruct. (??) 8502 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8503 // no match-rule 8504 effect(DEF dst, USE src1, USE src2); 8505 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8506 size(4); 8507 ins_encode %{ 8508 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8509 %} 8510 ins_pipe(pipe_class_default); 8511 %} 8512 8513 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8514 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8515 ins_cost(DEFAULT_COST*3); 8516 8517 expand %{ 8518 // FIXME: we should do this in the ideal world. 8519 iRegLdst tmp1; 8520 iRegLdst tmp2; 8521 addL_reg_reg(tmp1, src1, src2); 8522 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8523 addL_reg_reg(dst, tmp1, tmp2); 8524 %} 8525 %} 8526 8527 // AddL + ConvL2I. 8528 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8529 match(Set dst (ConvL2I (AddL src1 src2))); 8530 8531 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8532 size(4); 8533 ins_encode %{ 8534 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8535 %} 8536 ins_pipe(pipe_class_default); 8537 %} 8538 8539 // No constant pool entries required. 8540 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8541 match(Set dst (AddL src1 src2)); 8542 8543 format %{ "ADDI $dst, $src1, $src2" %} 8544 size(4); 8545 ins_encode %{ 8546 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8547 %} 8548 ins_pipe(pipe_class_default); 8549 %} 8550 8551 // Long Immediate Addition with 16-bit shifted operand. 8552 // No constant pool entries required. 8553 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8554 match(Set dst (AddL src1 src2)); 8555 8556 format %{ "ADDIS $dst, $src1, $src2" %} 8557 size(4); 8558 ins_encode %{ 8559 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8560 %} 8561 ins_pipe(pipe_class_default); 8562 %} 8563 8564 // Long Immediate Addition using prefixed addi 8565 // No constant pool entries required. 8566 instruct addL_reg_imm34(iRegLdst dst, iRegLsrc src1, immL34 src2) %{ 8567 match(Set dst (AddL src1 src2)); 8568 predicate(PowerArchitecturePPC64 >= 10); 8569 ins_cost(DEFAULT_COST+1); 8570 8571 format %{ "PADDI $dst, $src1, $src2" %} 8572 size(8); 8573 ins_encode %{ 8574 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 8575 __ paddi($dst$$Register, $src1$$Register, $src2$$constant); 8576 %} 8577 ins_pipe(pipe_class_default); 8578 ins_alignment(2); 8579 %} 8580 8581 // Pointer Register Addition 8582 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8583 match(Set dst (AddP src1 src2)); 8584 format %{ "ADD $dst, $src1, $src2" %} 8585 size(4); 8586 ins_encode %{ 8587 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8588 %} 8589 ins_pipe(pipe_class_default); 8590 %} 8591 8592 // Pointer Immediate Addition 8593 // No constant pool entries required. 8594 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8595 match(Set dst (AddP src1 src2)); 8596 8597 format %{ "ADDI $dst, $src1, $src2" %} 8598 size(4); 8599 ins_encode %{ 8600 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8601 %} 8602 ins_pipe(pipe_class_default); 8603 %} 8604 8605 // Pointer Immediate Addition with 16-bit shifted operand. 8606 // No constant pool entries required. 8607 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8608 match(Set dst (AddP src1 src2)); 8609 8610 format %{ "ADDIS $dst, $src1, $src2" %} 8611 size(4); 8612 ins_encode %{ 8613 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8614 %} 8615 ins_pipe(pipe_class_default); 8616 %} 8617 8618 // Pointer Immediate Addition using prefixed addi 8619 // No constant pool entries required. 8620 instruct addP_reg_imm34(iRegPdst dst, iRegP_N2P src1, immL34 src2) %{ 8621 match(Set dst (AddP src1 src2)); 8622 predicate(PowerArchitecturePPC64 >= 10); 8623 ins_cost(DEFAULT_COST+1); 8624 8625 format %{ "PADDI $dst, $src1, $src2" %} 8626 size(8); 8627 ins_encode %{ 8628 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 8629 __ paddi($dst$$Register, $src1$$Register, $src2$$constant); 8630 %} 8631 ins_pipe(pipe_class_default); 8632 ins_alignment(2); 8633 %} 8634 8635 //--------------------- 8636 // Subtraction Instructions 8637 8638 // Register Subtraction 8639 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8640 match(Set dst (SubI src1 src2)); 8641 format %{ "SUBF $dst, $src2, $src1" %} 8642 size(4); 8643 ins_encode %{ 8644 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8645 %} 8646 ins_pipe(pipe_class_default); 8647 %} 8648 8649 // Immediate Subtraction 8650 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 8651 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 8652 8653 // SubI from constant (using subfic). 8654 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 8655 match(Set dst (SubI src1 src2)); 8656 format %{ "SUBI $dst, $src1, $src2" %} 8657 8658 size(4); 8659 ins_encode %{ 8660 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 8661 %} 8662 ins_pipe(pipe_class_default); 8663 %} 8664 8665 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 8666 // positive integers and 0xF...F for negative ones. 8667 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 8668 // no match-rule, false predicate 8669 effect(DEF dst, USE src); 8670 predicate(false); 8671 8672 format %{ "SRAWI $dst, $src, #31" %} 8673 size(4); 8674 ins_encode %{ 8675 __ srawi($dst$$Register, $src$$Register, 0x1f); 8676 %} 8677 ins_pipe(pipe_class_default); 8678 %} 8679 8680 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 8681 match(Set dst (AbsI src)); 8682 ins_cost(DEFAULT_COST*3); 8683 8684 expand %{ 8685 iRegIdst tmp1; 8686 iRegIdst tmp2; 8687 signmask32I_regI(tmp1, src); 8688 xorI_reg_reg(tmp2, tmp1, src); 8689 subI_reg_reg(dst, tmp2, tmp1); 8690 %} 8691 %} 8692 8693 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 8694 match(Set dst (SubI zero src2)); 8695 format %{ "NEG $dst, $src2" %} 8696 size(4); 8697 ins_encode %{ 8698 __ neg($dst$$Register, $src2$$Register); 8699 %} 8700 ins_pipe(pipe_class_default); 8701 %} 8702 8703 // Long subtraction 8704 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8705 match(Set dst (SubL src1 src2)); 8706 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 8707 size(4); 8708 ins_encode %{ 8709 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8710 %} 8711 ins_pipe(pipe_class_default); 8712 %} 8713 8714 // SubL + convL2I. 8715 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8716 match(Set dst (ConvL2I (SubL src1 src2))); 8717 8718 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 8719 size(4); 8720 ins_encode %{ 8721 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8722 %} 8723 ins_pipe(pipe_class_default); 8724 %} 8725 8726 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8727 // positive longs and 0xF...F for negative ones. 8728 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 8729 // no match-rule, false predicate 8730 effect(DEF dst, USE src); 8731 predicate(false); 8732 8733 format %{ "SRADI $dst, $src, #63" %} 8734 size(4); 8735 ins_encode %{ 8736 __ sradi($dst$$Register, $src$$Register, 0x3f); 8737 %} 8738 ins_pipe(pipe_class_default); 8739 %} 8740 8741 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8742 // positive longs and 0xF...F for negative ones. 8743 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 8744 // no match-rule, false predicate 8745 effect(DEF dst, USE src); 8746 predicate(false); 8747 8748 format %{ "SRADI $dst, $src, #63" %} 8749 size(4); 8750 ins_encode %{ 8751 __ sradi($dst$$Register, $src$$Register, 0x3f); 8752 %} 8753 ins_pipe(pipe_class_default); 8754 %} 8755 8756 instruct absL_reg_Ex(iRegLdst dst, iRegLsrc src) %{ 8757 match(Set dst (AbsL src)); 8758 ins_cost(DEFAULT_COST*3); 8759 8760 expand %{ 8761 iRegLdst tmp1; 8762 iRegLdst tmp2; 8763 signmask64L_regL(tmp1, src); 8764 xorL_reg_reg(tmp2, tmp1, src); 8765 subL_reg_reg(dst, tmp2, tmp1); 8766 %} 8767 %} 8768 8769 // Long negation 8770 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 8771 match(Set dst (SubL zero src2)); 8772 format %{ "NEG $dst, $src2 \t// long" %} 8773 size(4); 8774 ins_encode %{ 8775 __ neg($dst$$Register, $src2$$Register); 8776 %} 8777 ins_pipe(pipe_class_default); 8778 %} 8779 8780 // NegL + ConvL2I. 8781 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 8782 match(Set dst (ConvL2I (SubL zero src2))); 8783 8784 format %{ "NEG $dst, $src2 \t// long + l2i" %} 8785 size(4); 8786 ins_encode %{ 8787 __ neg($dst$$Register, $src2$$Register); 8788 %} 8789 ins_pipe(pipe_class_default); 8790 %} 8791 8792 // Multiplication Instructions 8793 // Integer Multiplication 8794 8795 // Register Multiplication 8796 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8797 match(Set dst (MulI src1 src2)); 8798 ins_cost(DEFAULT_COST); 8799 8800 format %{ "MULLW $dst, $src1, $src2" %} 8801 size(4); 8802 ins_encode %{ 8803 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 8804 %} 8805 ins_pipe(pipe_class_default); 8806 %} 8807 8808 // Immediate Multiplication 8809 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8810 match(Set dst (MulI src1 src2)); 8811 ins_cost(DEFAULT_COST); 8812 8813 format %{ "MULLI $dst, $src1, $src2" %} 8814 size(4); 8815 ins_encode %{ 8816 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8817 %} 8818 ins_pipe(pipe_class_default); 8819 %} 8820 8821 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8822 match(Set dst (MulL src1 src2)); 8823 ins_cost(DEFAULT_COST); 8824 8825 format %{ "MULLD $dst $src1, $src2 \t// long" %} 8826 size(4); 8827 ins_encode %{ 8828 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 8829 %} 8830 ins_pipe(pipe_class_default); 8831 %} 8832 8833 // Multiply high for optimized long division by constant. 8834 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8835 match(Set dst (MulHiL src1 src2)); 8836 ins_cost(DEFAULT_COST); 8837 8838 format %{ "MULHD $dst $src1, $src2 \t// long" %} 8839 size(4); 8840 ins_encode %{ 8841 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 8842 %} 8843 ins_pipe(pipe_class_default); 8844 %} 8845 8846 // Immediate Multiplication 8847 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8848 match(Set dst (MulL src1 src2)); 8849 ins_cost(DEFAULT_COST); 8850 8851 format %{ "MULLI $dst, $src1, $src2" %} 8852 size(4); 8853 ins_encode %{ 8854 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8855 %} 8856 ins_pipe(pipe_class_default); 8857 %} 8858 8859 // Integer Division with Immediate -1: Negate. 8860 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 8861 match(Set dst (DivI src1 src2)); 8862 ins_cost(DEFAULT_COST); 8863 8864 format %{ "NEG $dst, $src1 \t// /-1" %} 8865 size(4); 8866 ins_encode %{ 8867 __ neg($dst$$Register, $src1$$Register); 8868 %} 8869 ins_pipe(pipe_class_default); 8870 %} 8871 8872 // Integer Division with constant, but not -1. 8873 // We should be able to improve this by checking the type of src2. 8874 // It might well be that src2 is known to be positive. 8875 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8876 match(Set dst (DivI src1 src2)); 8877 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 8878 ins_cost(2*DEFAULT_COST); 8879 8880 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 8881 size(4); 8882 ins_encode %{ 8883 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 8884 %} 8885 ins_pipe(pipe_class_default); 8886 %} 8887 8888 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 8889 effect(USE_DEF dst, USE src1, USE crx); 8890 predicate(false); 8891 8892 ins_variable_size_depending_on_alignment(true); 8893 8894 format %{ "CMOVE $dst, neg($src1), $crx" %} 8895 // Worst case is branch + move + stop, no stop without scheduler. 8896 size(8); 8897 ins_encode %{ 8898 Label done; 8899 __ bne($crx$$CondRegister, done); 8900 __ neg($dst$$Register, $src1$$Register); 8901 __ bind(done); 8902 %} 8903 ins_pipe(pipe_class_default); 8904 %} 8905 8906 // Integer Division with Registers not containing constants. 8907 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8908 match(Set dst (DivI src1 src2)); 8909 ins_cost(10*DEFAULT_COST); 8910 8911 expand %{ 8912 immI16 imm %{ (int)-1 %} 8913 flagsReg tmp1; 8914 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8915 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8916 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8917 %} 8918 %} 8919 8920 // Long Division with Immediate -1: Negate. 8921 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 8922 match(Set dst (DivL src1 src2)); 8923 ins_cost(DEFAULT_COST); 8924 8925 format %{ "NEG $dst, $src1 \t// /-1, long" %} 8926 size(4); 8927 ins_encode %{ 8928 __ neg($dst$$Register, $src1$$Register); 8929 %} 8930 ins_pipe(pipe_class_default); 8931 %} 8932 8933 // Long Division with constant, but not -1. 8934 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8935 match(Set dst (DivL src1 src2)); 8936 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 8937 ins_cost(2*DEFAULT_COST); 8938 8939 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 8940 size(4); 8941 ins_encode %{ 8942 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 8943 %} 8944 ins_pipe(pipe_class_default); 8945 %} 8946 8947 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 8948 effect(USE_DEF dst, USE src1, USE crx); 8949 predicate(false); 8950 8951 ins_variable_size_depending_on_alignment(true); 8952 8953 format %{ "CMOVE $dst, neg($src1), $crx" %} 8954 // Worst case is branch + move + stop, no stop without scheduler. 8955 size(8); 8956 ins_encode %{ 8957 Label done; 8958 __ bne($crx$$CondRegister, done); 8959 __ neg($dst$$Register, $src1$$Register); 8960 __ bind(done); 8961 %} 8962 ins_pipe(pipe_class_default); 8963 %} 8964 8965 // Long Division with Registers not containing constants. 8966 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8967 match(Set dst (DivL src1 src2)); 8968 ins_cost(10*DEFAULT_COST); 8969 8970 expand %{ 8971 immL16 imm %{ (int)-1 %} 8972 flagsReg tmp1; 8973 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8974 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8975 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8976 %} 8977 %} 8978 8979 // Integer Remainder with registers. 8980 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8981 match(Set dst (ModI src1 src2)); 8982 ins_cost(10*DEFAULT_COST); 8983 8984 expand %{ 8985 immI16 imm %{ (int)-1 %} 8986 flagsReg tmp1; 8987 iRegIdst tmp2; 8988 iRegIdst tmp3; 8989 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8990 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8991 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8992 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8993 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8994 %} 8995 %} 8996 8997 // Long Remainder with registers 8998 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8999 match(Set dst (ModL src1 src2)); 9000 ins_cost(10*DEFAULT_COST); 9001 9002 expand %{ 9003 immL16 imm %{ (int)-1 %} 9004 flagsReg tmp1; 9005 iRegLdst tmp2; 9006 iRegLdst tmp3; 9007 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9008 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9009 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9010 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9011 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9012 %} 9013 %} 9014 9015 // Integer Shift Instructions 9016 9017 // Register Shift Left 9018 9019 // Clear all but the lowest #mask bits. 9020 // Used to normalize shift amounts in registers. 9021 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9022 // no match-rule, false predicate 9023 effect(DEF dst, USE src, USE mask); 9024 predicate(false); 9025 9026 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9027 size(4); 9028 ins_encode %{ 9029 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9030 %} 9031 ins_pipe(pipe_class_default); 9032 %} 9033 9034 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9035 // no match-rule, false predicate 9036 effect(DEF dst, USE src1, USE src2); 9037 predicate(false); 9038 9039 format %{ "SLW $dst, $src1, $src2" %} 9040 size(4); 9041 ins_encode %{ 9042 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9043 %} 9044 ins_pipe(pipe_class_default); 9045 %} 9046 9047 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9048 match(Set dst (LShiftI src1 src2)); 9049 ins_cost(DEFAULT_COST*2); 9050 expand %{ 9051 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9052 iRegIdst tmpI; 9053 maskI_reg_imm(tmpI, src2, mask); 9054 lShiftI_reg_reg(dst, src1, tmpI); 9055 %} 9056 %} 9057 9058 // Register Shift Left Immediate 9059 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9060 match(Set dst (LShiftI src1 src2)); 9061 9062 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9063 size(4); 9064 ins_encode %{ 9065 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9066 %} 9067 ins_pipe(pipe_class_default); 9068 %} 9069 9070 // AndI with negpow2-constant + LShiftI 9071 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9072 match(Set dst (LShiftI (AndI src1 src2) src3)); 9073 predicate(UseRotateAndMaskInstructionsPPC64); 9074 9075 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9076 size(4); 9077 ins_encode %{ 9078 long src3 = $src3$$constant; 9079 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant); 9080 if (maskbits >= 32) { 9081 __ li($dst$$Register, 0); // addi 9082 } else { 9083 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9084 } 9085 %} 9086 ins_pipe(pipe_class_default); 9087 %} 9088 9089 // RShiftI + AndI with negpow2-constant + LShiftI 9090 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9091 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9092 predicate(UseRotateAndMaskInstructionsPPC64); 9093 9094 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9095 size(4); 9096 ins_encode %{ 9097 long src3 = $src3$$constant; 9098 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant); 9099 if (maskbits >= 32) { 9100 __ li($dst$$Register, 0); // addi 9101 } else { 9102 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9103 } 9104 %} 9105 ins_pipe(pipe_class_default); 9106 %} 9107 9108 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9109 // no match-rule, false predicate 9110 effect(DEF dst, USE src1, USE src2); 9111 predicate(false); 9112 9113 format %{ "SLD $dst, $src1, $src2" %} 9114 size(4); 9115 ins_encode %{ 9116 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9117 %} 9118 ins_pipe(pipe_class_default); 9119 %} 9120 9121 // Register Shift Left 9122 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9123 match(Set dst (LShiftL src1 src2)); 9124 ins_cost(DEFAULT_COST*2); 9125 expand %{ 9126 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9127 iRegIdst tmpI; 9128 maskI_reg_imm(tmpI, src2, mask); 9129 lShiftL_regL_regI(dst, src1, tmpI); 9130 %} 9131 %} 9132 9133 // Register Shift Left Immediate 9134 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9135 match(Set dst (LShiftL src1 src2)); 9136 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9137 size(4); 9138 ins_encode %{ 9139 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9140 %} 9141 ins_pipe(pipe_class_default); 9142 %} 9143 9144 // If we shift more than 32 bits, we need not convert I2L. 9145 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9146 match(Set dst (LShiftL (ConvI2L src1) src2)); 9147 ins_cost(DEFAULT_COST); 9148 9149 size(4); 9150 format %{ "SLDI $dst, i2l($src1), $src2" %} 9151 ins_encode %{ 9152 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9153 %} 9154 ins_pipe(pipe_class_default); 9155 %} 9156 9157 // Shift a postivie int to the left. 9158 // Clrlsldi clears the upper 32 bits and shifts. 9159 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9160 match(Set dst (LShiftL (ConvI2L src1) src2)); 9161 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9162 9163 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9164 size(4); 9165 ins_encode %{ 9166 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9167 %} 9168 ins_pipe(pipe_class_default); 9169 %} 9170 9171 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9172 // no match-rule, false predicate 9173 effect(DEF dst, USE src1, USE src2); 9174 predicate(false); 9175 9176 format %{ "SRAW $dst, $src1, $src2" %} 9177 size(4); 9178 ins_encode %{ 9179 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9180 %} 9181 ins_pipe(pipe_class_default); 9182 %} 9183 9184 // Register Arithmetic Shift Right 9185 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9186 match(Set dst (RShiftI src1 src2)); 9187 ins_cost(DEFAULT_COST*2); 9188 expand %{ 9189 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9190 iRegIdst tmpI; 9191 maskI_reg_imm(tmpI, src2, mask); 9192 arShiftI_reg_reg(dst, src1, tmpI); 9193 %} 9194 %} 9195 9196 // Register Arithmetic Shift Right Immediate 9197 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9198 match(Set dst (RShiftI src1 src2)); 9199 9200 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9201 size(4); 9202 ins_encode %{ 9203 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9204 %} 9205 ins_pipe(pipe_class_default); 9206 %} 9207 9208 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9209 // no match-rule, false predicate 9210 effect(DEF dst, USE src1, USE src2); 9211 predicate(false); 9212 9213 format %{ "SRAD $dst, $src1, $src2" %} 9214 size(4); 9215 ins_encode %{ 9216 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9217 %} 9218 ins_pipe(pipe_class_default); 9219 %} 9220 9221 // Register Shift Right Arithmetic Long 9222 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9223 match(Set dst (RShiftL src1 src2)); 9224 ins_cost(DEFAULT_COST*2); 9225 9226 expand %{ 9227 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9228 iRegIdst tmpI; 9229 maskI_reg_imm(tmpI, src2, mask); 9230 arShiftL_regL_regI(dst, src1, tmpI); 9231 %} 9232 %} 9233 9234 // Register Shift Right Immediate 9235 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9236 match(Set dst (RShiftL src1 src2)); 9237 9238 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9239 size(4); 9240 ins_encode %{ 9241 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9242 %} 9243 ins_pipe(pipe_class_default); 9244 %} 9245 9246 // RShiftL + ConvL2I 9247 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9248 match(Set dst (ConvL2I (RShiftL src1 src2))); 9249 9250 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9251 size(4); 9252 ins_encode %{ 9253 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9254 %} 9255 ins_pipe(pipe_class_default); 9256 %} 9257 9258 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9259 // no match-rule, false predicate 9260 effect(DEF dst, USE src1, USE src2); 9261 predicate(false); 9262 9263 format %{ "SRW $dst, $src1, $src2" %} 9264 size(4); 9265 ins_encode %{ 9266 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9267 %} 9268 ins_pipe(pipe_class_default); 9269 %} 9270 9271 // Register Shift Right 9272 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9273 match(Set dst (URShiftI src1 src2)); 9274 ins_cost(DEFAULT_COST*2); 9275 9276 expand %{ 9277 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9278 iRegIdst tmpI; 9279 maskI_reg_imm(tmpI, src2, mask); 9280 urShiftI_reg_reg(dst, src1, tmpI); 9281 %} 9282 %} 9283 9284 // Register Shift Right Immediate 9285 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9286 match(Set dst (URShiftI src1 src2)); 9287 9288 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9289 size(4); 9290 ins_encode %{ 9291 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9292 %} 9293 ins_pipe(pipe_class_default); 9294 %} 9295 9296 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9297 // no match-rule, false predicate 9298 effect(DEF dst, USE src1, USE src2); 9299 predicate(false); 9300 9301 format %{ "SRD $dst, $src1, $src2" %} 9302 size(4); 9303 ins_encode %{ 9304 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9305 %} 9306 ins_pipe(pipe_class_default); 9307 %} 9308 9309 // Register Shift Right 9310 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9311 match(Set dst (URShiftL src1 src2)); 9312 ins_cost(DEFAULT_COST*2); 9313 9314 expand %{ 9315 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9316 iRegIdst tmpI; 9317 maskI_reg_imm(tmpI, src2, mask); 9318 urShiftL_regL_regI(dst, src1, tmpI); 9319 %} 9320 %} 9321 9322 // Register Shift Right Immediate 9323 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9324 match(Set dst (URShiftL src1 src2)); 9325 9326 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9327 size(4); 9328 ins_encode %{ 9329 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9330 %} 9331 ins_pipe(pipe_class_default); 9332 %} 9333 9334 // URShiftL + ConvL2I. 9335 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9336 match(Set dst (ConvL2I (URShiftL src1 src2))); 9337 9338 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9339 size(4); 9340 ins_encode %{ 9341 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9342 %} 9343 ins_pipe(pipe_class_default); 9344 %} 9345 9346 // Register Shift Right Immediate with a CastP2X 9347 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9348 match(Set dst (URShiftL (CastP2X src1) src2)); 9349 9350 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9351 size(4); 9352 ins_encode %{ 9353 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9354 %} 9355 ins_pipe(pipe_class_default); 9356 %} 9357 9358 // Bitfield Extract: URShiftI + AndI 9359 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9360 match(Set dst (AndI (URShiftI src1 src2) src3)); 9361 9362 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9363 size(4); 9364 ins_encode %{ 9365 int rshift = ($src2$$constant) & 0x1f; 9366 int length = log2i_exact((juint)$src3$$constant + 1u); 9367 if (rshift + length > 32) { 9368 // if necessary, adjust mask to omit rotated bits. 9369 length = 32 - rshift; 9370 } 9371 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9372 %} 9373 ins_pipe(pipe_class_default); 9374 %} 9375 9376 // Bitfield Extract: URShiftL + AndL 9377 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9378 match(Set dst (AndL (URShiftL src1 src2) src3)); 9379 9380 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9381 size(4); 9382 ins_encode %{ 9383 int rshift = ($src2$$constant) & 0x3f; 9384 int length = log2i_exact((julong)$src3$$constant + 1ull); 9385 if (rshift + length > 64) { 9386 // if necessary, adjust mask to omit rotated bits. 9387 length = 64 - rshift; 9388 } 9389 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9390 %} 9391 ins_pipe(pipe_class_default); 9392 %} 9393 9394 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9395 match(Set dst (ConvL2I (ConvI2L src))); 9396 9397 format %{ "EXTSW $dst, $src \t// int->int" %} 9398 size(4); 9399 ins_encode %{ 9400 __ extsw($dst$$Register, $src$$Register); 9401 %} 9402 ins_pipe(pipe_class_default); 9403 %} 9404 9405 //----------Rotate Instructions------------------------------------------------ 9406 9407 // Rotate Left by 8-bit immediate 9408 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9409 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9410 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9411 9412 format %{ "ROTLWI $dst, $src, $lshift" %} 9413 size(4); 9414 ins_encode %{ 9415 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9416 %} 9417 ins_pipe(pipe_class_default); 9418 %} 9419 9420 // Rotate Right by 8-bit immediate 9421 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9422 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9423 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9424 9425 format %{ "ROTRWI $dst, $rshift" %} 9426 size(4); 9427 ins_encode %{ 9428 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9429 %} 9430 ins_pipe(pipe_class_default); 9431 %} 9432 9433 //----------Floating Point Arithmetic Instructions----------------------------- 9434 9435 // Add float single precision 9436 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9437 match(Set dst (AddF src1 src2)); 9438 9439 format %{ "FADDS $dst, $src1, $src2" %} 9440 size(4); 9441 ins_encode %{ 9442 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9443 %} 9444 ins_pipe(pipe_class_default); 9445 %} 9446 9447 // Add float double precision 9448 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9449 match(Set dst (AddD src1 src2)); 9450 9451 format %{ "FADD $dst, $src1, $src2" %} 9452 size(4); 9453 ins_encode %{ 9454 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9455 %} 9456 ins_pipe(pipe_class_default); 9457 %} 9458 9459 // Sub float single precision 9460 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9461 match(Set dst (SubF src1 src2)); 9462 9463 format %{ "FSUBS $dst, $src1, $src2" %} 9464 size(4); 9465 ins_encode %{ 9466 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9467 %} 9468 ins_pipe(pipe_class_default); 9469 %} 9470 9471 // Sub float double precision 9472 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9473 match(Set dst (SubD src1 src2)); 9474 format %{ "FSUB $dst, $src1, $src2" %} 9475 size(4); 9476 ins_encode %{ 9477 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9478 %} 9479 ins_pipe(pipe_class_default); 9480 %} 9481 9482 // Mul float single precision 9483 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9484 match(Set dst (MulF src1 src2)); 9485 format %{ "FMULS $dst, $src1, $src2" %} 9486 size(4); 9487 ins_encode %{ 9488 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9489 %} 9490 ins_pipe(pipe_class_default); 9491 %} 9492 9493 // Mul float double precision 9494 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9495 match(Set dst (MulD src1 src2)); 9496 format %{ "FMUL $dst, $src1, $src2" %} 9497 size(4); 9498 ins_encode %{ 9499 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9500 %} 9501 ins_pipe(pipe_class_default); 9502 %} 9503 9504 // Div float single precision 9505 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9506 match(Set dst (DivF src1 src2)); 9507 format %{ "FDIVS $dst, $src1, $src2" %} 9508 size(4); 9509 ins_encode %{ 9510 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9511 %} 9512 ins_pipe(pipe_class_default); 9513 %} 9514 9515 // Div float double precision 9516 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9517 match(Set dst (DivD src1 src2)); 9518 format %{ "FDIV $dst, $src1, $src2" %} 9519 size(4); 9520 ins_encode %{ 9521 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9522 %} 9523 ins_pipe(pipe_class_default); 9524 %} 9525 9526 // Absolute float single precision 9527 instruct absF_reg(regF dst, regF src) %{ 9528 match(Set dst (AbsF src)); 9529 format %{ "FABS $dst, $src \t// float" %} 9530 size(4); 9531 ins_encode %{ 9532 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9533 %} 9534 ins_pipe(pipe_class_default); 9535 %} 9536 9537 // Absolute float double precision 9538 instruct absD_reg(regD dst, regD src) %{ 9539 match(Set dst (AbsD src)); 9540 format %{ "FABS $dst, $src \t// double" %} 9541 size(4); 9542 ins_encode %{ 9543 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9544 %} 9545 ins_pipe(pipe_class_default); 9546 %} 9547 9548 instruct negF_reg(regF dst, regF src) %{ 9549 match(Set dst (NegF src)); 9550 format %{ "FNEG $dst, $src \t// float" %} 9551 size(4); 9552 ins_encode %{ 9553 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9554 %} 9555 ins_pipe(pipe_class_default); 9556 %} 9557 9558 instruct negD_reg(regD dst, regD src) %{ 9559 match(Set dst (NegD src)); 9560 format %{ "FNEG $dst, $src \t// double" %} 9561 size(4); 9562 ins_encode %{ 9563 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9564 %} 9565 ins_pipe(pipe_class_default); 9566 %} 9567 9568 // AbsF + NegF. 9569 instruct negF_absF_reg(regF dst, regF src) %{ 9570 match(Set dst (NegF (AbsF src))); 9571 format %{ "FNABS $dst, $src \t// float" %} 9572 size(4); 9573 ins_encode %{ 9574 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9575 %} 9576 ins_pipe(pipe_class_default); 9577 %} 9578 9579 // AbsD + NegD. 9580 instruct negD_absD_reg(regD dst, regD src) %{ 9581 match(Set dst (NegD (AbsD src))); 9582 format %{ "FNABS $dst, $src \t// double" %} 9583 size(4); 9584 ins_encode %{ 9585 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9586 %} 9587 ins_pipe(pipe_class_default); 9588 %} 9589 9590 // VM_Version::has_fsqrt() decides if this node will be used. 9591 // Sqrt float double precision 9592 instruct sqrtD_reg(regD dst, regD src) %{ 9593 match(Set dst (SqrtD src)); 9594 format %{ "FSQRT $dst, $src" %} 9595 size(4); 9596 ins_encode %{ 9597 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 9598 %} 9599 ins_pipe(pipe_class_default); 9600 %} 9601 9602 // Single-precision sqrt. 9603 instruct sqrtF_reg(regF dst, regF src) %{ 9604 match(Set dst (SqrtF src)); 9605 predicate(VM_Version::has_fsqrts()); 9606 ins_cost(DEFAULT_COST); 9607 9608 format %{ "FSQRTS $dst, $src" %} 9609 size(4); 9610 ins_encode %{ 9611 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 9612 %} 9613 ins_pipe(pipe_class_default); 9614 %} 9615 9616 instruct roundDouble_nop(regD dst) %{ 9617 match(Set dst (RoundDouble dst)); 9618 ins_cost(0); 9619 9620 format %{ " -- \t// RoundDouble not needed - empty" %} 9621 size(0); 9622 // PPC results are already "rounded" (i.e., normal-format IEEE). 9623 ins_encode( /*empty*/ ); 9624 ins_pipe(pipe_class_default); 9625 %} 9626 9627 instruct roundFloat_nop(regF dst) %{ 9628 match(Set dst (RoundFloat dst)); 9629 ins_cost(0); 9630 9631 format %{ " -- \t// RoundFloat not needed - empty" %} 9632 size(0); 9633 // PPC results are already "rounded" (i.e., normal-format IEEE). 9634 ins_encode( /*empty*/ ); 9635 ins_pipe(pipe_class_default); 9636 %} 9637 9638 9639 // Multiply-Accumulate 9640 // src1 * src2 + src3 9641 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9642 match(Set dst (FmaF src3 (Binary src1 src2))); 9643 9644 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 9645 size(4); 9646 ins_encode %{ 9647 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9648 %} 9649 ins_pipe(pipe_class_default); 9650 %} 9651 9652 // src1 * src2 + src3 9653 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9654 match(Set dst (FmaD src3 (Binary src1 src2))); 9655 9656 format %{ "FMADD $dst, $src1, $src2, $src3" %} 9657 size(4); 9658 ins_encode %{ 9659 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9660 %} 9661 ins_pipe(pipe_class_default); 9662 %} 9663 9664 // -src1 * src2 + src3 = -(src1*src2-src3) 9665 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9666 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 9667 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 9668 9669 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 9670 size(4); 9671 ins_encode %{ 9672 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9673 %} 9674 ins_pipe(pipe_class_default); 9675 %} 9676 9677 // -src1 * src2 + src3 = -(src1*src2-src3) 9678 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9679 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 9680 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 9681 9682 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 9683 size(4); 9684 ins_encode %{ 9685 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9686 %} 9687 ins_pipe(pipe_class_default); 9688 %} 9689 9690 // -src1 * src2 - src3 = -(src1*src2+src3) 9691 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9692 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 9693 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 9694 9695 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 9696 size(4); 9697 ins_encode %{ 9698 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9699 %} 9700 ins_pipe(pipe_class_default); 9701 %} 9702 9703 // -src1 * src2 - src3 = -(src1*src2+src3) 9704 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9705 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 9706 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 9707 9708 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 9709 size(4); 9710 ins_encode %{ 9711 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9712 %} 9713 ins_pipe(pipe_class_default); 9714 %} 9715 9716 // src1 * src2 - src3 9717 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9718 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 9719 9720 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 9721 size(4); 9722 ins_encode %{ 9723 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9724 %} 9725 ins_pipe(pipe_class_default); 9726 %} 9727 9728 // src1 * src2 - src3 9729 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9730 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 9731 9732 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 9733 size(4); 9734 ins_encode %{ 9735 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9736 %} 9737 ins_pipe(pipe_class_default); 9738 %} 9739 9740 9741 //----------Logical Instructions----------------------------------------------- 9742 9743 // And Instructions 9744 9745 // Register And 9746 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9747 match(Set dst (AndI src1 src2)); 9748 format %{ "AND $dst, $src1, $src2" %} 9749 size(4); 9750 ins_encode %{ 9751 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9752 %} 9753 ins_pipe(pipe_class_default); 9754 %} 9755 9756 // Left shifted Immediate And 9757 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 9758 match(Set dst (AndI src1 src2)); 9759 effect(KILL cr0); 9760 format %{ "ANDIS $dst, $src1, $src2.hi" %} 9761 size(4); 9762 ins_encode %{ 9763 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 9764 %} 9765 ins_pipe(pipe_class_default); 9766 %} 9767 9768 // Immediate And 9769 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 9770 match(Set dst (AndI src1 src2)); 9771 effect(KILL cr0); 9772 9773 format %{ "ANDI $dst, $src1, $src2" %} 9774 size(4); 9775 ins_encode %{ 9776 // FIXME: avoid andi_ ? 9777 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9778 %} 9779 ins_pipe(pipe_class_default); 9780 %} 9781 9782 // Immediate And where the immediate is a negative power of 2. 9783 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 9784 match(Set dst (AndI src1 src2)); 9785 format %{ "ANDWI $dst, $src1, $src2" %} 9786 size(4); 9787 ins_encode %{ 9788 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(juint)$src2$$constant)); 9789 %} 9790 ins_pipe(pipe_class_default); 9791 %} 9792 9793 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 9794 match(Set dst (AndI src1 src2)); 9795 format %{ "ANDWI $dst, $src1, $src2" %} 9796 size(4); 9797 ins_encode %{ 9798 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((juint)$src2$$constant + 1u)); 9799 %} 9800 ins_pipe(pipe_class_default); 9801 %} 9802 9803 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 9804 match(Set dst (AndI src1 src2)); 9805 predicate(UseRotateAndMaskInstructionsPPC64); 9806 format %{ "ANDWI $dst, $src1, $src2" %} 9807 size(4); 9808 ins_encode %{ 9809 int bitpos = 31 - log2i_exact((juint)$src2$$constant); 9810 __ rlwinm($dst$$Register, $src1$$Register, 0, bitpos, bitpos); 9811 %} 9812 ins_pipe(pipe_class_default); 9813 %} 9814 9815 // Register And Long 9816 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9817 match(Set dst (AndL src1 src2)); 9818 ins_cost(DEFAULT_COST); 9819 9820 format %{ "AND $dst, $src1, $src2 \t// long" %} 9821 size(4); 9822 ins_encode %{ 9823 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9824 %} 9825 ins_pipe(pipe_class_default); 9826 %} 9827 9828 // Immediate And long 9829 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 9830 match(Set dst (AndL src1 src2)); 9831 effect(KILL cr0); 9832 9833 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 9834 size(4); 9835 ins_encode %{ 9836 // FIXME: avoid andi_ ? 9837 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9838 %} 9839 ins_pipe(pipe_class_default); 9840 %} 9841 9842 // Immediate And Long where the immediate is a negative power of 2. 9843 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 9844 match(Set dst (AndL src1 src2)); 9845 format %{ "ANDDI $dst, $src1, $src2" %} 9846 size(4); 9847 ins_encode %{ 9848 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(julong)$src2$$constant)); 9849 %} 9850 ins_pipe(pipe_class_default); 9851 %} 9852 9853 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9854 match(Set dst (AndL src1 src2)); 9855 format %{ "ANDDI $dst, $src1, $src2" %} 9856 size(4); 9857 ins_encode %{ 9858 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull)); 9859 %} 9860 ins_pipe(pipe_class_default); 9861 %} 9862 9863 // AndL + ConvL2I. 9864 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9865 match(Set dst (ConvL2I (AndL src1 src2))); 9866 ins_cost(DEFAULT_COST); 9867 9868 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 9869 size(4); 9870 ins_encode %{ 9871 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull)); 9872 %} 9873 ins_pipe(pipe_class_default); 9874 %} 9875 9876 // Or Instructions 9877 9878 // Register Or 9879 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9880 match(Set dst (OrI src1 src2)); 9881 format %{ "OR $dst, $src1, $src2" %} 9882 size(4); 9883 ins_encode %{ 9884 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9885 %} 9886 ins_pipe(pipe_class_default); 9887 %} 9888 9889 // Expand does not work with above instruct. (??) 9890 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9891 // no match-rule 9892 effect(DEF dst, USE src1, USE src2); 9893 format %{ "OR $dst, $src1, $src2" %} 9894 size(4); 9895 ins_encode %{ 9896 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9897 %} 9898 ins_pipe(pipe_class_default); 9899 %} 9900 9901 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9902 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 9903 ins_cost(DEFAULT_COST*3); 9904 9905 expand %{ 9906 // FIXME: we should do this in the ideal world. 9907 iRegIdst tmp1; 9908 iRegIdst tmp2; 9909 orI_reg_reg(tmp1, src1, src2); 9910 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 9911 orI_reg_reg(dst, tmp1, tmp2); 9912 %} 9913 %} 9914 9915 // Immediate Or 9916 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9917 match(Set dst (OrI src1 src2)); 9918 format %{ "ORI $dst, $src1, $src2" %} 9919 size(4); 9920 ins_encode %{ 9921 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 9922 %} 9923 ins_pipe(pipe_class_default); 9924 %} 9925 9926 // Register Or Long 9927 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9928 match(Set dst (OrL src1 src2)); 9929 ins_cost(DEFAULT_COST); 9930 9931 size(4); 9932 format %{ "OR $dst, $src1, $src2 \t// long" %} 9933 ins_encode %{ 9934 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9935 %} 9936 ins_pipe(pipe_class_default); 9937 %} 9938 9939 // OrL + ConvL2I. 9940 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9941 match(Set dst (ConvL2I (OrL src1 src2))); 9942 ins_cost(DEFAULT_COST); 9943 9944 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 9945 size(4); 9946 ins_encode %{ 9947 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9948 %} 9949 ins_pipe(pipe_class_default); 9950 %} 9951 9952 // Immediate Or long 9953 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 9954 match(Set dst (OrL src1 con)); 9955 ins_cost(DEFAULT_COST); 9956 9957 format %{ "ORI $dst, $src1, $con \t// long" %} 9958 size(4); 9959 ins_encode %{ 9960 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 9961 %} 9962 ins_pipe(pipe_class_default); 9963 %} 9964 9965 // Xor Instructions 9966 9967 // Register Xor 9968 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9969 match(Set dst (XorI src1 src2)); 9970 format %{ "XOR $dst, $src1, $src2" %} 9971 size(4); 9972 ins_encode %{ 9973 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9974 %} 9975 ins_pipe(pipe_class_default); 9976 %} 9977 9978 // Expand does not work with above instruct. (??) 9979 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9980 // no match-rule 9981 effect(DEF dst, USE src1, USE src2); 9982 format %{ "XOR $dst, $src1, $src2" %} 9983 size(4); 9984 ins_encode %{ 9985 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9986 %} 9987 ins_pipe(pipe_class_default); 9988 %} 9989 9990 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9991 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 9992 ins_cost(DEFAULT_COST*3); 9993 9994 expand %{ 9995 // FIXME: we should do this in the ideal world. 9996 iRegIdst tmp1; 9997 iRegIdst tmp2; 9998 xorI_reg_reg(tmp1, src1, src2); 9999 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10000 xorI_reg_reg(dst, tmp1, tmp2); 10001 %} 10002 %} 10003 10004 // Immediate Xor 10005 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10006 match(Set dst (XorI src1 src2)); 10007 format %{ "XORI $dst, $src1, $src2" %} 10008 size(4); 10009 ins_encode %{ 10010 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10011 %} 10012 ins_pipe(pipe_class_default); 10013 %} 10014 10015 // Register Xor Long 10016 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10017 match(Set dst (XorL src1 src2)); 10018 ins_cost(DEFAULT_COST); 10019 10020 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10021 size(4); 10022 ins_encode %{ 10023 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10024 %} 10025 ins_pipe(pipe_class_default); 10026 %} 10027 10028 // XorL + ConvL2I. 10029 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10030 match(Set dst (ConvL2I (XorL src1 src2))); 10031 ins_cost(DEFAULT_COST); 10032 10033 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10034 size(4); 10035 ins_encode %{ 10036 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10037 %} 10038 ins_pipe(pipe_class_default); 10039 %} 10040 10041 // Immediate Xor Long 10042 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10043 match(Set dst (XorL src1 src2)); 10044 ins_cost(DEFAULT_COST); 10045 10046 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10047 size(4); 10048 ins_encode %{ 10049 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10050 %} 10051 ins_pipe(pipe_class_default); 10052 %} 10053 10054 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10055 match(Set dst (XorI src1 src2)); 10056 ins_cost(DEFAULT_COST); 10057 10058 format %{ "NOT $dst, $src1 ($src2)" %} 10059 size(4); 10060 ins_encode %{ 10061 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10062 %} 10063 ins_pipe(pipe_class_default); 10064 %} 10065 10066 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10067 match(Set dst (XorL src1 src2)); 10068 ins_cost(DEFAULT_COST); 10069 10070 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10071 size(4); 10072 ins_encode %{ 10073 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10074 %} 10075 ins_pipe(pipe_class_default); 10076 %} 10077 10078 // And-complement 10079 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10080 match(Set dst (AndI (XorI src1 src2) src3)); 10081 ins_cost(DEFAULT_COST); 10082 10083 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10084 size(4); 10085 ins_encode( enc_andc(dst, src3, src1) ); 10086 ins_pipe(pipe_class_default); 10087 %} 10088 10089 // And-complement 10090 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10091 // no match-rule, false predicate 10092 effect(DEF dst, USE src1, USE src2); 10093 predicate(false); 10094 10095 format %{ "ANDC $dst, $src1, $src2" %} 10096 size(4); 10097 ins_encode %{ 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 // For Power7 and earlier, the rules are limited to those which move between a 10114 // register and a stack-location, because we always have to go through memory 10115 // when moving between a float register and an integer register. 10116 // This restriction is removed in Power8 with the introduction of the mtfprd 10117 // and mffprd instructions. 10118 10119 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10120 match(Set dst (MoveL2D src)); 10121 predicate(VM_Version::has_mtfprd()); 10122 10123 format %{ "MTFPRD $dst, $src" %} 10124 size(4); 10125 ins_encode %{ 10126 __ mtfprd($dst$$FloatRegister, $src$$Register); 10127 %} 10128 ins_pipe(pipe_class_default); 10129 %} 10130 10131 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10132 // no match-rule, false predicate 10133 effect(DEF dst, USE src); 10134 predicate(false); 10135 10136 format %{ "MTFPRWA $dst, $src" %} 10137 size(4); 10138 ins_encode %{ 10139 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10140 %} 10141 ins_pipe(pipe_class_default); 10142 %} 10143 10144 //---------- Chain stack slots between similar types -------- 10145 10146 // These are needed so that the rules below can match. 10147 10148 // Load integer from stack slot 10149 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10150 match(Set dst src); 10151 ins_cost(MEMORY_REF_COST); 10152 10153 format %{ "LWZ $dst, $src" %} 10154 size(4); 10155 ins_encode( enc_lwz(dst, src) ); 10156 ins_pipe(pipe_class_memory); 10157 %} 10158 10159 // Store integer to stack slot 10160 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10161 match(Set dst src); 10162 ins_cost(MEMORY_REF_COST); 10163 10164 format %{ "STW $src, $dst \t// stk" %} 10165 size(4); 10166 ins_encode( enc_stw(src, dst) ); // rs=rt 10167 ins_pipe(pipe_class_memory); 10168 %} 10169 10170 // Load long from stack slot 10171 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10172 match(Set dst src); 10173 ins_cost(MEMORY_REF_COST); 10174 10175 format %{ "LD $dst, $src \t// long" %} 10176 size(4); 10177 ins_encode( enc_ld(dst, src) ); 10178 ins_pipe(pipe_class_memory); 10179 %} 10180 10181 // Store long to stack slot 10182 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10183 match(Set dst src); 10184 ins_cost(MEMORY_REF_COST); 10185 10186 format %{ "STD $src, $dst \t// long" %} 10187 size(4); 10188 ins_encode( enc_std(src, dst) ); // rs=rt 10189 ins_pipe(pipe_class_memory); 10190 %} 10191 10192 //----------Moves between int and float 10193 10194 // Move float value from float stack-location to integer register. 10195 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10196 match(Set dst (MoveF2I src)); 10197 ins_cost(MEMORY_REF_COST); 10198 10199 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10200 size(4); 10201 ins_encode( enc_lwz(dst, src) ); 10202 ins_pipe(pipe_class_memory); 10203 %} 10204 10205 // Move float value from float register to integer stack-location. 10206 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10207 match(Set dst (MoveF2I src)); 10208 ins_cost(MEMORY_REF_COST); 10209 10210 format %{ "STFS $src, $dst \t// MoveF2I" %} 10211 size(4); 10212 ins_encode( enc_stfs(src, dst) ); 10213 ins_pipe(pipe_class_memory); 10214 %} 10215 10216 // Move integer value from integer stack-location to float register. 10217 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10218 match(Set dst (MoveI2F src)); 10219 ins_cost(MEMORY_REF_COST); 10220 10221 format %{ "LFS $dst, $src \t// MoveI2F" %} 10222 size(4); 10223 ins_encode %{ 10224 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10225 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10226 %} 10227 ins_pipe(pipe_class_memory); 10228 %} 10229 10230 // Move integer value from integer register to float stack-location. 10231 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10232 match(Set dst (MoveI2F src)); 10233 ins_cost(MEMORY_REF_COST); 10234 10235 format %{ "STW $src, $dst \t// MoveI2F" %} 10236 size(4); 10237 ins_encode( enc_stw(src, dst) ); 10238 ins_pipe(pipe_class_memory); 10239 %} 10240 10241 //----------Moves between long and float 10242 10243 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10244 // no match-rule, false predicate 10245 effect(DEF dst, USE src); 10246 predicate(false); 10247 10248 format %{ "storeD $src, $dst \t// STACK" %} 10249 size(4); 10250 ins_encode( enc_stfd(src, dst) ); 10251 ins_pipe(pipe_class_default); 10252 %} 10253 10254 //----------Moves between long and double 10255 10256 // Move double value from double stack-location to long register. 10257 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10258 match(Set dst (MoveD2L src)); 10259 ins_cost(MEMORY_REF_COST); 10260 size(4); 10261 format %{ "LD $dst, $src \t// MoveD2L" %} 10262 ins_encode( enc_ld(dst, src) ); 10263 ins_pipe(pipe_class_memory); 10264 %} 10265 10266 // Move double value from double register to long stack-location. 10267 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10268 match(Set dst (MoveD2L src)); 10269 effect(DEF dst, USE src); 10270 ins_cost(MEMORY_REF_COST); 10271 10272 format %{ "STFD $src, $dst \t// MoveD2L" %} 10273 size(4); 10274 ins_encode( enc_stfd(src, dst) ); 10275 ins_pipe(pipe_class_memory); 10276 %} 10277 10278 // Move long value from long stack-location to double register. 10279 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10280 match(Set dst (MoveL2D src)); 10281 ins_cost(MEMORY_REF_COST); 10282 10283 format %{ "LFD $dst, $src \t// MoveL2D" %} 10284 size(4); 10285 ins_encode( enc_lfd(dst, src) ); 10286 ins_pipe(pipe_class_memory); 10287 %} 10288 10289 // Move long value from long register to double stack-location. 10290 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10291 match(Set dst (MoveL2D src)); 10292 ins_cost(MEMORY_REF_COST); 10293 10294 format %{ "STD $src, $dst \t// MoveL2D" %} 10295 size(4); 10296 ins_encode( enc_std(src, dst) ); 10297 ins_pipe(pipe_class_memory); 10298 %} 10299 10300 //----------Register Move Instructions----------------------------------------- 10301 10302 // Replicate for Superword 10303 10304 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10305 predicate(false); 10306 effect(DEF dst, USE src); 10307 10308 format %{ "MR $dst, $src \t// replicate " %} 10309 // variable size, 0 or 4. 10310 ins_encode %{ 10311 __ mr_if_needed($dst$$Register, $src$$Register); 10312 %} 10313 ins_pipe(pipe_class_default); 10314 %} 10315 10316 //----------Cast instructions (Java-level type cast)--------------------------- 10317 10318 // Cast Long to Pointer for unsafe natives. 10319 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10320 match(Set dst (CastX2P src)); 10321 10322 format %{ "MR $dst, $src \t// Long->Ptr" %} 10323 // variable size, 0 or 4. 10324 ins_encode %{ 10325 __ mr_if_needed($dst$$Register, $src$$Register); 10326 %} 10327 ins_pipe(pipe_class_default); 10328 %} 10329 10330 // Cast Pointer to Long for unsafe natives. 10331 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10332 match(Set dst (CastP2X src)); 10333 10334 format %{ "MR $dst, $src \t// Ptr->Long" %} 10335 // variable size, 0 or 4. 10336 ins_encode %{ 10337 __ mr_if_needed($dst$$Register, $src$$Register); 10338 %} 10339 ins_pipe(pipe_class_default); 10340 %} 10341 10342 instruct castPP(iRegPdst dst) %{ 10343 match(Set dst (CastPP dst)); 10344 format %{ " -- \t// castPP of $dst" %} 10345 size(0); 10346 ins_encode( /*empty*/ ); 10347 ins_pipe(pipe_class_default); 10348 %} 10349 10350 instruct castII(iRegIdst dst) %{ 10351 match(Set dst (CastII dst)); 10352 format %{ " -- \t// castII of $dst" %} 10353 size(0); 10354 ins_encode( /*empty*/ ); 10355 ins_pipe(pipe_class_default); 10356 %} 10357 10358 instruct castLL(iRegLdst dst) %{ 10359 match(Set dst (CastLL dst)); 10360 format %{ " -- \t// castLL of $dst" %} 10361 size(0); 10362 ins_encode( /*empty*/ ); 10363 ins_pipe(pipe_class_default); 10364 %} 10365 10366 instruct castFF(regF dst) %{ 10367 match(Set dst (CastFF dst)); 10368 format %{ " -- \t// castFF of $dst" %} 10369 size(0); 10370 ins_encode( /*empty*/ ); 10371 ins_pipe(pipe_class_default); 10372 %} 10373 10374 instruct castDD(regD dst) %{ 10375 match(Set dst (CastDD dst)); 10376 format %{ " -- \t// castDD of $dst" %} 10377 size(0); 10378 ins_encode( /*empty*/ ); 10379 ins_pipe(pipe_class_default); 10380 %} 10381 10382 instruct castVV8(iRegLdst dst) %{ 10383 match(Set dst (CastVV dst)); 10384 format %{ " -- \t// castVV of $dst" %} 10385 size(0); 10386 ins_encode( /*empty*/ ); 10387 ins_pipe(pipe_class_default); 10388 %} 10389 10390 instruct castVV16(vecX dst) %{ 10391 match(Set dst (CastVV dst)); 10392 format %{ " -- \t// castVV of $dst" %} 10393 size(0); 10394 ins_encode( /*empty*/ ); 10395 ins_pipe(pipe_class_default); 10396 %} 10397 10398 instruct checkCastPP(iRegPdst dst) %{ 10399 match(Set dst (CheckCastPP dst)); 10400 format %{ " -- \t// checkcastPP of $dst" %} 10401 size(0); 10402 ins_encode( /*empty*/ ); 10403 ins_pipe(pipe_class_default); 10404 %} 10405 10406 //----------Convert instructions----------------------------------------------- 10407 10408 // Convert to boolean. 10409 10410 // int_to_bool(src) : { 1 if src != 0 10411 // { 0 else 10412 // 10413 // strategy: 10414 // 1) Count leading zeros of 32 bit-value src, 10415 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10416 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10417 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10418 10419 // convI2Bool 10420 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10421 match(Set dst (Conv2B src)); 10422 predicate(UseCountLeadingZerosInstructionsPPC64); 10423 ins_cost(DEFAULT_COST); 10424 10425 expand %{ 10426 immI shiftAmount %{ 0x5 %} 10427 uimmI16 mask %{ 0x1 %} 10428 iRegIdst tmp1; 10429 iRegIdst tmp2; 10430 countLeadingZerosI(tmp1, src); 10431 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10432 xorI_reg_uimm16(dst, tmp2, mask); 10433 %} 10434 %} 10435 10436 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10437 match(Set dst (Conv2B src)); 10438 effect(TEMP crx); 10439 predicate(!UseCountLeadingZerosInstructionsPPC64); 10440 ins_cost(DEFAULT_COST); 10441 10442 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10443 "LI $dst, #0\n\t" 10444 "BEQ $crx, done\n\t" 10445 "LI $dst, #1\n" 10446 "done:" %} 10447 size(16); 10448 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10449 ins_pipe(pipe_class_compare); 10450 %} 10451 10452 // ConvI2B + XorI 10453 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10454 match(Set dst (XorI (Conv2B src) mask)); 10455 predicate(UseCountLeadingZerosInstructionsPPC64); 10456 ins_cost(DEFAULT_COST); 10457 10458 expand %{ 10459 immI shiftAmount %{ 0x5 %} 10460 iRegIdst tmp1; 10461 countLeadingZerosI(tmp1, src); 10462 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10463 %} 10464 %} 10465 10466 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10467 match(Set dst (XorI (Conv2B src) mask)); 10468 effect(TEMP crx); 10469 predicate(!UseCountLeadingZerosInstructionsPPC64); 10470 ins_cost(DEFAULT_COST); 10471 10472 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10473 "LI $dst, #1\n\t" 10474 "BEQ $crx, done\n\t" 10475 "LI $dst, #0\n" 10476 "done:" %} 10477 size(16); 10478 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10479 ins_pipe(pipe_class_compare); 10480 %} 10481 10482 // AndI 0b0..010..0 + ConvI2B 10483 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10484 match(Set dst (Conv2B (AndI src mask))); 10485 predicate(UseRotateAndMaskInstructionsPPC64); 10486 ins_cost(DEFAULT_COST); 10487 10488 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10489 size(4); 10490 ins_encode %{ 10491 __ rlwinm($dst$$Register, $src$$Register, 32 - log2i_exact((juint)($mask$$constant)), 31, 31); 10492 %} 10493 ins_pipe(pipe_class_default); 10494 %} 10495 10496 // Convert pointer to boolean. 10497 // 10498 // ptr_to_bool(src) : { 1 if src != 0 10499 // { 0 else 10500 // 10501 // strategy: 10502 // 1) Count leading zeros of 64 bit-value src, 10503 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10504 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10505 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10506 10507 // ConvP2B 10508 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10509 match(Set dst (Conv2B src)); 10510 predicate(UseCountLeadingZerosInstructionsPPC64); 10511 ins_cost(DEFAULT_COST); 10512 10513 expand %{ 10514 immI shiftAmount %{ 0x6 %} 10515 uimmI16 mask %{ 0x1 %} 10516 iRegIdst tmp1; 10517 iRegIdst tmp2; 10518 countLeadingZerosP(tmp1, src); 10519 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10520 xorI_reg_uimm16(dst, tmp2, mask); 10521 %} 10522 %} 10523 10524 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10525 match(Set dst (Conv2B src)); 10526 effect(TEMP crx); 10527 predicate(!UseCountLeadingZerosInstructionsPPC64); 10528 ins_cost(DEFAULT_COST); 10529 10530 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10531 "LI $dst, #0\n\t" 10532 "BEQ $crx, done\n\t" 10533 "LI $dst, #1\n" 10534 "done:" %} 10535 size(16); 10536 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10537 ins_pipe(pipe_class_compare); 10538 %} 10539 10540 // ConvP2B + XorI 10541 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10542 match(Set dst (XorI (Conv2B src) mask)); 10543 predicate(UseCountLeadingZerosInstructionsPPC64); 10544 ins_cost(DEFAULT_COST); 10545 10546 expand %{ 10547 immI shiftAmount %{ 0x6 %} 10548 iRegIdst tmp1; 10549 countLeadingZerosP(tmp1, src); 10550 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10551 %} 10552 %} 10553 10554 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10555 match(Set dst (XorI (Conv2B src) mask)); 10556 effect(TEMP crx); 10557 predicate(!UseCountLeadingZerosInstructionsPPC64); 10558 ins_cost(DEFAULT_COST); 10559 10560 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10561 "LI $dst, #1\n\t" 10562 "BEQ $crx, done\n\t" 10563 "LI $dst, #0\n" 10564 "done:" %} 10565 size(16); 10566 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10567 ins_pipe(pipe_class_compare); 10568 %} 10569 10570 // if src1 < src2, return -1 else return 0 10571 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10572 match(Set dst (CmpLTMask src1 src2)); 10573 ins_cost(DEFAULT_COST*4); 10574 10575 expand %{ 10576 iRegLdst src1s; 10577 iRegLdst src2s; 10578 iRegLdst diff; 10579 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10580 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10581 subL_reg_reg(diff, src1s, src2s); 10582 // Need to consider >=33 bit result, therefore we need signmaskL. 10583 signmask64I_regL(dst, diff); 10584 %} 10585 %} 10586 10587 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 10588 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 10589 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 10590 size(4); 10591 ins_encode %{ 10592 __ srawi($dst$$Register, $src1$$Register, 0x1f); 10593 %} 10594 ins_pipe(pipe_class_default); 10595 %} 10596 10597 //----------Arithmetic Conversion Instructions--------------------------------- 10598 10599 // Convert to Byte -- nop 10600 // Convert to Short -- nop 10601 10602 // Convert to Int 10603 10604 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 10605 match(Set dst (RShiftI (LShiftI src amount) amount)); 10606 format %{ "EXTSB $dst, $src \t// byte->int" %} 10607 size(4); 10608 ins_encode %{ 10609 __ extsb($dst$$Register, $src$$Register); 10610 %} 10611 ins_pipe(pipe_class_default); 10612 %} 10613 10614 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 10615 effect(DEF dst, USE src); 10616 10617 size(4); 10618 ins_encode %{ 10619 __ extsh($dst$$Register, $src$$Register); 10620 %} 10621 ins_pipe(pipe_class_default); 10622 %} 10623 10624 // LShiftI 16 + RShiftI 16 converts short to int. 10625 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 10626 match(Set dst (RShiftI (LShiftI src amount) amount)); 10627 format %{ "EXTSH $dst, $src \t// short->int" %} 10628 size(4); 10629 ins_encode %{ 10630 __ extsh($dst$$Register, $src$$Register); 10631 %} 10632 ins_pipe(pipe_class_default); 10633 %} 10634 10635 // ConvL2I + ConvI2L: Sign extend int in long register. 10636 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 10637 match(Set dst (ConvI2L (ConvL2I src))); 10638 10639 format %{ "EXTSW $dst, $src \t// long->long" %} 10640 size(4); 10641 ins_encode %{ 10642 __ extsw($dst$$Register, $src$$Register); 10643 %} 10644 ins_pipe(pipe_class_default); 10645 %} 10646 10647 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 10648 match(Set dst (ConvL2I src)); 10649 format %{ "MR $dst, $src \t// long->int" %} 10650 // variable size, 0 or 4 10651 ins_encode %{ 10652 __ mr_if_needed($dst$$Register, $src$$Register); 10653 %} 10654 ins_pipe(pipe_class_default); 10655 %} 10656 10657 instruct convD2IRaw_regD(regD dst, regD src) %{ 10658 // no match-rule, false predicate 10659 effect(DEF dst, USE src); 10660 predicate(false); 10661 10662 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 10663 size(4); 10664 ins_encode %{ 10665 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10666 %} 10667 ins_pipe(pipe_class_default); 10668 %} 10669 10670 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 10671 // no match-rule, false predicate 10672 effect(DEF dst, USE crx, USE src); 10673 predicate(false); 10674 10675 ins_variable_size_depending_on_alignment(true); 10676 10677 format %{ "cmovI $crx, $dst, $src" %} 10678 // Worst case is branch + move + stop, no stop without scheduler. 10679 size(8); 10680 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10681 ins_pipe(pipe_class_default); 10682 %} 10683 10684 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 10685 // no match-rule, false predicate 10686 effect(DEF dst, USE crx, USE src); 10687 predicate(false); 10688 10689 ins_variable_size_depending_on_alignment(true); 10690 10691 format %{ "cmovI $crx, $dst, $src" %} 10692 // Worst case is branch + move + stop, no stop without scheduler. 10693 size(8); 10694 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 10695 ins_pipe(pipe_class_default); 10696 %} 10697 10698 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10699 // no match-rule, false predicate 10700 effect(DEF dst, USE crx, USE mem); 10701 predicate(false); 10702 10703 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 10704 postalloc_expand %{ 10705 // 10706 // replaces 10707 // 10708 // region dst crx mem 10709 // \ | | / 10710 // dst=cmovI_bso_stackSlotL_conLvalue0 10711 // 10712 // with 10713 // 10714 // region dst 10715 // \ / 10716 // dst=loadConI16(0) 10717 // | 10718 // ^ region dst crx mem 10719 // | \ | | / 10720 // dst=cmovI_bso_stackSlotL 10721 // 10722 10723 // Create new nodes. 10724 MachNode *m1 = new loadConI16Node(); 10725 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 10726 10727 // inputs for new nodes 10728 m1->add_req(n_region); 10729 m2->add_req(n_region, n_crx, n_mem); 10730 10731 // precedences for new nodes 10732 m2->add_prec(m1); 10733 10734 // operands for new nodes 10735 m1->_opnds[0] = op_dst; 10736 m1->_opnds[1] = new immI16Oper(0); 10737 10738 m2->_opnds[0] = op_dst; 10739 m2->_opnds[1] = op_crx; 10740 m2->_opnds[2] = op_mem; 10741 10742 // registers for new nodes 10743 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10744 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10745 10746 // Insert new nodes. 10747 nodes->push(m1); 10748 nodes->push(m2); 10749 %} 10750 %} 10751 10752 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 10753 // no match-rule, false predicate 10754 effect(DEF dst, USE crx, USE src); 10755 predicate(false); 10756 10757 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 10758 postalloc_expand %{ 10759 // 10760 // replaces 10761 // 10762 // region dst crx src 10763 // \ | | / 10764 // dst=cmovI_bso_reg_conLvalue0 10765 // 10766 // with 10767 // 10768 // region dst 10769 // \ / 10770 // dst=loadConI16(0) 10771 // | 10772 // ^ region dst crx src 10773 // | \ | | / 10774 // dst=cmovI_bso_reg 10775 // 10776 10777 // Create new nodes. 10778 MachNode *m1 = new loadConI16Node(); 10779 MachNode *m2 = new cmovI_bso_regNode(); 10780 10781 // inputs for new nodes 10782 m1->add_req(n_region); 10783 m2->add_req(n_region, n_crx, n_src); 10784 10785 // precedences for new nodes 10786 m2->add_prec(m1); 10787 10788 // operands for new nodes 10789 m1->_opnds[0] = op_dst; 10790 m1->_opnds[1] = new immI16Oper(0); 10791 10792 m2->_opnds[0] = op_dst; 10793 m2->_opnds[1] = op_crx; 10794 m2->_opnds[2] = op_src; 10795 10796 // registers for new nodes 10797 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10798 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10799 10800 // Insert new nodes. 10801 nodes->push(m1); 10802 nodes->push(m2); 10803 %} 10804 %} 10805 10806 // Double to Int conversion, NaN is mapped to 0. 10807 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 10808 match(Set dst (ConvD2I src)); 10809 predicate(!VM_Version::has_mtfprd()); 10810 ins_cost(DEFAULT_COST); 10811 10812 expand %{ 10813 regD tmpD; 10814 stackSlotL tmpS; 10815 flagsReg crx; 10816 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10817 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10818 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10819 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10820 %} 10821 %} 10822 10823 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 10824 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 10825 match(Set dst (ConvD2I src)); 10826 predicate(VM_Version::has_mtfprd()); 10827 ins_cost(DEFAULT_COST); 10828 10829 expand %{ 10830 regD tmpD; 10831 flagsReg crx; 10832 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10833 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10834 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 10835 %} 10836 %} 10837 10838 instruct convF2IRaw_regF(regF dst, regF src) %{ 10839 // no match-rule, false predicate 10840 effect(DEF dst, USE src); 10841 predicate(false); 10842 10843 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 10844 size(4); 10845 ins_encode %{ 10846 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10847 %} 10848 ins_pipe(pipe_class_default); 10849 %} 10850 10851 // Float to Int conversion, NaN is mapped to 0. 10852 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 10853 match(Set dst (ConvF2I src)); 10854 predicate(!VM_Version::has_mtfprd()); 10855 ins_cost(DEFAULT_COST); 10856 10857 expand %{ 10858 regF tmpF; 10859 stackSlotL tmpS; 10860 flagsReg crx; 10861 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10862 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10863 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10864 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10865 %} 10866 %} 10867 10868 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 10869 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 10870 match(Set dst (ConvF2I src)); 10871 predicate(VM_Version::has_mtfprd()); 10872 ins_cost(DEFAULT_COST); 10873 10874 expand %{ 10875 regF tmpF; 10876 flagsReg crx; 10877 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10878 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10879 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 10880 %} 10881 %} 10882 10883 // Convert to Long 10884 10885 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 10886 match(Set dst (ConvI2L src)); 10887 format %{ "EXTSW $dst, $src \t// int->long" %} 10888 size(4); 10889 ins_encode %{ 10890 __ extsw($dst$$Register, $src$$Register); 10891 %} 10892 ins_pipe(pipe_class_default); 10893 %} 10894 10895 // Zero-extend: convert unsigned int to long (convUI2L). 10896 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 10897 match(Set dst (AndL (ConvI2L src) mask)); 10898 ins_cost(DEFAULT_COST); 10899 10900 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10901 size(4); 10902 ins_encode %{ 10903 __ clrldi($dst$$Register, $src$$Register, 32); 10904 %} 10905 ins_pipe(pipe_class_default); 10906 %} 10907 10908 // Zero-extend: convert unsigned int to long in long register. 10909 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 10910 match(Set dst (AndL src mask)); 10911 ins_cost(DEFAULT_COST); 10912 10913 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10914 size(4); 10915 ins_encode %{ 10916 __ clrldi($dst$$Register, $src$$Register, 32); 10917 %} 10918 ins_pipe(pipe_class_default); 10919 %} 10920 10921 instruct convF2LRaw_regF(regF dst, regF src) %{ 10922 // no match-rule, false predicate 10923 effect(DEF dst, USE src); 10924 predicate(false); 10925 10926 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 10927 size(4); 10928 ins_encode %{ 10929 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10930 %} 10931 ins_pipe(pipe_class_default); 10932 %} 10933 10934 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 10935 // no match-rule, false predicate 10936 effect(DEF dst, USE crx, USE src); 10937 predicate(false); 10938 10939 ins_variable_size_depending_on_alignment(true); 10940 10941 format %{ "cmovL $crx, $dst, $src" %} 10942 // Worst case is branch + move + stop, no stop without scheduler. 10943 size(8); 10944 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10945 ins_pipe(pipe_class_default); 10946 %} 10947 10948 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 10949 // no match-rule, false predicate 10950 effect(DEF dst, USE crx, USE src); 10951 predicate(false); 10952 10953 ins_variable_size_depending_on_alignment(true); 10954 10955 format %{ "cmovL $crx, $dst, $src" %} 10956 // Worst case is branch + move + stop, no stop without scheduler. 10957 size(8); 10958 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 10959 ins_pipe(pipe_class_default); 10960 %} 10961 10962 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10963 // no match-rule, false predicate 10964 effect(DEF dst, USE crx, USE mem); 10965 predicate(false); 10966 10967 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 10968 postalloc_expand %{ 10969 // 10970 // replaces 10971 // 10972 // region dst crx mem 10973 // \ | | / 10974 // dst=cmovL_bso_stackSlotL_conLvalue0 10975 // 10976 // with 10977 // 10978 // region dst 10979 // \ / 10980 // dst=loadConL16(0) 10981 // | 10982 // ^ region dst crx mem 10983 // | \ | | / 10984 // dst=cmovL_bso_stackSlotL 10985 // 10986 10987 // Create new nodes. 10988 MachNode *m1 = new loadConL16Node(); 10989 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 10990 10991 // inputs for new nodes 10992 m1->add_req(n_region); 10993 m2->add_req(n_region, n_crx, n_mem); 10994 m2->add_prec(m1); 10995 10996 // operands for new nodes 10997 m1->_opnds[0] = op_dst; 10998 m1->_opnds[1] = new immL16Oper(0); 10999 m2->_opnds[0] = op_dst; 11000 m2->_opnds[1] = op_crx; 11001 m2->_opnds[2] = op_mem; 11002 11003 // registers for new nodes 11004 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11005 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11006 11007 // Insert new nodes. 11008 nodes->push(m1); 11009 nodes->push(m2); 11010 %} 11011 %} 11012 11013 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11014 // no match-rule, false predicate 11015 effect(DEF dst, USE crx, USE src); 11016 predicate(false); 11017 11018 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11019 postalloc_expand %{ 11020 // 11021 // replaces 11022 // 11023 // region dst crx src 11024 // \ | | / 11025 // dst=cmovL_bso_reg_conLvalue0 11026 // 11027 // with 11028 // 11029 // region dst 11030 // \ / 11031 // dst=loadConL16(0) 11032 // | 11033 // ^ region dst crx src 11034 // | \ | | / 11035 // dst=cmovL_bso_reg 11036 // 11037 11038 // Create new nodes. 11039 MachNode *m1 = new loadConL16Node(); 11040 MachNode *m2 = new cmovL_bso_regNode(); 11041 11042 // inputs for new nodes 11043 m1->add_req(n_region); 11044 m2->add_req(n_region, n_crx, n_src); 11045 m2->add_prec(m1); 11046 11047 // operands for new nodes 11048 m1->_opnds[0] = op_dst; 11049 m1->_opnds[1] = new immL16Oper(0); 11050 m2->_opnds[0] = op_dst; 11051 m2->_opnds[1] = op_crx; 11052 m2->_opnds[2] = op_src; 11053 11054 // registers for new nodes 11055 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11056 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11057 11058 // Insert new nodes. 11059 nodes->push(m1); 11060 nodes->push(m2); 11061 %} 11062 %} 11063 11064 // Float to Long conversion, NaN is mapped to 0. 11065 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11066 match(Set dst (ConvF2L src)); 11067 predicate(!VM_Version::has_mtfprd()); 11068 ins_cost(DEFAULT_COST); 11069 11070 expand %{ 11071 regF tmpF; 11072 stackSlotL tmpS; 11073 flagsReg crx; 11074 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11075 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11076 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11077 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11078 %} 11079 %} 11080 11081 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11082 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11083 match(Set dst (ConvF2L src)); 11084 predicate(VM_Version::has_mtfprd()); 11085 ins_cost(DEFAULT_COST); 11086 11087 expand %{ 11088 regF tmpF; 11089 flagsReg crx; 11090 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11091 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11092 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11093 %} 11094 %} 11095 11096 instruct convD2LRaw_regD(regD dst, regD src) %{ 11097 // no match-rule, false predicate 11098 effect(DEF dst, USE src); 11099 predicate(false); 11100 11101 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11102 size(4); 11103 ins_encode %{ 11104 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11105 %} 11106 ins_pipe(pipe_class_default); 11107 %} 11108 11109 // Double to Long conversion, NaN is mapped to 0. 11110 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11111 match(Set dst (ConvD2L src)); 11112 predicate(!VM_Version::has_mtfprd()); 11113 ins_cost(DEFAULT_COST); 11114 11115 expand %{ 11116 regD tmpD; 11117 stackSlotL tmpS; 11118 flagsReg crx; 11119 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11120 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11121 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11122 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11123 %} 11124 %} 11125 11126 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11127 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11128 match(Set dst (ConvD2L src)); 11129 predicate(VM_Version::has_mtfprd()); 11130 ins_cost(DEFAULT_COST); 11131 11132 expand %{ 11133 regD tmpD; 11134 flagsReg crx; 11135 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11136 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11137 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11138 %} 11139 %} 11140 11141 // Convert to Float 11142 11143 // Placed here as needed in expand. 11144 instruct convL2DRaw_regD(regD dst, regD src) %{ 11145 // no match-rule, false predicate 11146 effect(DEF dst, USE src); 11147 predicate(false); 11148 11149 format %{ "FCFID $dst, $src \t// convL2D" %} 11150 size(4); 11151 ins_encode %{ 11152 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11153 %} 11154 ins_pipe(pipe_class_default); 11155 %} 11156 11157 // Placed here as needed in expand. 11158 instruct convD2F_reg(regF dst, regD src) %{ 11159 match(Set dst (ConvD2F src)); 11160 format %{ "FRSP $dst, $src \t// convD2F" %} 11161 size(4); 11162 ins_encode %{ 11163 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11164 %} 11165 ins_pipe(pipe_class_default); 11166 %} 11167 11168 // Integer to Float conversion. 11169 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11170 match(Set dst (ConvI2F src)); 11171 predicate(!VM_Version::has_fcfids()); 11172 ins_cost(DEFAULT_COST); 11173 11174 expand %{ 11175 iRegLdst tmpL; 11176 stackSlotL tmpS; 11177 regD tmpD; 11178 regD tmpD2; 11179 convI2L_reg(tmpL, src); // Sign-extension int to long. 11180 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11181 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11182 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11183 convD2F_reg(dst, tmpD2); // Convert double to float. 11184 %} 11185 %} 11186 11187 instruct convL2FRaw_regF(regF dst, regD src) %{ 11188 // no match-rule, false predicate 11189 effect(DEF dst, USE src); 11190 predicate(false); 11191 11192 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11193 size(4); 11194 ins_encode %{ 11195 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11196 %} 11197 ins_pipe(pipe_class_default); 11198 %} 11199 11200 // Integer to Float conversion. Special version for Power7. 11201 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11202 match(Set dst (ConvI2F src)); 11203 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11204 ins_cost(DEFAULT_COST); 11205 11206 expand %{ 11207 iRegLdst tmpL; 11208 stackSlotL tmpS; 11209 regD tmpD; 11210 convI2L_reg(tmpL, src); // Sign-extension int to long. 11211 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11212 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11213 convL2FRaw_regF(dst, tmpD); // Convert to float. 11214 %} 11215 %} 11216 11217 // Integer to Float conversion. Special version for Power8. 11218 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11219 match(Set dst (ConvI2F src)); 11220 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11221 ins_cost(DEFAULT_COST); 11222 11223 expand %{ 11224 regD tmpD; 11225 moveI2D_reg(tmpD, src); 11226 convL2FRaw_regF(dst, tmpD); // Convert to float. 11227 %} 11228 %} 11229 11230 // L2F to avoid runtime call. 11231 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11232 match(Set dst (ConvL2F src)); 11233 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11234 ins_cost(DEFAULT_COST); 11235 11236 expand %{ 11237 stackSlotL tmpS; 11238 regD tmpD; 11239 regL_to_stkL(tmpS, src); // Store long to stack. 11240 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11241 convL2FRaw_regF(dst, tmpD); // Convert to float. 11242 %} 11243 %} 11244 11245 // L2F to avoid runtime call. Special version for Power8. 11246 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11247 match(Set dst (ConvL2F src)); 11248 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11249 ins_cost(DEFAULT_COST); 11250 11251 expand %{ 11252 regD tmpD; 11253 moveL2D_reg(tmpD, src); 11254 convL2FRaw_regF(dst, tmpD); // Convert to float. 11255 %} 11256 %} 11257 11258 // Moved up as used in expand. 11259 //instruct convD2F_reg(regF dst, regD src) %{%} 11260 11261 // Convert to Double 11262 11263 // Integer to Double conversion. 11264 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11265 match(Set dst (ConvI2D src)); 11266 predicate(!VM_Version::has_mtfprd()); 11267 ins_cost(DEFAULT_COST); 11268 11269 expand %{ 11270 iRegLdst tmpL; 11271 stackSlotL tmpS; 11272 regD tmpD; 11273 convI2L_reg(tmpL, src); // Sign-extension int to long. 11274 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11275 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11276 convL2DRaw_regD(dst, tmpD); // Convert to double. 11277 %} 11278 %} 11279 11280 // Integer to Double conversion. Special version for Power8. 11281 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11282 match(Set dst (ConvI2D src)); 11283 predicate(VM_Version::has_mtfprd()); 11284 ins_cost(DEFAULT_COST); 11285 11286 expand %{ 11287 regD tmpD; 11288 moveI2D_reg(tmpD, src); 11289 convL2DRaw_regD(dst, tmpD); // Convert to double. 11290 %} 11291 %} 11292 11293 // Long to Double conversion 11294 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11295 match(Set dst (ConvL2D src)); 11296 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11297 11298 expand %{ 11299 regD tmpD; 11300 moveL2D_stack_reg(tmpD, src); 11301 convL2DRaw_regD(dst, tmpD); 11302 %} 11303 %} 11304 11305 // Long to Double conversion. Special version for Power8. 11306 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11307 match(Set dst (ConvL2D src)); 11308 predicate(VM_Version::has_mtfprd()); 11309 ins_cost(DEFAULT_COST); 11310 11311 expand %{ 11312 regD tmpD; 11313 moveL2D_reg(tmpD, src); 11314 convL2DRaw_regD(dst, tmpD); // Convert to double. 11315 %} 11316 %} 11317 11318 instruct convF2D_reg(regD dst, regF src) %{ 11319 match(Set dst (ConvF2D src)); 11320 format %{ "FMR $dst, $src \t// float->double" %} 11321 // variable size, 0 or 4 11322 ins_encode %{ 11323 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11324 %} 11325 ins_pipe(pipe_class_default); 11326 %} 11327 11328 //----------Control Flow Instructions------------------------------------------ 11329 // Compare Instructions 11330 11331 // Compare Integers 11332 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11333 match(Set crx (CmpI src1 src2)); 11334 size(4); 11335 format %{ "CMPW $crx, $src1, $src2" %} 11336 ins_encode %{ 11337 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11338 %} 11339 ins_pipe(pipe_class_compare); 11340 %} 11341 11342 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11343 match(Set crx (CmpI src1 src2)); 11344 format %{ "CMPWI $crx, $src1, $src2" %} 11345 size(4); 11346 ins_encode %{ 11347 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11348 %} 11349 ins_pipe(pipe_class_compare); 11350 %} 11351 11352 // (src1 & src2) == 0? 11353 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11354 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11355 // r0 is killed 11356 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11357 size(4); 11358 ins_encode %{ 11359 __ andi_(R0, $src1$$Register, $src2$$constant); 11360 %} 11361 ins_pipe(pipe_class_compare); 11362 %} 11363 11364 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11365 match(Set crx (CmpL src1 src2)); 11366 format %{ "CMPD $crx, $src1, $src2" %} 11367 size(4); 11368 ins_encode %{ 11369 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11370 %} 11371 ins_pipe(pipe_class_compare); 11372 %} 11373 11374 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11375 match(Set crx (CmpL src1 src2)); 11376 format %{ "CMPDI $crx, $src1, $src2" %} 11377 size(4); 11378 ins_encode %{ 11379 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11380 %} 11381 ins_pipe(pipe_class_compare); 11382 %} 11383 11384 // Added CmpUL for LoopPredicate. 11385 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11386 match(Set crx (CmpUL src1 src2)); 11387 format %{ "CMPLD $crx, $src1, $src2" %} 11388 size(4); 11389 ins_encode %{ 11390 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11391 %} 11392 ins_pipe(pipe_class_compare); 11393 %} 11394 11395 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11396 match(Set crx (CmpUL src1 src2)); 11397 format %{ "CMPLDI $crx, $src1, $src2" %} 11398 size(4); 11399 ins_encode %{ 11400 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11401 %} 11402 ins_pipe(pipe_class_compare); 11403 %} 11404 11405 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11406 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11407 // r0 is killed 11408 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11409 size(4); 11410 ins_encode %{ 11411 __ and_(R0, $src1$$Register, $src2$$Register); 11412 %} 11413 ins_pipe(pipe_class_compare); 11414 %} 11415 11416 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11417 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11418 // r0 is killed 11419 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11420 size(4); 11421 ins_encode %{ 11422 __ andi_(R0, $src1$$Register, $src2$$constant); 11423 %} 11424 ins_pipe(pipe_class_compare); 11425 %} 11426 11427 // Manifest a CmpL3 result in an integer register. 11428 instruct cmpL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 11429 match(Set dst (CmpL3 src1 src2)); 11430 effect(KILL cr0); 11431 ins_cost(DEFAULT_COST * 5); 11432 size(VM_Version::has_brw() ? 16 : 20); 11433 11434 format %{ "cmpL3_reg_reg $dst, $src1, $src2" %} 11435 11436 ins_encode %{ 11437 __ cmpd(CCR0, $src1$$Register, $src2$$Register); 11438 __ set_cmp3($dst$$Register); 11439 %} 11440 ins_pipe(pipe_class_default); 11441 %} 11442 11443 // Implicit range checks. 11444 // A range check in the ideal world has one of the following shapes: 11445 // - (If le (CmpU length index)), (IfTrue throw exception) 11446 // - (If lt (CmpU index length)), (IfFalse throw exception) 11447 // 11448 // Match range check 'If le (CmpU length index)'. 11449 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11450 match(If cmp (CmpU src_length index)); 11451 effect(USE labl); 11452 predicate(TrapBasedRangeChecks && 11453 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11454 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11455 (Matcher::branches_to_uncommon_trap(_leaf))); 11456 11457 ins_is_TrapBasedCheckNode(true); 11458 11459 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11460 size(4); 11461 ins_encode %{ 11462 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11463 __ trap_range_check_le($src_length$$Register, $index$$constant); 11464 } else { 11465 // Both successors are uncommon traps, probability is 0. 11466 // Node got flipped during fixup flow. 11467 assert($cmp$$cmpcode == 0x9, "must be greater"); 11468 __ trap_range_check_g($src_length$$Register, $index$$constant); 11469 } 11470 %} 11471 ins_pipe(pipe_class_trap); 11472 %} 11473 11474 // Match range check 'If lt (CmpU index length)'. 11475 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11476 match(If cmp (CmpU src_index src_length)); 11477 effect(USE labl); 11478 predicate(TrapBasedRangeChecks && 11479 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11480 _leaf->as_If()->_prob >= PROB_ALWAYS && 11481 (Matcher::branches_to_uncommon_trap(_leaf))); 11482 11483 ins_is_TrapBasedCheckNode(true); 11484 11485 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 11486 size(4); 11487 ins_encode %{ 11488 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11489 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 11490 } else { 11491 // Both successors are uncommon traps, probability is 0. 11492 // Node got flipped during fixup flow. 11493 assert($cmp$$cmpcode == 0x8, "must be less"); 11494 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 11495 } 11496 %} 11497 ins_pipe(pipe_class_trap); 11498 %} 11499 11500 // Match range check 'If lt (CmpU index length)'. 11501 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 11502 match(If cmp (CmpU src_index length)); 11503 effect(USE labl); 11504 predicate(TrapBasedRangeChecks && 11505 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11506 _leaf->as_If()->_prob >= PROB_ALWAYS && 11507 (Matcher::branches_to_uncommon_trap(_leaf))); 11508 11509 ins_is_TrapBasedCheckNode(true); 11510 11511 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 11512 size(4); 11513 ins_encode %{ 11514 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11515 __ trap_range_check_ge($src_index$$Register, $length$$constant); 11516 } else { 11517 // Both successors are uncommon traps, probability is 0. 11518 // Node got flipped during fixup flow. 11519 assert($cmp$$cmpcode == 0x8, "must be less"); 11520 __ trap_range_check_l($src_index$$Register, $length$$constant); 11521 } 11522 %} 11523 ins_pipe(pipe_class_trap); 11524 %} 11525 11526 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11527 match(Set crx (CmpU src1 src2)); 11528 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 11529 size(4); 11530 ins_encode %{ 11531 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11532 %} 11533 ins_pipe(pipe_class_compare); 11534 %} 11535 11536 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 11537 match(Set crx (CmpU src1 src2)); 11538 size(4); 11539 format %{ "CMPLWI $crx, $src1, $src2" %} 11540 ins_encode %{ 11541 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11542 %} 11543 ins_pipe(pipe_class_compare); 11544 %} 11545 11546 // Implicit zero checks (more implicit null checks). 11547 // No constant pool entries required. 11548 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 11549 match(If cmp (CmpN value zero)); 11550 effect(USE labl); 11551 predicate(TrapBasedNullChecks && 11552 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11553 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11554 Matcher::branches_to_uncommon_trap(_leaf)); 11555 ins_cost(1); 11556 11557 ins_is_TrapBasedCheckNode(true); 11558 11559 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 11560 size(4); 11561 ins_encode %{ 11562 if ($cmp$$cmpcode == 0xA) { 11563 __ trap_null_check($value$$Register); 11564 } else { 11565 // Both successors are uncommon traps, probability is 0. 11566 // Node got flipped during fixup flow. 11567 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11568 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11569 } 11570 %} 11571 ins_pipe(pipe_class_trap); 11572 %} 11573 11574 // Compare narrow oops. 11575 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 11576 match(Set crx (CmpN src1 src2)); 11577 11578 size(4); 11579 ins_cost(2); 11580 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 11581 ins_encode %{ 11582 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11583 %} 11584 ins_pipe(pipe_class_compare); 11585 %} 11586 11587 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 11588 match(Set crx (CmpN src1 src2)); 11589 // Make this more expensive than zeroCheckN_iReg_imm0. 11590 ins_cost(2); 11591 11592 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 11593 size(4); 11594 ins_encode %{ 11595 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11596 %} 11597 ins_pipe(pipe_class_compare); 11598 %} 11599 11600 // Implicit zero checks (more implicit null checks). 11601 // No constant pool entries required. 11602 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 11603 match(If cmp (CmpP value zero)); 11604 effect(USE labl); 11605 predicate(TrapBasedNullChecks && 11606 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11607 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11608 Matcher::branches_to_uncommon_trap(_leaf)); 11609 ins_cost(1); // Should not be cheaper than zeroCheckN. 11610 11611 ins_is_TrapBasedCheckNode(true); 11612 11613 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 11614 size(4); 11615 ins_encode %{ 11616 if ($cmp$$cmpcode == 0xA) { 11617 __ trap_null_check($value$$Register); 11618 } else { 11619 // Both successors are uncommon traps, probability is 0. 11620 // Node got flipped during fixup flow. 11621 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11622 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11623 } 11624 %} 11625 ins_pipe(pipe_class_trap); 11626 %} 11627 11628 // Compare Pointers 11629 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 11630 match(Set crx (CmpP src1 src2)); 11631 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 11632 size(4); 11633 ins_encode %{ 11634 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11635 %} 11636 ins_pipe(pipe_class_compare); 11637 %} 11638 11639 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 11640 match(Set crx (CmpP src1 src2)); 11641 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 11642 size(4); 11643 ins_encode %{ 11644 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 11645 %} 11646 ins_pipe(pipe_class_compare); 11647 %} 11648 11649 // Used in postalloc expand. 11650 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 11651 // This match rule prevents reordering of node before a safepoint. 11652 // This only makes sense if this instructions is used exclusively 11653 // for the expansion of EncodeP! 11654 match(Set crx (CmpP src1 src2)); 11655 predicate(false); 11656 11657 format %{ "CMPDI $crx, $src1, $src2" %} 11658 size(4); 11659 ins_encode %{ 11660 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11661 %} 11662 ins_pipe(pipe_class_compare); 11663 %} 11664 11665 //----------Float Compares---------------------------------------------------- 11666 11667 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 11668 // Needs matchrule, see cmpDUnordered. 11669 match(Set crx (CmpF src1 src2)); 11670 // no match-rule, false predicate 11671 predicate(false); 11672 11673 format %{ "cmpFUrd $crx, $src1, $src2" %} 11674 size(4); 11675 ins_encode %{ 11676 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11677 %} 11678 ins_pipe(pipe_class_default); 11679 %} 11680 11681 instruct cmov_bns_less(flagsReg crx) %{ 11682 // no match-rule, false predicate 11683 effect(DEF crx); 11684 predicate(false); 11685 11686 ins_variable_size_depending_on_alignment(true); 11687 11688 format %{ "cmov $crx" %} 11689 // Worst case is branch + move + stop, no stop without scheduler. 11690 size(12); 11691 ins_encode %{ 11692 Label done; 11693 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 11694 __ li(R0, 0); 11695 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 11696 __ bind(done); 11697 %} 11698 ins_pipe(pipe_class_default); 11699 %} 11700 11701 // Compare floating, generate condition code. 11702 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 11703 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 11704 // 11705 // The following code sequence occurs a lot in mpegaudio: 11706 // 11707 // block BXX: 11708 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 11709 // cmpFUrd CCR6, F11, F9 11710 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 11711 // cmov CCR6 11712 // 8: instruct branchConSched: 11713 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 11714 match(Set crx (CmpF src1 src2)); 11715 ins_cost(DEFAULT_COST+BRANCH_COST); 11716 11717 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 11718 postalloc_expand %{ 11719 // 11720 // replaces 11721 // 11722 // region src1 src2 11723 // \ | | 11724 // crx=cmpF_reg_reg 11725 // 11726 // with 11727 // 11728 // region src1 src2 11729 // \ | | 11730 // crx=cmpFUnordered_reg_reg 11731 // | 11732 // ^ region 11733 // | \ 11734 // crx=cmov_bns_less 11735 // 11736 11737 // Create new nodes. 11738 MachNode *m1 = new cmpFUnordered_reg_regNode(); 11739 MachNode *m2 = new cmov_bns_lessNode(); 11740 11741 // inputs for new nodes 11742 m1->add_req(n_region, n_src1, n_src2); 11743 m2->add_req(n_region); 11744 m2->add_prec(m1); 11745 11746 // operands for new nodes 11747 m1->_opnds[0] = op_crx; 11748 m1->_opnds[1] = op_src1; 11749 m1->_opnds[2] = op_src2; 11750 m2->_opnds[0] = op_crx; 11751 11752 // registers for new nodes 11753 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11754 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11755 11756 // Insert new nodes. 11757 nodes->push(m1); 11758 nodes->push(m2); 11759 %} 11760 %} 11761 11762 // Compare float, generate -1,0,1 11763 instruct cmpF3_reg_reg(iRegIdst dst, regF src1, regF src2, flagsRegCR0 cr0) %{ 11764 match(Set dst (CmpF3 src1 src2)); 11765 effect(KILL cr0); 11766 ins_cost(DEFAULT_COST * 6); 11767 size(VM_Version::has_brw() ? 20 : 24); 11768 11769 format %{ "cmpF3_reg_reg $dst, $src1, $src2" %} 11770 11771 ins_encode %{ 11772 __ fcmpu(CCR0, $src1$$FloatRegister, $src2$$FloatRegister); 11773 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less 11774 %} 11775 ins_pipe(pipe_class_default); 11776 %} 11777 11778 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 11779 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 11780 // node right before the conditional move using it. 11781 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 11782 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 11783 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 11784 // conditional move was supposed to be spilled. 11785 match(Set crx (CmpD src1 src2)); 11786 // False predicate, shall not be matched. 11787 predicate(false); 11788 11789 format %{ "cmpFUrd $crx, $src1, $src2" %} 11790 size(4); 11791 ins_encode %{ 11792 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11793 %} 11794 ins_pipe(pipe_class_default); 11795 %} 11796 11797 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 11798 match(Set crx (CmpD src1 src2)); 11799 ins_cost(DEFAULT_COST+BRANCH_COST); 11800 11801 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 11802 postalloc_expand %{ 11803 // 11804 // replaces 11805 // 11806 // region src1 src2 11807 // \ | | 11808 // crx=cmpD_reg_reg 11809 // 11810 // with 11811 // 11812 // region src1 src2 11813 // \ | | 11814 // crx=cmpDUnordered_reg_reg 11815 // | 11816 // ^ region 11817 // | \ 11818 // crx=cmov_bns_less 11819 // 11820 11821 // create new nodes 11822 MachNode *m1 = new cmpDUnordered_reg_regNode(); 11823 MachNode *m2 = new cmov_bns_lessNode(); 11824 11825 // inputs for new nodes 11826 m1->add_req(n_region, n_src1, n_src2); 11827 m2->add_req(n_region); 11828 m2->add_prec(m1); 11829 11830 // operands for new nodes 11831 m1->_opnds[0] = op_crx; 11832 m1->_opnds[1] = op_src1; 11833 m1->_opnds[2] = op_src2; 11834 m2->_opnds[0] = op_crx; 11835 11836 // registers for new nodes 11837 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11838 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11839 11840 // Insert new nodes. 11841 nodes->push(m1); 11842 nodes->push(m2); 11843 %} 11844 %} 11845 11846 // Compare double, generate -1,0,1 11847 instruct cmpD3_reg_reg(iRegIdst dst, regD src1, regD src2, flagsRegCR0 cr0) %{ 11848 match(Set dst (CmpD3 src1 src2)); 11849 effect(KILL cr0); 11850 ins_cost(DEFAULT_COST * 6); 11851 size(VM_Version::has_brw() ? 20 : 24); 11852 11853 format %{ "cmpD3_reg_reg $dst, $src1, $src2" %} 11854 11855 ins_encode %{ 11856 __ fcmpu(CCR0, $src1$$FloatRegister, $src2$$FloatRegister); 11857 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less 11858 %} 11859 ins_pipe(pipe_class_default); 11860 %} 11861 11862 // Compare char 11863 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 11864 match(Set dst (Digit src1)); 11865 effect(TEMP src2, TEMP crx); 11866 ins_cost(3 * DEFAULT_COST); 11867 11868 format %{ "LI $src2, 0x3930\n\t" 11869 "CMPRB $crx, 0, $src1, $src2\n\t" 11870 "SETB $dst, $crx" %} 11871 size(12); 11872 ins_encode %{ 11873 // 0x30: 0, 0x39: 9 11874 __ li($src2$$Register, 0x3930); 11875 // compare src1 with ranges 0x30 to 0x39 11876 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 11877 __ setb($dst$$Register, $crx$$CondRegister); 11878 %} 11879 ins_pipe(pipe_class_default); 11880 %} 11881 11882 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 11883 match(Set dst (LowerCase src1)); 11884 effect(TEMP src2, TEMP crx); 11885 ins_cost(12 * DEFAULT_COST); 11886 11887 format %{ "LI $src2, 0x7A61\n\t" 11888 "CMPRB $crx, 0, $src1, $src2\n\t" 11889 "BGT $crx, done\n\t" 11890 "LIS $src2, (signed short)0xF6DF\n\t" 11891 "ORI $src2, $src2, 0xFFF8\n\t" 11892 "CMPRB $crx, 1, $src1, $src2\n\t" 11893 "BGT $crx, done\n\t" 11894 "LIS $src2, (signed short)0xAAB5\n\t" 11895 "ORI $src2, $src2, 0xBABA\n\t" 11896 "INSRDI $src2, $src2, 32, 0\n\t" 11897 "CMPEQB $crx, 1, $src1, $src2\n" 11898 "done:\n\t" 11899 "SETB $dst, $crx" %} 11900 11901 size(48); 11902 ins_encode %{ 11903 Label done; 11904 // 0x61: a, 0x7A: z 11905 __ li($src2$$Register, 0x7A61); 11906 // compare src1 with ranges 0x61 to 0x7A 11907 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 11908 __ bgt($crx$$CondRegister, done); 11909 11910 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case 11911 __ lis($src2$$Register, (signed short)0xF6DF); 11912 __ ori($src2$$Register, $src2$$Register, 0xFFF8); 11913 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF 11914 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 11915 __ bgt($crx$$CondRegister, done); 11916 11917 // 0xAA: feminine ordinal indicator 11918 // 0xB5: micro sign 11919 // 0xBA: masculine ordinal indicator 11920 __ lis($src2$$Register, (signed short)0xAAB5); 11921 __ ori($src2$$Register, $src2$$Register, 0xBABA); 11922 __ insrdi($src2$$Register, $src2$$Register, 32, 0); 11923 // compare src1 with 0xAA, 0xB5, and 0xBA 11924 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register); 11925 11926 __ bind(done); 11927 __ setb($dst$$Register, $crx$$CondRegister); 11928 %} 11929 ins_pipe(pipe_class_default); 11930 %} 11931 11932 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 11933 match(Set dst (UpperCase src1)); 11934 effect(TEMP src2, TEMP crx); 11935 ins_cost(7 * DEFAULT_COST); 11936 11937 format %{ "LI $src2, 0x5A41\n\t" 11938 "CMPRB $crx, 0, $src1, $src2\n\t" 11939 "BGT $crx, done\n\t" 11940 "LIS $src2, (signed short)0xD6C0\n\t" 11941 "ORI $src2, $src2, 0xDED8\n\t" 11942 "CMPRB $crx, 1, $src1, $src2\n" 11943 "done:\n\t" 11944 "SETB $dst, $crx" %} 11945 11946 size(28); 11947 ins_encode %{ 11948 Label done; 11949 // 0x41: A, 0x5A: Z 11950 __ li($src2$$Register, 0x5A41); 11951 // compare src1 with a range 0x41 to 0x5A 11952 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 11953 __ bgt($crx$$CondRegister, done); 11954 11955 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case 11956 __ lis($src2$$Register, (signed short)0xD6C0); 11957 __ ori($src2$$Register, $src2$$Register, 0xDED8); 11958 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE 11959 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 11960 11961 __ bind(done); 11962 __ setb($dst$$Register, $crx$$CondRegister); 11963 %} 11964 ins_pipe(pipe_class_default); 11965 %} 11966 11967 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 11968 match(Set dst (Whitespace src1)); 11969 predicate(PowerArchitecturePPC64 <= 9); 11970 effect(TEMP src2, TEMP crx); 11971 ins_cost(4 * DEFAULT_COST); 11972 11973 format %{ "LI $src2, 0x0D09\n\t" 11974 "ADDIS $src2, 0x201C\n\t" 11975 "CMPRB $crx, 1, $src1, $src2\n\t" 11976 "SETB $dst, $crx" %} 11977 size(16); 11978 ins_encode %{ 11979 // 0x09 to 0x0D, 0x1C to 0x20 11980 __ li($src2$$Register, 0x0D09); 11981 __ addis($src2$$Register, $src2$$Register, 0x0201C); 11982 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20 11983 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 11984 __ setb($dst$$Register, $crx$$CondRegister); 11985 %} 11986 ins_pipe(pipe_class_default); 11987 %} 11988 11989 // Power 10 version, using prefixed addi to load 32-bit constant 11990 instruct cmprb_Whitespace_reg_reg_prefixed(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 11991 match(Set dst (Whitespace src1)); 11992 predicate(PowerArchitecturePPC64 >= 10); 11993 effect(TEMP src2, TEMP crx); 11994 ins_cost(3 * DEFAULT_COST); 11995 11996 format %{ "PLI $src2, 0x201C0D09\n\t" 11997 "CMPRB $crx, 1, $src1, $src2\n\t" 11998 "SETB $dst, $crx" %} 11999 size(16); 12000 ins_encode %{ 12001 // 0x09 to 0x0D, 0x1C to 0x20 12002 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 12003 __ pli($src2$$Register, 0x201C0D09); 12004 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20 12005 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12006 __ setb($dst$$Register, $crx$$CondRegister); 12007 %} 12008 ins_pipe(pipe_class_default); 12009 ins_alignment(2); 12010 %} 12011 12012 //----------Branches--------------------------------------------------------- 12013 // Jump 12014 12015 // Direct Branch. 12016 instruct branch(label labl) %{ 12017 match(Goto); 12018 effect(USE labl); 12019 ins_cost(BRANCH_COST); 12020 12021 format %{ "B $labl" %} 12022 size(4); 12023 ins_encode %{ 12024 Label d; // dummy 12025 __ bind(d); 12026 Label* p = $labl$$label; 12027 // `p' is `NULL' when this encoding class is used only to 12028 // determine the size of the encoded instruction. 12029 Label& l = (NULL == p)? d : *(p); 12030 __ b(l); 12031 %} 12032 ins_pipe(pipe_class_default); 12033 %} 12034 12035 // Conditional Near Branch 12036 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12037 // Same match rule as `branchConFar'. 12038 match(If cmp crx); 12039 effect(USE lbl); 12040 ins_cost(BRANCH_COST); 12041 12042 // If set to 1 this indicates that the current instruction is a 12043 // short variant of a long branch. This avoids using this 12044 // instruction in first-pass matching. It will then only be used in 12045 // the `Shorten_branches' pass. 12046 ins_short_branch(1); 12047 12048 format %{ "B$cmp $crx, $lbl" %} 12049 size(4); 12050 ins_encode( enc_bc(crx, cmp, lbl) ); 12051 ins_pipe(pipe_class_default); 12052 %} 12053 12054 // This is for cases when the ppc64 `bc' instruction does not 12055 // reach far enough. So we emit a far branch here, which is more 12056 // expensive. 12057 // 12058 // Conditional Far Branch 12059 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12060 // Same match rule as `branchCon'. 12061 match(If cmp crx); 12062 effect(USE crx, USE lbl); 12063 // Higher cost than `branchCon'. 12064 ins_cost(5*BRANCH_COST); 12065 12066 // This is not a short variant of a branch, but the long variant. 12067 ins_short_branch(0); 12068 12069 format %{ "B_FAR$cmp $crx, $lbl" %} 12070 size(8); 12071 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12072 ins_pipe(pipe_class_default); 12073 %} 12074 12075 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12076 match(CountedLoopEnd cmp crx); 12077 effect(USE labl); 12078 ins_cost(BRANCH_COST); 12079 12080 // short variant. 12081 ins_short_branch(1); 12082 12083 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12084 size(4); 12085 ins_encode( enc_bc(crx, cmp, labl) ); 12086 ins_pipe(pipe_class_default); 12087 %} 12088 12089 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12090 match(CountedLoopEnd cmp crx); 12091 effect(USE labl); 12092 ins_cost(BRANCH_COST); 12093 12094 // Long variant. 12095 ins_short_branch(0); 12096 12097 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12098 size(8); 12099 ins_encode( enc_bc_far(crx, cmp, labl) ); 12100 ins_pipe(pipe_class_default); 12101 %} 12102 12103 // ============================================================================ 12104 // Java runtime operations, intrinsics and other complex operations. 12105 12106 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12107 // array for an instance of the superklass. Set a hidden internal cache on a 12108 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12109 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12110 // 12111 // GL TODO: Improve this. 12112 // - result should not be a TEMP 12113 // - Add match rule as on sparc avoiding additional Cmp. 12114 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12115 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12116 match(Set result (PartialSubtypeCheck subklass superklass)); 12117 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12118 ins_cost(DEFAULT_COST*10); 12119 12120 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12121 ins_encode %{ 12122 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12123 $tmp_klass$$Register, NULL, $result$$Register); 12124 %} 12125 ins_pipe(pipe_class_default); 12126 %} 12127 12128 // inlined locking and unlocking 12129 12130 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12131 match(Set crx (FastLock oop box)); 12132 effect(TEMP tmp1, TEMP tmp2); 12133 predicate(!Compile::current()->use_rtm()); 12134 12135 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12136 ins_encode %{ 12137 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12138 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12139 UseBiasedLocking && !UseOptoBiasInlining); 12140 // If locking was successfull, crx should indicate 'EQ'. 12141 // The compiler generates a branch to the runtime call to 12142 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12143 %} 12144 ins_pipe(pipe_class_compare); 12145 %} 12146 12147 // Separate version for TM. Use bound register for box to enable USE_KILL. 12148 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12149 match(Set crx (FastLock oop box)); 12150 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12151 predicate(Compile::current()->use_rtm()); 12152 12153 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12154 ins_encode %{ 12155 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12156 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12157 /*Biased Locking*/ false, 12158 _rtm_counters, _stack_rtm_counters, 12159 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12160 /*TM*/ true, ra_->C->profile_rtm()); 12161 // If locking was successfull, crx should indicate 'EQ'. 12162 // The compiler generates a branch to the runtime call to 12163 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12164 %} 12165 ins_pipe(pipe_class_compare); 12166 %} 12167 12168 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12169 match(Set crx (FastUnlock oop box)); 12170 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12171 predicate(!Compile::current()->use_rtm()); 12172 12173 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12174 ins_encode %{ 12175 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12176 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12177 UseBiasedLocking && !UseOptoBiasInlining, 12178 false); 12179 // If unlocking was successfull, crx should indicate 'EQ'. 12180 // The compiler generates a branch to the runtime call to 12181 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12182 %} 12183 ins_pipe(pipe_class_compare); 12184 %} 12185 12186 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12187 match(Set crx (FastUnlock oop box)); 12188 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12189 predicate(Compile::current()->use_rtm()); 12190 12191 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12192 ins_encode %{ 12193 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12194 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12195 /*Biased Locking*/ false, /*TM*/ true); 12196 // If unlocking was successfull, crx should indicate 'EQ'. 12197 // The compiler generates a branch to the runtime call to 12198 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12199 %} 12200 ins_pipe(pipe_class_compare); 12201 %} 12202 12203 // Align address. 12204 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12205 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12206 12207 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12208 size(4); 12209 ins_encode %{ 12210 __ clrrdi($dst$$Register, $src$$Register, log2i_exact(-(julong)$mask$$constant)); 12211 %} 12212 ins_pipe(pipe_class_default); 12213 %} 12214 12215 // Array size computation. 12216 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12217 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12218 12219 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12220 size(4); 12221 ins_encode %{ 12222 __ subf($dst$$Register, $start$$Register, $end$$Register); 12223 %} 12224 ins_pipe(pipe_class_default); 12225 %} 12226 12227 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12228 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12229 match(Set dummy (ClearArray cnt base)); 12230 effect(USE_KILL base, KILL ctr); 12231 ins_cost(2 * MEMORY_REF_COST); 12232 12233 format %{ "ClearArray $cnt, $base" %} 12234 ins_encode %{ 12235 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12236 %} 12237 ins_pipe(pipe_class_default); 12238 %} 12239 12240 // Clear-array with constant large array length. 12241 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12242 match(Set dummy (ClearArray cnt base)); 12243 effect(USE_KILL base, TEMP tmp, KILL ctr); 12244 ins_cost(3 * MEMORY_REF_COST); 12245 12246 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12247 ins_encode %{ 12248 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12249 %} 12250 ins_pipe(pipe_class_default); 12251 %} 12252 12253 // Clear-array with dynamic array length. 12254 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12255 match(Set dummy (ClearArray cnt base)); 12256 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12257 ins_cost(4 * MEMORY_REF_COST); 12258 12259 format %{ "ClearArray $cnt, $base" %} 12260 ins_encode %{ 12261 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12262 %} 12263 ins_pipe(pipe_class_default); 12264 %} 12265 12266 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12267 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12268 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12269 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12270 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12271 ins_cost(300); 12272 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12273 ins_encode %{ 12274 __ string_compare($str1$$Register, $str2$$Register, 12275 $cnt1$$Register, $cnt2$$Register, 12276 $tmp$$Register, 12277 $result$$Register, StrIntrinsicNode::LL); 12278 %} 12279 ins_pipe(pipe_class_default); 12280 %} 12281 12282 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12283 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12284 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12285 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12286 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12287 ins_cost(300); 12288 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12289 ins_encode %{ 12290 __ string_compare($str1$$Register, $str2$$Register, 12291 $cnt1$$Register, $cnt2$$Register, 12292 $tmp$$Register, 12293 $result$$Register, StrIntrinsicNode::UU); 12294 %} 12295 ins_pipe(pipe_class_default); 12296 %} 12297 12298 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12299 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12300 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12301 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12302 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12303 ins_cost(300); 12304 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12305 ins_encode %{ 12306 __ string_compare($str1$$Register, $str2$$Register, 12307 $cnt1$$Register, $cnt2$$Register, 12308 $tmp$$Register, 12309 $result$$Register, StrIntrinsicNode::LU); 12310 %} 12311 ins_pipe(pipe_class_default); 12312 %} 12313 12314 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12315 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12316 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12317 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12318 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12319 ins_cost(300); 12320 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12321 ins_encode %{ 12322 __ string_compare($str2$$Register, $str1$$Register, 12323 $cnt2$$Register, $cnt1$$Register, 12324 $tmp$$Register, 12325 $result$$Register, StrIntrinsicNode::UL); 12326 %} 12327 ins_pipe(pipe_class_default); 12328 %} 12329 12330 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12331 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12332 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12333 match(Set result (StrEquals (Binary str1 str2) cnt)); 12334 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12335 ins_cost(300); 12336 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12337 ins_encode %{ 12338 __ array_equals(false, $str1$$Register, $str2$$Register, 12339 $cnt$$Register, $tmp$$Register, 12340 $result$$Register, true /* byte */); 12341 %} 12342 ins_pipe(pipe_class_default); 12343 %} 12344 12345 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12346 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12347 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12348 match(Set result (StrEquals (Binary str1 str2) cnt)); 12349 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12350 ins_cost(300); 12351 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12352 ins_encode %{ 12353 __ array_equals(false, $str1$$Register, $str2$$Register, 12354 $cnt$$Register, $tmp$$Register, 12355 $result$$Register, false /* byte */); 12356 %} 12357 ins_pipe(pipe_class_default); 12358 %} 12359 12360 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12361 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12362 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12363 match(Set result (AryEq ary1 ary2)); 12364 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12365 ins_cost(300); 12366 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12367 ins_encode %{ 12368 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12369 $tmp1$$Register, $tmp2$$Register, 12370 $result$$Register, true /* byte */); 12371 %} 12372 ins_pipe(pipe_class_default); 12373 %} 12374 12375 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12376 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12377 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12378 match(Set result (AryEq ary1 ary2)); 12379 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12380 ins_cost(300); 12381 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12382 ins_encode %{ 12383 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12384 $tmp1$$Register, $tmp2$$Register, 12385 $result$$Register, false /* byte */); 12386 %} 12387 ins_pipe(pipe_class_default); 12388 %} 12389 12390 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12391 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12392 iRegIdst tmp1, iRegIdst tmp2, 12393 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12394 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12395 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12396 // Required for EA: check if it is still a type_array. 12397 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12398 ins_cost(150); 12399 12400 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12401 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12402 12403 ins_encode %{ 12404 immPOper *needleOper = (immPOper *)$needleImm; 12405 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12406 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12407 jchar chr; 12408 #ifdef VM_LITTLE_ENDIAN 12409 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12410 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12411 #else 12412 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12413 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12414 #endif 12415 __ string_indexof_char($result$$Register, 12416 $haystack$$Register, $haycnt$$Register, 12417 R0, chr, 12418 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12419 %} 12420 ins_pipe(pipe_class_compare); 12421 %} 12422 12423 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12424 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12425 iRegIdst tmp1, iRegIdst tmp2, 12426 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12427 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12428 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12429 // Required for EA: check if it is still a type_array. 12430 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12431 ins_cost(150); 12432 12433 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12434 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12435 12436 ins_encode %{ 12437 immPOper *needleOper = (immPOper *)$needleImm; 12438 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12439 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12440 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12441 __ string_indexof_char($result$$Register, 12442 $haystack$$Register, $haycnt$$Register, 12443 R0, chr, 12444 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12445 %} 12446 ins_pipe(pipe_class_compare); 12447 %} 12448 12449 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12450 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12451 iRegIdst tmp1, iRegIdst tmp2, 12452 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12453 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12454 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12455 // Required for EA: check if it is still a type_array. 12456 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12457 ins_cost(150); 12458 12459 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12460 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12461 12462 ins_encode %{ 12463 immPOper *needleOper = (immPOper *)$needleImm; 12464 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12465 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12466 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12467 __ string_indexof_char($result$$Register, 12468 $haystack$$Register, $haycnt$$Register, 12469 R0, chr, 12470 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12471 %} 12472 ins_pipe(pipe_class_compare); 12473 %} 12474 12475 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12476 rscratch2RegP needle, immI_1 needlecntImm, 12477 iRegIdst tmp1, iRegIdst tmp2, 12478 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12479 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12480 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12481 // Required for EA: check if it is still a type_array. 12482 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12483 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12484 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12485 ins_cost(180); 12486 12487 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12488 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12489 ins_encode %{ 12490 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12491 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12492 guarantee(needle_values, "sanity"); 12493 jchar chr; 12494 #ifdef VM_LITTLE_ENDIAN 12495 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12496 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12497 #else 12498 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12499 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12500 #endif 12501 __ string_indexof_char($result$$Register, 12502 $haystack$$Register, $haycnt$$Register, 12503 R0, chr, 12504 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12505 %} 12506 ins_pipe(pipe_class_compare); 12507 %} 12508 12509 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12510 rscratch2RegP needle, immI_1 needlecntImm, 12511 iRegIdst tmp1, iRegIdst tmp2, 12512 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12513 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12514 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12515 // Required for EA: check if it is still a type_array. 12516 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12517 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12518 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12519 ins_cost(180); 12520 12521 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12522 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12523 ins_encode %{ 12524 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12525 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12526 guarantee(needle_values, "sanity"); 12527 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12528 __ string_indexof_char($result$$Register, 12529 $haystack$$Register, $haycnt$$Register, 12530 R0, chr, 12531 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12532 %} 12533 ins_pipe(pipe_class_compare); 12534 %} 12535 12536 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12537 rscratch2RegP needle, immI_1 needlecntImm, 12538 iRegIdst tmp1, iRegIdst tmp2, 12539 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12540 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12541 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12542 // Required for EA: check if it is still a type_array. 12543 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12544 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12545 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12546 ins_cost(180); 12547 12548 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12549 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12550 ins_encode %{ 12551 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12552 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12553 guarantee(needle_values, "sanity"); 12554 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12555 __ string_indexof_char($result$$Register, 12556 $haystack$$Register, $haycnt$$Register, 12557 R0, chr, 12558 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12559 %} 12560 ins_pipe(pipe_class_compare); 12561 %} 12562 12563 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12564 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12565 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12566 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12567 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12568 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U); 12569 ins_cost(180); 12570 12571 format %{ "StringUTF16 IndexOfChar $haystack[0..$haycnt], $ch" 12572 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12573 ins_encode %{ 12574 __ string_indexof_char($result$$Register, 12575 $haystack$$Register, $haycnt$$Register, 12576 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12577 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12578 %} 12579 ins_pipe(pipe_class_compare); 12580 %} 12581 12582 instruct indexOfChar_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12583 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12584 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12585 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12586 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12587 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L); 12588 ins_cost(180); 12589 12590 format %{ "StringLatin1 IndexOfChar $haystack[0..$haycnt], $ch" 12591 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12592 ins_encode %{ 12593 __ string_indexof_char($result$$Register, 12594 $haystack$$Register, $haycnt$$Register, 12595 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12596 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12597 %} 12598 ins_pipe(pipe_class_compare); 12599 %} 12600 12601 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12602 iRegPsrc needle, uimmI15 needlecntImm, 12603 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12604 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12605 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12606 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12607 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12608 // Required for EA: check if it is still a type_array. 12609 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12610 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12611 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12612 ins_cost(250); 12613 12614 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12615 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12616 ins_encode %{ 12617 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12618 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12619 12620 __ string_indexof($result$$Register, 12621 $haystack$$Register, $haycnt$$Register, 12622 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12623 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12624 %} 12625 ins_pipe(pipe_class_compare); 12626 %} 12627 12628 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12629 iRegPsrc needle, uimmI15 needlecntImm, 12630 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12631 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12632 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12633 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12634 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12635 // Required for EA: check if it is still a type_array. 12636 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12637 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12638 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12639 ins_cost(250); 12640 12641 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12642 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12643 ins_encode %{ 12644 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12645 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12646 12647 __ string_indexof($result$$Register, 12648 $haystack$$Register, $haycnt$$Register, 12649 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12650 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12651 %} 12652 ins_pipe(pipe_class_compare); 12653 %} 12654 12655 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12656 iRegPsrc needle, uimmI15 needlecntImm, 12657 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12658 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12659 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12660 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12661 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12662 // Required for EA: check if it is still a type_array. 12663 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12664 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12665 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12666 ins_cost(250); 12667 12668 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12669 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12670 ins_encode %{ 12671 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12672 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12673 12674 __ string_indexof($result$$Register, 12675 $haystack$$Register, $haycnt$$Register, 12676 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12677 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12678 %} 12679 ins_pipe(pipe_class_compare); 12680 %} 12681 12682 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12683 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12684 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12685 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12686 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12687 TEMP_DEF result, 12688 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12689 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12690 ins_cost(300); 12691 12692 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12693 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12694 ins_encode %{ 12695 __ string_indexof($result$$Register, 12696 $haystack$$Register, $haycnt$$Register, 12697 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12698 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12699 %} 12700 ins_pipe(pipe_class_compare); 12701 %} 12702 12703 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12704 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12705 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12706 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12707 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12708 TEMP_DEF result, 12709 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12710 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12711 ins_cost(300); 12712 12713 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12714 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12715 ins_encode %{ 12716 __ string_indexof($result$$Register, 12717 $haystack$$Register, $haycnt$$Register, 12718 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12719 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12720 %} 12721 ins_pipe(pipe_class_compare); 12722 %} 12723 12724 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12725 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12726 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12727 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12728 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12729 TEMP_DEF result, 12730 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12731 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12732 ins_cost(300); 12733 12734 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12735 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12736 ins_encode %{ 12737 __ string_indexof($result$$Register, 12738 $haystack$$Register, $haycnt$$Register, 12739 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12740 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12741 %} 12742 ins_pipe(pipe_class_compare); 12743 %} 12744 12745 // char[] to byte[] compression 12746 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12747 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12748 match(Set result (StrCompressedCopy src (Binary dst len))); 12749 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12750 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12751 ins_cost(300); 12752 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12753 ins_encode %{ 12754 Label Lskip, Ldone; 12755 __ li($result$$Register, 0); 12756 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12757 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 12758 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12759 __ beq(CCR0, Lskip); 12760 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 12761 __ bind(Lskip); 12762 __ mr($result$$Register, $len$$Register); 12763 __ bind(Ldone); 12764 %} 12765 ins_pipe(pipe_class_default); 12766 %} 12767 12768 // byte[] to char[] inflation 12769 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 12770 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12771 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12772 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12773 ins_cost(300); 12774 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12775 ins_encode %{ 12776 Label Ldone; 12777 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12778 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 12779 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12780 __ beq(CCR0, Ldone); 12781 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 12782 __ bind(Ldone); 12783 %} 12784 ins_pipe(pipe_class_default); 12785 %} 12786 12787 // StringCoding.java intrinsics 12788 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 12789 regCTR ctr, flagsRegCR0 cr0) 12790 %{ 12791 match(Set result (HasNegatives ary1 len)); 12792 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 12793 ins_cost(300); 12794 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 12795 ins_encode %{ 12796 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 12797 $tmp1$$Register, $tmp2$$Register); 12798 %} 12799 ins_pipe(pipe_class_default); 12800 %} 12801 12802 // encode char[] to byte[] in ISO_8859_1 12803 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12804 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12805 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 12806 match(Set result (EncodeISOArray src (Binary dst len))); 12807 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12808 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12809 ins_cost(300); 12810 format %{ "Encode iso array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12811 ins_encode %{ 12812 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register, 12813 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false); 12814 %} 12815 ins_pipe(pipe_class_default); 12816 %} 12817 12818 // encode char[] to byte[] in ASCII 12819 instruct encode_ascii_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12820 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12821 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 12822 match(Set result (EncodeISOArray src (Binary dst len))); 12823 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12824 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12825 ins_cost(300); 12826 format %{ "Encode ascii array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12827 ins_encode %{ 12828 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register, 12829 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, true); 12830 %} 12831 ins_pipe(pipe_class_default); 12832 %} 12833 12834 12835 //---------- Min/Max Instructions --------------------------------------------- 12836 12837 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12838 match(Set dst (MinI src1 src2)); 12839 ins_cost(DEFAULT_COST*6); 12840 12841 expand %{ 12842 iRegLdst src1s; 12843 iRegLdst src2s; 12844 iRegLdst diff; 12845 iRegLdst sm; 12846 iRegLdst doz; // difference or zero 12847 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12848 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12849 subL_reg_reg(diff, src2s, src1s); 12850 // Need to consider >=33 bit result, therefore we need signmaskL. 12851 signmask64L_regL(sm, diff); 12852 andL_reg_reg(doz, diff, sm); // <=0 12853 addI_regL_regL(dst, doz, src1s); 12854 %} 12855 %} 12856 12857 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12858 match(Set dst (MinI src1 src2)); 12859 effect(KILL cr0); 12860 predicate(VM_Version::has_isel()); 12861 ins_cost(DEFAULT_COST*2); 12862 12863 ins_encode %{ 12864 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12865 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 12866 %} 12867 ins_pipe(pipe_class_default); 12868 %} 12869 12870 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12871 match(Set dst (MaxI src1 src2)); 12872 ins_cost(DEFAULT_COST*6); 12873 12874 expand %{ 12875 iRegLdst src1s; 12876 iRegLdst src2s; 12877 iRegLdst diff; 12878 iRegLdst sm; 12879 iRegLdst doz; // difference or zero 12880 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12881 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12882 subL_reg_reg(diff, src2s, src1s); 12883 // Need to consider >=33 bit result, therefore we need signmaskL. 12884 signmask64L_regL(sm, diff); 12885 andcL_reg_reg(doz, diff, sm); // >=0 12886 addI_regL_regL(dst, doz, src1s); 12887 %} 12888 %} 12889 12890 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12891 match(Set dst (MaxI src1 src2)); 12892 effect(KILL cr0); 12893 predicate(VM_Version::has_isel()); 12894 ins_cost(DEFAULT_COST*2); 12895 12896 ins_encode %{ 12897 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12898 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 12899 %} 12900 ins_pipe(pipe_class_default); 12901 %} 12902 12903 //---------- Population Count Instructions ------------------------------------ 12904 12905 // Popcnt for Power7. 12906 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 12907 match(Set dst (PopCountI src)); 12908 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12909 ins_cost(DEFAULT_COST); 12910 12911 format %{ "POPCNTW $dst, $src" %} 12912 size(4); 12913 ins_encode %{ 12914 __ popcntw($dst$$Register, $src$$Register); 12915 %} 12916 ins_pipe(pipe_class_default); 12917 %} 12918 12919 // Popcnt for Power7. 12920 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 12921 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12922 match(Set dst (PopCountL src)); 12923 ins_cost(DEFAULT_COST); 12924 12925 format %{ "POPCNTD $dst, $src" %} 12926 size(4); 12927 ins_encode %{ 12928 __ popcntd($dst$$Register, $src$$Register); 12929 %} 12930 ins_pipe(pipe_class_default); 12931 %} 12932 12933 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 12934 match(Set dst (CountLeadingZerosI src)); 12935 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12936 ins_cost(DEFAULT_COST); 12937 12938 format %{ "CNTLZW $dst, $src" %} 12939 size(4); 12940 ins_encode %{ 12941 __ cntlzw($dst$$Register, $src$$Register); 12942 %} 12943 ins_pipe(pipe_class_default); 12944 %} 12945 12946 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 12947 match(Set dst (CountLeadingZerosL src)); 12948 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12949 ins_cost(DEFAULT_COST); 12950 12951 format %{ "CNTLZD $dst, $src" %} 12952 size(4); 12953 ins_encode %{ 12954 __ cntlzd($dst$$Register, $src$$Register); 12955 %} 12956 ins_pipe(pipe_class_default); 12957 %} 12958 12959 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 12960 // no match-rule, false predicate 12961 effect(DEF dst, USE src); 12962 predicate(false); 12963 12964 format %{ "CNTLZD $dst, $src" %} 12965 size(4); 12966 ins_encode %{ 12967 __ cntlzd($dst$$Register, $src$$Register); 12968 %} 12969 ins_pipe(pipe_class_default); 12970 %} 12971 12972 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 12973 match(Set dst (CountTrailingZerosI src)); 12974 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 12975 ins_cost(DEFAULT_COST); 12976 12977 expand %{ 12978 immI16 imm1 %{ (int)-1 %} 12979 immI16 imm2 %{ (int)32 %} 12980 immI_minus1 m1 %{ -1 %} 12981 iRegIdst tmpI1; 12982 iRegIdst tmpI2; 12983 iRegIdst tmpI3; 12984 addI_reg_imm16(tmpI1, src, imm1); 12985 andcI_reg_reg(tmpI2, src, m1, tmpI1); 12986 countLeadingZerosI(tmpI3, tmpI2); 12987 subI_imm16_reg(dst, imm2, tmpI3); 12988 %} 12989 %} 12990 12991 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{ 12992 match(Set dst (CountTrailingZerosI src)); 12993 predicate(UseCountTrailingZerosInstructionsPPC64); 12994 ins_cost(DEFAULT_COST); 12995 12996 format %{ "CNTTZW $dst, $src" %} 12997 size(4); 12998 ins_encode %{ 12999 __ cnttzw($dst$$Register, $src$$Register); 13000 %} 13001 ins_pipe(pipe_class_default); 13002 %} 13003 13004 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13005 match(Set dst (CountTrailingZerosL src)); 13006 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13007 ins_cost(DEFAULT_COST); 13008 13009 expand %{ 13010 immL16 imm1 %{ (long)-1 %} 13011 immI16 imm2 %{ (int)64 %} 13012 iRegLdst tmpL1; 13013 iRegLdst tmpL2; 13014 iRegIdst tmpL3; 13015 addL_reg_imm16(tmpL1, src, imm1); 13016 andcL_reg_reg(tmpL2, tmpL1, src); 13017 countLeadingZerosL(tmpL3, tmpL2); 13018 subI_imm16_reg(dst, imm2, tmpL3); 13019 %} 13020 %} 13021 13022 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{ 13023 match(Set dst (CountTrailingZerosL src)); 13024 predicate(UseCountTrailingZerosInstructionsPPC64); 13025 ins_cost(DEFAULT_COST); 13026 13027 format %{ "CNTTZD $dst, $src" %} 13028 size(4); 13029 ins_encode %{ 13030 __ cnttzd($dst$$Register, $src$$Register); 13031 %} 13032 ins_pipe(pipe_class_default); 13033 %} 13034 13035 // Expand nodes for byte_reverse_int. 13036 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13037 effect(DEF dst, USE src, USE pos, USE shift); 13038 predicate(false); 13039 13040 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13041 size(4); 13042 ins_encode %{ 13043 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13044 %} 13045 ins_pipe(pipe_class_default); 13046 %} 13047 13048 // As insrwi_a, but with USE_DEF. 13049 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13050 effect(USE_DEF dst, USE src, USE pos, USE shift); 13051 predicate(false); 13052 13053 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13054 size(4); 13055 ins_encode %{ 13056 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13057 %} 13058 ins_pipe(pipe_class_default); 13059 %} 13060 13061 // Just slightly faster than java implementation. 13062 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13063 match(Set dst (ReverseBytesI src)); 13064 predicate(!UseByteReverseInstructions); 13065 ins_cost(7*DEFAULT_COST); 13066 13067 expand %{ 13068 immI16 imm24 %{ (int) 24 %} 13069 immI16 imm16 %{ (int) 16 %} 13070 immI16 imm8 %{ (int) 8 %} 13071 immI16 imm4 %{ (int) 4 %} 13072 immI16 imm0 %{ (int) 0 %} 13073 iRegLdst tmpI1; 13074 iRegLdst tmpI2; 13075 iRegLdst tmpI3; 13076 13077 urShiftI_reg_imm(tmpI1, src, imm24); 13078 insrwi_a(dst, tmpI1, imm24, imm8); 13079 urShiftI_reg_imm(tmpI2, src, imm16); 13080 insrwi(dst, tmpI2, imm8, imm16); 13081 urShiftI_reg_imm(tmpI3, src, imm8); 13082 insrwi(dst, tmpI3, imm8, imm8); 13083 insrwi(dst, src, imm0, imm8); 13084 %} 13085 %} 13086 13087 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{ 13088 match(Set dst (ReverseBytesI src)); 13089 predicate(UseVectorByteReverseInstructionsPPC64); 13090 effect(TEMP tmpV); 13091 ins_cost(DEFAULT_COST*3); 13092 size(12); 13093 format %{ "MTVSRWZ $tmpV, $src\n" 13094 "\tXXBRW $tmpV, $tmpV\n" 13095 "\tMFVSRWZ $dst, $tmpV" %} 13096 13097 ins_encode %{ 13098 __ mtvsrwz($tmpV$$VectorSRegister, $src$$Register); 13099 __ xxbrw($tmpV$$VectorSRegister, $tmpV$$VectorSRegister); 13100 __ mfvsrwz($dst$$Register, $tmpV$$VectorSRegister); 13101 %} 13102 ins_pipe(pipe_class_default); 13103 %} 13104 13105 instruct bytes_reverse_int(iRegIdst dst, iRegIsrc src) %{ 13106 match(Set dst (ReverseBytesI src)); 13107 predicate(UseByteReverseInstructions); 13108 ins_cost(DEFAULT_COST); 13109 size(4); 13110 13111 format %{ "BRW $dst, $src" %} 13112 13113 ins_encode %{ 13114 __ brw($dst$$Register, $src$$Register); 13115 %} 13116 ins_pipe(pipe_class_default); 13117 %} 13118 13119 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13120 match(Set dst (ReverseBytesL src)); 13121 predicate(!UseByteReverseInstructions); 13122 ins_cost(15*DEFAULT_COST); 13123 13124 expand %{ 13125 immI16 imm56 %{ (int) 56 %} 13126 immI16 imm48 %{ (int) 48 %} 13127 immI16 imm40 %{ (int) 40 %} 13128 immI16 imm32 %{ (int) 32 %} 13129 immI16 imm24 %{ (int) 24 %} 13130 immI16 imm16 %{ (int) 16 %} 13131 immI16 imm8 %{ (int) 8 %} 13132 immI16 imm0 %{ (int) 0 %} 13133 iRegLdst tmpL1; 13134 iRegLdst tmpL2; 13135 iRegLdst tmpL3; 13136 iRegLdst tmpL4; 13137 iRegLdst tmpL5; 13138 iRegLdst tmpL6; 13139 13140 // src : |a|b|c|d|e|f|g|h| 13141 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13142 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13143 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13144 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13145 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13146 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13147 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13148 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13149 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13150 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13151 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13152 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13153 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13154 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13155 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13156 %} 13157 %} 13158 13159 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{ 13160 match(Set dst (ReverseBytesL src)); 13161 predicate(UseVectorByteReverseInstructionsPPC64); 13162 effect(TEMP tmpV); 13163 ins_cost(DEFAULT_COST*3); 13164 size(12); 13165 format %{ "MTVSRD $tmpV, $src\n" 13166 "\tXXBRD $tmpV, $tmpV\n" 13167 "\tMFVSRD $dst, $tmpV" %} 13168 13169 ins_encode %{ 13170 __ mtvsrd($tmpV$$VectorSRegister, $src$$Register); 13171 __ xxbrd($tmpV$$VectorSRegister, $tmpV$$VectorSRegister); 13172 __ mfvsrd($dst$$Register, $tmpV$$VectorSRegister); 13173 %} 13174 ins_pipe(pipe_class_default); 13175 %} 13176 13177 instruct bytes_reverse_long(iRegLdst dst, iRegLsrc src) %{ 13178 match(Set dst (ReverseBytesL src)); 13179 predicate(UseByteReverseInstructions); 13180 ins_cost(DEFAULT_COST); 13181 size(4); 13182 13183 format %{ "BRD $dst, $src" %} 13184 13185 ins_encode %{ 13186 __ brd($dst$$Register, $src$$Register); 13187 %} 13188 ins_pipe(pipe_class_default); 13189 %} 13190 13191 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13192 match(Set dst (ReverseBytesUS src)); 13193 predicate(!UseByteReverseInstructions); 13194 ins_cost(2*DEFAULT_COST); 13195 13196 expand %{ 13197 immI16 imm16 %{ (int) 16 %} 13198 immI16 imm8 %{ (int) 8 %} 13199 13200 urShiftI_reg_imm(dst, src, imm8); 13201 insrwi(dst, src, imm16, imm8); 13202 %} 13203 %} 13204 13205 instruct bytes_reverse_ushort(iRegIdst dst, iRegIsrc src) %{ 13206 match(Set dst (ReverseBytesUS src)); 13207 predicate(UseByteReverseInstructions); 13208 ins_cost(DEFAULT_COST); 13209 size(4); 13210 13211 format %{ "BRH $dst, $src" %} 13212 13213 ins_encode %{ 13214 __ brh($dst$$Register, $src$$Register); 13215 %} 13216 ins_pipe(pipe_class_default); 13217 %} 13218 13219 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13220 match(Set dst (ReverseBytesS src)); 13221 predicate(!UseByteReverseInstructions); 13222 ins_cost(3*DEFAULT_COST); 13223 13224 expand %{ 13225 immI16 imm16 %{ (int) 16 %} 13226 immI16 imm8 %{ (int) 8 %} 13227 iRegLdst tmpI1; 13228 13229 urShiftI_reg_imm(tmpI1, src, imm8); 13230 insrwi(tmpI1, src, imm16, imm8); 13231 extsh(dst, tmpI1); 13232 %} 13233 %} 13234 13235 instruct bytes_reverse_short(iRegIdst dst, iRegIsrc src) %{ 13236 match(Set dst (ReverseBytesS src)); 13237 predicate(UseByteReverseInstructions); 13238 ins_cost(DEFAULT_COST); 13239 size(8); 13240 13241 format %{ "BRH $dst, $src\n\t" 13242 "EXTSH $dst, $dst" %} 13243 13244 ins_encode %{ 13245 __ brh($dst$$Register, $src$$Register); 13246 __ extsh($dst$$Register, $dst$$Register); 13247 %} 13248 ins_pipe(pipe_class_default); 13249 %} 13250 13251 // Load Integer reversed byte order 13252 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13253 match(Set dst (ReverseBytesI (LoadI mem))); 13254 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13255 ins_cost(MEMORY_REF_COST); 13256 13257 size(4); 13258 ins_encode %{ 13259 __ lwbrx($dst$$Register, $mem$$Register); 13260 %} 13261 ins_pipe(pipe_class_default); 13262 %} 13263 13264 instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{ 13265 match(Set dst (ReverseBytesI (LoadI mem))); 13266 ins_cost(2 * MEMORY_REF_COST); 13267 13268 size(12); 13269 ins_encode %{ 13270 __ lwbrx($dst$$Register, $mem$$Register); 13271 __ twi_0($dst$$Register); 13272 __ isync(); 13273 %} 13274 ins_pipe(pipe_class_default); 13275 %} 13276 13277 // Load Long - aligned and reversed 13278 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13279 match(Set dst (ReverseBytesL (LoadL mem))); 13280 predicate(VM_Version::has_ldbrx() && (n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)))); 13281 ins_cost(MEMORY_REF_COST); 13282 13283 size(4); 13284 ins_encode %{ 13285 __ ldbrx($dst$$Register, $mem$$Register); 13286 %} 13287 ins_pipe(pipe_class_default); 13288 %} 13289 13290 instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{ 13291 match(Set dst (ReverseBytesL (LoadL mem))); 13292 predicate(VM_Version::has_ldbrx()); 13293 ins_cost(2 * MEMORY_REF_COST); 13294 13295 size(12); 13296 ins_encode %{ 13297 __ ldbrx($dst$$Register, $mem$$Register); 13298 __ twi_0($dst$$Register); 13299 __ isync(); 13300 %} 13301 ins_pipe(pipe_class_default); 13302 %} 13303 13304 // Load unsigned short / char reversed byte order 13305 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13306 match(Set dst (ReverseBytesUS (LoadUS mem))); 13307 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13308 ins_cost(MEMORY_REF_COST); 13309 13310 size(4); 13311 ins_encode %{ 13312 __ lhbrx($dst$$Register, $mem$$Register); 13313 %} 13314 ins_pipe(pipe_class_default); 13315 %} 13316 13317 instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{ 13318 match(Set dst (ReverseBytesUS (LoadUS mem))); 13319 ins_cost(2 * MEMORY_REF_COST); 13320 13321 size(12); 13322 ins_encode %{ 13323 __ lhbrx($dst$$Register, $mem$$Register); 13324 __ twi_0($dst$$Register); 13325 __ isync(); 13326 %} 13327 ins_pipe(pipe_class_default); 13328 %} 13329 13330 // Load short reversed byte order 13331 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13332 match(Set dst (ReverseBytesS (LoadS mem))); 13333 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13334 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13335 13336 size(8); 13337 ins_encode %{ 13338 __ lhbrx($dst$$Register, $mem$$Register); 13339 __ extsh($dst$$Register, $dst$$Register); 13340 %} 13341 ins_pipe(pipe_class_default); 13342 %} 13343 13344 instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{ 13345 match(Set dst (ReverseBytesS (LoadS mem))); 13346 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13347 13348 size(16); 13349 ins_encode %{ 13350 __ lhbrx($dst$$Register, $mem$$Register); 13351 __ twi_0($dst$$Register); 13352 __ extsh($dst$$Register, $dst$$Register); 13353 __ isync(); 13354 %} 13355 ins_pipe(pipe_class_default); 13356 %} 13357 13358 // Store Integer reversed byte order 13359 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13360 match(Set mem (StoreI mem (ReverseBytesI src))); 13361 ins_cost(MEMORY_REF_COST); 13362 13363 size(4); 13364 ins_encode %{ 13365 __ stwbrx($src$$Register, $mem$$Register); 13366 %} 13367 ins_pipe(pipe_class_default); 13368 %} 13369 13370 // Store Long reversed byte order 13371 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13372 match(Set mem (StoreL mem (ReverseBytesL src))); 13373 predicate(VM_Version::has_stdbrx()); 13374 ins_cost(MEMORY_REF_COST); 13375 13376 size(4); 13377 ins_encode %{ 13378 __ stdbrx($src$$Register, $mem$$Register); 13379 %} 13380 ins_pipe(pipe_class_default); 13381 %} 13382 13383 // Store unsigned short / char reversed byte order 13384 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13385 match(Set mem (StoreC mem (ReverseBytesUS src))); 13386 ins_cost(MEMORY_REF_COST); 13387 13388 size(4); 13389 ins_encode %{ 13390 __ sthbrx($src$$Register, $mem$$Register); 13391 %} 13392 ins_pipe(pipe_class_default); 13393 %} 13394 13395 // Store short reversed byte order 13396 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13397 match(Set mem (StoreC mem (ReverseBytesS src))); 13398 ins_cost(MEMORY_REF_COST); 13399 13400 size(4); 13401 ins_encode %{ 13402 __ sthbrx($src$$Register, $mem$$Register); 13403 %} 13404 ins_pipe(pipe_class_default); 13405 %} 13406 13407 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13408 effect(DEF temp1, USE src); 13409 13410 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %} 13411 size(4); 13412 ins_encode %{ 13413 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13414 %} 13415 ins_pipe(pipe_class_default); 13416 %} 13417 13418 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13419 effect(DEF dst, USE src, USE imm1); 13420 13421 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %} 13422 size(4); 13423 ins_encode %{ 13424 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13425 %} 13426 ins_pipe(pipe_class_default); 13427 %} 13428 13429 instruct xscvdpspn_regF(vecX dst, regF src) %{ 13430 effect(DEF dst, USE src); 13431 13432 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %} 13433 size(4); 13434 ins_encode %{ 13435 __ xscvdpspn($dst$$VectorSRegister, $src$$FloatRegister->to_vsr()); 13436 %} 13437 ins_pipe(pipe_class_default); 13438 %} 13439 13440 //---------- Replicate Vector Instructions ------------------------------------ 13441 13442 // Insrdi does replicate if src == dst. 13443 instruct repl32(iRegLdst dst) %{ 13444 predicate(false); 13445 effect(USE_DEF dst); 13446 13447 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13448 size(4); 13449 ins_encode %{ 13450 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13451 %} 13452 ins_pipe(pipe_class_default); 13453 %} 13454 13455 // Insrdi does replicate if src == dst. 13456 instruct repl48(iRegLdst dst) %{ 13457 predicate(false); 13458 effect(USE_DEF dst); 13459 13460 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13461 size(4); 13462 ins_encode %{ 13463 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13464 %} 13465 ins_pipe(pipe_class_default); 13466 %} 13467 13468 // Insrdi does replicate if src == dst. 13469 instruct repl56(iRegLdst dst) %{ 13470 predicate(false); 13471 effect(USE_DEF dst); 13472 13473 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13474 size(4); 13475 ins_encode %{ 13476 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 13477 %} 13478 ins_pipe(pipe_class_default); 13479 %} 13480 13481 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13482 match(Set dst (ReplicateB src)); 13483 predicate(n->as_Vector()->length() == 8); 13484 expand %{ 13485 moveReg(dst, src); 13486 repl56(dst); 13487 repl48(dst); 13488 repl32(dst); 13489 %} 13490 %} 13491 13492 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 13493 match(Set dst (ReplicateB zero)); 13494 predicate(n->as_Vector()->length() == 8); 13495 format %{ "LI $dst, #0 \t// replicate8B" %} 13496 size(4); 13497 ins_encode %{ 13498 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13499 %} 13500 ins_pipe(pipe_class_default); 13501 %} 13502 13503 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13504 match(Set dst (ReplicateB src)); 13505 predicate(n->as_Vector()->length() == 8); 13506 format %{ "LI $dst, #-1 \t// replicate8B" %} 13507 size(4); 13508 ins_encode %{ 13509 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13510 %} 13511 ins_pipe(pipe_class_default); 13512 %} 13513 13514 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 13515 match(Set dst (ReplicateB src)); 13516 predicate(n->as_Vector()->length() == 16); 13517 13518 expand %{ 13519 iRegLdst tmpL; 13520 vecX tmpV; 13521 immI8 imm1 %{ (int) 1 %} 13522 moveReg(tmpL, src); 13523 repl56(tmpL); 13524 repl48(tmpL); 13525 mtvsrwz(tmpV, tmpL); 13526 xxspltw(dst, tmpV, imm1); 13527 %} 13528 %} 13529 13530 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 13531 match(Set dst (ReplicateB zero)); 13532 predicate(n->as_Vector()->length() == 16); 13533 13534 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 13535 size(4); 13536 ins_encode %{ 13537 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13538 %} 13539 ins_pipe(pipe_class_default); 13540 %} 13541 13542 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 13543 match(Set dst (ReplicateB src)); 13544 predicate(n->as_Vector()->length() == 16); 13545 13546 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13547 size(4); 13548 ins_encode %{ 13549 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13550 %} 13551 ins_pipe(pipe_class_default); 13552 %} 13553 13554 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13555 match(Set dst (ReplicateS src)); 13556 predicate(n->as_Vector()->length() == 4); 13557 expand %{ 13558 moveReg(dst, src); 13559 repl48(dst); 13560 repl32(dst); 13561 %} 13562 %} 13563 13564 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 13565 match(Set dst (ReplicateS zero)); 13566 predicate(n->as_Vector()->length() == 4); 13567 format %{ "LI $dst, #0 \t// replicate4S" %} 13568 size(4); 13569 ins_encode %{ 13570 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13571 %} 13572 ins_pipe(pipe_class_default); 13573 %} 13574 13575 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13576 match(Set dst (ReplicateS src)); 13577 predicate(n->as_Vector()->length() == 4); 13578 format %{ "LI $dst, -1 \t// replicate4S" %} 13579 size(4); 13580 ins_encode %{ 13581 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13582 %} 13583 ins_pipe(pipe_class_default); 13584 %} 13585 13586 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 13587 match(Set dst (ReplicateS src)); 13588 predicate(n->as_Vector()->length() == 8); 13589 13590 expand %{ 13591 iRegLdst tmpL; 13592 vecX tmpV; 13593 immI8 zero %{ (int) 0 %} 13594 moveReg(tmpL, src); 13595 repl48(tmpL); 13596 repl32(tmpL); 13597 mtvsrd(tmpV, tmpL); 13598 xxpermdi(dst, tmpV, tmpV, zero); 13599 %} 13600 %} 13601 13602 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 13603 match(Set dst (ReplicateS zero)); 13604 predicate(n->as_Vector()->length() == 8); 13605 13606 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 13607 size(4); 13608 ins_encode %{ 13609 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13610 %} 13611 ins_pipe(pipe_class_default); 13612 %} 13613 13614 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 13615 match(Set dst (ReplicateS src)); 13616 predicate(n->as_Vector()->length() == 8); 13617 13618 format %{ "XXLEQV $dst, $src \t// replicate8S" %} 13619 size(4); 13620 ins_encode %{ 13621 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13622 %} 13623 ins_pipe(pipe_class_default); 13624 %} 13625 13626 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13627 match(Set dst (ReplicateI src)); 13628 predicate(n->as_Vector()->length() == 2); 13629 ins_cost(2 * DEFAULT_COST); 13630 expand %{ 13631 moveReg(dst, src); 13632 repl32(dst); 13633 %} 13634 %} 13635 13636 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 13637 match(Set dst (ReplicateI zero)); 13638 predicate(n->as_Vector()->length() == 2); 13639 format %{ "LI $dst, #0 \t// replicate2I" %} 13640 size(4); 13641 ins_encode %{ 13642 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13643 %} 13644 ins_pipe(pipe_class_default); 13645 %} 13646 13647 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13648 match(Set dst (ReplicateI src)); 13649 predicate(n->as_Vector()->length() == 2); 13650 format %{ "LI $dst, -1 \t// replicate2I" %} 13651 size(4); 13652 ins_encode %{ 13653 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13654 %} 13655 ins_pipe(pipe_class_default); 13656 %} 13657 13658 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 13659 match(Set dst (ReplicateI src)); 13660 predicate(n->as_Vector()->length() == 4); 13661 ins_cost(2 * DEFAULT_COST); 13662 13663 expand %{ 13664 iRegLdst tmpL; 13665 vecX tmpV; 13666 immI8 zero %{ (int) 0 %} 13667 moveReg(tmpL, src); 13668 repl32(tmpL); 13669 mtvsrd(tmpV, tmpL); 13670 xxpermdi(dst, tmpV, tmpV, zero); 13671 %} 13672 %} 13673 13674 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 13675 match(Set dst (ReplicateI zero)); 13676 predicate(n->as_Vector()->length() == 4); 13677 13678 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 13679 size(4); 13680 ins_encode %{ 13681 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13682 %} 13683 ins_pipe(pipe_class_default); 13684 %} 13685 13686 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 13687 match(Set dst (ReplicateI src)); 13688 predicate(n->as_Vector()->length() == 4); 13689 13690 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 13691 size(4); 13692 ins_encode %{ 13693 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13694 %} 13695 ins_pipe(pipe_class_default); 13696 %} 13697 13698 // Move float to int register via stack, replicate. 13699 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 13700 match(Set dst (ReplicateF src)); 13701 predicate(n->as_Vector()->length() == 2); 13702 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13703 expand %{ 13704 stackSlotL tmpS; 13705 iRegIdst tmpI; 13706 moveF2I_reg_stack(tmpS, src); // Move float to stack. 13707 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 13708 moveReg(dst, tmpI); // Move int to long reg. 13709 repl32(dst); // Replicate bitpattern. 13710 %} 13711 %} 13712 13713 // Replicate scalar constant to packed float values in Double register 13714 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 13715 match(Set dst (ReplicateF src)); 13716 predicate(n->as_Vector()->length() == 2); 13717 ins_cost(5 * DEFAULT_COST); 13718 13719 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 13720 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 13721 %} 13722 13723 // Replicate scalar zero constant to packed float values in Double register 13724 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 13725 match(Set dst (ReplicateF zero)); 13726 predicate(n->as_Vector()->length() == 2); 13727 13728 format %{ "LI $dst, #0 \t// replicate2F" %} 13729 ins_encode %{ 13730 __ li($dst$$Register, 0x0); 13731 %} 13732 ins_pipe(pipe_class_default); 13733 %} 13734 13735 13736 //----------Vector Arithmetic Instructions-------------------------------------- 13737 13738 // Vector Addition Instructions 13739 13740 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{ 13741 match(Set dst (AddVB src1 src2)); 13742 predicate(n->as_Vector()->length() == 16); 13743 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %} 13744 size(4); 13745 ins_encode %{ 13746 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13747 %} 13748 ins_pipe(pipe_class_default); 13749 %} 13750 13751 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{ 13752 match(Set dst (AddVS src1 src2)); 13753 predicate(n->as_Vector()->length() == 8); 13754 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %} 13755 size(4); 13756 ins_encode %{ 13757 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13758 %} 13759 ins_pipe(pipe_class_default); 13760 %} 13761 13762 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{ 13763 match(Set dst (AddVI src1 src2)); 13764 predicate(n->as_Vector()->length() == 4); 13765 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %} 13766 size(4); 13767 ins_encode %{ 13768 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13769 %} 13770 ins_pipe(pipe_class_default); 13771 %} 13772 13773 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{ 13774 match(Set dst (AddVF src1 src2)); 13775 predicate(n->as_Vector()->length() == 4); 13776 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %} 13777 size(4); 13778 ins_encode %{ 13779 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13780 %} 13781 ins_pipe(pipe_class_default); 13782 %} 13783 13784 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{ 13785 match(Set dst (AddVL src1 src2)); 13786 predicate(n->as_Vector()->length() == 2); 13787 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %} 13788 size(4); 13789 ins_encode %{ 13790 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13791 %} 13792 ins_pipe(pipe_class_default); 13793 %} 13794 13795 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{ 13796 match(Set dst (AddVD src1 src2)); 13797 predicate(n->as_Vector()->length() == 2); 13798 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %} 13799 size(4); 13800 ins_encode %{ 13801 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13802 %} 13803 ins_pipe(pipe_class_default); 13804 %} 13805 13806 // Vector Subtraction Instructions 13807 13808 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{ 13809 match(Set dst (SubVB src1 src2)); 13810 predicate(n->as_Vector()->length() == 16); 13811 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %} 13812 size(4); 13813 ins_encode %{ 13814 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13815 %} 13816 ins_pipe(pipe_class_default); 13817 %} 13818 13819 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{ 13820 match(Set dst (SubVS src1 src2)); 13821 predicate(n->as_Vector()->length() == 8); 13822 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %} 13823 size(4); 13824 ins_encode %{ 13825 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13826 %} 13827 ins_pipe(pipe_class_default); 13828 %} 13829 13830 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{ 13831 match(Set dst (SubVI src1 src2)); 13832 predicate(n->as_Vector()->length() == 4); 13833 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %} 13834 size(4); 13835 ins_encode %{ 13836 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13837 %} 13838 ins_pipe(pipe_class_default); 13839 %} 13840 13841 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{ 13842 match(Set dst (SubVF src1 src2)); 13843 predicate(n->as_Vector()->length() == 4); 13844 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %} 13845 size(4); 13846 ins_encode %{ 13847 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13848 %} 13849 ins_pipe(pipe_class_default); 13850 %} 13851 13852 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{ 13853 match(Set dst (SubVL src1 src2)); 13854 predicate(n->as_Vector()->length() == 2); 13855 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %} 13856 size(4); 13857 ins_encode %{ 13858 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13859 %} 13860 ins_pipe(pipe_class_default); 13861 %} 13862 13863 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{ 13864 match(Set dst (SubVD src1 src2)); 13865 predicate(n->as_Vector()->length() == 2); 13866 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %} 13867 size(4); 13868 ins_encode %{ 13869 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13870 %} 13871 ins_pipe(pipe_class_default); 13872 %} 13873 13874 // Vector Multiplication Instructions 13875 13876 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 13877 match(Set dst (MulVS src1 src2)); 13878 predicate(n->as_Vector()->length() == 8); 13879 effect(TEMP tmp); 13880 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %} 13881 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %} 13882 size(8); 13883 ins_encode %{ 13884 __ vspltish($tmp$$VectorSRegister->to_vr(), 0); 13885 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr()); 13886 %} 13887 ins_pipe(pipe_class_default); 13888 %} 13889 13890 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{ 13891 match(Set dst (MulVI src1 src2)); 13892 predicate(n->as_Vector()->length() == 4); 13893 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %} 13894 size(4); 13895 ins_encode %{ 13896 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13897 %} 13898 ins_pipe(pipe_class_default); 13899 %} 13900 13901 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{ 13902 match(Set dst (MulVF src1 src2)); 13903 predicate(n->as_Vector()->length() == 4); 13904 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %} 13905 size(4); 13906 ins_encode %{ 13907 __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13908 %} 13909 ins_pipe(pipe_class_default); 13910 %} 13911 13912 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{ 13913 match(Set dst (MulVD src1 src2)); 13914 predicate(n->as_Vector()->length() == 2); 13915 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %} 13916 size(4); 13917 ins_encode %{ 13918 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13919 %} 13920 ins_pipe(pipe_class_default); 13921 %} 13922 13923 // Vector Division Instructions 13924 13925 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{ 13926 match(Set dst (DivVF src1 src2)); 13927 predicate(n->as_Vector()->length() == 4); 13928 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %} 13929 size(4); 13930 ins_encode %{ 13931 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13932 %} 13933 ins_pipe(pipe_class_default); 13934 %} 13935 13936 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ 13937 match(Set dst (DivVD src1 src2)); 13938 predicate(n->as_Vector()->length() == 2); 13939 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %} 13940 size(4); 13941 ins_encode %{ 13942 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13943 %} 13944 ins_pipe(pipe_class_default); 13945 %} 13946 13947 // Vector Absolute Instructions 13948 13949 instruct vabs4F_reg(vecX dst, vecX src) %{ 13950 match(Set dst (AbsVF src)); 13951 predicate(n->as_Vector()->length() == 4); 13952 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %} 13953 size(4); 13954 ins_encode %{ 13955 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister); 13956 %} 13957 ins_pipe(pipe_class_default); 13958 %} 13959 13960 instruct vabs2D_reg(vecX dst, vecX src) %{ 13961 match(Set dst (AbsVD src)); 13962 predicate(n->as_Vector()->length() == 2); 13963 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %} 13964 size(4); 13965 ins_encode %{ 13966 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister); 13967 %} 13968 ins_pipe(pipe_class_default); 13969 %} 13970 13971 // Round Instructions 13972 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{ 13973 match(Set dst (RoundDoubleMode src rmode)); 13974 format %{ "RoundDoubleMode $src,$rmode" %} 13975 size(4); 13976 ins_encode %{ 13977 switch ($rmode$$constant) { 13978 case RoundDoubleModeNode::rmode_rint: 13979 __ xvrdpic($dst$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr()); 13980 break; 13981 case RoundDoubleModeNode::rmode_floor: 13982 __ frim($dst$$FloatRegister, $src$$FloatRegister); 13983 break; 13984 case RoundDoubleModeNode::rmode_ceil: 13985 __ frip($dst$$FloatRegister, $src$$FloatRegister); 13986 break; 13987 default: 13988 ShouldNotReachHere(); 13989 } 13990 %} 13991 ins_pipe(pipe_class_default); 13992 %} 13993 13994 // Vector Round Instructions 13995 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{ 13996 match(Set dst (RoundDoubleModeV src rmode)); 13997 predicate(n->as_Vector()->length() == 2); 13998 format %{ "RoundDoubleModeV $src,$rmode" %} 13999 size(4); 14000 ins_encode %{ 14001 switch ($rmode$$constant) { 14002 case RoundDoubleModeNode::rmode_rint: 14003 __ xvrdpic($dst$$VectorSRegister, $src$$VectorSRegister); 14004 break; 14005 case RoundDoubleModeNode::rmode_floor: 14006 __ xvrdpim($dst$$VectorSRegister, $src$$VectorSRegister); 14007 break; 14008 case RoundDoubleModeNode::rmode_ceil: 14009 __ xvrdpip($dst$$VectorSRegister, $src$$VectorSRegister); 14010 break; 14011 default: 14012 ShouldNotReachHere(); 14013 } 14014 %} 14015 ins_pipe(pipe_class_default); 14016 %} 14017 14018 // Vector Negate Instructions 14019 14020 instruct vneg4F_reg(vecX dst, vecX src) %{ 14021 match(Set dst (NegVF src)); 14022 predicate(n->as_Vector()->length() == 4); 14023 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %} 14024 size(4); 14025 ins_encode %{ 14026 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister); 14027 %} 14028 ins_pipe(pipe_class_default); 14029 %} 14030 14031 instruct vneg2D_reg(vecX dst, vecX src) %{ 14032 match(Set dst (NegVD src)); 14033 predicate(n->as_Vector()->length() == 2); 14034 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %} 14035 size(4); 14036 ins_encode %{ 14037 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister); 14038 %} 14039 ins_pipe(pipe_class_default); 14040 %} 14041 14042 // Vector Square Root Instructions 14043 14044 instruct vsqrt4F_reg(vecX dst, vecX src) %{ 14045 match(Set dst (SqrtVF src)); 14046 predicate(n->as_Vector()->length() == 4); 14047 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %} 14048 size(4); 14049 ins_encode %{ 14050 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister); 14051 %} 14052 ins_pipe(pipe_class_default); 14053 %} 14054 14055 instruct vsqrt2D_reg(vecX dst, vecX src) %{ 14056 match(Set dst (SqrtVD src)); 14057 predicate(n->as_Vector()->length() == 2); 14058 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %} 14059 size(4); 14060 ins_encode %{ 14061 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister); 14062 %} 14063 ins_pipe(pipe_class_default); 14064 %} 14065 14066 // Vector Population Count Instructions 14067 14068 instruct vpopcnt4I_reg(vecX dst, vecX src) %{ 14069 match(Set dst (PopCountVI src)); 14070 predicate(n->as_Vector()->length() == 4); 14071 format %{ "VPOPCNTW $dst,$src\t// pop count packed4I" %} 14072 size(4); 14073 ins_encode %{ 14074 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14075 %} 14076 ins_pipe(pipe_class_default); 14077 %} 14078 14079 // --------------------------------- FMA -------------------------------------- 14080 // dst + src1 * src2 14081 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{ 14082 match(Set dst (FmaVF dst (Binary src1 src2))); 14083 predicate(n->as_Vector()->length() == 4); 14084 14085 format %{ "XVMADDASP $dst, $src1, $src2" %} 14086 14087 size(4); 14088 ins_encode %{ 14089 __ xvmaddasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14090 %} 14091 ins_pipe(pipe_class_default); 14092 %} 14093 14094 // dst - src1 * src2 14095 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{ 14096 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 14097 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 14098 predicate(n->as_Vector()->length() == 4); 14099 14100 format %{ "XVNMSUBASP $dst, $src1, $src2" %} 14101 14102 size(4); 14103 ins_encode %{ 14104 __ xvnmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14105 %} 14106 ins_pipe(pipe_class_default); 14107 %} 14108 14109 // - dst + src1 * src2 14110 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{ 14111 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2))); 14112 predicate(n->as_Vector()->length() == 4); 14113 14114 format %{ "XVMSUBASP $dst, $src1, $src2" %} 14115 14116 size(4); 14117 ins_encode %{ 14118 __ xvmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14119 %} 14120 ins_pipe(pipe_class_default); 14121 %} 14122 14123 // dst + src1 * src2 14124 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{ 14125 match(Set dst (FmaVD dst (Binary src1 src2))); 14126 predicate(n->as_Vector()->length() == 2); 14127 14128 format %{ "XVMADDADP $dst, $src1, $src2" %} 14129 14130 size(4); 14131 ins_encode %{ 14132 __ xvmaddadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14133 %} 14134 ins_pipe(pipe_class_default); 14135 %} 14136 14137 // dst - src1 * src2 14138 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{ 14139 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 14140 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 14141 predicate(n->as_Vector()->length() == 2); 14142 14143 format %{ "XVNMSUBADP $dst, $src1, $src2" %} 14144 14145 size(4); 14146 ins_encode %{ 14147 __ xvnmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14148 %} 14149 ins_pipe(pipe_class_default); 14150 %} 14151 14152 // - dst + src1 * src2 14153 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{ 14154 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2))); 14155 predicate(n->as_Vector()->length() == 2); 14156 14157 format %{ "XVMSUBADP $dst, $src1, $src2" %} 14158 14159 size(4); 14160 ins_encode %{ 14161 __ xvmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14162 %} 14163 ins_pipe(pipe_class_default); 14164 %} 14165 14166 //----------Overflow Math Instructions----------------------------------------- 14167 14168 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 14169 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14170 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14171 14172 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14173 match(Set cr0 (OverflowAddL op1 op2)); 14174 14175 format %{ "add_ $op1, $op2\t# overflow check long" %} 14176 ins_encode %{ 14177 __ li(R0, 0); 14178 __ mtxer(R0); // clear XER.SO 14179 __ addo_(R0, $op1$$Register, $op2$$Register); 14180 %} 14181 ins_pipe(pipe_class_default); 14182 %} 14183 14184 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14185 match(Set cr0 (OverflowSubL op1 op2)); 14186 14187 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14188 ins_encode %{ 14189 __ li(R0, 0); 14190 __ mtxer(R0); // clear XER.SO 14191 __ subfo_(R0, $op2$$Register, $op1$$Register); 14192 %} 14193 ins_pipe(pipe_class_default); 14194 %} 14195 14196 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14197 match(Set cr0 (OverflowSubL zero op2)); 14198 14199 format %{ "nego_ R0, $op2\t# overflow check long" %} 14200 ins_encode %{ 14201 __ li(R0, 0); 14202 __ mtxer(R0); // clear XER.SO 14203 __ nego_(R0, $op2$$Register); 14204 %} 14205 ins_pipe(pipe_class_default); 14206 %} 14207 14208 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14209 match(Set cr0 (OverflowMulL op1 op2)); 14210 14211 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14212 ins_encode %{ 14213 __ li(R0, 0); 14214 __ mtxer(R0); // clear XER.SO 14215 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14216 %} 14217 ins_pipe(pipe_class_default); 14218 %} 14219 14220 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14221 match(Set dst (ReplicateF src)); 14222 predicate(n->as_Vector()->length() == 4); 14223 ins_cost(DEFAULT_COST); 14224 expand %{ 14225 vecX tmpV; 14226 immI8 zero %{ (int) 0 %} 14227 14228 xscvdpspn_regF(tmpV, src); 14229 xxspltw(dst, tmpV, zero); 14230 %} 14231 %} 14232 14233 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14234 match(Set dst (ReplicateF src)); 14235 predicate(n->as_Vector()->length() == 4); 14236 effect(TEMP tmp); 14237 ins_cost(10 * DEFAULT_COST); 14238 14239 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14240 %} 14241 14242 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14243 match(Set dst (ReplicateF zero)); 14244 predicate(n->as_Vector()->length() == 4); 14245 14246 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14247 ins_encode %{ 14248 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14249 %} 14250 ins_pipe(pipe_class_default); 14251 %} 14252 14253 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14254 match(Set dst (ReplicateD src)); 14255 predicate(n->as_Vector()->length() == 2); 14256 14257 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %} 14258 size(4); 14259 ins_encode %{ 14260 __ xxpermdi($dst$$VectorSRegister, $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0); 14261 %} 14262 ins_pipe(pipe_class_default); 14263 %} 14264 14265 instruct repl2D_immD0(vecX dst, immD_0 zero) %{ 14266 match(Set dst (ReplicateD zero)); 14267 predicate(n->as_Vector()->length() == 2); 14268 14269 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14270 size(4); 14271 ins_encode %{ 14272 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14273 %} 14274 ins_pipe(pipe_class_default); 14275 %} 14276 14277 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14278 predicate(false); 14279 effect(DEF dst, USE src); 14280 14281 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %} 14282 size(4); 14283 ins_encode %{ 14284 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14285 %} 14286 ins_pipe(pipe_class_default); 14287 %} 14288 14289 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14290 effect(DEF dst, USE src, USE zero); 14291 14292 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %} 14293 size(4); 14294 ins_encode %{ 14295 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14296 %} 14297 ins_pipe(pipe_class_default); 14298 %} 14299 14300 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14301 effect(DEF dst, USE src1, USE src2, USE zero); 14302 14303 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %} 14304 size(4); 14305 ins_encode %{ 14306 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14307 %} 14308 ins_pipe(pipe_class_default); 14309 %} 14310 14311 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14312 match(Set dst (ReplicateL src)); 14313 predicate(n->as_Vector()->length() == 2); 14314 expand %{ 14315 vecX tmpV; 14316 immI8 zero %{ (int) 0 %} 14317 mtvsrd(tmpV, src); 14318 xxpermdi(dst, tmpV, tmpV, zero); 14319 %} 14320 %} 14321 14322 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14323 match(Set dst (ReplicateL zero)); 14324 predicate(n->as_Vector()->length() == 2); 14325 14326 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14327 size(4); 14328 ins_encode %{ 14329 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14330 %} 14331 ins_pipe(pipe_class_default); 14332 %} 14333 14334 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14335 match(Set dst (ReplicateL src)); 14336 predicate(n->as_Vector()->length() == 2); 14337 14338 format %{ "XXLEQV $dst, $src \t// replicate2L" %} 14339 size(4); 14340 ins_encode %{ 14341 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14342 %} 14343 ins_pipe(pipe_class_default); 14344 %} 14345 14346 // ============================================================================ 14347 // Safepoint Instruction 14348 14349 instruct safePoint_poll(iRegPdst poll) %{ 14350 match(SafePoint poll); 14351 14352 // It caused problems to add the effect that r0 is killed, but this 14353 // effect no longer needs to be mentioned, since r0 is not contained 14354 // in a reg_class. 14355 14356 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14357 size(4); 14358 ins_encode( enc_poll(0x0, poll) ); 14359 ins_pipe(pipe_class_default); 14360 %} 14361 14362 // ============================================================================ 14363 // Call Instructions 14364 14365 // Call Java Static Instruction 14366 14367 // Schedulable version of call static node. 14368 instruct CallStaticJavaDirect(method meth) %{ 14369 match(CallStaticJava); 14370 effect(USE meth); 14371 ins_cost(CALL_COST); 14372 14373 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14374 14375 format %{ "CALL,static $meth \t// ==> " %} 14376 size(4); 14377 ins_encode( enc_java_static_call(meth) ); 14378 ins_pipe(pipe_class_call); 14379 %} 14380 14381 // Call Java Dynamic Instruction 14382 14383 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14384 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14385 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14386 // The call destination must still be placed in the constant pool. 14387 instruct CallDynamicJavaDirectSched(method meth) %{ 14388 match(CallDynamicJava); // To get all the data fields we need ... 14389 effect(USE meth); 14390 predicate(false); // ... but never match. 14391 14392 ins_field_load_ic_hi_node(loadConL_hiNode*); 14393 ins_field_load_ic_node(loadConLNode*); 14394 ins_num_consts(1 /* 1 patchable constant: call destination */); 14395 14396 format %{ "BL \t// dynamic $meth ==> " %} 14397 size(4); 14398 ins_encode( enc_java_dynamic_call_sched(meth) ); 14399 ins_pipe(pipe_class_call); 14400 %} 14401 14402 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14403 // We use postalloc expanded calls if we use inline caches 14404 // and do not update method data. 14405 // 14406 // This instruction has two constants: inline cache (IC) and call destination. 14407 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14408 // one constant. 14409 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14410 match(CallDynamicJava); 14411 effect(USE meth); 14412 predicate(UseInlineCaches); 14413 ins_cost(CALL_COST); 14414 14415 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14416 14417 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14418 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14419 %} 14420 14421 // Compound version of call dynamic java 14422 // We use postalloc expanded calls if we use inline caches 14423 // and do not update method data. 14424 instruct CallDynamicJavaDirect(method meth) %{ 14425 match(CallDynamicJava); 14426 effect(USE meth); 14427 predicate(!UseInlineCaches); 14428 ins_cost(CALL_COST); 14429 14430 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14431 ins_num_consts(4); 14432 14433 format %{ "CALL,dynamic $meth \t// ==> " %} 14434 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14435 ins_pipe(pipe_class_call); 14436 %} 14437 14438 // Call Runtime Instruction 14439 14440 instruct CallRuntimeDirect(method meth) %{ 14441 match(CallRuntime); 14442 effect(USE meth); 14443 ins_cost(CALL_COST); 14444 14445 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14446 // env for callee, C-toc. 14447 ins_num_consts(3); 14448 14449 format %{ "CALL,runtime" %} 14450 ins_encode( enc_java_to_runtime_call(meth) ); 14451 ins_pipe(pipe_class_call); 14452 %} 14453 14454 // Call Leaf 14455 14456 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14457 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14458 effect(DEF dst, USE src); 14459 14460 ins_num_consts(1); 14461 14462 format %{ "MTCTR $src" %} 14463 size(4); 14464 ins_encode( enc_leaf_call_mtctr(src) ); 14465 ins_pipe(pipe_class_default); 14466 %} 14467 14468 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 14469 instruct CallLeafDirect(method meth) %{ 14470 match(CallLeaf); // To get the data all the data fields we need ... 14471 effect(USE meth); 14472 predicate(false); // but never match. 14473 14474 format %{ "BCTRL \t// leaf call $meth ==> " %} 14475 size(4); 14476 ins_encode %{ 14477 __ bctrl(); 14478 %} 14479 ins_pipe(pipe_class_call); 14480 %} 14481 14482 // postalloc expand of CallLeafDirect. 14483 // Load adress to call from TOC, then bl to it. 14484 instruct CallLeafDirect_Ex(method meth) %{ 14485 match(CallLeaf); 14486 effect(USE meth); 14487 ins_cost(CALL_COST); 14488 14489 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14490 // env for callee, C-toc. 14491 ins_num_consts(3); 14492 14493 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14494 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14495 %} 14496 14497 // Call runtime without safepoint - same as CallLeaf. 14498 // postalloc expand of CallLeafNoFPDirect. 14499 // Load adress to call from TOC, then bl to it. 14500 instruct CallLeafNoFPDirect_Ex(method meth) %{ 14501 match(CallLeafNoFP); 14502 effect(USE meth); 14503 ins_cost(CALL_COST); 14504 14505 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14506 // env for callee, C-toc. 14507 ins_num_consts(3); 14508 14509 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14510 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14511 %} 14512 14513 // Tail Call; Jump from runtime stub to Java code. 14514 // Also known as an 'interprocedural jump'. 14515 // Target of jump will eventually return to caller. 14516 // TailJump below removes the return address. 14517 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ptr) %{ 14518 match(TailCall jump_target method_ptr); 14519 ins_cost(CALL_COST); 14520 14521 format %{ "MTCTR $jump_target \t// $method_ptr holds method\n\t" 14522 "BCTR \t// tail call" %} 14523 size(8); 14524 ins_encode %{ 14525 __ mtctr($jump_target$$Register); 14526 __ bctr(); 14527 %} 14528 ins_pipe(pipe_class_call); 14529 %} 14530 14531 // Return Instruction 14532 instruct Ret() %{ 14533 match(Return); 14534 format %{ "BLR \t// branch to link register" %} 14535 size(4); 14536 ins_encode %{ 14537 // LR is restored in MachEpilogNode. Just do the RET here. 14538 __ blr(); 14539 %} 14540 ins_pipe(pipe_class_default); 14541 %} 14542 14543 // Tail Jump; remove the return address; jump to target. 14544 // TailCall above leaves the return address around. 14545 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14546 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14547 // "restore" before this instruction (in Epilogue), we need to materialize it 14548 // in %i0. 14549 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14550 match(TailJump jump_target ex_oop); 14551 ins_cost(CALL_COST); 14552 14553 format %{ "LD R4_ARG2 = LR\n\t" 14554 "MTCTR $jump_target\n\t" 14555 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14556 size(12); 14557 ins_encode %{ 14558 __ ld(R4_ARG2/* issuing pc */, _abi0(lr), R1_SP); 14559 __ mtctr($jump_target$$Register); 14560 __ bctr(); 14561 %} 14562 ins_pipe(pipe_class_call); 14563 %} 14564 14565 // Create exception oop: created by stack-crawling runtime code. 14566 // Created exception is now available to this handler, and is setup 14567 // just prior to jumping to this handler. No code emitted. 14568 instruct CreateException(rarg1RegP ex_oop) %{ 14569 match(Set ex_oop (CreateEx)); 14570 ins_cost(0); 14571 14572 format %{ " -- \t// exception oop; no code emitted" %} 14573 size(0); 14574 ins_encode( /*empty*/ ); 14575 ins_pipe(pipe_class_default); 14576 %} 14577 14578 // Rethrow exception: The exception oop will come in the first 14579 // argument position. Then JUMP (not call) to the rethrow stub code. 14580 instruct RethrowException() %{ 14581 match(Rethrow); 14582 ins_cost(CALL_COST); 14583 14584 format %{ "Jmp rethrow_stub" %} 14585 ins_encode %{ 14586 cbuf.set_insts_mark(); 14587 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 14588 %} 14589 ins_pipe(pipe_class_call); 14590 %} 14591 14592 // Die now. 14593 instruct ShouldNotReachHere() %{ 14594 match(Halt); 14595 ins_cost(CALL_COST); 14596 14597 format %{ "ShouldNotReachHere" %} 14598 ins_encode %{ 14599 if (is_reachable()) { 14600 __ stop(_halt_reason); 14601 } 14602 %} 14603 ins_pipe(pipe_class_default); 14604 %} 14605 14606 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 14607 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 14608 // Get a DEF on threadRegP, no costs, no encoding, use 14609 // 'ins_should_rematerialize(true)' to avoid spilling. 14610 instruct tlsLoadP(threadRegP dst) %{ 14611 match(Set dst (ThreadLocal)); 14612 ins_cost(0); 14613 14614 ins_should_rematerialize(true); 14615 14616 format %{ " -- \t// $dst=Thread::current(), empty" %} 14617 size(0); 14618 ins_encode( /*empty*/ ); 14619 ins_pipe(pipe_class_empty); 14620 %} 14621 14622 //---Some PPC specific nodes--------------------------------------------------- 14623 14624 // Stop a group. 14625 instruct endGroup() %{ 14626 ins_cost(0); 14627 14628 ins_is_nop(true); 14629 14630 format %{ "End Bundle (ori r1, r1, 0)" %} 14631 size(4); 14632 ins_encode %{ 14633 __ endgroup(); 14634 %} 14635 ins_pipe(pipe_class_default); 14636 %} 14637 14638 // Nop instructions 14639 14640 instruct fxNop() %{ 14641 ins_cost(0); 14642 14643 ins_is_nop(true); 14644 14645 format %{ "fxNop" %} 14646 size(4); 14647 ins_encode %{ 14648 __ nop(); 14649 %} 14650 ins_pipe(pipe_class_default); 14651 %} 14652 14653 instruct fpNop0() %{ 14654 ins_cost(0); 14655 14656 ins_is_nop(true); 14657 14658 format %{ "fpNop0" %} 14659 size(4); 14660 ins_encode %{ 14661 __ fpnop0(); 14662 %} 14663 ins_pipe(pipe_class_default); 14664 %} 14665 14666 instruct fpNop1() %{ 14667 ins_cost(0); 14668 14669 ins_is_nop(true); 14670 14671 format %{ "fpNop1" %} 14672 size(4); 14673 ins_encode %{ 14674 __ fpnop1(); 14675 %} 14676 ins_pipe(pipe_class_default); 14677 %} 14678 14679 instruct brNop0() %{ 14680 ins_cost(0); 14681 size(4); 14682 format %{ "brNop0" %} 14683 ins_encode %{ 14684 __ brnop0(); 14685 %} 14686 ins_is_nop(true); 14687 ins_pipe(pipe_class_default); 14688 %} 14689 14690 instruct brNop1() %{ 14691 ins_cost(0); 14692 14693 ins_is_nop(true); 14694 14695 format %{ "brNop1" %} 14696 size(4); 14697 ins_encode %{ 14698 __ brnop1(); 14699 %} 14700 ins_pipe(pipe_class_default); 14701 %} 14702 14703 instruct brNop2() %{ 14704 ins_cost(0); 14705 14706 ins_is_nop(true); 14707 14708 format %{ "brNop2" %} 14709 size(4); 14710 ins_encode %{ 14711 __ brnop2(); 14712 %} 14713 ins_pipe(pipe_class_default); 14714 %} 14715 14716 instruct cacheWB(indirect addr) 14717 %{ 14718 match(CacheWB addr); 14719 14720 ins_cost(100); 14721 format %{ "cache writeback, address = $addr" %} 14722 ins_encode %{ 14723 assert($addr->index_position() < 0, "should be"); 14724 assert($addr$$disp == 0, "should be"); 14725 __ cache_wb(Address($addr$$base$$Register)); 14726 %} 14727 ins_pipe(pipe_class_default); 14728 %} 14729 14730 instruct cacheWBPreSync() 14731 %{ 14732 match(CacheWBPreSync); 14733 14734 ins_cost(0); 14735 format %{ "cache writeback presync" %} 14736 ins_encode %{ 14737 __ cache_wbsync(true); 14738 %} 14739 ins_pipe(pipe_class_default); 14740 %} 14741 14742 instruct cacheWBPostSync() 14743 %{ 14744 match(CacheWBPostSync); 14745 14746 ins_cost(100); 14747 format %{ "cache writeback postsync" %} 14748 ins_encode %{ 14749 __ cache_wbsync(false); 14750 %} 14751 ins_pipe(pipe_class_default); 14752 %} 14753 14754 //----------PEEPHOLE RULES----------------------------------------------------- 14755 // These must follow all instruction definitions as they use the names 14756 // defined in the instructions definitions. 14757 // 14758 // peepmatch ( root_instr_name [preceeding_instruction]* ); 14759 // 14760 // peepconstraint %{ 14761 // (instruction_number.operand_name relational_op instruction_number.operand_name 14762 // [, ...] ); 14763 // // instruction numbers are zero-based using left to right order in peepmatch 14764 // 14765 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14766 // // provide an instruction_number.operand_name for each operand that appears 14767 // // in the replacement instruction's match rule 14768 // 14769 // ---------VM FLAGS--------------------------------------------------------- 14770 // 14771 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14772 // 14773 // Each peephole rule is given an identifying number starting with zero and 14774 // increasing by one in the order seen by the parser. An individual peephole 14775 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14776 // on the command-line. 14777 // 14778 // ---------CURRENT LIMITATIONS---------------------------------------------- 14779 // 14780 // Only match adjacent instructions in same basic block 14781 // Only equality constraints 14782 // Only constraints between operands, not (0.dest_reg == EAX_enc) 14783 // Only one replacement instruction 14784 // 14785 // ---------EXAMPLE---------------------------------------------------------- 14786 // 14787 // // pertinent parts of existing instructions in architecture description 14788 // instruct movI(eRegI dst, eRegI src) %{ 14789 // match(Set dst (CopyI src)); 14790 // %} 14791 // 14792 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 14793 // match(Set dst (AddI dst src)); 14794 // effect(KILL cr); 14795 // %} 14796 // 14797 // // Change (inc mov) to lea 14798 // peephole %{ 14799 // // increment preceeded by register-register move 14800 // peepmatch ( incI_eReg movI ); 14801 // // require that the destination register of the increment 14802 // // match the destination register of the move 14803 // peepconstraint ( 0.dst == 1.dst ); 14804 // // construct a replacement instruction that sets 14805 // // the destination to ( move's source register + one ) 14806 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14807 // %} 14808 // 14809 // Implementation no longer uses movX instructions since 14810 // machine-independent system no longer uses CopyX nodes. 14811 // 14812 // peephole %{ 14813 // peepmatch ( incI_eReg movI ); 14814 // peepconstraint ( 0.dst == 1.dst ); 14815 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14816 // %} 14817 // 14818 // peephole %{ 14819 // peepmatch ( decI_eReg movI ); 14820 // peepconstraint ( 0.dst == 1.dst ); 14821 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14822 // %} 14823 // 14824 // peephole %{ 14825 // peepmatch ( addI_eReg_imm movI ); 14826 // peepconstraint ( 0.dst == 1.dst ); 14827 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14828 // %} 14829 // 14830 // peephole %{ 14831 // peepmatch ( addP_eReg_imm movP ); 14832 // peepconstraint ( 0.dst == 1.dst ); 14833 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 14834 // %} 14835 14836 // // Change load of spilled value to only a spill 14837 // instruct storeI(memory mem, eRegI src) %{ 14838 // match(Set mem (StoreI mem src)); 14839 // %} 14840 // 14841 // instruct loadI(eRegI dst, memory mem) %{ 14842 // match(Set dst (LoadI mem)); 14843 // %} 14844 // 14845 peephole %{ 14846 peepmatch ( loadI storeI ); 14847 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14848 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 14849 %} 14850 14851 peephole %{ 14852 peepmatch ( loadL storeL ); 14853 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14854 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 14855 %} 14856 14857 peephole %{ 14858 peepmatch ( loadP storeP ); 14859 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 14860 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 14861 %} 14862 14863 //----------SMARTSPILL RULES--------------------------------------------------- 14864 // These must follow all instruction definitions as they use the names 14865 // defined in the instructions definitions.