1 // 2 // Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2023 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 //============================================================================= 1132 1133 // condition code conversions 1134 1135 static int cc_to_boint(int cc) { 1136 return Assembler::bcondCRbiIs0 | (cc & 8); 1137 } 1138 1139 static int cc_to_inverse_boint(int cc) { 1140 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 1141 } 1142 1143 static int cc_to_biint(int cc, int flags_reg) { 1144 return (flags_reg << 2) | (cc & 3); 1145 } 1146 1147 //============================================================================= 1148 1149 // Compute padding required for nodes which need alignment. The padding 1150 // is the number of bytes (not instructions) which will be inserted before 1151 // the instruction. The padding must match the size of a NOP instruction. 1152 1153 // Add nop if a prefixed (two-word) instruction is going to cross a 64-byte boundary. 1154 // (See Section 1.6 of Power ISA Version 3.1) 1155 static int compute_prefix_padding(int current_offset) { 1156 assert(PowerArchitecturePPC64 >= 10 && (CodeEntryAlignment & 63) == 0, 1157 "Code buffer must be aligned to a multiple of 64 bytes"); 1158 if (is_aligned(current_offset + BytesPerInstWord, 64)) { 1159 return BytesPerInstWord; 1160 } 1161 return 0; 1162 } 1163 1164 int loadConI32Node::compute_padding(int current_offset) const { 1165 return compute_prefix_padding(current_offset); 1166 } 1167 1168 int loadConL34Node::compute_padding(int current_offset) const { 1169 return compute_prefix_padding(current_offset); 1170 } 1171 1172 int addI_reg_imm32Node::compute_padding(int current_offset) const { 1173 return compute_prefix_padding(current_offset); 1174 } 1175 1176 int addL_reg_imm34Node::compute_padding(int current_offset) const { 1177 return compute_prefix_padding(current_offset); 1178 } 1179 1180 int addP_reg_imm34Node::compute_padding(int current_offset) const { 1181 return compute_prefix_padding(current_offset); 1182 } 1183 1184 int cmprb_Whitespace_reg_reg_prefixedNode::compute_padding(int current_offset) const { 1185 return compute_prefix_padding(current_offset); 1186 } 1187 1188 1189 //============================================================================= 1190 1191 // Emit an interrupt that is caught by the debugger (for debugging compiler). 1192 void emit_break(CodeBuffer &cbuf) { 1193 C2_MacroAssembler _masm(&cbuf); 1194 __ illtrap(); 1195 } 1196 1197 #ifndef PRODUCT 1198 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1199 st->print("BREAKPOINT"); 1200 } 1201 #endif 1202 1203 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1204 emit_break(cbuf); 1205 } 1206 1207 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1208 return MachNode::size(ra_); 1209 } 1210 1211 //============================================================================= 1212 1213 void emit_nop(CodeBuffer &cbuf) { 1214 C2_MacroAssembler _masm(&cbuf); 1215 __ nop(); 1216 } 1217 1218 static inline void emit_long(CodeBuffer &cbuf, int value) { 1219 *((int*)(cbuf.insts_end())) = value; 1220 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1221 } 1222 1223 //============================================================================= 1224 1225 %} // interrupt source 1226 1227 source_hpp %{ // Header information of the source block. 1228 1229 //-------------------------------------------------------------- 1230 //---< Used for optimization in Compile::Shorten_branches >--- 1231 //-------------------------------------------------------------- 1232 1233 class C2_MacroAssembler; 1234 1235 class CallStubImpl { 1236 1237 public: 1238 1239 // Emit call stub, compiled java to interpreter. 1240 static void emit_trampoline_stub(C2_MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1241 1242 // Size of call trampoline stub. 1243 // This doesn't need to be accurate to the byte, but it 1244 // must be larger than or equal to the real size of the stub. 1245 static uint size_call_trampoline() { 1246 return MacroAssembler::trampoline_stub_size; 1247 } 1248 1249 // number of relocations needed by a call trampoline stub 1250 static uint reloc_call_trampoline() { 1251 return 5; 1252 } 1253 1254 }; 1255 1256 %} // end source_hpp 1257 1258 source %{ 1259 1260 // Emit a trampoline stub for a call to a target which is too far away. 1261 // 1262 // code sequences: 1263 // 1264 // call-site: 1265 // branch-and-link to <destination> or <trampoline stub> 1266 // 1267 // Related trampoline stub for this call-site in the stub section: 1268 // load the call target from the constant pool 1269 // branch via CTR (LR/link still points to the call-site above) 1270 1271 void CallStubImpl::emit_trampoline_stub(C2_MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1272 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1273 if (stub == NULL) { 1274 ciEnv::current()->record_out_of_memory_failure(); 1275 } 1276 } 1277 1278 //============================================================================= 1279 1280 // Emit an inline branch-and-link call and a related trampoline stub. 1281 // 1282 // code sequences: 1283 // 1284 // call-site: 1285 // branch-and-link to <destination> or <trampoline stub> 1286 // 1287 // Related trampoline stub for this call-site in the stub section: 1288 // load the call target from the constant pool 1289 // branch via CTR (LR/link still points to the call-site above) 1290 // 1291 1292 typedef struct { 1293 int insts_call_instruction_offset; 1294 int ret_addr_offset; 1295 } EmitCallOffsets; 1296 1297 // Emit a branch-and-link instruction that branches to a trampoline. 1298 // - Remember the offset of the branch-and-link instruction. 1299 // - Add a relocation at the branch-and-link instruction. 1300 // - Emit a branch-and-link. 1301 // - Remember the return pc offset. 1302 EmitCallOffsets emit_call_with_trampoline_stub(C2_MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1303 EmitCallOffsets offsets = { -1, -1 }; 1304 const int start_offset = __ offset(); 1305 offsets.insts_call_instruction_offset = __ offset(); 1306 1307 // No entry point given, use the current pc. 1308 if (entry_point == NULL) entry_point = __ pc(); 1309 1310 // Put the entry point as a constant into the constant pool. 1311 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1312 if (entry_point_toc_addr == NULL) { 1313 ciEnv::current()->record_out_of_memory_failure(); 1314 return offsets; 1315 } 1316 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1317 1318 // Emit the trampoline stub which will be related to the branch-and-link below. 1319 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1320 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1321 __ relocate(rtype); 1322 1323 // Note: At this point we do not have the address of the trampoline 1324 // stub, and the entry point might be too far away for bl, so __ pc() 1325 // serves as dummy and the bl will be patched later. 1326 __ bl((address) __ pc()); 1327 1328 offsets.ret_addr_offset = __ offset() - start_offset; 1329 1330 return offsets; 1331 } 1332 1333 //============================================================================= 1334 1335 // Factory for creating loadConL* nodes for large/small constant pool. 1336 1337 static inline jlong replicate_immF(float con) { 1338 // Replicate float con 2 times and pack into vector. 1339 int val = *((int*)&con); 1340 jlong lval = val; 1341 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1342 return lval; 1343 } 1344 1345 //============================================================================= 1346 1347 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1348 int ConstantTable::calculate_table_base_offset() const { 1349 return 0; // absolute addressing, no offset 1350 } 1351 1352 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1353 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1354 iRegPdstOper *op_dst = new iRegPdstOper(); 1355 MachNode *m1 = new loadToc_hiNode(); 1356 MachNode *m2 = new loadToc_loNode(); 1357 1358 m1->add_req(NULL); 1359 m2->add_req(NULL, m1); 1360 m1->_opnds[0] = op_dst; 1361 m2->_opnds[0] = op_dst; 1362 m2->_opnds[1] = op_dst; 1363 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1364 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1365 nodes->push(m1); 1366 nodes->push(m2); 1367 } 1368 1369 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1370 // Is postalloc expanded. 1371 ShouldNotReachHere(); 1372 } 1373 1374 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1375 return 0; 1376 } 1377 1378 #ifndef PRODUCT 1379 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1380 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1381 } 1382 #endif 1383 1384 //============================================================================= 1385 1386 #ifndef PRODUCT 1387 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1388 Compile* C = ra_->C; 1389 const long framesize = C->output()->frame_slots() << LogBytesPerInt; 1390 1391 st->print("PROLOG\n\t"); 1392 if (C->output()->need_stack_bang(framesize)) { 1393 st->print("stack_overflow_check\n\t"); 1394 } 1395 1396 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1397 st->print("save return pc\n\t"); 1398 st->print("push frame %ld\n\t", -framesize); 1399 } 1400 1401 if (C->stub_function() == NULL) { 1402 st->print("nmethod entry barrier\n\t"); 1403 } 1404 } 1405 #endif 1406 1407 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1408 Compile* C = ra_->C; 1409 C2_MacroAssembler _masm(&cbuf); 1410 1411 const long framesize = C->output()->frame_size_in_bytes(); 1412 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1413 1414 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1415 1416 const Register return_pc = R20; // Must match return_addr() in frame section. 1417 const Register callers_sp = R21; 1418 const Register push_frame_temp = R22; 1419 const Register toc_temp = R23; 1420 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1421 1422 if (method_is_frameless) { 1423 // Add nop at beginning of all frameless methods to prevent any 1424 // oop instructions from getting overwritten by make_not_entrant 1425 // (patching attempt would fail). 1426 __ nop(); 1427 } else { 1428 // Get return pc. 1429 __ mflr(return_pc); 1430 } 1431 1432 if (C->clinit_barrier_on_entry()) { 1433 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1434 1435 Label L_skip_barrier; 1436 Register klass = toc_temp; 1437 1438 // Notify OOP recorder (don't need the relocation) 1439 AddressLiteral md = __ constant_metadata_address(C->method()->holder()->constant_encoding()); 1440 __ load_const_optimized(klass, md.value(), R0); 1441 __ clinit_barrier(klass, R16_thread, &L_skip_barrier /*L_fast_path*/); 1442 1443 __ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub(), R0); 1444 __ mtctr(klass); 1445 __ bctr(); 1446 1447 __ bind(L_skip_barrier); 1448 } 1449 1450 // Calls to C2R adapters often do not accept exceptional returns. 1451 // We require that their callers must bang for them. But be 1452 // careful, because some VM calls (such as call site linkage) can 1453 // use several kilobytes of stack. But the stack safety zone should 1454 // account for that. See bugs 4446381, 4468289, 4497237. 1455 1456 int bangsize = C->output()->bang_size_in_bytes(); 1457 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1458 if (C->output()->need_stack_bang(bangsize)) { 1459 // Unfortunately we cannot use the function provided in 1460 // assembler.cpp as we have to emulate the pipes. So I had to 1461 // insert the code of generate_stack_overflow_check(), see 1462 // assembler.cpp for some illuminative comments. 1463 const int page_size = os::vm_page_size(); 1464 int bang_end = StackOverflow::stack_shadow_zone_size(); 1465 1466 // This is how far the previous frame's stack banging extended. 1467 const int bang_end_safe = bang_end; 1468 1469 if (bangsize > page_size) { 1470 bang_end += bangsize; 1471 } 1472 1473 int bang_offset = bang_end_safe; 1474 1475 while (bang_offset <= bang_end) { 1476 // Need at least one stack bang at end of shadow zone. 1477 1478 // Again I had to copy code, this time from assembler_ppc.cpp, 1479 // bang_stack_with_offset - see there for comments. 1480 1481 // Stack grows down, caller passes positive offset. 1482 assert(bang_offset > 0, "must bang with positive offset"); 1483 1484 long stdoffset = -bang_offset; 1485 1486 if (Assembler::is_simm(stdoffset, 16)) { 1487 // Signed 16 bit offset, a simple std is ok. 1488 if (UseLoadInstructionsForStackBangingPPC64) { 1489 __ ld(R0, (int)(signed short)stdoffset, R1_SP); 1490 } else { 1491 __ std(R0, (int)(signed short)stdoffset, R1_SP); 1492 } 1493 } else if (Assembler::is_simm(stdoffset, 31)) { 1494 // Use largeoffset calculations for addis & ld/std. 1495 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1496 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1497 1498 Register tmp = R11; 1499 __ addis(tmp, R1_SP, hi); 1500 if (UseLoadInstructionsForStackBangingPPC64) { 1501 __ ld(R0, lo, tmp); 1502 } else { 1503 __ std(R0, lo, tmp); 1504 } 1505 } else { 1506 ShouldNotReachHere(); 1507 } 1508 1509 bang_offset += page_size; 1510 } 1511 // R11 trashed 1512 } // C->output()->need_stack_bang(framesize) 1513 1514 unsigned int bytes = (unsigned int)framesize; 1515 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1516 ciMethod *currMethod = C->method(); 1517 1518 if (!method_is_frameless) { 1519 // Get callers sp. 1520 __ mr(callers_sp, R1_SP); 1521 1522 // Push method's frame, modifies SP. 1523 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1524 // The ABI is already accounted for in 'framesize' via the 1525 // 'out_preserve' area. 1526 Register tmp = push_frame_temp; 1527 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1528 if (Assembler::is_simm(-offset, 16)) { 1529 __ stdu(R1_SP, -offset, R1_SP); 1530 } else { 1531 long x = -offset; 1532 // Had to insert load_const(tmp, -offset). 1533 __ lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1534 __ ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1535 __ sldi(tmp, tmp, 32); 1536 __ oris(tmp, tmp, (x & 0xffff0000) >> 16); 1537 __ ori( tmp, tmp, (x & 0x0000ffff)); 1538 1539 __ stdux(R1_SP, R1_SP, tmp); 1540 } 1541 } 1542 #if 0 // TODO: PPC port 1543 // For testing large constant pools, emit a lot of constants to constant pool. 1544 // "Randomize" const_size. 1545 if (ConstantsALot) { 1546 const int num_consts = const_size(); 1547 for (int i = 0; i < num_consts; i++) { 1548 __ long_constant(0xB0B5B00BBABE); 1549 } 1550 } 1551 #endif 1552 if (!method_is_frameless) { 1553 // Save return pc. 1554 __ std(return_pc, _abi0(lr), callers_sp); 1555 } 1556 1557 if (C->stub_function() == NULL) { 1558 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); 1559 bs->nmethod_entry_barrier(&_masm, push_frame_temp); 1560 } 1561 1562 C->output()->set_frame_complete(cbuf.insts_size()); 1563 } 1564 1565 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1566 // Variable size. determine dynamically. 1567 return MachNode::size(ra_); 1568 } 1569 1570 int MachPrologNode::reloc() const { 1571 // Return number of relocatable values contained in this instruction. 1572 return 1; // 1 reloc entry for load_const(toc). 1573 } 1574 1575 //============================================================================= 1576 1577 #ifndef PRODUCT 1578 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1579 Compile* C = ra_->C; 1580 1581 st->print("EPILOG\n\t"); 1582 st->print("restore return pc\n\t"); 1583 st->print("pop frame\n\t"); 1584 1585 if (do_polling() && C->is_method_compilation()) { 1586 st->print("safepoint poll\n\t"); 1587 } 1588 } 1589 #endif 1590 1591 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1592 Compile* C = ra_->C; 1593 C2_MacroAssembler _masm(&cbuf); 1594 1595 const long framesize = ((long)C->output()->frame_slots()) << LogBytesPerInt; 1596 assert(framesize >= 0, "negative frame-size?"); 1597 1598 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1599 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1600 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1601 const Register temp = R12; 1602 1603 if (!method_is_frameless) { 1604 // Restore return pc relative to callers' sp. 1605 __ ld(return_pc, ((int)framesize) + _abi0(lr), R1_SP); 1606 // Move return pc to LR. 1607 __ mtlr(return_pc); 1608 // Pop frame (fixed frame-size). 1609 __ addi(R1_SP, R1_SP, (int)framesize); 1610 } 1611 1612 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1613 __ reserved_stack_check(return_pc); 1614 } 1615 1616 if (method_needs_polling) { 1617 Label dummy_label; 1618 Label* code_stub = &dummy_label; 1619 if (!UseSIGTRAP && !C->output()->in_scratch_emit_size()) { 1620 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 1621 C->output()->add_stub(stub); 1622 code_stub = &stub->entry(); 1623 __ relocate(relocInfo::poll_return_type); 1624 } 1625 __ safepoint_poll(*code_stub, temp, true /* at_return */, true /* in_nmethod */); 1626 } 1627 } 1628 1629 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1630 // Variable size. Determine dynamically. 1631 return MachNode::size(ra_); 1632 } 1633 1634 int MachEpilogNode::reloc() const { 1635 // Return number of relocatable values contained in this instruction. 1636 return 1; // 1 for load_from_polling_page. 1637 } 1638 1639 const Pipeline * MachEpilogNode::pipeline() const { 1640 return MachNode::pipeline_class(); 1641 } 1642 1643 // ============================================================================= 1644 1645 // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or 1646 // rc_stack. 1647 enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack }; 1648 1649 static enum RC rc_class(OptoReg::Name reg) { 1650 // Return the register class for the given register. The given register 1651 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1652 // enumeration in adGlobals_ppc.hpp. 1653 1654 if (reg == OptoReg::Bad) return rc_bad; 1655 1656 // We have 64 integer register halves, starting at index 0. 1657 if (reg < 64) return rc_int; 1658 1659 // We have 64 floating-point register halves, starting at index 64. 1660 if (reg < 64+64) return rc_float; 1661 1662 // We have 64 vector-scalar registers, starting at index 128. 1663 if (reg < 64+64+64) return rc_vs; 1664 1665 // Between float regs & stack are the flags regs. 1666 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1667 1668 return rc_stack; 1669 } 1670 1671 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1672 bool do_print, Compile* C, outputStream *st) { 1673 1674 assert(opcode == Assembler::LD_OPCODE || 1675 opcode == Assembler::STD_OPCODE || 1676 opcode == Assembler::LWZ_OPCODE || 1677 opcode == Assembler::STW_OPCODE || 1678 opcode == Assembler::LFD_OPCODE || 1679 opcode == Assembler::STFD_OPCODE || 1680 opcode == Assembler::LFS_OPCODE || 1681 opcode == Assembler::STFS_OPCODE, 1682 "opcode not supported"); 1683 1684 if (cbuf) { 1685 int d = 1686 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1687 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1688 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1689 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1690 } 1691 #ifndef PRODUCT 1692 else if (do_print) { 1693 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1694 op_str, 1695 Matcher::regName[reg], 1696 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1697 } 1698 #endif 1699 return 4; // size 1700 } 1701 1702 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1703 Compile* C = ra_->C; 1704 1705 // Get registers to move. 1706 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1707 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1708 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1709 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1710 1711 enum RC src_hi_rc = rc_class(src_hi); 1712 enum RC src_lo_rc = rc_class(src_lo); 1713 enum RC dst_hi_rc = rc_class(dst_hi); 1714 enum RC dst_lo_rc = rc_class(dst_lo); 1715 1716 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1717 if (src_hi != OptoReg::Bad) 1718 assert((src_lo&1)==0 && src_lo+1==src_hi && 1719 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1720 "expected aligned-adjacent pairs"); 1721 // Generate spill code! 1722 int size = 0; 1723 1724 if (src_lo == dst_lo && src_hi == dst_hi) 1725 return size; // Self copy, no move. 1726 1727 if (bottom_type()->isa_vect() != NULL && ideal_reg() == Op_VecX) { 1728 // Memory->Memory Spill. 1729 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1730 int src_offset = ra_->reg2offset(src_lo); 1731 int dst_offset = ra_->reg2offset(dst_lo); 1732 if (cbuf) { 1733 C2_MacroAssembler _masm(cbuf); 1734 __ ld(R0, src_offset, R1_SP); 1735 __ std(R0, dst_offset, R1_SP); 1736 __ ld(R0, src_offset+8, R1_SP); 1737 __ std(R0, dst_offset+8, R1_SP); 1738 } 1739 size += 16; 1740 } 1741 // VectorSRegister->Memory Spill. 1742 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) { 1743 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1744 int dst_offset = ra_->reg2offset(dst_lo); 1745 if (cbuf) { 1746 C2_MacroAssembler _masm(cbuf); 1747 __ addi(R0, R1_SP, dst_offset); 1748 __ stxvd2x(Rsrc, R0); 1749 } 1750 size += 8; 1751 } 1752 // Memory->VectorSRegister Spill. 1753 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) { 1754 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1755 int src_offset = ra_->reg2offset(src_lo); 1756 if (cbuf) { 1757 C2_MacroAssembler _masm(cbuf); 1758 __ addi(R0, R1_SP, src_offset); 1759 __ lxvd2x(Rdst, R0); 1760 } 1761 size += 8; 1762 } 1763 // VectorSRegister->VectorSRegister. 1764 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) { 1765 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1766 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1767 if (cbuf) { 1768 C2_MacroAssembler _masm(cbuf); 1769 __ xxlor(Rdst, Rsrc, Rsrc); 1770 } 1771 size += 4; 1772 } 1773 else { 1774 ShouldNotReachHere(); // No VSR spill. 1775 } 1776 return size; 1777 } 1778 1779 // -------------------------------------- 1780 // Memory->Memory Spill. Use R0 to hold the value. 1781 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1782 int src_offset = ra_->reg2offset(src_lo); 1783 int dst_offset = ra_->reg2offset(dst_lo); 1784 if (src_hi != OptoReg::Bad) { 1785 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1786 "expected same type of move for high parts"); 1787 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1788 if (!cbuf && !do_size) st->print("\n\t"); 1789 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1790 } else { 1791 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1792 if (!cbuf && !do_size) st->print("\n\t"); 1793 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1794 } 1795 return size; 1796 } 1797 1798 // -------------------------------------- 1799 // Check for float->int copy; requires a trip through memory. 1800 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1801 Unimplemented(); 1802 } 1803 1804 // -------------------------------------- 1805 // Check for integer reg-reg copy. 1806 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1807 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1808 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1809 size = (Rsrc != Rdst) ? 4 : 0; 1810 1811 if (cbuf) { 1812 C2_MacroAssembler _masm(cbuf); 1813 if (size) { 1814 __ mr(Rdst, Rsrc); 1815 } 1816 } 1817 #ifndef PRODUCT 1818 else if (!do_size) { 1819 if (size) { 1820 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1821 } else { 1822 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1823 } 1824 } 1825 #endif 1826 return size; 1827 } 1828 1829 // Check for integer store. 1830 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1831 int dst_offset = ra_->reg2offset(dst_lo); 1832 if (src_hi != OptoReg::Bad) { 1833 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1834 "expected same type of move for high parts"); 1835 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1836 } else { 1837 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1838 } 1839 return size; 1840 } 1841 1842 // Check for integer load. 1843 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1844 int src_offset = ra_->reg2offset(src_lo); 1845 if (src_hi != OptoReg::Bad) { 1846 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1847 "expected same type of move for high parts"); 1848 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1849 } else { 1850 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1851 } 1852 return size; 1853 } 1854 1855 // Check for float reg-reg copy. 1856 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1857 if (cbuf) { 1858 C2_MacroAssembler _masm(cbuf); 1859 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1860 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1861 __ fmr(Rdst, Rsrc); 1862 } 1863 #ifndef PRODUCT 1864 else if (!do_size) { 1865 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1866 } 1867 #endif 1868 return 4; 1869 } 1870 1871 // Check for float store. 1872 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1873 int dst_offset = ra_->reg2offset(dst_lo); 1874 if (src_hi != OptoReg::Bad) { 1875 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1876 "expected same type of move for high parts"); 1877 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1878 } else { 1879 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1880 } 1881 return size; 1882 } 1883 1884 // Check for float load. 1885 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1886 int src_offset = ra_->reg2offset(src_lo); 1887 if (src_hi != OptoReg::Bad) { 1888 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1889 "expected same type of move for high parts"); 1890 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1891 } else { 1892 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1893 } 1894 return size; 1895 } 1896 1897 // -------------------------------------------------------------------- 1898 // Check for hi bits still needing moving. Only happens for misaligned 1899 // arguments to native calls. 1900 if (src_hi == dst_hi) 1901 return size; // Self copy; no move. 1902 1903 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1904 ShouldNotReachHere(); // Unimplemented 1905 return 0; 1906 } 1907 1908 #ifndef PRODUCT 1909 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1910 if (!ra_) 1911 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1912 else 1913 implementation(NULL, ra_, false, st); 1914 } 1915 #endif 1916 1917 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1918 implementation(&cbuf, ra_, false, NULL); 1919 } 1920 1921 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1922 return implementation(NULL, ra_, true, NULL); 1923 } 1924 1925 #ifndef PRODUCT 1926 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1927 st->print("NOP \t// %d nops to pad for loops or prefixed instructions.", _count); 1928 } 1929 #endif 1930 1931 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 1932 C2_MacroAssembler _masm(&cbuf); 1933 // _count contains the number of nops needed for padding. 1934 for (int i = 0; i < _count; i++) { 1935 __ nop(); 1936 } 1937 } 1938 1939 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 1940 return _count * 4; 1941 } 1942 1943 #ifndef PRODUCT 1944 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1945 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1946 char reg_str[128]; 1947 ra_->dump_register(this, reg_str, sizeof(reg_str)); 1948 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 1949 } 1950 #endif 1951 1952 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1953 C2_MacroAssembler _masm(&cbuf); 1954 1955 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1956 int reg = ra_->get_encode(this); 1957 1958 if (Assembler::is_simm(offset, 16)) { 1959 __ addi(as_Register(reg), R1, offset); 1960 } else { 1961 ShouldNotReachHere(); 1962 } 1963 } 1964 1965 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1966 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1967 return 4; 1968 } 1969 1970 #ifndef PRODUCT 1971 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1972 st->print_cr("---- MachUEPNode ----"); 1973 st->print_cr("..."); 1974 } 1975 #endif 1976 1977 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1978 // This is the unverified entry point. 1979 C2_MacroAssembler _masm(&cbuf); 1980 1981 // Inline_cache contains a klass. 1982 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 1983 Register receiver_klass = R12_scratch2; // tmp 1984 1985 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 1986 assert(R11_scratch1 == R11, "need prologue scratch register"); 1987 1988 // Check for NULL argument if we don't have implicit null checks. 1989 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 1990 if (TrapBasedNullChecks) { 1991 __ trap_null_check(R3_ARG1); 1992 } else { 1993 Label valid; 1994 __ cmpdi(CCR0, R3_ARG1, 0); 1995 __ bne_predict_taken(CCR0, valid); 1996 // We have a null argument, branch to ic_miss_stub. 1997 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 1998 relocInfo::runtime_call_type); 1999 __ bind(valid); 2000 } 2001 } 2002 // Assume argument is not NULL, load klass from receiver. 2003 __ load_klass(receiver_klass, R3_ARG1); 2004 2005 if (TrapBasedICMissChecks) { 2006 __ trap_ic_miss_check(receiver_klass, ic_klass); 2007 } else { 2008 Label valid; 2009 __ cmpd(CCR0, receiver_klass, ic_klass); 2010 __ beq_predict_taken(CCR0, valid); 2011 // We have an unexpected klass, branch to ic_miss_stub. 2012 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2013 relocInfo::runtime_call_type); 2014 __ bind(valid); 2015 } 2016 2017 // Argument is valid and klass is as expected, continue. 2018 } 2019 2020 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2021 // Variable size. Determine dynamically. 2022 return MachNode::size(ra_); 2023 } 2024 2025 //============================================================================= 2026 2027 %} // interrupt source 2028 2029 source_hpp %{ // Header information of the source block. 2030 2031 class HandlerImpl { 2032 2033 public: 2034 2035 static int emit_exception_handler(CodeBuffer &cbuf); 2036 static int emit_deopt_handler(CodeBuffer& cbuf); 2037 2038 static uint size_exception_handler() { 2039 // The exception_handler is a b64_patchable. 2040 return MacroAssembler::b64_patchable_size; 2041 } 2042 2043 static uint size_deopt_handler() { 2044 // The deopt_handler is a bl64_patchable. 2045 return MacroAssembler::bl64_patchable_size; 2046 } 2047 2048 }; 2049 2050 class Node::PD { 2051 public: 2052 enum NodeFlags { 2053 _last_flag = Node::_last_flag 2054 }; 2055 }; 2056 2057 %} // end source_hpp 2058 2059 source %{ 2060 2061 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2062 C2_MacroAssembler _masm(&cbuf); 2063 2064 address base = __ start_a_stub(size_exception_handler()); 2065 if (base == NULL) return 0; // CodeBuffer::expand failed 2066 2067 int offset = __ offset(); 2068 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2069 relocInfo::runtime_call_type); 2070 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2071 __ end_a_stub(); 2072 2073 return offset; 2074 } 2075 2076 // The deopt_handler is like the exception handler, but it calls to 2077 // the deoptimization blob instead of jumping to the exception blob. 2078 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2079 C2_MacroAssembler _masm(&cbuf); 2080 2081 address base = __ start_a_stub(size_deopt_handler()); 2082 if (base == NULL) return 0; // CodeBuffer::expand failed 2083 2084 int offset = __ offset(); 2085 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2086 relocInfo::runtime_call_type); 2087 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2088 __ end_a_stub(); 2089 2090 return offset; 2091 } 2092 2093 //============================================================================= 2094 2095 // Use a frame slots bias for frameless methods if accessing the stack. 2096 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2097 if (as_Register(reg_enc) == R1_SP) { 2098 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2099 } 2100 return 0; 2101 } 2102 2103 const bool Matcher::match_rule_supported(int opcode) { 2104 if (!has_match_rule(opcode)) { 2105 return false; // no match rule present 2106 } 2107 2108 switch (opcode) { 2109 case Op_SqrtD: 2110 return VM_Version::has_fsqrt(); 2111 case Op_RoundDoubleMode: 2112 return VM_Version::has_vsx(); 2113 case Op_CountLeadingZerosI: 2114 case Op_CountLeadingZerosL: 2115 return UseCountLeadingZerosInstructionsPPC64; 2116 case Op_CountTrailingZerosI: 2117 case Op_CountTrailingZerosL: 2118 return (UseCountLeadingZerosInstructionsPPC64 || UseCountTrailingZerosInstructionsPPC64); 2119 case Op_PopCountI: 2120 case Op_PopCountL: 2121 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2122 2123 case Op_AddVB: 2124 case Op_AddVS: 2125 case Op_AddVI: 2126 case Op_AddVF: 2127 case Op_AddVD: 2128 case Op_SubVB: 2129 case Op_SubVS: 2130 case Op_SubVI: 2131 case Op_SubVF: 2132 case Op_SubVD: 2133 case Op_MulVS: 2134 case Op_MulVF: 2135 case Op_MulVD: 2136 case Op_DivVF: 2137 case Op_DivVD: 2138 case Op_AbsVF: 2139 case Op_AbsVD: 2140 case Op_NegVF: 2141 case Op_NegVD: 2142 case Op_SqrtVF: 2143 case Op_SqrtVD: 2144 case Op_AddVL: 2145 case Op_SubVL: 2146 case Op_MulVI: 2147 case Op_RoundDoubleModeV: 2148 return SuperwordUseVSX; 2149 case Op_PopCountVI: 2150 return (SuperwordUseVSX && UsePopCountInstruction); 2151 case Op_FmaVF: 2152 case Op_FmaVD: 2153 return (SuperwordUseVSX && UseFMA); 2154 2155 case Op_Digit: 2156 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isDigit); 2157 case Op_LowerCase: 2158 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isLowerCase); 2159 case Op_UpperCase: 2160 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isUpperCase); 2161 case Op_Whitespace: 2162 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isWhitespace); 2163 2164 case Op_CacheWB: 2165 case Op_CacheWBPreSync: 2166 case Op_CacheWBPostSync: 2167 return VM_Version::supports_data_cache_line_flush(); 2168 } 2169 2170 return true; // Per default match rules are supported. 2171 } 2172 2173 const bool Matcher::match_rule_supported_superword(int opcode, int vlen, BasicType bt) { 2174 return match_rule_supported_vector(opcode, vlen, bt); 2175 } 2176 2177 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { 2178 if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) { 2179 return false; 2180 } 2181 return true; // Per default match rules are supported. 2182 } 2183 2184 const bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) { 2185 return false; 2186 } 2187 2188 const bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) { 2189 return false; 2190 } 2191 2192 const RegMask* Matcher::predicate_reg_mask(void) { 2193 return NULL; 2194 } 2195 2196 const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) { 2197 return NULL; 2198 } 2199 2200 // Vector calling convention not yet implemented. 2201 const bool Matcher::supports_vector_calling_convention(void) { 2202 return false; 2203 } 2204 2205 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 2206 Unimplemented(); 2207 return OptoRegPair(0, 0); 2208 } 2209 2210 // Vector width in bytes. 2211 const int Matcher::vector_width_in_bytes(BasicType bt) { 2212 if (SuperwordUseVSX) { 2213 assert(MaxVectorSize == 16, ""); 2214 return 16; 2215 } else { 2216 assert(MaxVectorSize == 8, ""); 2217 return 8; 2218 } 2219 } 2220 2221 // Vector ideal reg. 2222 const uint Matcher::vector_ideal_reg(int size) { 2223 if (SuperwordUseVSX) { 2224 assert(MaxVectorSize == 16 && size == 16, ""); 2225 return Op_VecX; 2226 } else { 2227 assert(MaxVectorSize == 8 && size == 8, ""); 2228 return Op_RegL; 2229 } 2230 } 2231 2232 // Limits on vector size (number of elements) loaded into vector. 2233 const int Matcher::max_vector_size(const BasicType bt) { 2234 assert(is_java_primitive(bt), "only primitive type vectors"); 2235 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2236 } 2237 2238 const int Matcher::min_vector_size(const BasicType bt) { 2239 return max_vector_size(bt); // Same as max. 2240 } 2241 2242 const int Matcher::superword_max_vector_size(const BasicType bt) { 2243 return Matcher::max_vector_size(bt); 2244 } 2245 2246 const int Matcher::scalable_vector_reg_size(const BasicType bt) { 2247 return -1; 2248 } 2249 2250 // RETURNS: whether this branch offset is short enough that a short 2251 // branch can be used. 2252 // 2253 // If the platform does not provide any short branch variants, then 2254 // this method should return `false' for offset 0. 2255 // 2256 // `Compile::Fill_buffer' will decide on basis of this information 2257 // whether to do the pass `Compile::Shorten_branches' at all. 2258 // 2259 // And `Compile::Shorten_branches' will decide on basis of this 2260 // information whether to replace particular branch sites by short 2261 // ones. 2262 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2263 // Is the offset within the range of a ppc64 pc relative branch? 2264 bool b; 2265 2266 const int safety_zone = 3 * BytesPerInstWord; 2267 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2268 29 - 16 + 1 + 2); 2269 return b; 2270 } 2271 2272 /* TODO: PPC port 2273 // Make a new machine dependent decode node (with its operands). 2274 MachTypeNode *Matcher::make_decode_node() { 2275 assert(CompressedOops::base() == NULL && CompressedOops::shift() == 0, 2276 "This method is only implemented for unscaled cOops mode so far"); 2277 MachTypeNode *decode = new decodeN_unscaledNode(); 2278 decode->set_opnd_array(0, new iRegPdstOper()); 2279 decode->set_opnd_array(1, new iRegNsrcOper()); 2280 return decode; 2281 } 2282 */ 2283 2284 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { 2285 ShouldNotReachHere(); // generic vector operands not supported 2286 return NULL; 2287 } 2288 2289 bool Matcher::is_reg2reg_move(MachNode* m) { 2290 ShouldNotReachHere(); // generic vector operands not supported 2291 return false; 2292 } 2293 2294 bool Matcher::is_generic_vector(MachOper* opnd) { 2295 ShouldNotReachHere(); // generic vector operands not supported 2296 return false; 2297 } 2298 2299 // Constants for c2c and c calling conventions. 2300 2301 const MachRegisterNumbers iarg_reg[8] = { 2302 R3_num, R4_num, R5_num, R6_num, 2303 R7_num, R8_num, R9_num, R10_num 2304 }; 2305 2306 const MachRegisterNumbers farg_reg[13] = { 2307 F1_num, F2_num, F3_num, F4_num, 2308 F5_num, F6_num, F7_num, F8_num, 2309 F9_num, F10_num, F11_num, F12_num, 2310 F13_num 2311 }; 2312 2313 const MachRegisterNumbers vsarg_reg[64] = { 2314 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2315 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2316 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2317 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2318 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2319 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2320 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2321 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2322 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2323 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2324 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2325 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2326 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2327 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2328 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2329 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2330 }; 2331 2332 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2333 2334 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2335 2336 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2337 2338 // Return whether or not this register is ever used as an argument. This 2339 // function is used on startup to build the trampoline stubs in generateOptoStub. 2340 // Registers not mentioned will be killed by the VM call in the trampoline, and 2341 // arguments in those registers not be available to the callee. 2342 bool Matcher::can_be_java_arg(int reg) { 2343 // We return true for all registers contained in iarg_reg[] and 2344 // farg_reg[] and their virtual halves. 2345 // We must include the virtual halves in order to get STDs and LDs 2346 // instead of STWs and LWs in the trampoline stubs. 2347 2348 if ( reg == R3_num || reg == R3_H_num 2349 || reg == R4_num || reg == R4_H_num 2350 || reg == R5_num || reg == R5_H_num 2351 || reg == R6_num || reg == R6_H_num 2352 || reg == R7_num || reg == R7_H_num 2353 || reg == R8_num || reg == R8_H_num 2354 || reg == R9_num || reg == R9_H_num 2355 || reg == R10_num || reg == R10_H_num) 2356 return true; 2357 2358 if ( reg == F1_num || reg == F1_H_num 2359 || reg == F2_num || reg == F2_H_num 2360 || reg == F3_num || reg == F3_H_num 2361 || reg == F4_num || reg == F4_H_num 2362 || reg == F5_num || reg == F5_H_num 2363 || reg == F6_num || reg == F6_H_num 2364 || reg == F7_num || reg == F7_H_num 2365 || reg == F8_num || reg == F8_H_num 2366 || reg == F9_num || reg == F9_H_num 2367 || reg == F10_num || reg == F10_H_num 2368 || reg == F11_num || reg == F11_H_num 2369 || reg == F12_num || reg == F12_H_num 2370 || reg == F13_num || reg == F13_H_num) 2371 return true; 2372 2373 return false; 2374 } 2375 2376 bool Matcher::is_spillable_arg(int reg) { 2377 return can_be_java_arg(reg); 2378 } 2379 2380 uint Matcher::int_pressure_limit() 2381 { 2382 return (INTPRESSURE == -1) ? 26 : INTPRESSURE; 2383 } 2384 2385 uint Matcher::float_pressure_limit() 2386 { 2387 return (FLOATPRESSURE == -1) ? 28 : FLOATPRESSURE; 2388 } 2389 2390 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2391 return false; 2392 } 2393 2394 // Register for DIVI projection of divmodI. 2395 RegMask Matcher::divI_proj_mask() { 2396 ShouldNotReachHere(); 2397 return RegMask(); 2398 } 2399 2400 // Register for MODI projection of divmodI. 2401 RegMask Matcher::modI_proj_mask() { 2402 ShouldNotReachHere(); 2403 return RegMask(); 2404 } 2405 2406 // Register for DIVL projection of divmodL. 2407 RegMask Matcher::divL_proj_mask() { 2408 ShouldNotReachHere(); 2409 return RegMask(); 2410 } 2411 2412 // Register for MODL projection of divmodL. 2413 RegMask Matcher::modL_proj_mask() { 2414 ShouldNotReachHere(); 2415 return RegMask(); 2416 } 2417 2418 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2419 return RegMask(); 2420 } 2421 2422 %} 2423 2424 //----------ENCODING BLOCK----------------------------------------------------- 2425 // This block specifies the encoding classes used by the compiler to output 2426 // byte streams. Encoding classes are parameterized macros used by 2427 // Machine Instruction Nodes in order to generate the bit encoding of the 2428 // instruction. Operands specify their base encoding interface with the 2429 // interface keyword. There are currently supported four interfaces, 2430 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2431 // operand to generate a function which returns its register number when 2432 // queried. CONST_INTER causes an operand to generate a function which 2433 // returns the value of the constant when queried. MEMORY_INTER causes an 2434 // operand to generate four functions which return the Base Register, the 2435 // Index Register, the Scale Value, and the Offset Value of the operand when 2436 // queried. COND_INTER causes an operand to generate six functions which 2437 // return the encoding code (ie - encoding bits for the instruction) 2438 // associated with each basic boolean condition for a conditional instruction. 2439 // 2440 // Instructions specify two basic values for encoding. Again, a function 2441 // is available to check if the constant displacement is an oop. They use the 2442 // ins_encode keyword to specify their encoding classes (which must be 2443 // a sequence of enc_class names, and their parameters, specified in 2444 // the encoding block), and they use the 2445 // opcode keyword to specify, in order, their primary, secondary, and 2446 // tertiary opcode. Only the opcode sections which a particular instruction 2447 // needs for encoding need to be specified. 2448 encode %{ 2449 enc_class enc_unimplemented %{ 2450 C2_MacroAssembler _masm(&cbuf); 2451 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2452 %} 2453 2454 enc_class enc_untested %{ 2455 #ifdef ASSERT 2456 C2_MacroAssembler _masm(&cbuf); 2457 __ untested("Untested mach node encoding in AD file."); 2458 #else 2459 #endif 2460 %} 2461 2462 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2463 C2_MacroAssembler _masm(&cbuf); 2464 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2465 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2466 %} 2467 2468 // Load acquire. 2469 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2470 C2_MacroAssembler _masm(&cbuf); 2471 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2472 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2473 __ twi_0($dst$$Register); 2474 __ isync(); 2475 %} 2476 2477 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2478 2479 C2_MacroAssembler _masm(&cbuf); 2480 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2481 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2482 %} 2483 2484 // Load acquire. 2485 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2486 2487 C2_MacroAssembler _masm(&cbuf); 2488 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2489 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2490 __ twi_0($dst$$Register); 2491 __ isync(); 2492 %} 2493 2494 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2495 2496 C2_MacroAssembler _masm(&cbuf); 2497 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2498 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2499 %} 2500 2501 // Load acquire. 2502 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2503 2504 C2_MacroAssembler _masm(&cbuf); 2505 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2506 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2507 __ twi_0($dst$$Register); 2508 __ isync(); 2509 %} 2510 2511 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2512 C2_MacroAssembler _masm(&cbuf); 2513 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2514 // Operand 'ds' requires 4-alignment. 2515 assert((Idisp & 0x3) == 0, "unaligned offset"); 2516 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2517 %} 2518 2519 // Load acquire. 2520 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2521 C2_MacroAssembler _masm(&cbuf); 2522 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2523 // Operand 'ds' requires 4-alignment. 2524 assert((Idisp & 0x3) == 0, "unaligned offset"); 2525 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2526 __ twi_0($dst$$Register); 2527 __ isync(); 2528 %} 2529 2530 enc_class enc_lfd(RegF dst, memory mem) %{ 2531 C2_MacroAssembler _masm(&cbuf); 2532 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2533 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2534 %} 2535 2536 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2537 2538 C2_MacroAssembler _masm(&cbuf); 2539 int toc_offset = 0; 2540 2541 address const_toc_addr; 2542 // Create a non-oop constant, no relocation needed. 2543 // If it is an IC, it has a virtual_call_Relocation. 2544 const_toc_addr = __ long_constant((jlong)$src$$constant); 2545 if (const_toc_addr == NULL) { 2546 ciEnv::current()->record_out_of_memory_failure(); 2547 return; 2548 } 2549 2550 // Get the constant's TOC offset. 2551 toc_offset = __ offset_to_method_toc(const_toc_addr); 2552 2553 // Keep the current instruction offset in mind. 2554 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2555 2556 __ ld($dst$$Register, toc_offset, $toc$$Register); 2557 %} 2558 2559 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2560 2561 C2_MacroAssembler _masm(&cbuf); 2562 2563 if (!ra_->C->output()->in_scratch_emit_size()) { 2564 address const_toc_addr; 2565 // Create a non-oop constant, no relocation needed. 2566 // If it is an IC, it has a virtual_call_Relocation. 2567 const_toc_addr = __ long_constant((jlong)$src$$constant); 2568 if (const_toc_addr == NULL) { 2569 ciEnv::current()->record_out_of_memory_failure(); 2570 return; 2571 } 2572 2573 // Get the constant's TOC offset. 2574 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2575 // Store the toc offset of the constant. 2576 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2577 2578 // Also keep the current instruction offset in mind. 2579 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2580 } 2581 2582 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2583 %} 2584 2585 %} // encode 2586 2587 source %{ 2588 2589 typedef struct { 2590 loadConL_hiNode *_large_hi; 2591 loadConL_loNode *_large_lo; 2592 loadConLNode *_small; 2593 MachNode *_last; 2594 } loadConLNodesTuple; 2595 2596 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2597 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2598 loadConLNodesTuple nodes; 2599 2600 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2601 if (large_constant_pool) { 2602 // Create new nodes. 2603 loadConL_hiNode *m1 = new loadConL_hiNode(); 2604 loadConL_loNode *m2 = new loadConL_loNode(); 2605 2606 // inputs for new nodes 2607 m1->add_req(NULL, toc); 2608 m2->add_req(NULL, m1); 2609 2610 // operands for new nodes 2611 m1->_opnds[0] = new iRegLdstOper(); // dst 2612 m1->_opnds[1] = immSrc; // src 2613 m1->_opnds[2] = new iRegPdstOper(); // toc 2614 m2->_opnds[0] = new iRegLdstOper(); // dst 2615 m2->_opnds[1] = immSrc; // src 2616 m2->_opnds[2] = new iRegLdstOper(); // base 2617 2618 // Initialize ins_attrib TOC fields. 2619 m1->_const_toc_offset = -1; 2620 m2->_const_toc_offset_hi_node = m1; 2621 2622 // Initialize ins_attrib instruction offset. 2623 m1->_cbuf_insts_offset = -1; 2624 2625 // register allocation for new nodes 2626 ra_->set_pair(m1->_idx, reg_second, reg_first); 2627 ra_->set_pair(m2->_idx, reg_second, reg_first); 2628 2629 // Create result. 2630 nodes._large_hi = m1; 2631 nodes._large_lo = m2; 2632 nodes._small = NULL; 2633 nodes._last = nodes._large_lo; 2634 assert(m2->bottom_type()->isa_long(), "must be long"); 2635 } else { 2636 loadConLNode *m2 = new loadConLNode(); 2637 2638 // inputs for new nodes 2639 m2->add_req(NULL, toc); 2640 2641 // operands for new nodes 2642 m2->_opnds[0] = new iRegLdstOper(); // dst 2643 m2->_opnds[1] = immSrc; // src 2644 m2->_opnds[2] = new iRegPdstOper(); // toc 2645 2646 // Initialize ins_attrib instruction offset. 2647 m2->_cbuf_insts_offset = -1; 2648 2649 // register allocation for new nodes 2650 ra_->set_pair(m2->_idx, reg_second, reg_first); 2651 2652 // Create result. 2653 nodes._large_hi = NULL; 2654 nodes._large_lo = NULL; 2655 nodes._small = m2; 2656 nodes._last = nodes._small; 2657 assert(m2->bottom_type()->isa_long(), "must be long"); 2658 } 2659 2660 return nodes; 2661 } 2662 2663 typedef struct { 2664 loadConL_hiNode *_large_hi; 2665 loadConL_loNode *_large_lo; 2666 mtvsrdNode *_moved; 2667 xxspltdNode *_replicated; 2668 loadConLNode *_small; 2669 MachNode *_last; 2670 } loadConLReplicatedNodesTuple; 2671 2672 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2673 vecXOper *dst, immI_0Oper *zero, 2674 OptoReg::Name reg_second, OptoReg::Name reg_first, 2675 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2676 loadConLReplicatedNodesTuple nodes; 2677 2678 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2679 if (large_constant_pool) { 2680 // Create new nodes. 2681 loadConL_hiNode *m1 = new loadConL_hiNode(); 2682 loadConL_loNode *m2 = new loadConL_loNode(); 2683 mtvsrdNode *m3 = new mtvsrdNode(); 2684 xxspltdNode *m4 = new xxspltdNode(); 2685 2686 // inputs for new nodes 2687 m1->add_req(NULL, toc); 2688 m2->add_req(NULL, m1); 2689 m3->add_req(NULL, m2); 2690 m4->add_req(NULL, m3); 2691 2692 // operands for new nodes 2693 m1->_opnds[0] = new iRegLdstOper(); // dst 2694 m1->_opnds[1] = immSrc; // src 2695 m1->_opnds[2] = new iRegPdstOper(); // toc 2696 2697 m2->_opnds[0] = new iRegLdstOper(); // dst 2698 m2->_opnds[1] = immSrc; // src 2699 m2->_opnds[2] = new iRegLdstOper(); // base 2700 2701 m3->_opnds[0] = new vecXOper(); // dst 2702 m3->_opnds[1] = new iRegLdstOper(); // src 2703 2704 m4->_opnds[0] = new vecXOper(); // dst 2705 m4->_opnds[1] = new vecXOper(); // src 2706 m4->_opnds[2] = zero; 2707 2708 // Initialize ins_attrib TOC fields. 2709 m1->_const_toc_offset = -1; 2710 m2->_const_toc_offset_hi_node = m1; 2711 2712 // Initialize ins_attrib instruction offset. 2713 m1->_cbuf_insts_offset = -1; 2714 2715 // register allocation for new nodes 2716 ra_->set_pair(m1->_idx, reg_second, reg_first); 2717 ra_->set_pair(m2->_idx, reg_second, reg_first); 2718 ra_->set1(m3->_idx, reg_second); 2719 ra_->set2(m3->_idx, reg_vec_first); 2720 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2721 2722 // Create result. 2723 nodes._large_hi = m1; 2724 nodes._large_lo = m2; 2725 nodes._moved = m3; 2726 nodes._replicated = m4; 2727 nodes._small = NULL; 2728 nodes._last = nodes._replicated; 2729 assert(m2->bottom_type()->isa_long(), "must be long"); 2730 } else { 2731 loadConLNode *m2 = new loadConLNode(); 2732 mtvsrdNode *m3 = new mtvsrdNode(); 2733 xxspltdNode *m4 = new xxspltdNode(); 2734 2735 // inputs for new nodes 2736 m2->add_req(NULL, toc); 2737 2738 // operands for new nodes 2739 m2->_opnds[0] = new iRegLdstOper(); // dst 2740 m2->_opnds[1] = immSrc; // src 2741 m2->_opnds[2] = new iRegPdstOper(); // toc 2742 2743 m3->_opnds[0] = new vecXOper(); // dst 2744 m3->_opnds[1] = new iRegLdstOper(); // src 2745 2746 m4->_opnds[0] = new vecXOper(); // dst 2747 m4->_opnds[1] = new vecXOper(); // src 2748 m4->_opnds[2] = zero; 2749 2750 // Initialize ins_attrib instruction offset. 2751 m2->_cbuf_insts_offset = -1; 2752 ra_->set1(m3->_idx, reg_second); 2753 ra_->set2(m3->_idx, reg_vec_first); 2754 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2755 2756 // register allocation for new nodes 2757 ra_->set_pair(m2->_idx, reg_second, reg_first); 2758 2759 // Create result. 2760 nodes._large_hi = NULL; 2761 nodes._large_lo = NULL; 2762 nodes._small = m2; 2763 nodes._moved = m3; 2764 nodes._replicated = m4; 2765 nodes._last = nodes._replicated; 2766 assert(m2->bottom_type()->isa_long(), "must be long"); 2767 } 2768 2769 return nodes; 2770 } 2771 2772 %} // source 2773 2774 encode %{ 2775 // Postalloc expand emitter for loading a long constant from the method's TOC. 2776 // Enc_class needed as consttanttablebase is not supported by postalloc 2777 // expand. 2778 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2779 // Create new nodes. 2780 loadConLNodesTuple loadConLNodes = 2781 loadConLNodesTuple_create(ra_, n_toc, op_src, 2782 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2783 2784 // Push new nodes. 2785 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2786 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2787 2788 // some asserts 2789 assert(nodes->length() >= 1, "must have created at least 1 node"); 2790 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2791 %} 2792 2793 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2794 2795 C2_MacroAssembler _masm(&cbuf); 2796 int toc_offset = 0; 2797 2798 intptr_t val = $src$$constant; 2799 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2800 address const_toc_addr; 2801 if (constant_reloc == relocInfo::oop_type) { 2802 // Create an oop constant and a corresponding relocation. 2803 AddressLiteral a = __ allocate_oop_address((jobject)val); 2804 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2805 __ relocate(a.rspec()); 2806 } else if (constant_reloc == relocInfo::metadata_type) { 2807 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2808 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2809 __ relocate(a.rspec()); 2810 } else { 2811 // Create a non-oop constant, no relocation needed. 2812 const_toc_addr = __ long_constant((jlong)$src$$constant); 2813 } 2814 2815 if (const_toc_addr == NULL) { 2816 ciEnv::current()->record_out_of_memory_failure(); 2817 return; 2818 } 2819 // Get the constant's TOC offset. 2820 toc_offset = __ offset_to_method_toc(const_toc_addr); 2821 2822 __ ld($dst$$Register, toc_offset, $toc$$Register); 2823 %} 2824 2825 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2826 2827 C2_MacroAssembler _masm(&cbuf); 2828 if (!ra_->C->output()->in_scratch_emit_size()) { 2829 intptr_t val = $src$$constant; 2830 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2831 address const_toc_addr; 2832 if (constant_reloc == relocInfo::oop_type) { 2833 // Create an oop constant and a corresponding relocation. 2834 AddressLiteral a = __ allocate_oop_address((jobject)val); 2835 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2836 __ relocate(a.rspec()); 2837 } else if (constant_reloc == relocInfo::metadata_type) { 2838 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2839 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2840 __ relocate(a.rspec()); 2841 } else { // non-oop pointers, e.g. card mark base, heap top 2842 // Create a non-oop constant, no relocation needed. 2843 const_toc_addr = __ long_constant((jlong)$src$$constant); 2844 } 2845 2846 if (const_toc_addr == NULL) { 2847 ciEnv::current()->record_out_of_memory_failure(); 2848 return; 2849 } 2850 // Get the constant's TOC offset. 2851 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2852 // Store the toc offset of the constant. 2853 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 2854 } 2855 2856 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2857 %} 2858 2859 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 2860 // Enc_class needed as consttanttablebase is not supported by postalloc 2861 // expand. 2862 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 2863 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2864 if (large_constant_pool) { 2865 // Create new nodes. 2866 loadConP_hiNode *m1 = new loadConP_hiNode(); 2867 loadConP_loNode *m2 = new loadConP_loNode(); 2868 2869 // inputs for new nodes 2870 m1->add_req(NULL, n_toc); 2871 m2->add_req(NULL, m1); 2872 2873 // operands for new nodes 2874 m1->_opnds[0] = new iRegPdstOper(); // dst 2875 m1->_opnds[1] = op_src; // src 2876 m1->_opnds[2] = new iRegPdstOper(); // toc 2877 m2->_opnds[0] = new iRegPdstOper(); // dst 2878 m2->_opnds[1] = op_src; // src 2879 m2->_opnds[2] = new iRegLdstOper(); // base 2880 2881 // Initialize ins_attrib TOC fields. 2882 m1->_const_toc_offset = -1; 2883 m2->_const_toc_offset_hi_node = m1; 2884 2885 // Register allocation for new nodes. 2886 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2887 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2888 2889 nodes->push(m1); 2890 nodes->push(m2); 2891 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2892 } else { 2893 loadConPNode *m2 = new loadConPNode(); 2894 2895 // inputs for new nodes 2896 m2->add_req(NULL, n_toc); 2897 2898 // operands for new nodes 2899 m2->_opnds[0] = new iRegPdstOper(); // dst 2900 m2->_opnds[1] = op_src; // src 2901 m2->_opnds[2] = new iRegPdstOper(); // toc 2902 2903 // Register allocation for new nodes. 2904 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2905 2906 nodes->push(m2); 2907 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2908 } 2909 %} 2910 2911 // Enc_class needed as consttanttablebase is not supported by postalloc 2912 // expand. 2913 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 2914 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2915 2916 MachNode *m2; 2917 if (large_constant_pool) { 2918 m2 = new loadConFCompNode(); 2919 } else { 2920 m2 = new loadConFNode(); 2921 } 2922 // inputs for new nodes 2923 m2->add_req(NULL, n_toc); 2924 2925 // operands for new nodes 2926 m2->_opnds[0] = op_dst; 2927 m2->_opnds[1] = op_src; 2928 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2929 2930 // register allocation for new nodes 2931 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2932 nodes->push(m2); 2933 %} 2934 2935 // Enc_class needed as consttanttablebase is not supported by postalloc 2936 // expand. 2937 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 2938 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2939 2940 MachNode *m2; 2941 if (large_constant_pool) { 2942 m2 = new loadConDCompNode(); 2943 } else { 2944 m2 = new loadConDNode(); 2945 } 2946 // inputs for new nodes 2947 m2->add_req(NULL, n_toc); 2948 2949 // operands for new nodes 2950 m2->_opnds[0] = op_dst; 2951 m2->_opnds[1] = op_src; 2952 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2953 2954 // register allocation for new nodes 2955 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2956 nodes->push(m2); 2957 %} 2958 2959 enc_class enc_stw(iRegIsrc src, memory mem) %{ 2960 C2_MacroAssembler _masm(&cbuf); 2961 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2962 __ stw($src$$Register, Idisp, $mem$$base$$Register); 2963 %} 2964 2965 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 2966 C2_MacroAssembler _masm(&cbuf); 2967 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2968 // Operand 'ds' requires 4-alignment. 2969 assert((Idisp & 0x3) == 0, "unaligned offset"); 2970 __ std($src$$Register, Idisp, $mem$$base$$Register); 2971 %} 2972 2973 enc_class enc_stfs(RegF src, memory mem) %{ 2974 C2_MacroAssembler _masm(&cbuf); 2975 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2976 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 2977 %} 2978 2979 enc_class enc_stfd(RegF src, memory mem) %{ 2980 C2_MacroAssembler _masm(&cbuf); 2981 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2982 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 2983 %} 2984 2985 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 2986 2987 if (VM_Version::has_isel()) { 2988 // use isel instruction with Power 7 2989 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2990 encodeP_subNode *n_sub_base = new encodeP_subNode(); 2991 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2992 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 2993 2994 n_compare->add_req(n_region, n_src); 2995 n_compare->_opnds[0] = op_crx; 2996 n_compare->_opnds[1] = op_src; 2997 n_compare->_opnds[2] = new immL16Oper(0); 2998 2999 n_sub_base->add_req(n_region, n_src); 3000 n_sub_base->_opnds[0] = op_dst; 3001 n_sub_base->_opnds[1] = op_src; 3002 n_sub_base->_bottom_type = _bottom_type; 3003 3004 n_shift->add_req(n_region, n_sub_base); 3005 n_shift->_opnds[0] = op_dst; 3006 n_shift->_opnds[1] = op_dst; 3007 n_shift->_bottom_type = _bottom_type; 3008 3009 n_cond_set->add_req(n_region, n_compare, n_shift); 3010 n_cond_set->_opnds[0] = op_dst; 3011 n_cond_set->_opnds[1] = op_crx; 3012 n_cond_set->_opnds[2] = op_dst; 3013 n_cond_set->_bottom_type = _bottom_type; 3014 3015 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3016 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3017 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3018 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3019 3020 nodes->push(n_compare); 3021 nodes->push(n_sub_base); 3022 nodes->push(n_shift); 3023 nodes->push(n_cond_set); 3024 3025 } else { 3026 // before Power 7 3027 moveRegNode *n_move = new moveRegNode(); 3028 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3029 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3030 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3031 3032 n_move->add_req(n_region, n_src); 3033 n_move->_opnds[0] = op_dst; 3034 n_move->_opnds[1] = op_src; 3035 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3036 3037 n_compare->add_req(n_region, n_src); 3038 n_compare->add_prec(n_move); 3039 3040 n_compare->_opnds[0] = op_crx; 3041 n_compare->_opnds[1] = op_src; 3042 n_compare->_opnds[2] = new immL16Oper(0); 3043 3044 n_sub_base->add_req(n_region, n_compare, n_src); 3045 n_sub_base->_opnds[0] = op_dst; 3046 n_sub_base->_opnds[1] = op_crx; 3047 n_sub_base->_opnds[2] = op_src; 3048 n_sub_base->_bottom_type = _bottom_type; 3049 3050 n_shift->add_req(n_region, n_sub_base); 3051 n_shift->_opnds[0] = op_dst; 3052 n_shift->_opnds[1] = op_dst; 3053 n_shift->_bottom_type = _bottom_type; 3054 3055 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3056 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3057 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3058 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3059 3060 nodes->push(n_move); 3061 nodes->push(n_compare); 3062 nodes->push(n_sub_base); 3063 nodes->push(n_shift); 3064 } 3065 3066 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3067 %} 3068 3069 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3070 3071 encodeP_subNode *n1 = new encodeP_subNode(); 3072 n1->add_req(n_region, n_src); 3073 n1->_opnds[0] = op_dst; 3074 n1->_opnds[1] = op_src; 3075 n1->_bottom_type = _bottom_type; 3076 3077 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3078 n2->add_req(n_region, n1); 3079 n2->_opnds[0] = op_dst; 3080 n2->_opnds[1] = op_dst; 3081 n2->_bottom_type = _bottom_type; 3082 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3083 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3084 3085 nodes->push(n1); 3086 nodes->push(n2); 3087 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3088 %} 3089 3090 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3091 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3092 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3093 3094 n_compare->add_req(n_region, n_src); 3095 n_compare->_opnds[0] = op_crx; 3096 n_compare->_opnds[1] = op_src; 3097 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3098 3099 n_shift->add_req(n_region, n_src); 3100 n_shift->_opnds[0] = op_dst; 3101 n_shift->_opnds[1] = op_src; 3102 n_shift->_bottom_type = _bottom_type; 3103 3104 if (VM_Version::has_isel()) { 3105 // use isel instruction with Power 7 3106 3107 decodeN_addNode *n_add_base = new decodeN_addNode(); 3108 n_add_base->add_req(n_region, n_shift); 3109 n_add_base->_opnds[0] = op_dst; 3110 n_add_base->_opnds[1] = op_dst; 3111 n_add_base->_bottom_type = _bottom_type; 3112 3113 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3114 n_cond_set->add_req(n_region, n_compare, n_add_base); 3115 n_cond_set->_opnds[0] = op_dst; 3116 n_cond_set->_opnds[1] = op_crx; 3117 n_cond_set->_opnds[2] = op_dst; 3118 n_cond_set->_bottom_type = _bottom_type; 3119 3120 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3121 ra_->set_oop(n_cond_set, true); 3122 3123 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3124 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3125 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3126 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3127 3128 nodes->push(n_compare); 3129 nodes->push(n_shift); 3130 nodes->push(n_add_base); 3131 nodes->push(n_cond_set); 3132 3133 } else { 3134 // before Power 7 3135 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3136 3137 n_add_base->add_req(n_region, n_compare, n_shift); 3138 n_add_base->_opnds[0] = op_dst; 3139 n_add_base->_opnds[1] = op_crx; 3140 n_add_base->_opnds[2] = op_dst; 3141 n_add_base->_bottom_type = _bottom_type; 3142 3143 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3144 ra_->set_oop(n_add_base, true); 3145 3146 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3147 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3148 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3149 3150 nodes->push(n_compare); 3151 nodes->push(n_shift); 3152 nodes->push(n_add_base); 3153 } 3154 %} 3155 3156 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3157 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3158 n1->add_req(n_region, n_src); 3159 n1->_opnds[0] = op_dst; 3160 n1->_opnds[1] = op_src; 3161 n1->_bottom_type = _bottom_type; 3162 3163 decodeN_addNode *n2 = new decodeN_addNode(); 3164 n2->add_req(n_region, n1); 3165 n2->_opnds[0] = op_dst; 3166 n2->_opnds[1] = op_dst; 3167 n2->_bottom_type = _bottom_type; 3168 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3169 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3170 3171 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3172 ra_->set_oop(n2, true); 3173 3174 nodes->push(n1); 3175 nodes->push(n2); 3176 %} 3177 3178 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3179 3180 C2_MacroAssembler _masm(&cbuf); 3181 int cc = $cmp$$cmpcode; 3182 int flags_reg = $crx$$reg; 3183 Label done; 3184 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3185 // Branch if not (cmp crx). 3186 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3187 __ mr($dst$$Register, $src$$Register); 3188 __ bind(done); 3189 %} 3190 3191 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3192 3193 C2_MacroAssembler _masm(&cbuf); 3194 Label done; 3195 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3196 // Branch if not (cmp crx). 3197 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3198 __ li($dst$$Register, $src$$constant); 3199 __ bind(done); 3200 %} 3201 3202 // This enc_class is needed so that scheduler gets proper 3203 // input mapping for latency computation. 3204 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3205 C2_MacroAssembler _masm(&cbuf); 3206 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3207 %} 3208 3209 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3210 3211 C2_MacroAssembler _masm(&cbuf); 3212 3213 Label done; 3214 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3215 __ li($dst$$Register, $zero$$constant); 3216 __ beq($crx$$CondRegister, done); 3217 __ li($dst$$Register, $notzero$$constant); 3218 __ bind(done); 3219 %} 3220 3221 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3222 3223 C2_MacroAssembler _masm(&cbuf); 3224 3225 Label done; 3226 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3227 __ li($dst$$Register, $zero$$constant); 3228 __ beq($crx$$CondRegister, done); 3229 __ li($dst$$Register, $notzero$$constant); 3230 __ bind(done); 3231 %} 3232 3233 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3234 3235 C2_MacroAssembler _masm(&cbuf); 3236 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3237 Label done; 3238 __ bso($crx$$CondRegister, done); 3239 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3240 __ bind(done); 3241 %} 3242 3243 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3244 3245 C2_MacroAssembler _masm(&cbuf); 3246 Label done; 3247 __ bso($crx$$CondRegister, done); 3248 __ mffprd($dst$$Register, $src$$FloatRegister); 3249 __ bind(done); 3250 %} 3251 3252 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3253 3254 C2_MacroAssembler _masm(&cbuf); 3255 Label d; // dummy 3256 __ bind(d); 3257 Label* p = ($lbl$$label); 3258 // `p' is `NULL' when this encoding class is used only to 3259 // determine the size of the encoded instruction. 3260 Label& l = (NULL == p)? d : *(p); 3261 int cc = $cmp$$cmpcode; 3262 int flags_reg = $crx$$reg; 3263 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3264 int bhint = Assembler::bhintNoHint; 3265 3266 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3267 if (_prob <= PROB_NEVER) { 3268 bhint = Assembler::bhintIsNotTaken; 3269 } else if (_prob >= PROB_ALWAYS) { 3270 bhint = Assembler::bhintIsTaken; 3271 } 3272 } 3273 3274 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3275 cc_to_biint(cc, flags_reg), 3276 l); 3277 %} 3278 3279 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3280 // The scheduler doesn't know about branch shortening, so we set the opcode 3281 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3282 3283 C2_MacroAssembler _masm(&cbuf); 3284 Label d; // dummy 3285 __ bind(d); 3286 Label* p = ($lbl$$label); 3287 // `p' is `NULL' when this encoding class is used only to 3288 // determine the size of the encoded instruction. 3289 Label& l = (NULL == p)? d : *(p); 3290 int cc = $cmp$$cmpcode; 3291 int flags_reg = $crx$$reg; 3292 int bhint = Assembler::bhintNoHint; 3293 3294 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3295 if (_prob <= PROB_NEVER) { 3296 bhint = Assembler::bhintIsNotTaken; 3297 } else if (_prob >= PROB_ALWAYS) { 3298 bhint = Assembler::bhintIsTaken; 3299 } 3300 } 3301 3302 // Tell the conditional far branch to optimize itself when being relocated. 3303 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3304 cc_to_biint(cc, flags_reg), 3305 l, 3306 MacroAssembler::bc_far_optimize_on_relocate); 3307 %} 3308 3309 // Postalloc expand emitter for loading a replicatef float constant from 3310 // the method's TOC. 3311 // Enc_class needed as consttanttablebase is not supported by postalloc 3312 // expand. 3313 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3314 // Create new nodes. 3315 3316 // Make an operand with the bit pattern to load as float. 3317 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3318 3319 loadConLNodesTuple loadConLNodes = 3320 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3321 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3322 3323 // Push new nodes. 3324 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3325 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3326 3327 assert(nodes->length() >= 1, "must have created at least 1 node"); 3328 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3329 %} 3330 3331 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3332 // Create new nodes. 3333 3334 // Make an operand with the bit pattern to load as float. 3335 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3336 immI_0Oper *op_zero = new immI_0Oper(0); 3337 3338 loadConLReplicatedNodesTuple loadConLNodes = 3339 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3340 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3341 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3342 3343 // Push new nodes. 3344 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3345 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3346 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3347 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3348 3349 assert(nodes->length() >= 1, "must have created at least 1 node"); 3350 %} 3351 3352 // This enc_class is needed so that scheduler gets proper 3353 // input mapping for latency computation. 3354 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3355 // Fake operand dst needed for PPC scheduler. 3356 assert($dst$$constant == 0x0, "dst must be 0x0"); 3357 3358 C2_MacroAssembler _masm(&cbuf); 3359 // Mark the code position where the load from the safepoint 3360 // polling page was emitted as relocInfo::poll_type. 3361 __ relocate(relocInfo::poll_type); 3362 __ load_from_polling_page($poll$$Register); 3363 %} 3364 3365 // A Java static call or a runtime call. 3366 // 3367 // Branch-and-link relative to a trampoline. 3368 // The trampoline loads the target address and does a long branch to there. 3369 // In case we call java, the trampoline branches to a interpreter_stub 3370 // which loads the inline cache and the real call target from the constant pool. 3371 // 3372 // This basically looks like this: 3373 // 3374 // >>>> consts -+ -+ 3375 // | |- offset1 3376 // [call target1] | <-+ 3377 // [IC cache] |- offset2 3378 // [call target2] <--+ 3379 // 3380 // <<<< consts 3381 // >>>> insts 3382 // 3383 // bl offset16 -+ -+ ??? // How many bits available? 3384 // | | 3385 // <<<< insts | | 3386 // >>>> stubs | | 3387 // | |- trampoline_stub_Reloc 3388 // trampoline stub: | <-+ 3389 // r2 = toc | 3390 // r2 = [r2 + offset1] | // Load call target1 from const section 3391 // mtctr r2 | 3392 // bctr |- static_stub_Reloc 3393 // comp_to_interp_stub: <---+ 3394 // r1 = toc 3395 // ICreg = [r1 + IC_offset] // Load IC from const section 3396 // r1 = [r1 + offset2] // Load call target2 from const section 3397 // mtctr r1 3398 // bctr 3399 // 3400 // <<<< stubs 3401 // 3402 // The call instruction in the code either 3403 // - Branches directly to a compiled method if the offset is encodable in instruction. 3404 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3405 // - Branches to the compiled_to_interp stub if the target is interpreted. 3406 // 3407 // Further there are three relocations from the loads to the constants in 3408 // the constant section. 3409 // 3410 // Usage of r1 and r2 in the stubs allows to distinguish them. 3411 enc_class enc_java_static_call(method meth) %{ 3412 3413 C2_MacroAssembler _masm(&cbuf); 3414 address entry_point = (address)$meth$$method; 3415 3416 if (!_method) { 3417 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3418 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3419 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3420 } else { 3421 // Remember the offset not the address. 3422 const int start_offset = __ offset(); 3423 3424 // The trampoline stub. 3425 // No entry point given, use the current pc. 3426 // Make sure branch fits into 3427 if (entry_point == 0) entry_point = __ pc(); 3428 3429 // Put the entry point as a constant into the constant pool. 3430 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3431 if (entry_point_toc_addr == NULL) { 3432 ciEnv::current()->record_out_of_memory_failure(); 3433 return; 3434 } 3435 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3436 3437 // Emit the trampoline stub which will be related to the branch-and-link below. 3438 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3439 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3440 int method_index = resolved_method_index(cbuf); 3441 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3442 : static_call_Relocation::spec(method_index)); 3443 3444 // The real call. 3445 // Note: At this point we do not have the address of the trampoline 3446 // stub, and the entry point might be too far away for bl, so __ pc() 3447 // serves as dummy and the bl will be patched later. 3448 cbuf.set_insts_mark(); 3449 __ bl(__ pc()); // Emits a relocation. 3450 3451 // The stub for call to interpreter. 3452 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3453 if (stub == NULL) { 3454 ciEnv::current()->record_failure("CodeCache is full"); 3455 return; 3456 } 3457 } 3458 __ post_call_nop(); 3459 %} 3460 3461 // Second node of expanded dynamic call - the call. 3462 enc_class enc_java_dynamic_call_sched(method meth) %{ 3463 3464 C2_MacroAssembler _masm(&cbuf); 3465 3466 if (!ra_->C->output()->in_scratch_emit_size()) { 3467 // Create a call trampoline stub for the given method. 3468 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3469 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3470 if (entry_point_const == NULL) { 3471 ciEnv::current()->record_out_of_memory_failure(); 3472 return; 3473 } 3474 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3475 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3476 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3477 3478 // Build relocation at call site with ic position as data. 3479 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3480 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3481 "must have one, but can't have both"); 3482 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3483 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3484 "must contain instruction offset"); 3485 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3486 ? _load_ic_hi_node->_cbuf_insts_offset 3487 : _load_ic_node->_cbuf_insts_offset; 3488 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3489 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3490 "should be load from TOC"); 3491 int method_index = resolved_method_index(cbuf); 3492 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3493 } 3494 3495 // At this point I do not have the address of the trampoline stub, 3496 // and the entry point might be too far away for bl. Pc() serves 3497 // as dummy and bl will be patched later. 3498 __ bl((address) __ pc()); 3499 __ post_call_nop(); 3500 %} 3501 3502 // postalloc expand emitter for virtual calls. 3503 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3504 3505 // Create the nodes for loading the IC from the TOC. 3506 loadConLNodesTuple loadConLNodes_IC = 3507 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3508 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3509 3510 // Create the call node. 3511 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3512 call->_method_handle_invoke = _method_handle_invoke; 3513 call->_vtable_index = _vtable_index; 3514 call->_method = _method; 3515 call->_optimized_virtual = _optimized_virtual; 3516 call->_tf = _tf; 3517 call->_entry_point = _entry_point; 3518 call->_cnt = _cnt; 3519 call->_guaranteed_safepoint = true; 3520 call->_oop_map = _oop_map; 3521 call->_jvms = _jvms; 3522 call->_jvmadj = _jvmadj; 3523 call->_in_rms = _in_rms; 3524 call->_nesting = _nesting; 3525 call->_override_symbolic_info = _override_symbolic_info; 3526 3527 // New call needs all inputs of old call. 3528 // Req... 3529 for (uint i = 0; i < req(); ++i) { 3530 // The expanded node does not need toc any more. 3531 // Add the inline cache constant here instead. This expresses the 3532 // register of the inline cache must be live at the call. 3533 // Else we would have to adapt JVMState by -1. 3534 if (i == mach_constant_base_node_input()) { 3535 call->add_req(loadConLNodes_IC._last); 3536 } else { 3537 call->add_req(in(i)); 3538 } 3539 } 3540 // ...as well as prec 3541 for (uint i = req(); i < len(); ++i) { 3542 call->add_prec(in(i)); 3543 } 3544 3545 // Remember nodes loading the inline cache into r19. 3546 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3547 call->_load_ic_node = loadConLNodes_IC._small; 3548 3549 // Operands for new nodes. 3550 call->_opnds[0] = _opnds[0]; 3551 call->_opnds[1] = _opnds[1]; 3552 3553 // Only the inline cache is associated with a register. 3554 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3555 3556 // Push new nodes. 3557 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3558 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3559 nodes->push(call); 3560 %} 3561 3562 // Compound version of call dynamic 3563 // Toc is only passed so that it can be used in ins_encode statement. 3564 // In the code we have to use $constanttablebase. 3565 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3566 C2_MacroAssembler _masm(&cbuf); 3567 int start_offset = __ offset(); 3568 3569 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3570 3571 int vtable_index = this->_vtable_index; 3572 if (vtable_index < 0) { 3573 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3574 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3575 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3576 3577 // Virtual call relocation will point to ic load. 3578 address virtual_call_meta_addr = __ pc(); 3579 // Load a clear inline cache. 3580 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3581 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3582 if (!success) { 3583 ciEnv::current()->record_out_of_memory_failure(); 3584 return; 3585 } 3586 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3587 // to determine who we intended to call. 3588 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3589 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3590 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3591 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3592 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset); 3593 } else { 3594 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3595 // Go thru the vtable. Get receiver klass. Receiver already 3596 // checked for non-null. If we'll go thru a C2I adapter, the 3597 // interpreter expects method in R19_method. 3598 3599 __ load_klass(R11_scratch1, R3); 3600 3601 int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index * vtableEntry::size_in_bytes(); 3602 int v_off = entry_offset + in_bytes(vtableEntry::method_offset()); 3603 __ li(R19_method, v_off); 3604 __ ldx(R19_method/*method*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3605 // NOTE: for vtable dispatches, the vtable entry will never be 3606 // null. However it may very well end up in handle_wrong_method 3607 // if the method is abstract for the particular class. 3608 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3609 // Call target. Either compiled code or C2I adapter. 3610 __ mtctr(R11_scratch1); 3611 __ bctrl(); 3612 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3613 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset); 3614 } 3615 __ post_call_nop(); 3616 %} 3617 3618 // a runtime call 3619 enc_class enc_java_to_runtime_call (method meth) %{ 3620 3621 C2_MacroAssembler _masm(&cbuf); 3622 const address start_pc = __ pc(); 3623 3624 #if defined(ABI_ELFv2) 3625 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3626 __ call_c(entry, relocInfo::runtime_call_type); 3627 __ post_call_nop(); 3628 #else 3629 // The function we're going to call. 3630 FunctionDescriptor fdtemp; 3631 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3632 3633 Register Rtoc = R12_scratch2; 3634 // Calculate the method's TOC. 3635 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3636 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3637 // pool entries; call_c_using_toc will optimize the call. 3638 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3639 if (!success) { 3640 ciEnv::current()->record_out_of_memory_failure(); 3641 return; 3642 } 3643 __ post_call_nop(); 3644 #endif 3645 3646 // Check the ret_addr_offset. 3647 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3648 "Fix constant in ret_addr_offset()"); 3649 %} 3650 3651 // Move to ctr for leaf call. 3652 // This enc_class is needed so that scheduler gets proper 3653 // input mapping for latency computation. 3654 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3655 C2_MacroAssembler _masm(&cbuf); 3656 __ mtctr($src$$Register); 3657 %} 3658 3659 // Postalloc expand emitter for runtime leaf calls. 3660 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3661 loadConLNodesTuple loadConLNodes_Entry; 3662 #if defined(ABI_ELFv2) 3663 jlong entry_address = (jlong) this->entry_point(); 3664 assert(entry_address, "need address here"); 3665 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3666 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3667 #else 3668 // Get the struct that describes the function we are about to call. 3669 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3670 assert(fd, "need fd here"); 3671 jlong entry_address = (jlong) fd->entry(); 3672 // new nodes 3673 loadConLNodesTuple loadConLNodes_Env; 3674 loadConLNodesTuple loadConLNodes_Toc; 3675 3676 // Create nodes and operands for loading the entry point. 3677 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3678 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3679 3680 3681 // Create nodes and operands for loading the env pointer. 3682 if (fd->env() != NULL) { 3683 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3684 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3685 } else { 3686 loadConLNodes_Env._large_hi = NULL; 3687 loadConLNodes_Env._large_lo = NULL; 3688 loadConLNodes_Env._small = NULL; 3689 loadConLNodes_Env._last = new loadConL16Node(); 3690 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3691 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3692 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3693 } 3694 3695 // Create nodes and operands for loading the Toc point. 3696 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3697 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3698 #endif // ABI_ELFv2 3699 // mtctr node 3700 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3701 3702 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3703 mtctr->add_req(0, loadConLNodes_Entry._last); 3704 3705 mtctr->_opnds[0] = new iRegLdstOper(); 3706 mtctr->_opnds[1] = new iRegLdstOper(); 3707 3708 // call node 3709 MachCallLeafNode *call = new CallLeafDirectNode(); 3710 3711 call->_opnds[0] = _opnds[0]; 3712 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3713 3714 // Make the new call node look like the old one. 3715 call->_name = _name; 3716 call->_tf = _tf; 3717 call->_entry_point = _entry_point; 3718 call->_cnt = _cnt; 3719 call->_guaranteed_safepoint = false; 3720 call->_oop_map = _oop_map; 3721 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3722 call->_jvms = NULL; 3723 call->_jvmadj = _jvmadj; 3724 call->_in_rms = _in_rms; 3725 call->_nesting = _nesting; 3726 3727 // New call needs all inputs of old call. 3728 // Req... 3729 for (uint i = 0; i < req(); ++i) { 3730 if (i != mach_constant_base_node_input()) { 3731 call->add_req(in(i)); 3732 } 3733 } 3734 3735 // These must be reqired edges, as the registers are live up to 3736 // the call. Else the constants are handled as kills. 3737 call->add_req(mtctr); 3738 #if !defined(ABI_ELFv2) 3739 call->add_req(loadConLNodes_Env._last); 3740 call->add_req(loadConLNodes_Toc._last); 3741 #endif 3742 3743 // ...as well as prec 3744 for (uint i = req(); i < len(); ++i) { 3745 call->add_prec(in(i)); 3746 } 3747 3748 // registers 3749 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 3750 3751 // Insert the new nodes. 3752 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 3753 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 3754 #if !defined(ABI_ELFv2) 3755 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 3756 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 3757 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 3758 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 3759 #endif 3760 nodes->push(mtctr); 3761 nodes->push(call); 3762 %} 3763 %} 3764 3765 //----------FRAME-------------------------------------------------------------- 3766 // Definition of frame structure and management information. 3767 3768 frame %{ 3769 // These two registers define part of the calling convention between 3770 // compiled code and the interpreter. 3771 3772 // Inline Cache Register or method for I2C. 3773 inline_cache_reg(R19); // R19_method 3774 3775 // Optional: name the operand used by cisc-spilling to access 3776 // [stack_pointer + offset]. 3777 cisc_spilling_operand_name(indOffset); 3778 3779 // Number of stack slots consumed by a Monitor enter. 3780 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 3781 3782 // Compiled code's Frame Pointer. 3783 frame_pointer(R1); // R1_SP 3784 3785 // Interpreter stores its frame pointer in a register which is 3786 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 3787 // interpreted java to compiled java. 3788 // 3789 // R14_state holds pointer to caller's cInterpreter. 3790 interpreter_frame_pointer(R14); // R14_state 3791 3792 stack_alignment(frame::alignment_in_bytes); 3793 3794 // Number of outgoing stack slots killed above the 3795 // out_preserve_stack_slots for calls to C. Supports the var-args 3796 // backing area for register parms. 3797 // 3798 varargs_C_out_slots_killed(((frame::native_abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 3799 3800 // The after-PROLOG location of the return address. Location of 3801 // return address specifies a type (REG or STACK) and a number 3802 // representing the register number (i.e. - use a register name) or 3803 // stack slot. 3804 // 3805 // A: Link register is stored in stack slot ... 3806 // M: ... but it's in the caller's frame according to PPC-64 ABI. 3807 // J: Therefore, we make sure that the link register is also in R11_scratch1 3808 // at the end of the prolog. 3809 // B: We use R20, now. 3810 //return_addr(REG R20); 3811 3812 // G: After reading the comments made by all the luminaries on their 3813 // failure to tell the compiler where the return address really is, 3814 // I hardly dare to try myself. However, I'm convinced it's in slot 3815 // 4 what apparently works and saves us some spills. 3816 return_addr(STACK 4); 3817 3818 // Location of native (C/C++) and interpreter return values. This 3819 // is specified to be the same as Java. In the 32-bit VM, long 3820 // values are actually returned from native calls in O0:O1 and 3821 // returned to the interpreter in I0:I1. The copying to and from 3822 // the register pairs is done by the appropriate call and epilog 3823 // opcodes. This simplifies the register allocator. 3824 c_return_value %{ 3825 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3826 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0), 3827 "only return normal values"); 3828 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3829 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3830 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3831 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3832 %} 3833 3834 // Location of compiled Java return values. Same as C 3835 return_value %{ 3836 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3837 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0), 3838 "only return normal values"); 3839 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3840 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3841 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3842 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3843 %} 3844 %} 3845 3846 3847 //----------ATTRIBUTES--------------------------------------------------------- 3848 3849 //----------Operand Attributes------------------------------------------------- 3850 op_attrib op_cost(1); // Required cost attribute. 3851 3852 //----------Instruction Attributes--------------------------------------------- 3853 3854 // Cost attribute. required. 3855 ins_attrib ins_cost(DEFAULT_COST); 3856 3857 // Is this instruction a non-matching short branch variant of some 3858 // long branch? Not required. 3859 ins_attrib ins_short_branch(0); 3860 3861 ins_attrib ins_is_TrapBasedCheckNode(true); 3862 3863 // Number of constants. 3864 // This instruction uses the given number of constants 3865 // (optional attribute). 3866 // This is needed to determine in time whether the constant pool will 3867 // exceed 4000 entries. Before postalloc_expand the overall number of constants 3868 // is determined. It's also used to compute the constant pool size 3869 // in Output(). 3870 ins_attrib ins_num_consts(0); 3871 3872 // Required alignment attribute (must be a power of 2) specifies the 3873 // alignment that some part of the instruction (not necessarily the 3874 // start) requires. If > 1, a compute_padding() function must be 3875 // provided for the instruction. 3876 ins_attrib ins_alignment(1); 3877 3878 // Enforce/prohibit rematerializations. 3879 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 3880 // then rematerialization of that instruction is prohibited and the 3881 // instruction's value will be spilled if necessary. 3882 // Causes that MachNode::rematerialize() returns false. 3883 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 3884 // then rematerialization should be enforced and a copy of the instruction 3885 // should be inserted if possible; rematerialization is not guaranteed. 3886 // Note: this may result in rematerializations in front of every use. 3887 // Causes that MachNode::rematerialize() can return true. 3888 // (optional attribute) 3889 ins_attrib ins_cannot_rematerialize(false); 3890 ins_attrib ins_should_rematerialize(false); 3891 3892 // Instruction has variable size depending on alignment. 3893 ins_attrib ins_variable_size_depending_on_alignment(false); 3894 3895 // Instruction is a nop. 3896 ins_attrib ins_is_nop(false); 3897 3898 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 3899 ins_attrib ins_use_mach_if_fast_lock_node(false); 3900 3901 // Field for the toc offset of a constant. 3902 // 3903 // This is needed if the toc offset is not encodable as an immediate in 3904 // the PPC load instruction. If so, the upper (hi) bits of the offset are 3905 // added to the toc, and from this a load with immediate is performed. 3906 // With postalloc expand, we get two nodes that require the same offset 3907 // but which don't know about each other. The offset is only known 3908 // when the constant is added to the constant pool during emitting. 3909 // It is generated in the 'hi'-node adding the upper bits, and saved 3910 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 3911 // the offset from there when it gets encoded. 3912 ins_attrib ins_field_const_toc_offset(0); 3913 ins_attrib ins_field_const_toc_offset_hi_node(0); 3914 3915 // A field that can hold the instructions offset in the code buffer. 3916 // Set in the nodes emitter. 3917 ins_attrib ins_field_cbuf_insts_offset(-1); 3918 3919 // Fields for referencing a call's load-IC-node. 3920 // If the toc offset can not be encoded as an immediate in a load, we 3921 // use two nodes. 3922 ins_attrib ins_field_load_ic_hi_node(0); 3923 ins_attrib ins_field_load_ic_node(0); 3924 3925 //----------OPERANDS----------------------------------------------------------- 3926 // Operand definitions must precede instruction definitions for correct 3927 // parsing in the ADLC because operands constitute user defined types 3928 // which are used in instruction definitions. 3929 // 3930 // Formats are generated automatically for constants and base registers. 3931 3932 operand vecX() %{ 3933 constraint(ALLOC_IN_RC(vs_reg)); 3934 match(VecX); 3935 3936 format %{ %} 3937 interface(REG_INTER); 3938 %} 3939 3940 //----------Simple Operands---------------------------------------------------- 3941 // Immediate Operands 3942 3943 // Integer Immediate: 32-bit 3944 operand immI() %{ 3945 match(ConI); 3946 op_cost(40); 3947 format %{ %} 3948 interface(CONST_INTER); 3949 %} 3950 3951 operand immI8() %{ 3952 predicate(Assembler::is_simm(n->get_int(), 8)); 3953 op_cost(0); 3954 match(ConI); 3955 format %{ %} 3956 interface(CONST_INTER); 3957 %} 3958 3959 // Integer Immediate: 16-bit 3960 operand immI16() %{ 3961 predicate(Assembler::is_simm(n->get_int(), 16)); 3962 op_cost(0); 3963 match(ConI); 3964 format %{ %} 3965 interface(CONST_INTER); 3966 %} 3967 3968 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 3969 operand immIhi16() %{ 3970 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 3971 match(ConI); 3972 op_cost(0); 3973 format %{ %} 3974 interface(CONST_INTER); 3975 %} 3976 3977 // Integer Immediate: 32-bit immediate for prefixed addi and load/store. 3978 operand immI32() %{ 3979 predicate(PowerArchitecturePPC64 >= 10); 3980 op_cost(0); 3981 match(ConI); 3982 format %{ %} 3983 interface(CONST_INTER); 3984 %} 3985 3986 operand immInegpow2() %{ 3987 predicate(is_power_of_2(-(juint)(n->get_int()))); 3988 match(ConI); 3989 op_cost(0); 3990 format %{ %} 3991 interface(CONST_INTER); 3992 %} 3993 3994 operand immIpow2minus1() %{ 3995 predicate(is_power_of_2((juint)(n->get_int()) + 1u)); 3996 match(ConI); 3997 op_cost(0); 3998 format %{ %} 3999 interface(CONST_INTER); 4000 %} 4001 4002 operand immIpowerOf2() %{ 4003 predicate(is_power_of_2((juint)(n->get_int()))); 4004 match(ConI); 4005 op_cost(0); 4006 format %{ %} 4007 interface(CONST_INTER); 4008 %} 4009 4010 // Unsigned Integer Immediate: the values 0-31 4011 operand uimmI5() %{ 4012 predicate(Assembler::is_uimm(n->get_int(), 5)); 4013 match(ConI); 4014 op_cost(0); 4015 format %{ %} 4016 interface(CONST_INTER); 4017 %} 4018 4019 // Unsigned Integer Immediate: 6-bit 4020 operand uimmI6() %{ 4021 predicate(Assembler::is_uimm(n->get_int(), 6)); 4022 match(ConI); 4023 op_cost(0); 4024 format %{ %} 4025 interface(CONST_INTER); 4026 %} 4027 4028 // Unsigned Integer Immediate: 6-bit int, greater than 32 4029 operand uimmI6_ge32() %{ 4030 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4031 match(ConI); 4032 op_cost(0); 4033 format %{ %} 4034 interface(CONST_INTER); 4035 %} 4036 4037 // Unsigned Integer Immediate: 15-bit 4038 operand uimmI15() %{ 4039 predicate(Assembler::is_uimm(n->get_int(), 15)); 4040 match(ConI); 4041 op_cost(0); 4042 format %{ %} 4043 interface(CONST_INTER); 4044 %} 4045 4046 // Unsigned Integer Immediate: 16-bit 4047 operand uimmI16() %{ 4048 predicate(Assembler::is_uimm(n->get_int(), 16)); 4049 match(ConI); 4050 op_cost(0); 4051 format %{ %} 4052 interface(CONST_INTER); 4053 %} 4054 4055 // constant 'int 0'. 4056 operand immI_0() %{ 4057 predicate(n->get_int() == 0); 4058 match(ConI); 4059 op_cost(0); 4060 format %{ %} 4061 interface(CONST_INTER); 4062 %} 4063 4064 // constant 'int 1'. 4065 operand immI_1() %{ 4066 predicate(n->get_int() == 1); 4067 match(ConI); 4068 op_cost(0); 4069 format %{ %} 4070 interface(CONST_INTER); 4071 %} 4072 4073 // constant 'int -1'. 4074 operand immI_minus1() %{ 4075 predicate(n->get_int() == -1); 4076 match(ConI); 4077 op_cost(0); 4078 format %{ %} 4079 interface(CONST_INTER); 4080 %} 4081 4082 // int value 16. 4083 operand immI_16() %{ 4084 predicate(n->get_int() == 16); 4085 match(ConI); 4086 op_cost(0); 4087 format %{ %} 4088 interface(CONST_INTER); 4089 %} 4090 4091 // int value 24. 4092 operand immI_24() %{ 4093 predicate(n->get_int() == 24); 4094 match(ConI); 4095 op_cost(0); 4096 format %{ %} 4097 interface(CONST_INTER); 4098 %} 4099 4100 // Compressed oops constants 4101 // Pointer Immediate 4102 operand immN() %{ 4103 match(ConN); 4104 4105 op_cost(10); 4106 format %{ %} 4107 interface(CONST_INTER); 4108 %} 4109 4110 // NULL Pointer Immediate 4111 operand immN_0() %{ 4112 predicate(n->get_narrowcon() == 0); 4113 match(ConN); 4114 4115 op_cost(0); 4116 format %{ %} 4117 interface(CONST_INTER); 4118 %} 4119 4120 // Compressed klass constants 4121 operand immNKlass() %{ 4122 match(ConNKlass); 4123 4124 op_cost(0); 4125 format %{ %} 4126 interface(CONST_INTER); 4127 %} 4128 4129 // This operand can be used to avoid matching of an instruct 4130 // with chain rule. 4131 operand immNKlass_NM() %{ 4132 match(ConNKlass); 4133 predicate(false); 4134 op_cost(0); 4135 format %{ %} 4136 interface(CONST_INTER); 4137 %} 4138 4139 // Pointer Immediate: 64-bit 4140 operand immP() %{ 4141 match(ConP); 4142 op_cost(0); 4143 format %{ %} 4144 interface(CONST_INTER); 4145 %} 4146 4147 // Operand to avoid match of loadConP. 4148 // This operand can be used to avoid matching of an instruct 4149 // with chain rule. 4150 operand immP_NM() %{ 4151 match(ConP); 4152 predicate(false); 4153 op_cost(0); 4154 format %{ %} 4155 interface(CONST_INTER); 4156 %} 4157 4158 // constant 'pointer 0'. 4159 operand immP_0() %{ 4160 predicate(n->get_ptr() == 0); 4161 match(ConP); 4162 op_cost(0); 4163 format %{ %} 4164 interface(CONST_INTER); 4165 %} 4166 4167 // pointer 0x0 or 0x1 4168 operand immP_0or1() %{ 4169 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4170 match(ConP); 4171 op_cost(0); 4172 format %{ %} 4173 interface(CONST_INTER); 4174 %} 4175 4176 operand immL() %{ 4177 match(ConL); 4178 op_cost(40); 4179 format %{ %} 4180 interface(CONST_INTER); 4181 %} 4182 4183 operand immLmax30() %{ 4184 predicate((n->get_long() <= 30)); 4185 match(ConL); 4186 op_cost(0); 4187 format %{ %} 4188 interface(CONST_INTER); 4189 %} 4190 4191 // Long Immediate: 16-bit 4192 operand immL16() %{ 4193 predicate(Assembler::is_simm(n->get_long(), 16)); 4194 match(ConL); 4195 op_cost(0); 4196 format %{ %} 4197 interface(CONST_INTER); 4198 %} 4199 4200 // Long Immediate: 16-bit, 4-aligned 4201 operand immL16Alg4() %{ 4202 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4203 match(ConL); 4204 op_cost(0); 4205 format %{ %} 4206 interface(CONST_INTER); 4207 %} 4208 4209 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4210 operand immL32hi16() %{ 4211 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4212 match(ConL); 4213 op_cost(0); 4214 format %{ %} 4215 interface(CONST_INTER); 4216 %} 4217 4218 // Long Immediate: 32-bit 4219 operand immL32() %{ 4220 predicate(Assembler::is_simm(n->get_long(), 32)); 4221 match(ConL); 4222 op_cost(0); 4223 format %{ %} 4224 interface(CONST_INTER); 4225 %} 4226 4227 // Long Immediate: 34-bit, immediate field in prefixed addi and load/store. 4228 operand immL34() %{ 4229 predicate(PowerArchitecturePPC64 >= 10 && Assembler::is_simm(n->get_long(), 34)); 4230 match(ConL); 4231 op_cost(0); 4232 format %{ %} 4233 interface(CONST_INTER); 4234 %} 4235 4236 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4237 operand immLhighest16() %{ 4238 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4239 match(ConL); 4240 op_cost(0); 4241 format %{ %} 4242 interface(CONST_INTER); 4243 %} 4244 4245 operand immLnegpow2() %{ 4246 predicate(is_power_of_2(-(julong)(n->get_long()))); 4247 match(ConL); 4248 op_cost(0); 4249 format %{ %} 4250 interface(CONST_INTER); 4251 %} 4252 4253 operand immLpow2minus1() %{ 4254 predicate(is_power_of_2((julong)(n->get_long()) + 1ull)); 4255 match(ConL); 4256 op_cost(0); 4257 format %{ %} 4258 interface(CONST_INTER); 4259 %} 4260 4261 // constant 'long 0'. 4262 operand immL_0() %{ 4263 predicate(n->get_long() == 0L); 4264 match(ConL); 4265 op_cost(0); 4266 format %{ %} 4267 interface(CONST_INTER); 4268 %} 4269 4270 // constat ' long -1'. 4271 operand immL_minus1() %{ 4272 predicate(n->get_long() == -1L); 4273 match(ConL); 4274 op_cost(0); 4275 format %{ %} 4276 interface(CONST_INTER); 4277 %} 4278 4279 // Long Immediate: low 32-bit mask 4280 operand immL_32bits() %{ 4281 predicate(n->get_long() == 0xFFFFFFFFL); 4282 match(ConL); 4283 op_cost(0); 4284 format %{ %} 4285 interface(CONST_INTER); 4286 %} 4287 4288 // Unsigned Long Immediate: 16-bit 4289 operand uimmL16() %{ 4290 predicate(Assembler::is_uimm(n->get_long(), 16)); 4291 match(ConL); 4292 op_cost(0); 4293 format %{ %} 4294 interface(CONST_INTER); 4295 %} 4296 4297 // Float Immediate 4298 operand immF() %{ 4299 match(ConF); 4300 op_cost(40); 4301 format %{ %} 4302 interface(CONST_INTER); 4303 %} 4304 4305 // Float Immediate: +0.0f. 4306 operand immF_0() %{ 4307 predicate(jint_cast(n->getf()) == 0); 4308 match(ConF); 4309 4310 op_cost(0); 4311 format %{ %} 4312 interface(CONST_INTER); 4313 %} 4314 4315 // Double Immediate 4316 operand immD() %{ 4317 match(ConD); 4318 op_cost(40); 4319 format %{ %} 4320 interface(CONST_INTER); 4321 %} 4322 4323 // Double Immediate: +0.0d. 4324 operand immD_0() %{ 4325 predicate(jlong_cast(n->getd()) == 0); 4326 match(ConD); 4327 4328 op_cost(0); 4329 format %{ %} 4330 interface(CONST_INTER); 4331 %} 4332 4333 // Integer Register Operands 4334 // Integer Destination Register 4335 // See definition of reg_class bits32_reg_rw. 4336 operand iRegIdst() %{ 4337 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4338 match(RegI); 4339 match(rscratch1RegI); 4340 match(rscratch2RegI); 4341 match(rarg1RegI); 4342 match(rarg2RegI); 4343 match(rarg3RegI); 4344 match(rarg4RegI); 4345 format %{ %} 4346 interface(REG_INTER); 4347 %} 4348 4349 // Integer Source Register 4350 // See definition of reg_class bits32_reg_ro. 4351 operand iRegIsrc() %{ 4352 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4353 match(RegI); 4354 match(rscratch1RegI); 4355 match(rscratch2RegI); 4356 match(rarg1RegI); 4357 match(rarg2RegI); 4358 match(rarg3RegI); 4359 match(rarg4RegI); 4360 format %{ %} 4361 interface(REG_INTER); 4362 %} 4363 4364 operand rscratch1RegI() %{ 4365 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4366 match(iRegIdst); 4367 format %{ %} 4368 interface(REG_INTER); 4369 %} 4370 4371 operand rscratch2RegI() %{ 4372 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4373 match(iRegIdst); 4374 format %{ %} 4375 interface(REG_INTER); 4376 %} 4377 4378 operand rarg1RegI() %{ 4379 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4380 match(iRegIdst); 4381 format %{ %} 4382 interface(REG_INTER); 4383 %} 4384 4385 operand rarg2RegI() %{ 4386 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4387 match(iRegIdst); 4388 format %{ %} 4389 interface(REG_INTER); 4390 %} 4391 4392 operand rarg3RegI() %{ 4393 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4394 match(iRegIdst); 4395 format %{ %} 4396 interface(REG_INTER); 4397 %} 4398 4399 operand rarg4RegI() %{ 4400 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4401 match(iRegIdst); 4402 format %{ %} 4403 interface(REG_INTER); 4404 %} 4405 4406 operand rarg1RegL() %{ 4407 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4408 match(iRegLdst); 4409 format %{ %} 4410 interface(REG_INTER); 4411 %} 4412 4413 operand rarg2RegL() %{ 4414 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4415 match(iRegLdst); 4416 format %{ %} 4417 interface(REG_INTER); 4418 %} 4419 4420 operand rarg3RegL() %{ 4421 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4422 match(iRegLdst); 4423 format %{ %} 4424 interface(REG_INTER); 4425 %} 4426 4427 operand rarg4RegL() %{ 4428 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4429 match(iRegLdst); 4430 format %{ %} 4431 interface(REG_INTER); 4432 %} 4433 4434 // Pointer Destination Register 4435 // See definition of reg_class bits64_reg_rw. 4436 operand iRegPdst() %{ 4437 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4438 match(RegP); 4439 match(rscratch1RegP); 4440 match(rscratch2RegP); 4441 match(rarg1RegP); 4442 match(rarg2RegP); 4443 match(rarg3RegP); 4444 match(rarg4RegP); 4445 format %{ %} 4446 interface(REG_INTER); 4447 %} 4448 4449 // Pointer Destination Register 4450 // Operand not using r11 and r12 (killed in epilog). 4451 operand iRegPdstNoScratch() %{ 4452 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4453 match(RegP); 4454 match(rarg1RegP); 4455 match(rarg2RegP); 4456 match(rarg3RegP); 4457 match(rarg4RegP); 4458 format %{ %} 4459 interface(REG_INTER); 4460 %} 4461 4462 // Pointer Source Register 4463 // See definition of reg_class bits64_reg_ro. 4464 operand iRegPsrc() %{ 4465 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4466 match(RegP); 4467 match(iRegPdst); 4468 match(rscratch1RegP); 4469 match(rscratch2RegP); 4470 match(rarg1RegP); 4471 match(rarg2RegP); 4472 match(rarg3RegP); 4473 match(rarg4RegP); 4474 match(threadRegP); 4475 format %{ %} 4476 interface(REG_INTER); 4477 %} 4478 4479 // Thread operand. 4480 operand threadRegP() %{ 4481 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4482 match(iRegPdst); 4483 format %{ "R16" %} 4484 interface(REG_INTER); 4485 %} 4486 4487 operand rscratch1RegP() %{ 4488 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4489 match(iRegPdst); 4490 format %{ "R11" %} 4491 interface(REG_INTER); 4492 %} 4493 4494 operand rscratch2RegP() %{ 4495 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4496 match(iRegPdst); 4497 format %{ %} 4498 interface(REG_INTER); 4499 %} 4500 4501 operand rarg1RegP() %{ 4502 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4503 match(iRegPdst); 4504 format %{ %} 4505 interface(REG_INTER); 4506 %} 4507 4508 operand rarg2RegP() %{ 4509 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4510 match(iRegPdst); 4511 format %{ %} 4512 interface(REG_INTER); 4513 %} 4514 4515 operand rarg3RegP() %{ 4516 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4517 match(iRegPdst); 4518 format %{ %} 4519 interface(REG_INTER); 4520 %} 4521 4522 operand rarg4RegP() %{ 4523 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4524 match(iRegPdst); 4525 format %{ %} 4526 interface(REG_INTER); 4527 %} 4528 4529 operand iRegNsrc() %{ 4530 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4531 match(RegN); 4532 match(iRegNdst); 4533 4534 format %{ %} 4535 interface(REG_INTER); 4536 %} 4537 4538 operand iRegNdst() %{ 4539 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4540 match(RegN); 4541 4542 format %{ %} 4543 interface(REG_INTER); 4544 %} 4545 4546 // Long Destination Register 4547 // See definition of reg_class bits64_reg_rw. 4548 operand iRegLdst() %{ 4549 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4550 match(RegL); 4551 match(rscratch1RegL); 4552 match(rscratch2RegL); 4553 format %{ %} 4554 interface(REG_INTER); 4555 %} 4556 4557 // Long Source Register 4558 // See definition of reg_class bits64_reg_ro. 4559 operand iRegLsrc() %{ 4560 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4561 match(RegL); 4562 match(iRegLdst); 4563 match(rscratch1RegL); 4564 match(rscratch2RegL); 4565 format %{ %} 4566 interface(REG_INTER); 4567 %} 4568 4569 // Special operand for ConvL2I. 4570 operand iRegL2Isrc(iRegLsrc reg) %{ 4571 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4572 match(ConvL2I reg); 4573 format %{ "ConvL2I($reg)" %} 4574 interface(REG_INTER) 4575 %} 4576 4577 operand rscratch1RegL() %{ 4578 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4579 match(RegL); 4580 format %{ %} 4581 interface(REG_INTER); 4582 %} 4583 4584 operand rscratch2RegL() %{ 4585 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4586 match(RegL); 4587 format %{ %} 4588 interface(REG_INTER); 4589 %} 4590 4591 // Condition Code Flag Registers 4592 operand flagsReg() %{ 4593 constraint(ALLOC_IN_RC(int_flags)); 4594 match(RegFlags); 4595 format %{ %} 4596 interface(REG_INTER); 4597 %} 4598 4599 operand flagsRegSrc() %{ 4600 constraint(ALLOC_IN_RC(int_flags_ro)); 4601 match(RegFlags); 4602 match(flagsReg); 4603 match(flagsRegCR0); 4604 format %{ %} 4605 interface(REG_INTER); 4606 %} 4607 4608 // Condition Code Flag Register CR0 4609 operand flagsRegCR0() %{ 4610 constraint(ALLOC_IN_RC(int_flags_CR0)); 4611 match(RegFlags); 4612 format %{ "CR0" %} 4613 interface(REG_INTER); 4614 %} 4615 4616 operand flagsRegCR1() %{ 4617 constraint(ALLOC_IN_RC(int_flags_CR1)); 4618 match(RegFlags); 4619 format %{ "CR1" %} 4620 interface(REG_INTER); 4621 %} 4622 4623 operand flagsRegCR6() %{ 4624 constraint(ALLOC_IN_RC(int_flags_CR6)); 4625 match(RegFlags); 4626 format %{ "CR6" %} 4627 interface(REG_INTER); 4628 %} 4629 4630 operand regCTR() %{ 4631 constraint(ALLOC_IN_RC(ctr_reg)); 4632 // RegFlags should work. Introducing a RegSpecial type would cause a 4633 // lot of changes. 4634 match(RegFlags); 4635 format %{"SR_CTR" %} 4636 interface(REG_INTER); 4637 %} 4638 4639 operand regD() %{ 4640 constraint(ALLOC_IN_RC(dbl_reg)); 4641 match(RegD); 4642 format %{ %} 4643 interface(REG_INTER); 4644 %} 4645 4646 operand regF() %{ 4647 constraint(ALLOC_IN_RC(flt_reg)); 4648 match(RegF); 4649 format %{ %} 4650 interface(REG_INTER); 4651 %} 4652 4653 // Special Registers 4654 4655 // Method Register 4656 operand inline_cache_regP(iRegPdst reg) %{ 4657 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4658 match(reg); 4659 format %{ %} 4660 interface(REG_INTER); 4661 %} 4662 4663 // Operands to remove register moves in unscaled mode. 4664 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4665 operand iRegP2N(iRegPsrc reg) %{ 4666 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0); 4667 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4668 match(EncodeP reg); 4669 format %{ "$reg" %} 4670 interface(REG_INTER) 4671 %} 4672 4673 operand iRegN2P(iRegNsrc reg) %{ 4674 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4675 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4676 match(DecodeN reg); 4677 format %{ "$reg" %} 4678 interface(REG_INTER) 4679 %} 4680 4681 operand iRegN2P_klass(iRegNsrc reg) %{ 4682 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 4683 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4684 match(DecodeNKlass reg); 4685 format %{ "$reg" %} 4686 interface(REG_INTER) 4687 %} 4688 4689 //----------Complex Operands--------------------------------------------------- 4690 // Indirect Memory Reference 4691 operand indirect(iRegPsrc reg) %{ 4692 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4693 match(reg); 4694 op_cost(100); 4695 format %{ "[$reg]" %} 4696 interface(MEMORY_INTER) %{ 4697 base($reg); 4698 index(0x0); 4699 scale(0x0); 4700 disp(0x0); 4701 %} 4702 %} 4703 4704 // Indirect with Offset 4705 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 4706 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4707 match(AddP reg offset); 4708 op_cost(100); 4709 format %{ "[$reg + $offset]" %} 4710 interface(MEMORY_INTER) %{ 4711 base($reg); 4712 index(0x0); 4713 scale(0x0); 4714 disp($offset); 4715 %} 4716 %} 4717 4718 // Indirect with 4-aligned Offset 4719 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 4720 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4721 match(AddP reg offset); 4722 op_cost(100); 4723 format %{ "[$reg + $offset]" %} 4724 interface(MEMORY_INTER) %{ 4725 base($reg); 4726 index(0x0); 4727 scale(0x0); 4728 disp($offset); 4729 %} 4730 %} 4731 4732 //----------Complex Operands for Compressed OOPs------------------------------- 4733 // Compressed OOPs with narrow_oop_shift == 0. 4734 4735 // Indirect Memory Reference, compressed OOP 4736 operand indirectNarrow(iRegNsrc reg) %{ 4737 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4738 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4739 match(DecodeN reg); 4740 op_cost(100); 4741 format %{ "[$reg]" %} 4742 interface(MEMORY_INTER) %{ 4743 base($reg); 4744 index(0x0); 4745 scale(0x0); 4746 disp(0x0); 4747 %} 4748 %} 4749 4750 operand indirectNarrow_klass(iRegNsrc reg) %{ 4751 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 4752 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4753 match(DecodeNKlass reg); 4754 op_cost(100); 4755 format %{ "[$reg]" %} 4756 interface(MEMORY_INTER) %{ 4757 base($reg); 4758 index(0x0); 4759 scale(0x0); 4760 disp(0x0); 4761 %} 4762 %} 4763 4764 // Indirect with Offset, compressed OOP 4765 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 4766 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4767 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4768 match(AddP (DecodeN reg) offset); 4769 op_cost(100); 4770 format %{ "[$reg + $offset]" %} 4771 interface(MEMORY_INTER) %{ 4772 base($reg); 4773 index(0x0); 4774 scale(0x0); 4775 disp($offset); 4776 %} 4777 %} 4778 4779 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 4780 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 4781 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4782 match(AddP (DecodeNKlass reg) offset); 4783 op_cost(100); 4784 format %{ "[$reg + $offset]" %} 4785 interface(MEMORY_INTER) %{ 4786 base($reg); 4787 index(0x0); 4788 scale(0x0); 4789 disp($offset); 4790 %} 4791 %} 4792 4793 // Indirect with 4-aligned Offset, compressed OOP 4794 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 4795 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4796 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4797 match(AddP (DecodeN reg) offset); 4798 op_cost(100); 4799 format %{ "[$reg + $offset]" %} 4800 interface(MEMORY_INTER) %{ 4801 base($reg); 4802 index(0x0); 4803 scale(0x0); 4804 disp($offset); 4805 %} 4806 %} 4807 4808 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 4809 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 4810 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4811 match(AddP (DecodeNKlass reg) offset); 4812 op_cost(100); 4813 format %{ "[$reg + $offset]" %} 4814 interface(MEMORY_INTER) %{ 4815 base($reg); 4816 index(0x0); 4817 scale(0x0); 4818 disp($offset); 4819 %} 4820 %} 4821 4822 //----------Special Memory Operands-------------------------------------------- 4823 // Stack Slot Operand 4824 // 4825 // This operand is used for loading and storing temporary values on 4826 // the stack where a match requires a value to flow through memory. 4827 operand stackSlotI(sRegI reg) %{ 4828 constraint(ALLOC_IN_RC(stack_slots)); 4829 op_cost(100); 4830 //match(RegI); 4831 format %{ "[sp+$reg]" %} 4832 interface(MEMORY_INTER) %{ 4833 base(0x1); // R1_SP 4834 index(0x0); 4835 scale(0x0); 4836 disp($reg); // Stack Offset 4837 %} 4838 %} 4839 4840 operand stackSlotL(sRegL reg) %{ 4841 constraint(ALLOC_IN_RC(stack_slots)); 4842 op_cost(100); 4843 //match(RegL); 4844 format %{ "[sp+$reg]" %} 4845 interface(MEMORY_INTER) %{ 4846 base(0x1); // R1_SP 4847 index(0x0); 4848 scale(0x0); 4849 disp($reg); // Stack Offset 4850 %} 4851 %} 4852 4853 operand stackSlotP(sRegP reg) %{ 4854 constraint(ALLOC_IN_RC(stack_slots)); 4855 op_cost(100); 4856 //match(RegP); 4857 format %{ "[sp+$reg]" %} 4858 interface(MEMORY_INTER) %{ 4859 base(0x1); // R1_SP 4860 index(0x0); 4861 scale(0x0); 4862 disp($reg); // Stack Offset 4863 %} 4864 %} 4865 4866 operand stackSlotF(sRegF reg) %{ 4867 constraint(ALLOC_IN_RC(stack_slots)); 4868 op_cost(100); 4869 //match(RegF); 4870 format %{ "[sp+$reg]" %} 4871 interface(MEMORY_INTER) %{ 4872 base(0x1); // R1_SP 4873 index(0x0); 4874 scale(0x0); 4875 disp($reg); // Stack Offset 4876 %} 4877 %} 4878 4879 operand stackSlotD(sRegD reg) %{ 4880 constraint(ALLOC_IN_RC(stack_slots)); 4881 op_cost(100); 4882 //match(RegD); 4883 format %{ "[sp+$reg]" %} 4884 interface(MEMORY_INTER) %{ 4885 base(0x1); // R1_SP 4886 index(0x0); 4887 scale(0x0); 4888 disp($reg); // Stack Offset 4889 %} 4890 %} 4891 4892 // Operands for expressing Control Flow 4893 // NOTE: Label is a predefined operand which should not be redefined in 4894 // the AD file. It is generically handled within the ADLC. 4895 4896 //----------Conditional Branch Operands---------------------------------------- 4897 // Comparison Op 4898 // 4899 // This is the operation of the comparison, and is limited to the 4900 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 4901 // (!=). 4902 // 4903 // Other attributes of the comparison, such as unsignedness, are specified 4904 // by the comparison instruction that sets a condition code flags register. 4905 // That result is represented by a flags operand whose subtype is appropriate 4906 // to the unsignedness (etc.) of the comparison. 4907 // 4908 // Later, the instruction which matches both the Comparison Op (a Bool) and 4909 // the flags (produced by the Cmp) specifies the coding of the comparison op 4910 // by matching a specific subtype of Bool operand below. 4911 4912 // When used for floating point comparisons: unordered same as less. 4913 operand cmpOp() %{ 4914 match(Bool); 4915 format %{ "" %} 4916 interface(COND_INTER) %{ 4917 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 4918 // BO & BI 4919 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 4920 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 4921 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 4922 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 4923 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 4924 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 4925 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 4926 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 4927 %} 4928 %} 4929 4930 //----------OPERAND CLASSES---------------------------------------------------- 4931 // Operand Classes are groups of operands that are used to simplify 4932 // instruction definitions by not requiring the AD writer to specify 4933 // separate instructions for every form of operand when the 4934 // instruction accepts multiple operand types with the same basic 4935 // encoding and format. The classic case of this is memory operands. 4936 // Indirect is not included since its use is limited to Compare & Swap. 4937 4938 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 4939 // Memory operand where offsets are 4-aligned. Required for ld, std. 4940 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 4941 opclass indirectMemory(indirect, indirectNarrow); 4942 4943 // Special opclass for I and ConvL2I. 4944 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 4945 4946 // Operand classes to match encode and decode. iRegN_P2N is only used 4947 // for storeN. I have never seen an encode node elsewhere. 4948 opclass iRegN_P2N(iRegNsrc, iRegP2N); 4949 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 4950 4951 //----------PIPELINE----------------------------------------------------------- 4952 4953 pipeline %{ 4954 4955 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 4956 // J. Res. & Dev., No. 1, Jan. 2002. 4957 4958 //----------ATTRIBUTES--------------------------------------------------------- 4959 attributes %{ 4960 4961 // Power4 instructions are of fixed length. 4962 fixed_size_instructions; 4963 4964 // TODO: if `bundle' means number of instructions fetched 4965 // per cycle, this is 8. If `bundle' means Power4 `group', that is 4966 // max instructions issued per cycle, this is 5. 4967 max_instructions_per_bundle = 8; 4968 4969 // A Power4 instruction is 4 bytes long. 4970 instruction_unit_size = 4; 4971 4972 // The Power4 processor fetches 64 bytes... 4973 instruction_fetch_unit_size = 64; 4974 4975 // ...in one line 4976 instruction_fetch_units = 1 4977 4978 // Unused, list one so that array generated by adlc is not empty. 4979 // Aix compiler chokes if _nop_count = 0. 4980 nops(fxNop); 4981 %} 4982 4983 //----------RESOURCES---------------------------------------------------------- 4984 // Resources are the functional units available to the machine 4985 resources( 4986 PPC_BR, // branch unit 4987 PPC_CR, // condition unit 4988 PPC_FX1, // integer arithmetic unit 1 4989 PPC_FX2, // integer arithmetic unit 2 4990 PPC_LDST1, // load/store unit 1 4991 PPC_LDST2, // load/store unit 2 4992 PPC_FP1, // float arithmetic unit 1 4993 PPC_FP2, // float arithmetic unit 2 4994 PPC_LDST = PPC_LDST1 | PPC_LDST2, 4995 PPC_FX = PPC_FX1 | PPC_FX2, 4996 PPC_FP = PPC_FP1 | PPC_FP2 4997 ); 4998 4999 //----------PIPELINE DESCRIPTION----------------------------------------------- 5000 // Pipeline Description specifies the stages in the machine's pipeline 5001 pipe_desc( 5002 // Power4 longest pipeline path 5003 PPC_IF, // instruction fetch 5004 PPC_IC, 5005 //PPC_BP, // branch prediction 5006 PPC_D0, // decode 5007 PPC_D1, // decode 5008 PPC_D2, // decode 5009 PPC_D3, // decode 5010 PPC_Xfer1, 5011 PPC_GD, // group definition 5012 PPC_MP, // map 5013 PPC_ISS, // issue 5014 PPC_RF, // resource fetch 5015 PPC_EX1, // execute (all units) 5016 PPC_EX2, // execute (FP, LDST) 5017 PPC_EX3, // execute (FP, LDST) 5018 PPC_EX4, // execute (FP) 5019 PPC_EX5, // execute (FP) 5020 PPC_EX6, // execute (FP) 5021 PPC_WB, // write back 5022 PPC_Xfer2, 5023 PPC_CP 5024 ); 5025 5026 //----------PIPELINE CLASSES--------------------------------------------------- 5027 // Pipeline Classes describe the stages in which input and output are 5028 // referenced by the hardware pipeline. 5029 5030 // Simple pipeline classes. 5031 5032 // Default pipeline class. 5033 pipe_class pipe_class_default() %{ 5034 single_instruction; 5035 fixed_latency(2); 5036 %} 5037 5038 // Pipeline class for empty instructions. 5039 pipe_class pipe_class_empty() %{ 5040 single_instruction; 5041 fixed_latency(0); 5042 %} 5043 5044 // Pipeline class for compares. 5045 pipe_class pipe_class_compare() %{ 5046 single_instruction; 5047 fixed_latency(16); 5048 %} 5049 5050 // Pipeline class for traps. 5051 pipe_class pipe_class_trap() %{ 5052 single_instruction; 5053 fixed_latency(100); 5054 %} 5055 5056 // Pipeline class for memory operations. 5057 pipe_class pipe_class_memory() %{ 5058 single_instruction; 5059 fixed_latency(16); 5060 %} 5061 5062 // Pipeline class for call. 5063 pipe_class pipe_class_call() %{ 5064 single_instruction; 5065 fixed_latency(100); 5066 %} 5067 5068 // Define the class for the Nop node. 5069 define %{ 5070 MachNop = pipe_class_default; 5071 %} 5072 5073 %} 5074 5075 //----------INSTRUCTIONS------------------------------------------------------- 5076 5077 // Naming of instructions: 5078 // opA_operB / opA_operB_operC: 5079 // Operation 'op' with one or two source operands 'oper'. Result 5080 // type is A, source operand types are B and C. 5081 // Iff A == B == C, B and C are left out. 5082 // 5083 // The instructions are ordered according to the following scheme: 5084 // - loads 5085 // - load constants 5086 // - prefetch 5087 // - store 5088 // - encode/decode 5089 // - membar 5090 // - conditional moves 5091 // - compare & swap 5092 // - arithmetic and logic operations 5093 // * int: Add, Sub, Mul, Div, Mod 5094 // * int: lShift, arShift, urShift, rot 5095 // * float: Add, Sub, Mul, Div 5096 // * and, or, xor ... 5097 // - register moves: float <-> int, reg <-> stack, repl 5098 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5099 // - conv (low level type cast requiring bit changes (sign extend etc) 5100 // - compares, range & zero checks. 5101 // - branches 5102 // - complex operations, intrinsics, min, max, replicate 5103 // - lock 5104 // - Calls 5105 // 5106 // If there are similar instructions with different types they are sorted: 5107 // int before float 5108 // small before big 5109 // signed before unsigned 5110 // e.g., loadS before loadUS before loadI before loadF. 5111 5112 5113 //----------Load/Store Instructions-------------------------------------------- 5114 5115 //----------Load Instructions-------------------------------------------------- 5116 5117 // Converts byte to int. 5118 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5119 // reuses the 'amount' operand, but adlc expects that operand specification 5120 // and operands in match rule are equivalent. 5121 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5122 effect(DEF dst, USE src); 5123 format %{ "EXTSB $dst, $src \t// byte->int" %} 5124 size(4); 5125 ins_encode %{ 5126 __ extsb($dst$$Register, $src$$Register); 5127 %} 5128 ins_pipe(pipe_class_default); 5129 %} 5130 5131 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5132 // match-rule, false predicate 5133 match(Set dst (LoadB mem)); 5134 predicate(false); 5135 5136 format %{ "LBZ $dst, $mem" %} 5137 size(4); 5138 ins_encode( enc_lbz(dst, mem) ); 5139 ins_pipe(pipe_class_memory); 5140 %} 5141 5142 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5143 // match-rule, false predicate 5144 match(Set dst (LoadB mem)); 5145 predicate(false); 5146 5147 format %{ "LBZ $dst, $mem\n\t" 5148 "TWI $dst\n\t" 5149 "ISYNC" %} 5150 size(12); 5151 ins_encode( enc_lbz_ac(dst, mem) ); 5152 ins_pipe(pipe_class_memory); 5153 %} 5154 5155 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5156 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5157 match(Set dst (LoadB mem)); 5158 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5159 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5160 expand %{ 5161 iRegIdst tmp; 5162 loadUB_indirect(tmp, mem); 5163 convB2I_reg_2(dst, tmp); 5164 %} 5165 %} 5166 5167 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5168 match(Set dst (LoadB mem)); 5169 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5170 expand %{ 5171 iRegIdst tmp; 5172 loadUB_indirect_ac(tmp, mem); 5173 convB2I_reg_2(dst, tmp); 5174 %} 5175 %} 5176 5177 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5178 // match-rule, false predicate 5179 match(Set dst (LoadB mem)); 5180 predicate(false); 5181 5182 format %{ "LBZ $dst, $mem" %} 5183 size(4); 5184 ins_encode( enc_lbz(dst, mem) ); 5185 ins_pipe(pipe_class_memory); 5186 %} 5187 5188 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5189 // match-rule, false predicate 5190 match(Set dst (LoadB mem)); 5191 predicate(false); 5192 5193 format %{ "LBZ $dst, $mem\n\t" 5194 "TWI $dst\n\t" 5195 "ISYNC" %} 5196 size(12); 5197 ins_encode( enc_lbz_ac(dst, mem) ); 5198 ins_pipe(pipe_class_memory); 5199 %} 5200 5201 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5202 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5203 match(Set dst (LoadB mem)); 5204 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5205 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5206 5207 expand %{ 5208 iRegIdst tmp; 5209 loadUB_indOffset16(tmp, mem); 5210 convB2I_reg_2(dst, tmp); 5211 %} 5212 %} 5213 5214 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5215 match(Set dst (LoadB mem)); 5216 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5217 5218 expand %{ 5219 iRegIdst tmp; 5220 loadUB_indOffset16_ac(tmp, mem); 5221 convB2I_reg_2(dst, tmp); 5222 %} 5223 %} 5224 5225 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5226 instruct loadUB(iRegIdst dst, memory mem) %{ 5227 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5228 match(Set dst (LoadUB mem)); 5229 ins_cost(MEMORY_REF_COST); 5230 5231 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5232 size(4); 5233 ins_encode( enc_lbz(dst, mem) ); 5234 ins_pipe(pipe_class_memory); 5235 %} 5236 5237 // Load Unsigned Byte (8bit UNsigned) acquire. 5238 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5239 match(Set dst (LoadUB mem)); 5240 ins_cost(3*MEMORY_REF_COST); 5241 5242 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, 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 Unsigned Byte (8bit UNsigned) into a Long Register. 5251 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5252 match(Set dst (ConvI2L (LoadUB mem))); 5253 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5254 ins_cost(MEMORY_REF_COST); 5255 5256 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5257 size(4); 5258 ins_encode( enc_lbz(dst, mem) ); 5259 ins_pipe(pipe_class_memory); 5260 %} 5261 5262 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5263 match(Set dst (ConvI2L (LoadUB mem))); 5264 ins_cost(3*MEMORY_REF_COST); 5265 5266 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5267 "TWI $dst\n\t" 5268 "ISYNC" %} 5269 size(12); 5270 ins_encode( enc_lbz_ac(dst, mem) ); 5271 ins_pipe(pipe_class_memory); 5272 %} 5273 5274 // Load Short (16bit signed) 5275 instruct loadS(iRegIdst dst, memory mem) %{ 5276 match(Set dst (LoadS mem)); 5277 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5278 ins_cost(MEMORY_REF_COST); 5279 5280 format %{ "LHA $dst, $mem" %} 5281 size(4); 5282 ins_encode %{ 5283 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5284 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5285 %} 5286 ins_pipe(pipe_class_memory); 5287 %} 5288 5289 // Load Short (16bit signed) acquire. 5290 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5291 match(Set dst (LoadS mem)); 5292 ins_cost(3*MEMORY_REF_COST); 5293 5294 format %{ "LHA $dst, $mem\t acquire\n\t" 5295 "TWI $dst\n\t" 5296 "ISYNC" %} 5297 size(12); 5298 ins_encode %{ 5299 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5300 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5301 __ twi_0($dst$$Register); 5302 __ isync(); 5303 %} 5304 ins_pipe(pipe_class_memory); 5305 %} 5306 5307 // Load Char (16bit unsigned) 5308 instruct loadUS(iRegIdst dst, memory mem) %{ 5309 match(Set dst (LoadUS mem)); 5310 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5311 ins_cost(MEMORY_REF_COST); 5312 5313 format %{ "LHZ $dst, $mem" %} 5314 size(4); 5315 ins_encode( enc_lhz(dst, mem) ); 5316 ins_pipe(pipe_class_memory); 5317 %} 5318 5319 // Load Char (16bit unsigned) acquire. 5320 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5321 match(Set dst (LoadUS mem)); 5322 ins_cost(3*MEMORY_REF_COST); 5323 5324 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5325 "TWI $dst\n\t" 5326 "ISYNC" %} 5327 size(12); 5328 ins_encode( enc_lhz_ac(dst, mem) ); 5329 ins_pipe(pipe_class_memory); 5330 %} 5331 5332 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5333 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5334 match(Set dst (ConvI2L (LoadUS mem))); 5335 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5336 ins_cost(MEMORY_REF_COST); 5337 5338 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5339 size(4); 5340 ins_encode( enc_lhz(dst, mem) ); 5341 ins_pipe(pipe_class_memory); 5342 %} 5343 5344 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5345 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5346 match(Set dst (ConvI2L (LoadUS mem))); 5347 ins_cost(3*MEMORY_REF_COST); 5348 5349 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5350 "TWI $dst\n\t" 5351 "ISYNC" %} 5352 size(12); 5353 ins_encode( enc_lhz_ac(dst, mem) ); 5354 ins_pipe(pipe_class_memory); 5355 %} 5356 5357 // Load Integer. 5358 instruct loadI(iRegIdst dst, memory mem) %{ 5359 match(Set dst (LoadI mem)); 5360 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5361 ins_cost(MEMORY_REF_COST); 5362 5363 format %{ "LWZ $dst, $mem" %} 5364 size(4); 5365 ins_encode( enc_lwz(dst, mem) ); 5366 ins_pipe(pipe_class_memory); 5367 %} 5368 5369 // Load Integer acquire. 5370 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5371 match(Set dst (LoadI mem)); 5372 ins_cost(3*MEMORY_REF_COST); 5373 5374 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5375 "TWI $dst\n\t" 5376 "ISYNC" %} 5377 size(12); 5378 ins_encode( enc_lwz_ac(dst, mem) ); 5379 ins_pipe(pipe_class_memory); 5380 %} 5381 5382 // Match loading integer and casting it to unsigned int in 5383 // long register. 5384 // LoadI + ConvI2L + AndL 0xffffffff. 5385 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5386 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5387 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5388 ins_cost(MEMORY_REF_COST); 5389 5390 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5391 size(4); 5392 ins_encode( enc_lwz(dst, mem) ); 5393 ins_pipe(pipe_class_memory); 5394 %} 5395 5396 // Match loading integer and casting it to long. 5397 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5398 match(Set dst (ConvI2L (LoadI mem))); 5399 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5400 ins_cost(MEMORY_REF_COST); 5401 5402 format %{ "LWA $dst, $mem \t// loadI2L" %} 5403 size(4); 5404 ins_encode %{ 5405 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5406 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5407 %} 5408 ins_pipe(pipe_class_memory); 5409 %} 5410 5411 // Match loading integer and casting it to long - acquire. 5412 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5413 match(Set dst (ConvI2L (LoadI mem))); 5414 ins_cost(3*MEMORY_REF_COST); 5415 5416 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5417 "TWI $dst\n\t" 5418 "ISYNC" %} 5419 size(12); 5420 ins_encode %{ 5421 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5422 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5423 __ twi_0($dst$$Register); 5424 __ isync(); 5425 %} 5426 ins_pipe(pipe_class_memory); 5427 %} 5428 5429 // Load Long - aligned 5430 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5431 match(Set dst (LoadL mem)); 5432 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5433 ins_cost(MEMORY_REF_COST); 5434 5435 format %{ "LD $dst, $mem \t// long" %} 5436 size(4); 5437 ins_encode( enc_ld(dst, mem) ); 5438 ins_pipe(pipe_class_memory); 5439 %} 5440 5441 // Load Long - aligned acquire. 5442 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5443 match(Set dst (LoadL mem)); 5444 ins_cost(3*MEMORY_REF_COST); 5445 5446 format %{ "LD $dst, $mem \t// long acquire\n\t" 5447 "TWI $dst\n\t" 5448 "ISYNC" %} 5449 size(12); 5450 ins_encode( enc_ld_ac(dst, mem) ); 5451 ins_pipe(pipe_class_memory); 5452 %} 5453 5454 // Load Long - UNaligned 5455 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5456 match(Set dst (LoadL_unaligned mem)); 5457 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5458 ins_cost(MEMORY_REF_COST); 5459 5460 format %{ "LD $dst, $mem \t// unaligned long" %} 5461 size(4); 5462 ins_encode( enc_ld(dst, mem) ); 5463 ins_pipe(pipe_class_memory); 5464 %} 5465 5466 // Load nodes for superwords 5467 5468 // Load Aligned Packed Byte 5469 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5470 predicate(n->as_LoadVector()->memory_size() == 8); 5471 match(Set dst (LoadVector mem)); 5472 ins_cost(MEMORY_REF_COST); 5473 5474 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5475 size(4); 5476 ins_encode( enc_ld(dst, mem) ); 5477 ins_pipe(pipe_class_memory); 5478 %} 5479 5480 // Load Aligned Packed Byte 5481 instruct loadV16(vecX dst, indirect mem) %{ 5482 predicate(n->as_LoadVector()->memory_size() == 16); 5483 match(Set dst (LoadVector mem)); 5484 ins_cost(MEMORY_REF_COST); 5485 5486 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5487 size(4); 5488 ins_encode %{ 5489 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5490 %} 5491 ins_pipe(pipe_class_default); 5492 %} 5493 5494 // Load Range, range = array length (=jint) 5495 instruct loadRange(iRegIdst dst, memory mem) %{ 5496 match(Set dst (LoadRange mem)); 5497 ins_cost(MEMORY_REF_COST); 5498 5499 format %{ "LWZ $dst, $mem \t// range" %} 5500 size(4); 5501 ins_encode( enc_lwz(dst, mem) ); 5502 ins_pipe(pipe_class_memory); 5503 %} 5504 5505 // Load Compressed Pointer 5506 instruct loadN(iRegNdst dst, memory mem) %{ 5507 match(Set dst (LoadN mem)); 5508 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5509 ins_cost(MEMORY_REF_COST); 5510 5511 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5512 size(4); 5513 ins_encode( enc_lwz(dst, mem) ); 5514 ins_pipe(pipe_class_memory); 5515 %} 5516 5517 // Load Compressed Pointer acquire. 5518 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5519 match(Set dst (LoadN mem)); 5520 ins_cost(3*MEMORY_REF_COST); 5521 5522 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5523 "TWI $dst\n\t" 5524 "ISYNC" %} 5525 size(12); 5526 ins_encode( enc_lwz_ac(dst, mem) ); 5527 ins_pipe(pipe_class_memory); 5528 %} 5529 5530 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5531 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5532 match(Set dst (DecodeN (LoadN mem))); 5533 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0); 5534 ins_cost(MEMORY_REF_COST); 5535 5536 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5537 size(4); 5538 ins_encode( enc_lwz(dst, mem) ); 5539 ins_pipe(pipe_class_memory); 5540 %} 5541 5542 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5543 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5544 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0 && 5545 _kids[0]->_leaf->as_Load()->is_unordered()); 5546 ins_cost(MEMORY_REF_COST); 5547 5548 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5549 size(4); 5550 ins_encode( enc_lwz(dst, mem) ); 5551 ins_pipe(pipe_class_memory); 5552 %} 5553 5554 // Load Pointer 5555 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5556 match(Set dst (LoadP mem)); 5557 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0); 5558 ins_cost(MEMORY_REF_COST); 5559 5560 format %{ "LD $dst, $mem \t// ptr" %} 5561 size(4); 5562 ins_encode( enc_ld(dst, mem) ); 5563 ins_pipe(pipe_class_memory); 5564 %} 5565 5566 // Load Pointer acquire. 5567 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5568 match(Set dst (LoadP mem)); 5569 ins_cost(3*MEMORY_REF_COST); 5570 5571 predicate(n->as_Load()->barrier_data() == 0); 5572 5573 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5574 "TWI $dst\n\t" 5575 "ISYNC" %} 5576 size(12); 5577 ins_encode( enc_ld_ac(dst, mem) ); 5578 ins_pipe(pipe_class_memory); 5579 %} 5580 5581 // LoadP + CastP2L 5582 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5583 match(Set dst (CastP2X (LoadP mem))); 5584 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && _kids[0]->_leaf->as_Load()->barrier_data() == 0); 5585 ins_cost(MEMORY_REF_COST); 5586 5587 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5588 size(4); 5589 ins_encode( enc_ld(dst, mem) ); 5590 ins_pipe(pipe_class_memory); 5591 %} 5592 5593 // Load compressed klass pointer. 5594 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5595 match(Set dst (LoadNKlass mem)); 5596 ins_cost(MEMORY_REF_COST); 5597 5598 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5599 size(4); 5600 ins_encode( enc_lwz(dst, mem) ); 5601 ins_pipe(pipe_class_memory); 5602 %} 5603 5604 // Load Klass Pointer 5605 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5606 match(Set dst (LoadKlass mem)); 5607 ins_cost(MEMORY_REF_COST); 5608 5609 format %{ "LD $dst, $mem \t// klass ptr" %} 5610 size(4); 5611 ins_encode( enc_ld(dst, mem) ); 5612 ins_pipe(pipe_class_memory); 5613 %} 5614 5615 // Load Float 5616 instruct loadF(regF dst, memory mem) %{ 5617 match(Set dst (LoadF mem)); 5618 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5619 ins_cost(MEMORY_REF_COST); 5620 5621 format %{ "LFS $dst, $mem" %} 5622 size(4); 5623 ins_encode %{ 5624 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5625 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5626 %} 5627 ins_pipe(pipe_class_memory); 5628 %} 5629 5630 // Load Float acquire. 5631 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5632 match(Set dst (LoadF mem)); 5633 effect(TEMP cr0); 5634 ins_cost(3*MEMORY_REF_COST); 5635 5636 format %{ "LFS $dst, $mem \t// acquire\n\t" 5637 "FCMPU cr0, $dst, $dst\n\t" 5638 "BNE cr0, next\n" 5639 "next:\n\t" 5640 "ISYNC" %} 5641 size(16); 5642 ins_encode %{ 5643 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5644 Label next; 5645 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5646 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5647 __ bne(CCR0, next); 5648 __ bind(next); 5649 __ isync(); 5650 %} 5651 ins_pipe(pipe_class_memory); 5652 %} 5653 5654 // Load Double - aligned 5655 instruct loadD(regD dst, memory mem) %{ 5656 match(Set dst (LoadD mem)); 5657 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5658 ins_cost(MEMORY_REF_COST); 5659 5660 format %{ "LFD $dst, $mem" %} 5661 size(4); 5662 ins_encode( enc_lfd(dst, mem) ); 5663 ins_pipe(pipe_class_memory); 5664 %} 5665 5666 // Load Double - aligned acquire. 5667 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5668 match(Set dst (LoadD mem)); 5669 effect(TEMP cr0); 5670 ins_cost(3*MEMORY_REF_COST); 5671 5672 format %{ "LFD $dst, $mem \t// acquire\n\t" 5673 "FCMPU cr0, $dst, $dst\n\t" 5674 "BNE cr0, next\n" 5675 "next:\n\t" 5676 "ISYNC" %} 5677 size(16); 5678 ins_encode %{ 5679 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5680 Label next; 5681 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5682 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5683 __ bne(CCR0, next); 5684 __ bind(next); 5685 __ isync(); 5686 %} 5687 ins_pipe(pipe_class_memory); 5688 %} 5689 5690 // Load Double - UNaligned 5691 instruct loadD_unaligned(regD dst, memory mem) %{ 5692 match(Set dst (LoadD_unaligned mem)); 5693 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5694 ins_cost(MEMORY_REF_COST); 5695 5696 format %{ "LFD $dst, $mem" %} 5697 size(4); 5698 ins_encode( enc_lfd(dst, mem) ); 5699 ins_pipe(pipe_class_memory); 5700 %} 5701 5702 //----------Constants-------------------------------------------------------- 5703 5704 // Load MachConstantTableBase: add hi offset to global toc. 5705 // TODO: Handle hidden register r29 in bundler! 5706 instruct loadToc_hi(iRegLdst dst) %{ 5707 effect(DEF dst); 5708 ins_cost(DEFAULT_COST); 5709 5710 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 5711 size(4); 5712 ins_encode %{ 5713 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 5714 %} 5715 ins_pipe(pipe_class_default); 5716 %} 5717 5718 // Load MachConstantTableBase: add lo offset to global toc. 5719 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 5720 effect(DEF dst, USE src); 5721 ins_cost(DEFAULT_COST); 5722 5723 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 5724 size(4); 5725 ins_encode %{ 5726 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 5727 %} 5728 ins_pipe(pipe_class_default); 5729 %} 5730 5731 // Load 16-bit integer constant 0xssss???? 5732 instruct loadConI16(iRegIdst dst, immI16 src) %{ 5733 match(Set dst src); 5734 5735 format %{ "LI $dst, $src" %} 5736 size(4); 5737 ins_encode %{ 5738 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 5739 %} 5740 ins_pipe(pipe_class_default); 5741 %} 5742 5743 // Load integer constant 0x????0000 5744 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 5745 match(Set dst src); 5746 ins_cost(DEFAULT_COST); 5747 5748 format %{ "LIS $dst, $src.hi" %} 5749 size(4); 5750 ins_encode %{ 5751 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 5752 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5753 %} 5754 ins_pipe(pipe_class_default); 5755 %} 5756 5757 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 5758 // and sign extended), this adds the low 16 bits. 5759 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 5760 // no match-rule, false predicate 5761 effect(DEF dst, USE src1, USE src2); 5762 predicate(false); 5763 5764 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 5765 size(4); 5766 ins_encode %{ 5767 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5768 %} 5769 ins_pipe(pipe_class_default); 5770 %} 5771 5772 instruct loadConI32(iRegIdst dst, immI32 src) %{ 5773 match(Set dst src); 5774 // This macro is valid only in Power 10 and up, but adding the following predicate here 5775 // caused a build error, so we comment it out for now. 5776 // predicate(PowerArchitecturePPC64 >= 10); 5777 ins_cost(DEFAULT_COST+1); 5778 5779 format %{ "PLI $dst, $src" %} 5780 size(8); 5781 ins_encode %{ 5782 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 5783 __ pli($dst$$Register, $src$$constant); 5784 %} 5785 ins_pipe(pipe_class_default); 5786 ins_alignment(2); 5787 %} 5788 5789 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 5790 match(Set dst src); 5791 ins_cost(DEFAULT_COST*2); 5792 5793 expand %{ 5794 // Would like to use $src$$constant. 5795 immI16 srcLo %{ _opnds[1]->constant() %} 5796 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5797 immIhi16 srcHi %{ _opnds[1]->constant() %} 5798 iRegIdst tmpI; 5799 loadConIhi16(tmpI, srcHi); 5800 loadConI32_lo16(dst, tmpI, srcLo); 5801 %} 5802 %} 5803 5804 // No constant pool entries required. 5805 instruct loadConL16(iRegLdst dst, immL16 src) %{ 5806 match(Set dst src); 5807 5808 format %{ "LI $dst, $src \t// long" %} 5809 size(4); 5810 ins_encode %{ 5811 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 5812 %} 5813 ins_pipe(pipe_class_default); 5814 %} 5815 5816 // Load long constant 0xssssssss????0000 5817 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 5818 match(Set dst src); 5819 ins_cost(DEFAULT_COST); 5820 5821 format %{ "LIS $dst, $src.hi \t// long" %} 5822 size(4); 5823 ins_encode %{ 5824 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5825 %} 5826 ins_pipe(pipe_class_default); 5827 %} 5828 5829 // To load a 32 bit constant: merge lower 16 bits into already loaded 5830 // high 16 bits. 5831 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 5832 // no match-rule, false predicate 5833 effect(DEF dst, USE src1, USE src2); 5834 predicate(false); 5835 5836 format %{ "ORI $dst, $src1, $src2.lo" %} 5837 size(4); 5838 ins_encode %{ 5839 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5840 %} 5841 ins_pipe(pipe_class_default); 5842 %} 5843 5844 // Load 32-bit long constant 5845 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 5846 match(Set dst src); 5847 ins_cost(DEFAULT_COST*2); 5848 5849 expand %{ 5850 // Would like to use $src$$constant. 5851 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 5852 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5853 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 5854 iRegLdst tmpL; 5855 loadConL32hi16(tmpL, srcHi); 5856 loadConL32_lo16(dst, tmpL, srcLo); 5857 %} 5858 %} 5859 5860 // Load 34-bit long constant using prefixed addi. No constant pool entries required. 5861 instruct loadConL34(iRegLdst dst, immL34 src) %{ 5862 match(Set dst src); 5863 // This macro is valid only in Power 10 and up, but adding the following predicate here 5864 // caused a build error, so we comment it out for now. 5865 // predicate(PowerArchitecturePPC64 >= 10); 5866 ins_cost(DEFAULT_COST+1); 5867 5868 format %{ "PLI $dst, $src \t// long" %} 5869 size(8); 5870 ins_encode %{ 5871 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 5872 __ pli($dst$$Register, $src$$constant); 5873 %} 5874 ins_pipe(pipe_class_default); 5875 ins_alignment(2); 5876 %} 5877 5878 // Load long constant 0x????000000000000. 5879 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 5880 match(Set dst src); 5881 ins_cost(DEFAULT_COST); 5882 5883 expand %{ 5884 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 5885 immI shift32 %{ 32 %} 5886 iRegLdst tmpL; 5887 loadConL32hi16(tmpL, srcHi); 5888 lshiftL_regL_immI(dst, tmpL, shift32); 5889 %} 5890 %} 5891 5892 // Expand node for constant pool load: small offset. 5893 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 5894 effect(DEF dst, USE src, USE toc); 5895 ins_cost(MEMORY_REF_COST); 5896 5897 ins_num_consts(1); 5898 // Needed so that CallDynamicJavaDirect can compute the address of this 5899 // instruction for relocation. 5900 ins_field_cbuf_insts_offset(int); 5901 5902 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 5903 size(4); 5904 ins_encode( enc_load_long_constL(dst, src, toc) ); 5905 ins_pipe(pipe_class_memory); 5906 %} 5907 5908 // Expand node for constant pool load: large offset. 5909 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 5910 effect(DEF dst, USE src, USE toc); 5911 predicate(false); 5912 5913 ins_num_consts(1); 5914 ins_field_const_toc_offset(int); 5915 // Needed so that CallDynamicJavaDirect can compute the address of this 5916 // instruction for relocation. 5917 ins_field_cbuf_insts_offset(int); 5918 5919 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 5920 size(4); 5921 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 5922 ins_pipe(pipe_class_default); 5923 %} 5924 5925 // Expand node for constant pool load: large offset. 5926 // No constant pool entries required. 5927 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 5928 effect(DEF dst, USE src, USE base); 5929 predicate(false); 5930 5931 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 5932 5933 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 5934 size(4); 5935 ins_encode %{ 5936 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 5937 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 5938 %} 5939 ins_pipe(pipe_class_memory); 5940 %} 5941 5942 // Load long constant from constant table. Expand in case of 5943 // offset > 16 bit is needed. 5944 // Adlc adds toc node MachConstantTableBase. 5945 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 5946 match(Set dst src); 5947 ins_cost(MEMORY_REF_COST); 5948 5949 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 5950 // We can not inline the enc_class for the expand as that does not support constanttablebase. 5951 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 5952 %} 5953 5954 // Load NULL as compressed oop. 5955 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 5956 match(Set dst src); 5957 ins_cost(DEFAULT_COST); 5958 5959 format %{ "LI $dst, $src \t// compressed ptr" %} 5960 size(4); 5961 ins_encode %{ 5962 __ li($dst$$Register, 0); 5963 %} 5964 ins_pipe(pipe_class_default); 5965 %} 5966 5967 // Load hi part of compressed oop constant. 5968 instruct loadConN_hi(iRegNdst dst, immN src) %{ 5969 effect(DEF dst, USE src); 5970 ins_cost(DEFAULT_COST); 5971 5972 format %{ "LIS $dst, $src \t// narrow oop hi" %} 5973 size(4); 5974 ins_encode %{ 5975 __ lis($dst$$Register, 0); // Will get patched. 5976 %} 5977 ins_pipe(pipe_class_default); 5978 %} 5979 5980 // Add lo part of compressed oop constant to already loaded hi part. 5981 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 5982 effect(DEF dst, USE src1, USE src2); 5983 ins_cost(DEFAULT_COST); 5984 5985 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 5986 size(4); 5987 ins_encode %{ 5988 AddressLiteral addrlit = __ constant_oop_address((jobject)$src2$$constant); 5989 __ relocate(addrlit.rspec(), /*compressed format*/ 1); 5990 __ ori($dst$$Register, $src1$$Register, 0); // Will get patched. 5991 %} 5992 ins_pipe(pipe_class_default); 5993 %} 5994 5995 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 5996 effect(DEF dst, USE src, USE shift, USE mask_begin); 5997 5998 size(4); 5999 ins_encode %{ 6000 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6001 %} 6002 ins_pipe(pipe_class_default); 6003 %} 6004 6005 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6006 // leaving the upper 32 bits with sign-extension bits. 6007 // This clears these bits: dst = src & 0xFFFFFFFF. 6008 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6009 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6010 effect(DEF dst, USE src); 6011 predicate(false); 6012 6013 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6014 size(4); 6015 ins_encode %{ 6016 __ clrldi($dst$$Register, $src$$Register, 0x20); 6017 %} 6018 ins_pipe(pipe_class_default); 6019 %} 6020 6021 // Optimize DecodeN for disjoint base. 6022 // Load base of compressed oops into a register 6023 instruct loadBase(iRegLdst dst) %{ 6024 effect(DEF dst); 6025 6026 format %{ "LoadConst $dst, heapbase" %} 6027 ins_encode %{ 6028 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0); 6029 %} 6030 ins_pipe(pipe_class_default); 6031 %} 6032 6033 // Loading ConN must be postalloc expanded so that edges between 6034 // the nodes are safe. They may not interfere with a safepoint. 6035 // GL TODO: This needs three instructions: better put this into the constant pool. 6036 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6037 match(Set dst src); 6038 ins_cost(DEFAULT_COST*2); 6039 6040 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6041 postalloc_expand %{ 6042 MachNode *m1 = new loadConN_hiNode(); 6043 MachNode *m2 = new loadConN_loNode(); 6044 MachNode *m3 = new clearMs32bNode(); 6045 m1->add_req(NULL); 6046 m2->add_req(NULL, m1); 6047 m3->add_req(NULL, m2); 6048 m1->_opnds[0] = op_dst; 6049 m1->_opnds[1] = op_src; 6050 m2->_opnds[0] = op_dst; 6051 m2->_opnds[1] = op_dst; 6052 m2->_opnds[2] = op_src; 6053 m3->_opnds[0] = op_dst; 6054 m3->_opnds[1] = op_dst; 6055 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6056 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6057 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6058 nodes->push(m1); 6059 nodes->push(m2); 6060 nodes->push(m3); 6061 %} 6062 %} 6063 6064 // We have seen a safepoint between the hi and lo parts, and this node was handled 6065 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6066 // not a narrow oop. 6067 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6068 match(Set dst src); 6069 effect(DEF dst, USE src); 6070 ins_cost(DEFAULT_COST); 6071 6072 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6073 size(4); 6074 ins_encode %{ 6075 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant); 6076 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6077 %} 6078 ins_pipe(pipe_class_default); 6079 %} 6080 6081 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6082 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6083 match(Set dst src1); 6084 effect(TEMP src2); 6085 ins_cost(DEFAULT_COST); 6086 6087 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6088 size(4); 6089 ins_encode %{ 6090 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6091 %} 6092 ins_pipe(pipe_class_default); 6093 %} 6094 6095 // This needs a match rule so that build_oop_map knows this is 6096 // not a narrow oop. 6097 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6098 match(Set dst src1); 6099 effect(TEMP src2); 6100 ins_cost(DEFAULT_COST); 6101 6102 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6103 size(4); 6104 ins_encode %{ 6105 // Notify OOP recorder (don't need the relocation) 6106 AddressLiteral md = __ constant_metadata_address((Klass*)$src1$$constant); 6107 intptr_t Csrc = CompressedKlassPointers::encode((Klass*)md.value()); 6108 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6109 %} 6110 ins_pipe(pipe_class_default); 6111 %} 6112 6113 // Loading ConNKlass must be postalloc expanded so that edges between 6114 // the nodes are safe. They may not interfere with a safepoint. 6115 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6116 match(Set dst src); 6117 ins_cost(DEFAULT_COST*2); 6118 6119 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6120 postalloc_expand %{ 6121 // Load high bits into register. Sign extended. 6122 MachNode *m1 = new loadConNKlass_hiNode(); 6123 m1->add_req(NULL); 6124 m1->_opnds[0] = op_dst; 6125 m1->_opnds[1] = op_src; 6126 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6127 nodes->push(m1); 6128 6129 MachNode *m2 = m1; 6130 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) { 6131 // Value might be 1-extended. Mask out these bits. 6132 m2 = new loadConNKlass_maskNode(); 6133 m2->add_req(NULL, m1); 6134 m2->_opnds[0] = op_dst; 6135 m2->_opnds[1] = op_src; 6136 m2->_opnds[2] = op_dst; 6137 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6138 nodes->push(m2); 6139 } 6140 6141 MachNode *m3 = new loadConNKlass_loNode(); 6142 m3->add_req(NULL, m2); 6143 m3->_opnds[0] = op_dst; 6144 m3->_opnds[1] = op_src; 6145 m3->_opnds[2] = op_dst; 6146 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6147 nodes->push(m3); 6148 %} 6149 %} 6150 6151 // 0x1 is used in object initialization (initial object header). 6152 // No constant pool entries required. 6153 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6154 match(Set dst src); 6155 6156 format %{ "LI $dst, $src \t// ptr" %} 6157 size(4); 6158 ins_encode %{ 6159 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6160 %} 6161 ins_pipe(pipe_class_default); 6162 %} 6163 6164 // Expand node for constant pool load: small offset. 6165 // The match rule is needed to generate the correct bottom_type(), 6166 // however this node should never match. The use of predicate is not 6167 // possible since ADLC forbids predicates for chain rules. The higher 6168 // costs do not prevent matching in this case. For that reason the 6169 // operand immP_NM with predicate(false) is used. 6170 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6171 match(Set dst src); 6172 effect(TEMP toc); 6173 6174 ins_num_consts(1); 6175 6176 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6177 size(4); 6178 ins_encode( enc_load_long_constP(dst, src, toc) ); 6179 ins_pipe(pipe_class_memory); 6180 %} 6181 6182 // Expand node for constant pool load: large offset. 6183 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6184 effect(DEF dst, USE src, USE toc); 6185 predicate(false); 6186 6187 ins_num_consts(1); 6188 ins_field_const_toc_offset(int); 6189 6190 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6191 size(4); 6192 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6193 ins_pipe(pipe_class_default); 6194 %} 6195 6196 // Expand node for constant pool load: large offset. 6197 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6198 match(Set dst src); 6199 effect(TEMP base); 6200 6201 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6202 6203 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6204 size(4); 6205 ins_encode %{ 6206 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6207 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6208 %} 6209 ins_pipe(pipe_class_memory); 6210 %} 6211 6212 // Load pointer constant from constant table. Expand in case an 6213 // offset > 16 bit is needed. 6214 // Adlc adds toc node MachConstantTableBase. 6215 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6216 match(Set dst src); 6217 ins_cost(MEMORY_REF_COST); 6218 6219 // This rule does not use "expand" because then 6220 // the result type is not known to be an Oop. An ADLC 6221 // enhancement will be needed to make that work - not worth it! 6222 6223 // If this instruction rematerializes, it prolongs the live range 6224 // of the toc node, causing illegal graphs. 6225 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6226 ins_cannot_rematerialize(true); 6227 6228 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6229 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6230 %} 6231 6232 // Expand node for constant pool load: small offset. 6233 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6234 effect(DEF dst, USE src, USE toc); 6235 ins_cost(MEMORY_REF_COST); 6236 6237 ins_num_consts(1); 6238 6239 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6240 size(4); 6241 ins_encode %{ 6242 address float_address = __ float_constant($src$$constant); 6243 if (float_address == NULL) { 6244 ciEnv::current()->record_out_of_memory_failure(); 6245 return; 6246 } 6247 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6248 %} 6249 ins_pipe(pipe_class_memory); 6250 %} 6251 6252 // Expand node for constant pool load: large offset. 6253 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6254 effect(DEF dst, USE src, USE toc); 6255 ins_cost(MEMORY_REF_COST); 6256 6257 ins_num_consts(1); 6258 6259 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6260 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6261 "ADDIS $toc, $toc, -offset_hi"%} 6262 size(12); 6263 ins_encode %{ 6264 FloatRegister Rdst = $dst$$FloatRegister; 6265 Register Rtoc = $toc$$Register; 6266 address float_address = __ float_constant($src$$constant); 6267 if (float_address == NULL) { 6268 ciEnv::current()->record_out_of_memory_failure(); 6269 return; 6270 } 6271 int offset = __ offset_to_method_toc(float_address); 6272 int hi = (offset + (1<<15))>>16; 6273 int lo = offset - hi * (1<<16); 6274 6275 __ addis(Rtoc, Rtoc, hi); 6276 __ lfs(Rdst, lo, Rtoc); 6277 __ addis(Rtoc, Rtoc, -hi); 6278 %} 6279 ins_pipe(pipe_class_memory); 6280 %} 6281 6282 // Adlc adds toc node MachConstantTableBase. 6283 instruct loadConF_Ex(regF dst, immF src) %{ 6284 match(Set dst src); 6285 ins_cost(MEMORY_REF_COST); 6286 6287 // See loadConP. 6288 ins_cannot_rematerialize(true); 6289 6290 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6291 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6292 %} 6293 6294 // Expand node for constant pool load: small offset. 6295 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6296 effect(DEF dst, USE src, USE toc); 6297 ins_cost(MEMORY_REF_COST); 6298 6299 ins_num_consts(1); 6300 6301 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6302 size(4); 6303 ins_encode %{ 6304 address float_address = __ double_constant($src$$constant); 6305 if (float_address == NULL) { 6306 ciEnv::current()->record_out_of_memory_failure(); 6307 return; 6308 } 6309 int offset = __ offset_to_method_toc(float_address); 6310 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6311 %} 6312 ins_pipe(pipe_class_memory); 6313 %} 6314 6315 // Expand node for constant pool load: large offset. 6316 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6317 effect(DEF dst, USE src, USE toc); 6318 ins_cost(MEMORY_REF_COST); 6319 6320 ins_num_consts(1); 6321 6322 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6323 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6324 "ADDIS $toc, $toc, -offset_hi" %} 6325 size(12); 6326 ins_encode %{ 6327 FloatRegister Rdst = $dst$$FloatRegister; 6328 Register Rtoc = $toc$$Register; 6329 address float_address = __ double_constant($src$$constant); 6330 if (float_address == NULL) { 6331 ciEnv::current()->record_out_of_memory_failure(); 6332 return; 6333 } 6334 int offset = __ offset_to_method_toc(float_address); 6335 int hi = (offset + (1<<15))>>16; 6336 int lo = offset - hi * (1<<16); 6337 6338 __ addis(Rtoc, Rtoc, hi); 6339 __ lfd(Rdst, lo, Rtoc); 6340 __ addis(Rtoc, Rtoc, -hi); 6341 %} 6342 ins_pipe(pipe_class_memory); 6343 %} 6344 6345 // Adlc adds toc node MachConstantTableBase. 6346 instruct loadConD_Ex(regD dst, immD src) %{ 6347 match(Set dst src); 6348 ins_cost(MEMORY_REF_COST); 6349 6350 // See loadConP. 6351 ins_cannot_rematerialize(true); 6352 6353 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6354 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6355 %} 6356 6357 // Prefetch instructions. 6358 // Must be safe to execute with invalid address (cannot fault). 6359 6360 // Special prefetch versions which use the dcbz instruction. 6361 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6362 match(PrefetchAllocation (AddP mem src)); 6363 predicate(AllocatePrefetchStyle == 3); 6364 ins_cost(MEMORY_REF_COST); 6365 6366 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6367 size(4); 6368 ins_encode %{ 6369 __ dcbz($src$$Register, $mem$$base$$Register); 6370 %} 6371 ins_pipe(pipe_class_memory); 6372 %} 6373 6374 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6375 match(PrefetchAllocation mem); 6376 predicate(AllocatePrefetchStyle == 3); 6377 ins_cost(MEMORY_REF_COST); 6378 6379 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6380 size(4); 6381 ins_encode %{ 6382 __ dcbz($mem$$base$$Register); 6383 %} 6384 ins_pipe(pipe_class_memory); 6385 %} 6386 6387 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6388 match(PrefetchAllocation (AddP mem src)); 6389 predicate(AllocatePrefetchStyle != 3); 6390 ins_cost(MEMORY_REF_COST); 6391 6392 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6393 size(4); 6394 ins_encode %{ 6395 __ dcbtst($src$$Register, $mem$$base$$Register); 6396 %} 6397 ins_pipe(pipe_class_memory); 6398 %} 6399 6400 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6401 match(PrefetchAllocation mem); 6402 predicate(AllocatePrefetchStyle != 3); 6403 ins_cost(MEMORY_REF_COST); 6404 6405 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6406 size(4); 6407 ins_encode %{ 6408 __ dcbtst($mem$$base$$Register); 6409 %} 6410 ins_pipe(pipe_class_memory); 6411 %} 6412 6413 //----------Store Instructions------------------------------------------------- 6414 6415 // Store Byte 6416 instruct storeB(memory mem, iRegIsrc src) %{ 6417 match(Set mem (StoreB mem src)); 6418 ins_cost(MEMORY_REF_COST); 6419 6420 format %{ "STB $src, $mem \t// byte" %} 6421 size(4); 6422 ins_encode %{ 6423 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6424 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6425 %} 6426 ins_pipe(pipe_class_memory); 6427 %} 6428 6429 // Store Char/Short 6430 instruct storeC(memory mem, iRegIsrc src) %{ 6431 match(Set mem (StoreC mem src)); 6432 ins_cost(MEMORY_REF_COST); 6433 6434 format %{ "STH $src, $mem \t// short" %} 6435 size(4); 6436 ins_encode %{ 6437 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6438 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6439 %} 6440 ins_pipe(pipe_class_memory); 6441 %} 6442 6443 // Store Integer 6444 instruct storeI(memory mem, iRegIsrc src) %{ 6445 match(Set mem (StoreI mem src)); 6446 ins_cost(MEMORY_REF_COST); 6447 6448 format %{ "STW $src, $mem" %} 6449 size(4); 6450 ins_encode( enc_stw(src, mem) ); 6451 ins_pipe(pipe_class_memory); 6452 %} 6453 6454 // ConvL2I + StoreI. 6455 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6456 match(Set mem (StoreI mem (ConvL2I src))); 6457 ins_cost(MEMORY_REF_COST); 6458 6459 format %{ "STW l2i($src), $mem" %} 6460 size(4); 6461 ins_encode( enc_stw(src, mem) ); 6462 ins_pipe(pipe_class_memory); 6463 %} 6464 6465 // Store Long 6466 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6467 match(Set mem (StoreL mem src)); 6468 ins_cost(MEMORY_REF_COST); 6469 6470 format %{ "STD $src, $mem \t// long" %} 6471 size(4); 6472 ins_encode( enc_std(src, mem) ); 6473 ins_pipe(pipe_class_memory); 6474 %} 6475 6476 // Store super word nodes. 6477 6478 // Store Aligned Packed Byte long register to memory 6479 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6480 predicate(n->as_StoreVector()->memory_size() == 8); 6481 match(Set mem (StoreVector mem src)); 6482 ins_cost(MEMORY_REF_COST); 6483 6484 format %{ "STD $mem, $src \t// packed8B" %} 6485 size(4); 6486 ins_encode( enc_std(src, mem) ); 6487 ins_pipe(pipe_class_memory); 6488 %} 6489 6490 // Store Packed Byte long register to memory 6491 instruct storeV16(indirect mem, vecX src) %{ 6492 predicate(n->as_StoreVector()->memory_size() == 16); 6493 match(Set mem (StoreVector mem src)); 6494 ins_cost(MEMORY_REF_COST); 6495 6496 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6497 size(4); 6498 ins_encode %{ 6499 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6500 %} 6501 ins_pipe(pipe_class_default); 6502 %} 6503 6504 // Reinterpret: only one vector size used: either L or X 6505 instruct reinterpretL(iRegLdst dst) %{ 6506 match(Set dst (VectorReinterpret dst)); 6507 ins_cost(0); 6508 format %{ "reinterpret $dst" %} 6509 ins_encode( /*empty*/ ); 6510 ins_pipe(pipe_class_empty); 6511 %} 6512 6513 instruct reinterpretX(vecX dst) %{ 6514 match(Set dst (VectorReinterpret dst)); 6515 ins_cost(0); 6516 format %{ "reinterpret $dst" %} 6517 ins_encode( /*empty*/ ); 6518 ins_pipe(pipe_class_empty); 6519 %} 6520 6521 // Store Compressed Oop 6522 instruct storeN(memory dst, iRegN_P2N src) %{ 6523 match(Set dst (StoreN dst src)); 6524 ins_cost(MEMORY_REF_COST); 6525 6526 format %{ "STW $src, $dst \t// compressed oop" %} 6527 size(4); 6528 ins_encode( enc_stw(src, dst) ); 6529 ins_pipe(pipe_class_memory); 6530 %} 6531 6532 // Store Compressed KLass 6533 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6534 match(Set dst (StoreNKlass dst src)); 6535 ins_cost(MEMORY_REF_COST); 6536 6537 format %{ "STW $src, $dst \t// compressed klass" %} 6538 size(4); 6539 ins_encode( enc_stw(src, dst) ); 6540 ins_pipe(pipe_class_memory); 6541 %} 6542 6543 // Store Pointer 6544 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6545 match(Set dst (StoreP dst src)); 6546 predicate(n->as_Store()->barrier_data() == 0); 6547 ins_cost(MEMORY_REF_COST); 6548 6549 format %{ "STD $src, $dst \t// ptr" %} 6550 size(4); 6551 ins_encode( enc_std(src, dst) ); 6552 ins_pipe(pipe_class_memory); 6553 %} 6554 6555 // Store Float 6556 instruct storeF(memory mem, regF src) %{ 6557 match(Set mem (StoreF mem src)); 6558 ins_cost(MEMORY_REF_COST); 6559 6560 format %{ "STFS $src, $mem" %} 6561 size(4); 6562 ins_encode( enc_stfs(src, mem) ); 6563 ins_pipe(pipe_class_memory); 6564 %} 6565 6566 // Store Double 6567 instruct storeD(memory mem, regD src) %{ 6568 match(Set mem (StoreD mem src)); 6569 ins_cost(MEMORY_REF_COST); 6570 6571 format %{ "STFD $src, $mem" %} 6572 size(4); 6573 ins_encode( enc_stfd(src, mem) ); 6574 ins_pipe(pipe_class_memory); 6575 %} 6576 6577 //----------Store Instructions With Zeros-------------------------------------- 6578 6579 instruct storeCM(memory mem, immI_0 zero) %{ 6580 match(Set mem (StoreCM mem zero)); 6581 ins_cost(MEMORY_REF_COST); 6582 6583 format %{ "STB #0, $mem \t// CMS card-mark byte store" %} 6584 size(8); 6585 ins_encode %{ 6586 __ li(R0, 0); 6587 // No release barrier: Oops are allowed to get visible after marking. 6588 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6589 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6590 %} 6591 ins_pipe(pipe_class_memory); 6592 %} 6593 6594 // Convert oop pointer into compressed form. 6595 6596 // Nodes for postalloc expand. 6597 6598 // Shift node for expand. 6599 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6600 // The match rule is needed to make it a 'MachTypeNode'! 6601 match(Set dst (EncodeP src)); 6602 predicate(false); 6603 6604 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6605 size(4); 6606 ins_encode %{ 6607 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 6608 %} 6609 ins_pipe(pipe_class_default); 6610 %} 6611 6612 // Add node for expand. 6613 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6614 // The match rule is needed to make it a 'MachTypeNode'! 6615 match(Set dst (EncodeP src)); 6616 predicate(false); 6617 6618 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6619 ins_encode %{ 6620 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 6621 %} 6622 ins_pipe(pipe_class_default); 6623 %} 6624 6625 // Conditional sub base. 6626 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6627 // The match rule is needed to make it a 'MachTypeNode'! 6628 match(Set dst (EncodeP (Binary crx src1))); 6629 predicate(false); 6630 6631 format %{ "BEQ $crx, done\n\t" 6632 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6633 "done:" %} 6634 ins_encode %{ 6635 Label done; 6636 __ beq($crx$$CondRegister, done); 6637 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0); 6638 __ bind(done); 6639 %} 6640 ins_pipe(pipe_class_default); 6641 %} 6642 6643 // Power 7 can use isel instruction 6644 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6645 // The match rule is needed to make it a 'MachTypeNode'! 6646 match(Set dst (EncodeP (Binary crx src1))); 6647 predicate(false); 6648 6649 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6650 size(4); 6651 ins_encode %{ 6652 // This is a Power7 instruction for which no machine description exists. 6653 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6654 %} 6655 ins_pipe(pipe_class_default); 6656 %} 6657 6658 // Disjoint narrow oop base. 6659 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6660 match(Set dst (EncodeP src)); 6661 predicate(CompressedOops::base_disjoint()); 6662 6663 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6664 size(4); 6665 ins_encode %{ 6666 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32); 6667 %} 6668 ins_pipe(pipe_class_default); 6669 %} 6670 6671 // shift != 0, base != 0 6672 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6673 match(Set dst (EncodeP src)); 6674 effect(TEMP crx); 6675 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6676 CompressedOops::shift() != 0 && 6677 CompressedOops::base_overlaps()); 6678 6679 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 6680 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 6681 %} 6682 6683 // shift != 0, base != 0 6684 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 6685 match(Set dst (EncodeP src)); 6686 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 6687 CompressedOops::shift() != 0 && 6688 CompressedOops::base_overlaps()); 6689 6690 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 6691 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 6692 %} 6693 6694 // shift != 0, base == 0 6695 // TODO: This is the same as encodeP_shift. Merge! 6696 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 6697 match(Set dst (EncodeP src)); 6698 predicate(CompressedOops::shift() != 0 && 6699 CompressedOops::base() ==0); 6700 6701 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 6702 size(4); 6703 ins_encode %{ 6704 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 6705 %} 6706 ins_pipe(pipe_class_default); 6707 %} 6708 6709 // Compressed OOPs with narrow_oop_shift == 0. 6710 // shift == 0, base == 0 6711 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 6712 match(Set dst (EncodeP src)); 6713 predicate(CompressedOops::shift() == 0); 6714 6715 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 6716 // variable size, 0 or 4. 6717 ins_encode %{ 6718 __ mr_if_needed($dst$$Register, $src$$Register); 6719 %} 6720 ins_pipe(pipe_class_default); 6721 %} 6722 6723 // Decode nodes. 6724 6725 // Shift node for expand. 6726 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 6727 // The match rule is needed to make it a 'MachTypeNode'! 6728 match(Set dst (DecodeN src)); 6729 predicate(false); 6730 6731 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 6732 size(4); 6733 ins_encode %{ 6734 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 6735 %} 6736 ins_pipe(pipe_class_default); 6737 %} 6738 6739 // Add node for expand. 6740 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 6741 // The match rule is needed to make it a 'MachTypeNode'! 6742 match(Set dst (DecodeN src)); 6743 predicate(false); 6744 6745 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 6746 ins_encode %{ 6747 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 6748 %} 6749 ins_pipe(pipe_class_default); 6750 %} 6751 6752 // conditianal add base for expand 6753 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 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 src))); 6759 predicate(false); 6760 6761 format %{ "BEQ $crx, done\n\t" 6762 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 6763 "done:" %} 6764 ins_encode %{ 6765 Label done; 6766 __ beq($crx$$CondRegister, done); 6767 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 6768 __ bind(done); 6769 %} 6770 ins_pipe(pipe_class_default); 6771 %} 6772 6773 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6774 // The match rule is needed to make it a 'MachTypeNode'! 6775 // NOTICE that the rule is nonsense - we just have to make sure that: 6776 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6777 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6778 match(Set dst (DecodeN (Binary crx src1))); 6779 predicate(false); 6780 6781 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 6782 size(4); 6783 ins_encode %{ 6784 // This is a Power7 instruction for which no machine description exists. 6785 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6786 %} 6787 ins_pipe(pipe_class_default); 6788 %} 6789 6790 // shift != 0, base != 0 6791 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6792 match(Set dst (DecodeN src)); 6793 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6794 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6795 CompressedOops::shift() != 0 && 6796 CompressedOops::base() != 0); 6797 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 6798 effect(TEMP crx); 6799 6800 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 6801 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 6802 %} 6803 6804 // shift != 0, base == 0 6805 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 6806 match(Set dst (DecodeN src)); 6807 predicate(CompressedOops::shift() != 0 && 6808 CompressedOops::base() == 0); 6809 6810 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 6811 size(4); 6812 ins_encode %{ 6813 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 6814 %} 6815 ins_pipe(pipe_class_default); 6816 %} 6817 6818 // Optimize DecodeN for disjoint base. 6819 // Shift narrow oop and or it into register that already contains the heap base. 6820 // Base == dst must hold, and is assured by construction in postaloc_expand. 6821 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 6822 match(Set dst (DecodeN src)); 6823 effect(TEMP base); 6824 predicate(false); 6825 6826 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 6827 size(4); 6828 ins_encode %{ 6829 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift()); 6830 %} 6831 ins_pipe(pipe_class_default); 6832 %} 6833 6834 // Optimize DecodeN for disjoint base. 6835 // This node requires only one cycle on the critical path. 6836 // We must postalloc_expand as we can not express use_def effects where 6837 // the used register is L and the def'ed register P. 6838 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 6839 match(Set dst (DecodeN src)); 6840 effect(TEMP_DEF dst); 6841 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6842 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6843 CompressedOops::base_disjoint()); 6844 ins_cost(DEFAULT_COST); 6845 6846 format %{ "MOV $dst, heapbase \t\n" 6847 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 6848 postalloc_expand %{ 6849 loadBaseNode *n1 = new loadBaseNode(); 6850 n1->add_req(NULL); 6851 n1->_opnds[0] = op_dst; 6852 6853 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6854 n2->add_req(n_region, n_src, n1); 6855 n2->_opnds[0] = op_dst; 6856 n2->_opnds[1] = op_src; 6857 n2->_opnds[2] = op_dst; 6858 n2->_bottom_type = _bottom_type; 6859 6860 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 6861 ra_->set_oop(n2, true); 6862 6863 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6864 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6865 6866 nodes->push(n1); 6867 nodes->push(n2); 6868 %} 6869 %} 6870 6871 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6872 match(Set dst (DecodeN src)); 6873 effect(TEMP_DEF dst, TEMP crx); 6874 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6875 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6876 CompressedOops::base_disjoint() && VM_Version::has_isel()); 6877 ins_cost(3 * DEFAULT_COST); 6878 6879 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 6880 postalloc_expand %{ 6881 loadBaseNode *n1 = new loadBaseNode(); 6882 n1->add_req(NULL); 6883 n1->_opnds[0] = op_dst; 6884 6885 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 6886 n_compare->add_req(n_region, n_src); 6887 n_compare->_opnds[0] = op_crx; 6888 n_compare->_opnds[1] = op_src; 6889 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 6890 6891 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6892 n2->add_req(n_region, n_src, n1); 6893 n2->_opnds[0] = op_dst; 6894 n2->_opnds[1] = op_src; 6895 n2->_opnds[2] = op_dst; 6896 n2->_bottom_type = _bottom_type; 6897 6898 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 6899 n_cond_set->add_req(n_region, n_compare, n2); 6900 n_cond_set->_opnds[0] = op_dst; 6901 n_cond_set->_opnds[1] = op_crx; 6902 n_cond_set->_opnds[2] = op_dst; 6903 n_cond_set->_bottom_type = _bottom_type; 6904 6905 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 6906 ra_->set_oop(n_cond_set, true); 6907 6908 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6909 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 6910 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6911 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6912 6913 nodes->push(n1); 6914 nodes->push(n_compare); 6915 nodes->push(n2); 6916 nodes->push(n_cond_set); 6917 %} 6918 %} 6919 6920 // src != 0, shift != 0, base != 0 6921 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 6922 match(Set dst (DecodeN src)); 6923 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6924 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6925 CompressedOops::shift() != 0 && 6926 CompressedOops::base() != 0); 6927 ins_cost(2 * DEFAULT_COST); 6928 6929 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 6930 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 6931 %} 6932 6933 // Compressed OOPs with narrow_oop_shift == 0. 6934 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 6935 match(Set dst (DecodeN src)); 6936 predicate(CompressedOops::shift() == 0); 6937 ins_cost(DEFAULT_COST); 6938 6939 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 6940 // variable size, 0 or 4. 6941 ins_encode %{ 6942 __ mr_if_needed($dst$$Register, $src$$Register); 6943 %} 6944 ins_pipe(pipe_class_default); 6945 %} 6946 6947 // Convert compressed oop into int for vectors alignment masking. 6948 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 6949 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6950 predicate(CompressedOops::shift() == 0); 6951 ins_cost(DEFAULT_COST); 6952 6953 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 6954 // variable size, 0 or 4. 6955 ins_encode %{ 6956 __ mr_if_needed($dst$$Register, $src$$Register); 6957 %} 6958 ins_pipe(pipe_class_default); 6959 %} 6960 6961 // Convert klass pointer into compressed form. 6962 6963 // Nodes for postalloc expand. 6964 6965 // Shift node for expand. 6966 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 6967 // The match rule is needed to make it a 'MachTypeNode'! 6968 match(Set dst (EncodePKlass src)); 6969 predicate(false); 6970 6971 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6972 size(4); 6973 ins_encode %{ 6974 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 6975 %} 6976 ins_pipe(pipe_class_default); 6977 %} 6978 6979 // Add node for expand. 6980 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6981 // The match rule is needed to make it a 'MachTypeNode'! 6982 match(Set dst (EncodePKlass (Binary base src))); 6983 predicate(false); 6984 6985 format %{ "SUB $dst, $base, $src \t// encode" %} 6986 size(4); 6987 ins_encode %{ 6988 __ subf($dst$$Register, $base$$Register, $src$$Register); 6989 %} 6990 ins_pipe(pipe_class_default); 6991 %} 6992 6993 // Disjoint narrow oop base. 6994 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6995 match(Set dst (EncodePKlass src)); 6996 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/); 6997 6998 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6999 size(4); 7000 ins_encode %{ 7001 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32); 7002 %} 7003 ins_pipe(pipe_class_default); 7004 %} 7005 7006 // shift != 0, base != 0 7007 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7008 match(Set dst (EncodePKlass (Binary base src))); 7009 predicate(false); 7010 7011 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7012 postalloc_expand %{ 7013 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7014 n1->add_req(n_region, n_base, n_src); 7015 n1->_opnds[0] = op_dst; 7016 n1->_opnds[1] = op_base; 7017 n1->_opnds[2] = op_src; 7018 n1->_bottom_type = _bottom_type; 7019 7020 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7021 n2->add_req(n_region, n1); 7022 n2->_opnds[0] = op_dst; 7023 n2->_opnds[1] = op_dst; 7024 n2->_bottom_type = _bottom_type; 7025 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7026 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7027 7028 nodes->push(n1); 7029 nodes->push(n2); 7030 %} 7031 %} 7032 7033 // shift != 0, base != 0 7034 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7035 match(Set dst (EncodePKlass src)); 7036 //predicate(CompressedKlassPointers::shift() != 0 && 7037 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/); 7038 7039 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7040 ins_cost(DEFAULT_COST*2); // Don't count constant. 7041 expand %{ 7042 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %} 7043 iRegLdst base; 7044 loadConL_Ex(base, baseImm); 7045 encodePKlass_not_null_Ex(dst, base, src); 7046 %} 7047 %} 7048 7049 // Decode nodes. 7050 7051 // Shift node for expand. 7052 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7053 // The match rule is needed to make it a 'MachTypeNode'! 7054 match(Set dst (DecodeNKlass src)); 7055 predicate(false); 7056 7057 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7058 size(4); 7059 ins_encode %{ 7060 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 7061 %} 7062 ins_pipe(pipe_class_default); 7063 %} 7064 7065 // Add node for expand. 7066 7067 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7068 // The match rule is needed to make it a 'MachTypeNode'! 7069 match(Set dst (DecodeNKlass (Binary base src))); 7070 predicate(false); 7071 7072 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7073 size(4); 7074 ins_encode %{ 7075 __ add($dst$$Register, $base$$Register, $src$$Register); 7076 %} 7077 ins_pipe(pipe_class_default); 7078 %} 7079 7080 // src != 0, shift != 0, base != 0 7081 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7082 match(Set dst (DecodeNKlass (Binary base src))); 7083 //effect(kill src); // We need a register for the immediate result after shifting. 7084 predicate(false); 7085 7086 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7087 postalloc_expand %{ 7088 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7089 n1->add_req(n_region, n_base, n_src); 7090 n1->_opnds[0] = op_dst; 7091 n1->_opnds[1] = op_base; 7092 n1->_opnds[2] = op_src; 7093 n1->_bottom_type = _bottom_type; 7094 7095 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7096 n2->add_req(n_region, n1); 7097 n2->_opnds[0] = op_dst; 7098 n2->_opnds[1] = op_dst; 7099 n2->_bottom_type = _bottom_type; 7100 7101 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7102 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7103 7104 nodes->push(n1); 7105 nodes->push(n2); 7106 %} 7107 %} 7108 7109 // src != 0, shift != 0, base != 0 7110 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7111 match(Set dst (DecodeNKlass src)); 7112 // predicate(CompressedKlassPointers::shift() != 0 && 7113 // CompressedKlassPointers::base() != 0); 7114 7115 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7116 7117 ins_cost(DEFAULT_COST*2); // Don't count constant. 7118 expand %{ 7119 // We add first, then we shift. Like this, we can get along with one register less. 7120 // But we have to load the base pre-shifted. 7121 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %} 7122 iRegLdst base; 7123 loadConL_Ex(base, baseImm); 7124 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7125 %} 7126 %} 7127 7128 //----------MemBar Instructions----------------------------------------------- 7129 // Memory barrier flavors 7130 7131 instruct membar_acquire() %{ 7132 match(LoadFence); 7133 ins_cost(4*MEMORY_REF_COST); 7134 7135 format %{ "MEMBAR-acquire" %} 7136 size(4); 7137 ins_encode %{ 7138 __ acquire(); 7139 %} 7140 ins_pipe(pipe_class_default); 7141 %} 7142 7143 instruct unnecessary_membar_acquire() %{ 7144 match(MemBarAcquire); 7145 ins_cost(0); 7146 7147 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7148 size(0); 7149 ins_encode( /*empty*/ ); 7150 ins_pipe(pipe_class_default); 7151 %} 7152 7153 instruct membar_acquire_lock() %{ 7154 match(MemBarAcquireLock); 7155 ins_cost(0); 7156 7157 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7158 size(0); 7159 ins_encode( /*empty*/ ); 7160 ins_pipe(pipe_class_default); 7161 %} 7162 7163 instruct membar_release() %{ 7164 match(MemBarRelease); 7165 match(StoreFence); 7166 ins_cost(4*MEMORY_REF_COST); 7167 7168 format %{ "MEMBAR-release" %} 7169 size(4); 7170 ins_encode %{ 7171 __ release(); 7172 %} 7173 ins_pipe(pipe_class_default); 7174 %} 7175 7176 instruct membar_storestore() %{ 7177 match(MemBarStoreStore); 7178 match(StoreStoreFence); 7179 ins_cost(4*MEMORY_REF_COST); 7180 7181 format %{ "MEMBAR-store-store" %} 7182 size(4); 7183 ins_encode %{ 7184 __ membar(Assembler::StoreStore); 7185 %} 7186 ins_pipe(pipe_class_default); 7187 %} 7188 7189 instruct membar_release_lock() %{ 7190 match(MemBarReleaseLock); 7191 ins_cost(0); 7192 7193 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7194 size(0); 7195 ins_encode( /*empty*/ ); 7196 ins_pipe(pipe_class_default); 7197 %} 7198 7199 instruct membar_volatile() %{ 7200 match(MemBarVolatile); 7201 ins_cost(4*MEMORY_REF_COST); 7202 7203 format %{ "MEMBAR-volatile" %} 7204 size(4); 7205 ins_encode %{ 7206 __ fence(); 7207 %} 7208 ins_pipe(pipe_class_default); 7209 %} 7210 7211 // This optimization is wrong on PPC. The following pattern is not supported: 7212 // MemBarVolatile 7213 // ^ ^ 7214 // | | 7215 // CtrlProj MemProj 7216 // ^ ^ 7217 // | | 7218 // | Load 7219 // | 7220 // MemBarVolatile 7221 // 7222 // The first MemBarVolatile could get optimized out! According to 7223 // Vladimir, this pattern can not occur on Oracle platforms. 7224 // However, it does occur on PPC64 (because of membars in 7225 // inline_unsafe_load_store). 7226 // 7227 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7228 // Don't forget to look at the implementation of post_store_load_barrier again, 7229 // we did other fixes in that method. 7230 //instruct unnecessary_membar_volatile() %{ 7231 // match(MemBarVolatile); 7232 // predicate(Matcher::post_store_load_barrier(n)); 7233 // ins_cost(0); 7234 // 7235 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7236 // size(0); 7237 // ins_encode( /*empty*/ ); 7238 // ins_pipe(pipe_class_default); 7239 //%} 7240 7241 instruct membar_CPUOrder() %{ 7242 match(MemBarCPUOrder); 7243 ins_cost(0); 7244 7245 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7246 size(0); 7247 ins_encode( /*empty*/ ); 7248 ins_pipe(pipe_class_default); 7249 %} 7250 7251 //----------Conditional Move--------------------------------------------------- 7252 7253 // Cmove using isel. 7254 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7255 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7256 predicate(VM_Version::has_isel()); 7257 ins_cost(DEFAULT_COST); 7258 7259 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7260 size(4); 7261 ins_encode %{ 7262 // This is a Power7 instruction for which no machine description 7263 // exists. Anyways, the scheduler should be off on Power7. 7264 int cc = $cmp$$cmpcode; 7265 __ isel($dst$$Register, $crx$$CondRegister, 7266 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7267 %} 7268 ins_pipe(pipe_class_default); 7269 %} 7270 7271 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7272 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7273 predicate(!VM_Version::has_isel()); 7274 ins_cost(DEFAULT_COST+BRANCH_COST); 7275 7276 ins_variable_size_depending_on_alignment(true); 7277 7278 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7279 // Worst case is branch + move + stop, no stop without scheduler 7280 size(8); 7281 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7282 ins_pipe(pipe_class_default); 7283 %} 7284 7285 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7286 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7287 ins_cost(DEFAULT_COST+BRANCH_COST); 7288 7289 ins_variable_size_depending_on_alignment(true); 7290 7291 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7292 // Worst case is branch + move + stop, no stop without scheduler 7293 size(8); 7294 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7295 ins_pipe(pipe_class_default); 7296 %} 7297 7298 // Cmove using isel. 7299 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7300 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7301 predicate(VM_Version::has_isel()); 7302 ins_cost(DEFAULT_COST); 7303 7304 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7305 size(4); 7306 ins_encode %{ 7307 // This is a Power7 instruction for which no machine description 7308 // exists. Anyways, the scheduler should be off on Power7. 7309 int cc = $cmp$$cmpcode; 7310 __ isel($dst$$Register, $crx$$CondRegister, 7311 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7312 %} 7313 ins_pipe(pipe_class_default); 7314 %} 7315 7316 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7317 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7318 predicate(!VM_Version::has_isel()); 7319 ins_cost(DEFAULT_COST+BRANCH_COST); 7320 7321 ins_variable_size_depending_on_alignment(true); 7322 7323 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7324 // Worst case is branch + move + stop, no stop without scheduler. 7325 size(8); 7326 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7327 ins_pipe(pipe_class_default); 7328 %} 7329 7330 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7331 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7332 ins_cost(DEFAULT_COST+BRANCH_COST); 7333 7334 ins_variable_size_depending_on_alignment(true); 7335 7336 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7337 // Worst case is branch + move + stop, no stop without scheduler. 7338 size(8); 7339 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7340 ins_pipe(pipe_class_default); 7341 %} 7342 7343 // Cmove using isel. 7344 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7345 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7346 predicate(VM_Version::has_isel()); 7347 ins_cost(DEFAULT_COST); 7348 7349 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7350 size(4); 7351 ins_encode %{ 7352 // This is a Power7 instruction for which no machine description 7353 // exists. Anyways, the scheduler should be off on Power7. 7354 int cc = $cmp$$cmpcode; 7355 __ isel($dst$$Register, $crx$$CondRegister, 7356 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7357 %} 7358 ins_pipe(pipe_class_default); 7359 %} 7360 7361 // Conditional move for RegN. Only cmov(reg, reg). 7362 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7363 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7364 predicate(!VM_Version::has_isel()); 7365 ins_cost(DEFAULT_COST+BRANCH_COST); 7366 7367 ins_variable_size_depending_on_alignment(true); 7368 7369 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7370 // Worst case is branch + move + stop, no stop without scheduler. 7371 size(8); 7372 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7373 ins_pipe(pipe_class_default); 7374 %} 7375 7376 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7377 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7378 ins_cost(DEFAULT_COST+BRANCH_COST); 7379 7380 ins_variable_size_depending_on_alignment(true); 7381 7382 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7383 // Worst case is branch + move + stop, no stop without scheduler. 7384 size(8); 7385 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7386 ins_pipe(pipe_class_default); 7387 %} 7388 7389 // Cmove using isel. 7390 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7391 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7392 predicate(VM_Version::has_isel()); 7393 ins_cost(DEFAULT_COST); 7394 7395 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7396 size(4); 7397 ins_encode %{ 7398 // This is a Power7 instruction for which no machine description 7399 // exists. Anyways, the scheduler should be off on Power7. 7400 int cc = $cmp$$cmpcode; 7401 __ isel($dst$$Register, $crx$$CondRegister, 7402 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7403 %} 7404 ins_pipe(pipe_class_default); 7405 %} 7406 7407 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7408 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7409 predicate(!VM_Version::has_isel()); 7410 ins_cost(DEFAULT_COST+BRANCH_COST); 7411 7412 ins_variable_size_depending_on_alignment(true); 7413 7414 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7415 // Worst case is branch + move + stop, no stop without scheduler. 7416 size(8); 7417 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7418 ins_pipe(pipe_class_default); 7419 %} 7420 7421 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7422 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7423 ins_cost(DEFAULT_COST+BRANCH_COST); 7424 7425 ins_variable_size_depending_on_alignment(true); 7426 7427 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7428 // Worst case is branch + move + stop, no stop without scheduler. 7429 size(8); 7430 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7431 ins_pipe(pipe_class_default); 7432 %} 7433 7434 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7435 match(Set dst (CMoveF (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 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7455 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7456 ins_cost(DEFAULT_COST+BRANCH_COST); 7457 7458 ins_variable_size_depending_on_alignment(true); 7459 7460 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7461 // Worst case is branch + move + stop, no stop without scheduler. 7462 size(8); 7463 ins_encode %{ 7464 Label done; 7465 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7466 // Branch if not (cmp crx). 7467 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7468 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7469 __ bind(done); 7470 %} 7471 ins_pipe(pipe_class_default); 7472 %} 7473 7474 //----------Compare-And-Swap--------------------------------------------------- 7475 7476 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7477 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7478 // matched. 7479 7480 // Strong versions: 7481 7482 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7483 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7484 predicate(VM_Version::has_lqarx()); 7485 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7486 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7487 ins_encode %{ 7488 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7489 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7490 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7491 $res$$Register, true); 7492 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7493 __ isync(); 7494 } else { 7495 __ sync(); 7496 } 7497 %} 7498 ins_pipe(pipe_class_default); 7499 %} 7500 7501 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7502 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7503 predicate(!VM_Version::has_lqarx()); 7504 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7505 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7506 ins_encode %{ 7507 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7508 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7509 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7510 $res$$Register, true); 7511 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7512 __ isync(); 7513 } else { 7514 __ sync(); 7515 } 7516 %} 7517 ins_pipe(pipe_class_default); 7518 %} 7519 7520 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7521 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7522 predicate(VM_Version::has_lqarx()); 7523 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7524 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7525 ins_encode %{ 7526 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7527 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7528 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7529 $res$$Register, true); 7530 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7531 __ isync(); 7532 } else { 7533 __ sync(); 7534 } 7535 %} 7536 ins_pipe(pipe_class_default); 7537 %} 7538 7539 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7540 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7541 predicate(!VM_Version::has_lqarx()); 7542 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7543 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7544 ins_encode %{ 7545 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7546 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7547 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7548 $res$$Register, true); 7549 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7550 __ isync(); 7551 } else { 7552 __ sync(); 7553 } 7554 %} 7555 ins_pipe(pipe_class_default); 7556 %} 7557 7558 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7559 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7560 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7561 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7562 ins_encode %{ 7563 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7564 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7565 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7566 $res$$Register, true); 7567 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7568 __ isync(); 7569 } else { 7570 __ sync(); 7571 } 7572 %} 7573 ins_pipe(pipe_class_default); 7574 %} 7575 7576 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7577 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7578 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7579 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7580 ins_encode %{ 7581 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7582 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$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 compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7595 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 7596 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7597 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7598 ins_encode %{ 7599 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7600 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7601 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7602 $res$$Register, NULL, 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 compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7613 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 7614 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7615 predicate(n->as_LoadStore()->barrier_data() == 0); 7616 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7617 ins_encode %{ 7618 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7619 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7620 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7621 $res$$Register, NULL, true); 7622 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7623 __ isync(); 7624 } else { 7625 __ sync(); 7626 } 7627 %} 7628 ins_pipe(pipe_class_default); 7629 %} 7630 7631 // Weak versions: 7632 7633 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7634 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7635 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7636 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7637 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7638 ins_encode %{ 7639 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7640 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7641 MacroAssembler::MemBarNone, 7642 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7643 %} 7644 ins_pipe(pipe_class_default); 7645 %} 7646 7647 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7648 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7649 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7650 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7651 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7652 ins_encode %{ 7653 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7654 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7655 MacroAssembler::MemBarNone, 7656 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7657 %} 7658 ins_pipe(pipe_class_default); 7659 %} 7660 7661 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7662 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7663 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7664 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7665 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7666 ins_encode %{ 7667 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7668 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7669 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7670 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7671 %} 7672 ins_pipe(pipe_class_default); 7673 %} 7674 7675 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7676 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7677 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7678 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7679 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7680 ins_encode %{ 7681 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7682 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7683 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7684 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7685 %} 7686 ins_pipe(pipe_class_default); 7687 %} 7688 7689 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7690 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7691 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7692 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7693 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7694 ins_encode %{ 7695 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7696 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7697 MacroAssembler::MemBarNone, 7698 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7699 %} 7700 ins_pipe(pipe_class_default); 7701 %} 7702 7703 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7704 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7705 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7706 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7707 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7708 ins_encode %{ 7709 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7710 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7711 MacroAssembler::MemBarNone, 7712 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7713 %} 7714 ins_pipe(pipe_class_default); 7715 %} 7716 7717 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7718 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7719 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7720 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7721 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7722 ins_encode %{ 7723 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7724 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7725 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7726 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7727 %} 7728 ins_pipe(pipe_class_default); 7729 %} 7730 7731 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7732 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7733 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7734 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7735 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7736 ins_encode %{ 7737 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7738 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7739 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7740 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7741 %} 7742 ins_pipe(pipe_class_default); 7743 %} 7744 7745 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7746 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7747 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7748 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7749 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7750 ins_encode %{ 7751 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7752 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7753 MacroAssembler::MemBarNone, 7754 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7755 %} 7756 ins_pipe(pipe_class_default); 7757 %} 7758 7759 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7760 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7761 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7762 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7763 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7764 ins_encode %{ 7765 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7766 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7767 // value is never passed to caller. 7768 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7769 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7770 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7771 %} 7772 ins_pipe(pipe_class_default); 7773 %} 7774 7775 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7776 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7777 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7778 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7779 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7780 ins_encode %{ 7781 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7782 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7783 MacroAssembler::MemBarNone, 7784 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7785 %} 7786 ins_pipe(pipe_class_default); 7787 %} 7788 7789 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7790 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7791 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7792 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7793 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7794 ins_encode %{ 7795 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7796 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7797 // value is never passed to caller. 7798 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7799 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7800 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7801 %} 7802 ins_pipe(pipe_class_default); 7803 %} 7804 7805 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7806 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7807 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7808 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7809 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7810 ins_encode %{ 7811 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7812 // value is never passed to caller. 7813 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7814 MacroAssembler::MemBarNone, 7815 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7816 %} 7817 ins_pipe(pipe_class_default); 7818 %} 7819 7820 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7821 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7822 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7823 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7824 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 7825 ins_encode %{ 7826 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7827 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7828 // value is never passed to caller. 7829 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7830 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7831 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7832 %} 7833 ins_pipe(pipe_class_default); 7834 %} 7835 7836 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7837 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7838 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0); 7839 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7840 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7841 ins_encode %{ 7842 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7843 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7844 MacroAssembler::MemBarNone, 7845 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7846 %} 7847 ins_pipe(pipe_class_default); 7848 %} 7849 7850 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7851 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7852 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0); 7853 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7854 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7855 ins_encode %{ 7856 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7857 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7858 // value is never passed to caller. 7859 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7860 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7861 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7862 %} 7863 ins_pipe(pipe_class_default); 7864 %} 7865 7866 // CompareAndExchange 7867 7868 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7869 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7870 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7871 effect(TEMP_DEF res, TEMP cr0); 7872 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7873 ins_encode %{ 7874 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7875 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7876 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7877 noreg, true); 7878 %} 7879 ins_pipe(pipe_class_default); 7880 %} 7881 7882 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7883 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7884 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7885 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7886 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7887 ins_encode %{ 7888 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7889 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7890 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7891 noreg, true); 7892 %} 7893 ins_pipe(pipe_class_default); 7894 %} 7895 7896 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7897 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7898 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7899 effect(TEMP_DEF res, TEMP cr0); 7900 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7901 ins_encode %{ 7902 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7903 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7904 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7905 noreg, true); 7906 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7907 __ isync(); 7908 } else { 7909 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7910 __ sync(); 7911 } 7912 %} 7913 ins_pipe(pipe_class_default); 7914 %} 7915 7916 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7917 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7918 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7919 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7920 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7921 ins_encode %{ 7922 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7923 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7924 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7925 noreg, true); 7926 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7927 __ isync(); 7928 } else { 7929 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7930 __ sync(); 7931 } 7932 %} 7933 ins_pipe(pipe_class_default); 7934 %} 7935 7936 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7937 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7938 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7939 effect(TEMP_DEF res, TEMP cr0); 7940 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7941 ins_encode %{ 7942 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7943 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7944 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7945 noreg, true); 7946 %} 7947 ins_pipe(pipe_class_default); 7948 %} 7949 7950 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7951 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7952 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7953 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7954 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7955 ins_encode %{ 7956 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7957 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7958 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7959 noreg, true); 7960 %} 7961 ins_pipe(pipe_class_default); 7962 %} 7963 7964 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7965 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7966 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7967 effect(TEMP_DEF res, TEMP cr0); 7968 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7969 ins_encode %{ 7970 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7971 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7972 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7973 noreg, true); 7974 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7975 __ isync(); 7976 } else { 7977 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7978 __ sync(); 7979 } 7980 %} 7981 ins_pipe(pipe_class_default); 7982 %} 7983 7984 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7985 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7986 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7987 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7988 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7989 ins_encode %{ 7990 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7991 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7992 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7993 noreg, true); 7994 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7995 __ isync(); 7996 } else { 7997 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7998 __ sync(); 7999 } 8000 %} 8001 ins_pipe(pipe_class_default); 8002 %} 8003 8004 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8005 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8006 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8007 effect(TEMP_DEF res, TEMP cr0); 8008 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8009 ins_encode %{ 8010 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8011 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8012 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8013 noreg, true); 8014 %} 8015 ins_pipe(pipe_class_default); 8016 %} 8017 8018 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8019 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8020 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8021 effect(TEMP_DEF res, TEMP cr0); 8022 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8023 ins_encode %{ 8024 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8025 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8026 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8027 noreg, true); 8028 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8029 __ isync(); 8030 } else { 8031 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8032 __ sync(); 8033 } 8034 %} 8035 ins_pipe(pipe_class_default); 8036 %} 8037 8038 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8039 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8040 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8041 effect(TEMP_DEF res, TEMP cr0); 8042 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8043 ins_encode %{ 8044 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8045 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8046 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8047 noreg, true); 8048 %} 8049 ins_pipe(pipe_class_default); 8050 %} 8051 8052 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8053 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8054 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8055 effect(TEMP_DEF res, TEMP cr0); 8056 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8057 ins_encode %{ 8058 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8059 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8060 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8061 noreg, true); 8062 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8063 __ isync(); 8064 } else { 8065 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8066 __ sync(); 8067 } 8068 %} 8069 ins_pipe(pipe_class_default); 8070 %} 8071 8072 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8073 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8074 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8075 effect(TEMP_DEF res, TEMP cr0); 8076 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8077 ins_encode %{ 8078 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8079 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8080 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8081 noreg, NULL, true); 8082 %} 8083 ins_pipe(pipe_class_default); 8084 %} 8085 8086 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8087 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8088 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8089 effect(TEMP_DEF res, TEMP cr0); 8090 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8091 ins_encode %{ 8092 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8093 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8094 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8095 noreg, NULL, true); 8096 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8097 __ isync(); 8098 } else { 8099 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8100 __ sync(); 8101 } 8102 %} 8103 ins_pipe(pipe_class_default); 8104 %} 8105 8106 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8107 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8108 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) 8109 && n->as_LoadStore()->barrier_data() == 0); 8110 effect(TEMP_DEF res, TEMP cr0); 8111 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8112 ins_encode %{ 8113 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8114 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8115 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8116 noreg, NULL, true); 8117 %} 8118 ins_pipe(pipe_class_default); 8119 %} 8120 8121 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8122 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8123 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) 8124 && n->as_LoadStore()->barrier_data() == 0); 8125 effect(TEMP_DEF res, TEMP cr0); 8126 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 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 // Special RMW 8143 8144 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8145 match(Set res (GetAndAddB mem_ptr src)); 8146 predicate(VM_Version::has_lqarx()); 8147 effect(TEMP_DEF res, TEMP cr0); 8148 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8149 ins_encode %{ 8150 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8151 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8152 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8153 __ isync(); 8154 } else { 8155 __ sync(); 8156 } 8157 %} 8158 ins_pipe(pipe_class_default); 8159 %} 8160 8161 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8162 match(Set res (GetAndAddB mem_ptr src)); 8163 predicate(!VM_Version::has_lqarx()); 8164 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8165 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8166 ins_encode %{ 8167 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8168 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8169 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8170 __ isync(); 8171 } else { 8172 __ sync(); 8173 } 8174 %} 8175 ins_pipe(pipe_class_default); 8176 %} 8177 8178 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8179 match(Set res (GetAndAddS mem_ptr src)); 8180 predicate(VM_Version::has_lqarx()); 8181 effect(TEMP_DEF res, TEMP cr0); 8182 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8183 ins_encode %{ 8184 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8185 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8186 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8187 __ isync(); 8188 } else { 8189 __ sync(); 8190 } 8191 %} 8192 ins_pipe(pipe_class_default); 8193 %} 8194 8195 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8196 match(Set res (GetAndAddS mem_ptr src)); 8197 predicate(!VM_Version::has_lqarx()); 8198 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8199 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8200 ins_encode %{ 8201 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8202 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8203 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8204 __ isync(); 8205 } else { 8206 __ sync(); 8207 } 8208 %} 8209 ins_pipe(pipe_class_default); 8210 %} 8211 8212 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8213 match(Set res (GetAndAddI mem_ptr src)); 8214 effect(TEMP_DEF res, TEMP cr0); 8215 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8216 ins_encode %{ 8217 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8218 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8219 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8220 __ isync(); 8221 } else { 8222 __ sync(); 8223 } 8224 %} 8225 ins_pipe(pipe_class_default); 8226 %} 8227 8228 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8229 match(Set res (GetAndAddL mem_ptr src)); 8230 effect(TEMP_DEF res, TEMP cr0); 8231 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8232 ins_encode %{ 8233 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8234 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8235 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8236 __ isync(); 8237 } else { 8238 __ sync(); 8239 } 8240 %} 8241 ins_pipe(pipe_class_default); 8242 %} 8243 8244 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8245 match(Set res (GetAndSetB mem_ptr src)); 8246 predicate(VM_Version::has_lqarx()); 8247 effect(TEMP_DEF res, TEMP cr0); 8248 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8249 ins_encode %{ 8250 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8251 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8252 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8253 __ isync(); 8254 } else { 8255 __ sync(); 8256 } 8257 %} 8258 ins_pipe(pipe_class_default); 8259 %} 8260 8261 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8262 match(Set res (GetAndSetB mem_ptr src)); 8263 predicate(!VM_Version::has_lqarx()); 8264 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8265 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8266 ins_encode %{ 8267 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8268 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8269 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8270 __ isync(); 8271 } else { 8272 __ sync(); 8273 } 8274 %} 8275 ins_pipe(pipe_class_default); 8276 %} 8277 8278 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8279 match(Set res (GetAndSetS mem_ptr src)); 8280 predicate(VM_Version::has_lqarx()); 8281 effect(TEMP_DEF res, TEMP cr0); 8282 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8283 ins_encode %{ 8284 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8285 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8286 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8287 __ isync(); 8288 } else { 8289 __ sync(); 8290 } 8291 %} 8292 ins_pipe(pipe_class_default); 8293 %} 8294 8295 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8296 match(Set res (GetAndSetS mem_ptr src)); 8297 predicate(!VM_Version::has_lqarx()); 8298 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8299 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8300 ins_encode %{ 8301 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8302 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8303 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8304 __ isync(); 8305 } else { 8306 __ sync(); 8307 } 8308 %} 8309 ins_pipe(pipe_class_default); 8310 %} 8311 8312 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8313 match(Set res (GetAndSetI mem_ptr src)); 8314 effect(TEMP_DEF res, TEMP cr0); 8315 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8316 ins_encode %{ 8317 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8318 MacroAssembler::cmpxchgx_hint_atomic_update()); 8319 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8320 __ isync(); 8321 } else { 8322 __ sync(); 8323 } 8324 %} 8325 ins_pipe(pipe_class_default); 8326 %} 8327 8328 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8329 match(Set res (GetAndSetL mem_ptr src)); 8330 effect(TEMP_DEF res, TEMP cr0); 8331 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8332 ins_encode %{ 8333 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8334 MacroAssembler::cmpxchgx_hint_atomic_update()); 8335 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8336 __ isync(); 8337 } else { 8338 __ sync(); 8339 } 8340 %} 8341 ins_pipe(pipe_class_default); 8342 %} 8343 8344 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8345 match(Set res (GetAndSetP mem_ptr src)); 8346 predicate(n->as_LoadStore()->barrier_data() == 0); 8347 effect(TEMP_DEF res, TEMP cr0); 8348 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8349 ins_encode %{ 8350 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8351 MacroAssembler::cmpxchgx_hint_atomic_update()); 8352 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8353 __ isync(); 8354 } else { 8355 __ sync(); 8356 } 8357 %} 8358 ins_pipe(pipe_class_default); 8359 %} 8360 8361 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8362 match(Set res (GetAndSetN mem_ptr src)); 8363 effect(TEMP_DEF res, TEMP cr0); 8364 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8365 ins_encode %{ 8366 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8367 MacroAssembler::cmpxchgx_hint_atomic_update()); 8368 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8369 __ isync(); 8370 } else { 8371 __ sync(); 8372 } 8373 %} 8374 ins_pipe(pipe_class_default); 8375 %} 8376 8377 //----------Arithmetic Instructions-------------------------------------------- 8378 // Addition Instructions 8379 8380 // Register Addition 8381 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8382 match(Set dst (AddI src1 src2)); 8383 format %{ "ADD $dst, $src1, $src2" %} 8384 size(4); 8385 ins_encode %{ 8386 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8387 %} 8388 ins_pipe(pipe_class_default); 8389 %} 8390 8391 // Expand does not work with above instruct. (??) 8392 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8393 // no match-rule 8394 effect(DEF dst, USE src1, USE src2); 8395 format %{ "ADD $dst, $src1, $src2" %} 8396 size(4); 8397 ins_encode %{ 8398 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8399 %} 8400 ins_pipe(pipe_class_default); 8401 %} 8402 8403 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8404 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8405 ins_cost(DEFAULT_COST*3); 8406 8407 expand %{ 8408 // FIXME: we should do this in the ideal world. 8409 iRegIdst tmp1; 8410 iRegIdst tmp2; 8411 addI_reg_reg(tmp1, src1, src2); 8412 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8413 addI_reg_reg(dst, tmp1, tmp2); 8414 %} 8415 %} 8416 8417 // Immediate Addition 8418 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8419 match(Set dst (AddI src1 src2)); 8420 format %{ "ADDI $dst, $src1, $src2" %} 8421 size(4); 8422 ins_encode %{ 8423 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8424 %} 8425 ins_pipe(pipe_class_default); 8426 %} 8427 8428 // Immediate Addition with 16-bit shifted operand 8429 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8430 match(Set dst (AddI src1 src2)); 8431 format %{ "ADDIS $dst, $src1, $src2" %} 8432 size(4); 8433 ins_encode %{ 8434 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8435 %} 8436 ins_pipe(pipe_class_default); 8437 %} 8438 8439 // Immediate Addition using prefixed addi 8440 instruct addI_reg_imm32(iRegIdst dst, iRegIsrc src1, immI32 src2) %{ 8441 match(Set dst (AddI src1 src2)); 8442 predicate(PowerArchitecturePPC64 >= 10); 8443 ins_cost(DEFAULT_COST+1); 8444 format %{ "PADDI $dst, $src1, $src2" %} 8445 size(8); 8446 ins_encode %{ 8447 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 8448 __ paddi($dst$$Register, $src1$$Register, $src2$$constant); 8449 %} 8450 ins_pipe(pipe_class_default); 8451 ins_alignment(2); 8452 %} 8453 8454 // Long Addition 8455 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8456 match(Set dst (AddL src1 src2)); 8457 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8458 size(4); 8459 ins_encode %{ 8460 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8461 %} 8462 ins_pipe(pipe_class_default); 8463 %} 8464 8465 // Expand does not work with above instruct. (??) 8466 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8467 // no match-rule 8468 effect(DEF dst, USE src1, USE src2); 8469 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8470 size(4); 8471 ins_encode %{ 8472 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8473 %} 8474 ins_pipe(pipe_class_default); 8475 %} 8476 8477 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8478 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8479 ins_cost(DEFAULT_COST*3); 8480 8481 expand %{ 8482 // FIXME: we should do this in the ideal world. 8483 iRegLdst tmp1; 8484 iRegLdst tmp2; 8485 addL_reg_reg(tmp1, src1, src2); 8486 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8487 addL_reg_reg(dst, tmp1, tmp2); 8488 %} 8489 %} 8490 8491 // AddL + ConvL2I. 8492 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8493 match(Set dst (ConvL2I (AddL src1 src2))); 8494 8495 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8496 size(4); 8497 ins_encode %{ 8498 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8499 %} 8500 ins_pipe(pipe_class_default); 8501 %} 8502 8503 // No constant pool entries required. 8504 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8505 match(Set dst (AddL src1 src2)); 8506 8507 format %{ "ADDI $dst, $src1, $src2" %} 8508 size(4); 8509 ins_encode %{ 8510 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8511 %} 8512 ins_pipe(pipe_class_default); 8513 %} 8514 8515 // Long Immediate Addition with 16-bit shifted operand. 8516 // No constant pool entries required. 8517 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8518 match(Set dst (AddL src1 src2)); 8519 8520 format %{ "ADDIS $dst, $src1, $src2" %} 8521 size(4); 8522 ins_encode %{ 8523 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8524 %} 8525 ins_pipe(pipe_class_default); 8526 %} 8527 8528 // Long Immediate Addition using prefixed addi 8529 // No constant pool entries required. 8530 instruct addL_reg_imm34(iRegLdst dst, iRegLsrc src1, immL34 src2) %{ 8531 match(Set dst (AddL src1 src2)); 8532 predicate(PowerArchitecturePPC64 >= 10); 8533 ins_cost(DEFAULT_COST+1); 8534 8535 format %{ "PADDI $dst, $src1, $src2" %} 8536 size(8); 8537 ins_encode %{ 8538 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 8539 __ paddi($dst$$Register, $src1$$Register, $src2$$constant); 8540 %} 8541 ins_pipe(pipe_class_default); 8542 ins_alignment(2); 8543 %} 8544 8545 // Pointer Register Addition 8546 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8547 match(Set dst (AddP src1 src2)); 8548 format %{ "ADD $dst, $src1, $src2" %} 8549 size(4); 8550 ins_encode %{ 8551 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8552 %} 8553 ins_pipe(pipe_class_default); 8554 %} 8555 8556 // Pointer Immediate Addition 8557 // No constant pool entries required. 8558 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8559 match(Set dst (AddP src1 src2)); 8560 8561 format %{ "ADDI $dst, $src1, $src2" %} 8562 size(4); 8563 ins_encode %{ 8564 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8565 %} 8566 ins_pipe(pipe_class_default); 8567 %} 8568 8569 // Pointer Immediate Addition with 16-bit shifted operand. 8570 // No constant pool entries required. 8571 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8572 match(Set dst (AddP src1 src2)); 8573 8574 format %{ "ADDIS $dst, $src1, $src2" %} 8575 size(4); 8576 ins_encode %{ 8577 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8578 %} 8579 ins_pipe(pipe_class_default); 8580 %} 8581 8582 // Pointer Immediate Addition using prefixed addi 8583 // No constant pool entries required. 8584 instruct addP_reg_imm34(iRegPdst dst, iRegP_N2P src1, immL34 src2) %{ 8585 match(Set dst (AddP src1 src2)); 8586 predicate(PowerArchitecturePPC64 >= 10); 8587 ins_cost(DEFAULT_COST+1); 8588 8589 format %{ "PADDI $dst, $src1, $src2" %} 8590 size(8); 8591 ins_encode %{ 8592 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 8593 __ paddi($dst$$Register, $src1$$Register, $src2$$constant); 8594 %} 8595 ins_pipe(pipe_class_default); 8596 ins_alignment(2); 8597 %} 8598 8599 //--------------------- 8600 // Subtraction Instructions 8601 8602 // Register Subtraction 8603 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8604 match(Set dst (SubI src1 src2)); 8605 format %{ "SUBF $dst, $src2, $src1" %} 8606 size(4); 8607 ins_encode %{ 8608 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8609 %} 8610 ins_pipe(pipe_class_default); 8611 %} 8612 8613 // Immediate Subtraction 8614 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 8615 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 8616 8617 // SubI from constant (using subfic). 8618 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 8619 match(Set dst (SubI src1 src2)); 8620 format %{ "SUBI $dst, $src1, $src2" %} 8621 8622 size(4); 8623 ins_encode %{ 8624 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 8625 %} 8626 ins_pipe(pipe_class_default); 8627 %} 8628 8629 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 8630 // positive integers and 0xF...F for negative ones. 8631 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 8632 // no match-rule, false predicate 8633 effect(DEF dst, USE src); 8634 predicate(false); 8635 8636 format %{ "SRAWI $dst, $src, #31" %} 8637 size(4); 8638 ins_encode %{ 8639 __ srawi($dst$$Register, $src$$Register, 0x1f); 8640 %} 8641 ins_pipe(pipe_class_default); 8642 %} 8643 8644 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 8645 match(Set dst (AbsI src)); 8646 ins_cost(DEFAULT_COST*3); 8647 8648 expand %{ 8649 iRegIdst tmp1; 8650 iRegIdst tmp2; 8651 signmask32I_regI(tmp1, src); 8652 xorI_reg_reg(tmp2, tmp1, src); 8653 subI_reg_reg(dst, tmp2, tmp1); 8654 %} 8655 %} 8656 8657 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 8658 match(Set dst (SubI zero src2)); 8659 format %{ "NEG $dst, $src2" %} 8660 size(4); 8661 ins_encode %{ 8662 __ neg($dst$$Register, $src2$$Register); 8663 %} 8664 ins_pipe(pipe_class_default); 8665 %} 8666 8667 // Long subtraction 8668 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8669 match(Set dst (SubL src1 src2)); 8670 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 8671 size(4); 8672 ins_encode %{ 8673 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8674 %} 8675 ins_pipe(pipe_class_default); 8676 %} 8677 8678 // SubL + convL2I. 8679 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8680 match(Set dst (ConvL2I (SubL src1 src2))); 8681 8682 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 8683 size(4); 8684 ins_encode %{ 8685 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8686 %} 8687 ins_pipe(pipe_class_default); 8688 %} 8689 8690 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8691 // positive longs and 0xF...F for negative ones. 8692 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 8693 // no match-rule, false predicate 8694 effect(DEF dst, USE src); 8695 predicate(false); 8696 8697 format %{ "SRADI $dst, $src, #63" %} 8698 size(4); 8699 ins_encode %{ 8700 __ sradi($dst$$Register, $src$$Register, 0x3f); 8701 %} 8702 ins_pipe(pipe_class_default); 8703 %} 8704 8705 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8706 // positive longs and 0xF...F for negative ones. 8707 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 8708 // no match-rule, false predicate 8709 effect(DEF dst, USE src); 8710 predicate(false); 8711 8712 format %{ "SRADI $dst, $src, #63" %} 8713 size(4); 8714 ins_encode %{ 8715 __ sradi($dst$$Register, $src$$Register, 0x3f); 8716 %} 8717 ins_pipe(pipe_class_default); 8718 %} 8719 8720 instruct absL_reg_Ex(iRegLdst dst, iRegLsrc src) %{ 8721 match(Set dst (AbsL src)); 8722 ins_cost(DEFAULT_COST*3); 8723 8724 expand %{ 8725 iRegLdst tmp1; 8726 iRegLdst tmp2; 8727 signmask64L_regL(tmp1, src); 8728 xorL_reg_reg(tmp2, tmp1, src); 8729 subL_reg_reg(dst, tmp2, tmp1); 8730 %} 8731 %} 8732 8733 // Long negation 8734 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 8735 match(Set dst (SubL zero src2)); 8736 format %{ "NEG $dst, $src2 \t// long" %} 8737 size(4); 8738 ins_encode %{ 8739 __ neg($dst$$Register, $src2$$Register); 8740 %} 8741 ins_pipe(pipe_class_default); 8742 %} 8743 8744 // NegL + ConvL2I. 8745 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 8746 match(Set dst (ConvL2I (SubL zero src2))); 8747 8748 format %{ "NEG $dst, $src2 \t// long + l2i" %} 8749 size(4); 8750 ins_encode %{ 8751 __ neg($dst$$Register, $src2$$Register); 8752 %} 8753 ins_pipe(pipe_class_default); 8754 %} 8755 8756 // Multiplication Instructions 8757 // Integer Multiplication 8758 8759 // Register Multiplication 8760 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8761 match(Set dst (MulI src1 src2)); 8762 ins_cost(DEFAULT_COST); 8763 8764 format %{ "MULLW $dst, $src1, $src2" %} 8765 size(4); 8766 ins_encode %{ 8767 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 8768 %} 8769 ins_pipe(pipe_class_default); 8770 %} 8771 8772 // Immediate Multiplication 8773 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8774 match(Set dst (MulI src1 src2)); 8775 ins_cost(DEFAULT_COST); 8776 8777 format %{ "MULLI $dst, $src1, $src2" %} 8778 size(4); 8779 ins_encode %{ 8780 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8781 %} 8782 ins_pipe(pipe_class_default); 8783 %} 8784 8785 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8786 match(Set dst (MulL src1 src2)); 8787 ins_cost(DEFAULT_COST); 8788 8789 format %{ "MULLD $dst $src1, $src2 \t// long" %} 8790 size(4); 8791 ins_encode %{ 8792 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 8793 %} 8794 ins_pipe(pipe_class_default); 8795 %} 8796 8797 // Multiply high for optimized long division by constant. 8798 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8799 match(Set dst (MulHiL src1 src2)); 8800 ins_cost(DEFAULT_COST); 8801 8802 format %{ "MULHD $dst $src1, $src2 \t// long" %} 8803 size(4); 8804 ins_encode %{ 8805 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 8806 %} 8807 ins_pipe(pipe_class_default); 8808 %} 8809 8810 // Immediate Multiplication 8811 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8812 match(Set dst (MulL src1 src2)); 8813 ins_cost(DEFAULT_COST); 8814 8815 format %{ "MULLI $dst, $src1, $src2" %} 8816 size(4); 8817 ins_encode %{ 8818 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8819 %} 8820 ins_pipe(pipe_class_default); 8821 %} 8822 8823 // Integer Division with Immediate -1: Negate. 8824 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 8825 match(Set dst (DivI src1 src2)); 8826 ins_cost(DEFAULT_COST); 8827 8828 format %{ "NEG $dst, $src1 \t// /-1" %} 8829 size(4); 8830 ins_encode %{ 8831 __ neg($dst$$Register, $src1$$Register); 8832 %} 8833 ins_pipe(pipe_class_default); 8834 %} 8835 8836 // Integer Division with constant, but not -1. 8837 // We should be able to improve this by checking the type of src2. 8838 // It might well be that src2 is known to be positive. 8839 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8840 match(Set dst (DivI src1 src2)); 8841 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 8842 ins_cost(2*DEFAULT_COST); 8843 8844 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 8845 size(4); 8846 ins_encode %{ 8847 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 8848 %} 8849 ins_pipe(pipe_class_default); 8850 %} 8851 8852 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 8853 effect(USE_DEF dst, USE src1, USE crx); 8854 predicate(false); 8855 8856 ins_variable_size_depending_on_alignment(true); 8857 8858 format %{ "CMOVE $dst, neg($src1), $crx" %} 8859 // Worst case is branch + move + stop, no stop without scheduler. 8860 size(8); 8861 ins_encode %{ 8862 Label done; 8863 __ bne($crx$$CondRegister, done); 8864 __ neg($dst$$Register, $src1$$Register); 8865 __ bind(done); 8866 %} 8867 ins_pipe(pipe_class_default); 8868 %} 8869 8870 // Integer Division with Registers not containing constants. 8871 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8872 match(Set dst (DivI src1 src2)); 8873 ins_cost(10*DEFAULT_COST); 8874 8875 expand %{ 8876 immI16 imm %{ (int)-1 %} 8877 flagsReg tmp1; 8878 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8879 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8880 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8881 %} 8882 %} 8883 8884 // Long Division with Immediate -1: Negate. 8885 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 8886 match(Set dst (DivL src1 src2)); 8887 ins_cost(DEFAULT_COST); 8888 8889 format %{ "NEG $dst, $src1 \t// /-1, long" %} 8890 size(4); 8891 ins_encode %{ 8892 __ neg($dst$$Register, $src1$$Register); 8893 %} 8894 ins_pipe(pipe_class_default); 8895 %} 8896 8897 // Long Division with constant, but not -1. 8898 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8899 match(Set dst (DivL src1 src2)); 8900 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 8901 ins_cost(2*DEFAULT_COST); 8902 8903 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 8904 size(4); 8905 ins_encode %{ 8906 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 8907 %} 8908 ins_pipe(pipe_class_default); 8909 %} 8910 8911 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 8912 effect(USE_DEF dst, USE src1, USE crx); 8913 predicate(false); 8914 8915 ins_variable_size_depending_on_alignment(true); 8916 8917 format %{ "CMOVE $dst, neg($src1), $crx" %} 8918 // Worst case is branch + move + stop, no stop without scheduler. 8919 size(8); 8920 ins_encode %{ 8921 Label done; 8922 __ bne($crx$$CondRegister, done); 8923 __ neg($dst$$Register, $src1$$Register); 8924 __ bind(done); 8925 %} 8926 ins_pipe(pipe_class_default); 8927 %} 8928 8929 // Long Division with Registers not containing constants. 8930 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8931 match(Set dst (DivL src1 src2)); 8932 ins_cost(10*DEFAULT_COST); 8933 8934 expand %{ 8935 immL16 imm %{ (int)-1 %} 8936 flagsReg tmp1; 8937 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8938 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8939 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8940 %} 8941 %} 8942 8943 // Integer Remainder with registers. 8944 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8945 match(Set dst (ModI src1 src2)); 8946 ins_cost(10*DEFAULT_COST); 8947 8948 expand %{ 8949 immI16 imm %{ (int)-1 %} 8950 flagsReg tmp1; 8951 iRegIdst tmp2; 8952 iRegIdst tmp3; 8953 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8954 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8955 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8956 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8957 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8958 %} 8959 %} 8960 8961 // Long Remainder with registers 8962 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8963 match(Set dst (ModL src1 src2)); 8964 ins_cost(10*DEFAULT_COST); 8965 8966 expand %{ 8967 immL16 imm %{ (int)-1 %} 8968 flagsReg tmp1; 8969 iRegLdst tmp2; 8970 iRegLdst tmp3; 8971 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8972 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8973 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8974 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8975 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8976 %} 8977 %} 8978 8979 instruct udivI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8980 match(Set dst (UDivI src1 src2)); 8981 format %{ "DIVWU $dst, $src1, $src2" %} 8982 size(4); 8983 ins_encode %{ 8984 __ divwu($dst$$Register, $src1$$Register, $src2$$Register); 8985 %} 8986 ins_pipe(pipe_class_default); 8987 %} 8988 8989 instruct umodI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8990 match(Set dst (UModI src1 src2)); 8991 expand %{ 8992 iRegIdst tmp1; 8993 iRegIdst tmp2; 8994 udivI_reg_reg(tmp1, src1, src2); 8995 // Compute lower 32 bit result using signed instructions as suggested by ISA. 8996 // Upper 32 bit will contain garbage. 8997 mulI_reg_reg(tmp2, src2, tmp1); 8998 subI_reg_reg(dst, src1, tmp2); 8999 %} 9000 %} 9001 9002 instruct udivL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9003 match(Set dst (UDivL src1 src2)); 9004 format %{ "DIVDU $dst, $src1, $src2" %} 9005 size(4); 9006 ins_encode %{ 9007 __ divdu($dst$$Register, $src1$$Register, $src2$$Register); 9008 %} 9009 ins_pipe(pipe_class_default); 9010 %} 9011 9012 instruct umodL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9013 match(Set dst (UModL src1 src2)); 9014 expand %{ 9015 iRegLdst tmp1; 9016 iRegLdst tmp2; 9017 udivL_reg_reg(tmp1, src1, src2); 9018 mulL_reg_reg(tmp2, src2, tmp1); 9019 subL_reg_reg(dst, src1, tmp2); 9020 %} 9021 %} 9022 9023 // Integer Shift Instructions 9024 9025 // Register Shift Left 9026 9027 // Clear all but the lowest #mask bits. 9028 // Used to normalize shift amounts in registers. 9029 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9030 // no match-rule, false predicate 9031 effect(DEF dst, USE src, USE mask); 9032 predicate(false); 9033 9034 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9035 size(4); 9036 ins_encode %{ 9037 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9038 %} 9039 ins_pipe(pipe_class_default); 9040 %} 9041 9042 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9043 // no match-rule, false predicate 9044 effect(DEF dst, USE src1, USE src2); 9045 predicate(false); 9046 9047 format %{ "SLW $dst, $src1, $src2" %} 9048 size(4); 9049 ins_encode %{ 9050 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9051 %} 9052 ins_pipe(pipe_class_default); 9053 %} 9054 9055 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9056 match(Set dst (LShiftI src1 src2)); 9057 ins_cost(DEFAULT_COST*2); 9058 expand %{ 9059 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9060 iRegIdst tmpI; 9061 maskI_reg_imm(tmpI, src2, mask); 9062 lShiftI_reg_reg(dst, src1, tmpI); 9063 %} 9064 %} 9065 9066 // Register Shift Left Immediate 9067 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9068 match(Set dst (LShiftI src1 src2)); 9069 9070 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9071 size(4); 9072 ins_encode %{ 9073 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9074 %} 9075 ins_pipe(pipe_class_default); 9076 %} 9077 9078 // AndI with negpow2-constant + LShiftI 9079 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9080 match(Set dst (LShiftI (AndI src1 src2) src3)); 9081 predicate(UseRotateAndMaskInstructionsPPC64); 9082 9083 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9084 size(4); 9085 ins_encode %{ 9086 long src3 = $src3$$constant; 9087 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant); 9088 if (maskbits >= 32) { 9089 __ li($dst$$Register, 0); // addi 9090 } else { 9091 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9092 } 9093 %} 9094 ins_pipe(pipe_class_default); 9095 %} 9096 9097 // RShiftI + AndI with negpow2-constant + LShiftI 9098 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9099 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9100 predicate(UseRotateAndMaskInstructionsPPC64); 9101 9102 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9103 size(4); 9104 ins_encode %{ 9105 long src3 = $src3$$constant; 9106 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant); 9107 if (maskbits >= 32) { 9108 __ li($dst$$Register, 0); // addi 9109 } else { 9110 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9111 } 9112 %} 9113 ins_pipe(pipe_class_default); 9114 %} 9115 9116 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9117 // no match-rule, false predicate 9118 effect(DEF dst, USE src1, USE src2); 9119 predicate(false); 9120 9121 format %{ "SLD $dst, $src1, $src2" %} 9122 size(4); 9123 ins_encode %{ 9124 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9125 %} 9126 ins_pipe(pipe_class_default); 9127 %} 9128 9129 // Register Shift Left 9130 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9131 match(Set dst (LShiftL src1 src2)); 9132 ins_cost(DEFAULT_COST*2); 9133 expand %{ 9134 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9135 iRegIdst tmpI; 9136 maskI_reg_imm(tmpI, src2, mask); 9137 lShiftL_regL_regI(dst, src1, tmpI); 9138 %} 9139 %} 9140 9141 // Register Shift Left Immediate 9142 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9143 match(Set dst (LShiftL src1 src2)); 9144 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9145 size(4); 9146 ins_encode %{ 9147 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9148 %} 9149 ins_pipe(pipe_class_default); 9150 %} 9151 9152 // If we shift more than 32 bits, we need not convert I2L. 9153 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9154 match(Set dst (LShiftL (ConvI2L src1) src2)); 9155 ins_cost(DEFAULT_COST); 9156 9157 size(4); 9158 format %{ "SLDI $dst, i2l($src1), $src2" %} 9159 ins_encode %{ 9160 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9161 %} 9162 ins_pipe(pipe_class_default); 9163 %} 9164 9165 // Shift a postivie int to the left. 9166 // Clrlsldi clears the upper 32 bits and shifts. 9167 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9168 match(Set dst (LShiftL (ConvI2L src1) src2)); 9169 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9170 9171 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9172 size(4); 9173 ins_encode %{ 9174 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9175 %} 9176 ins_pipe(pipe_class_default); 9177 %} 9178 9179 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9180 // no match-rule, false predicate 9181 effect(DEF dst, USE src1, USE src2); 9182 predicate(false); 9183 9184 format %{ "SRAW $dst, $src1, $src2" %} 9185 size(4); 9186 ins_encode %{ 9187 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9188 %} 9189 ins_pipe(pipe_class_default); 9190 %} 9191 9192 // Register Arithmetic Shift Right 9193 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9194 match(Set dst (RShiftI src1 src2)); 9195 ins_cost(DEFAULT_COST*2); 9196 expand %{ 9197 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9198 iRegIdst tmpI; 9199 maskI_reg_imm(tmpI, src2, mask); 9200 arShiftI_reg_reg(dst, src1, tmpI); 9201 %} 9202 %} 9203 9204 // Register Arithmetic Shift Right Immediate 9205 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9206 match(Set dst (RShiftI src1 src2)); 9207 9208 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9209 size(4); 9210 ins_encode %{ 9211 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9212 %} 9213 ins_pipe(pipe_class_default); 9214 %} 9215 9216 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9217 // no match-rule, false predicate 9218 effect(DEF dst, USE src1, USE src2); 9219 predicate(false); 9220 9221 format %{ "SRAD $dst, $src1, $src2" %} 9222 size(4); 9223 ins_encode %{ 9224 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9225 %} 9226 ins_pipe(pipe_class_default); 9227 %} 9228 9229 // Register Shift Right Arithmetic Long 9230 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9231 match(Set dst (RShiftL src1 src2)); 9232 ins_cost(DEFAULT_COST*2); 9233 9234 expand %{ 9235 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9236 iRegIdst tmpI; 9237 maskI_reg_imm(tmpI, src2, mask); 9238 arShiftL_regL_regI(dst, src1, tmpI); 9239 %} 9240 %} 9241 9242 // Register Shift Right Immediate 9243 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9244 match(Set dst (RShiftL src1 src2)); 9245 9246 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9247 size(4); 9248 ins_encode %{ 9249 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9250 %} 9251 ins_pipe(pipe_class_default); 9252 %} 9253 9254 // RShiftL + ConvL2I 9255 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9256 match(Set dst (ConvL2I (RShiftL src1 src2))); 9257 9258 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9259 size(4); 9260 ins_encode %{ 9261 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9262 %} 9263 ins_pipe(pipe_class_default); 9264 %} 9265 9266 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9267 // no match-rule, false predicate 9268 effect(DEF dst, USE src1, USE src2); 9269 predicate(false); 9270 9271 format %{ "SRW $dst, $src1, $src2" %} 9272 size(4); 9273 ins_encode %{ 9274 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9275 %} 9276 ins_pipe(pipe_class_default); 9277 %} 9278 9279 // Register Shift Right 9280 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9281 match(Set dst (URShiftI src1 src2)); 9282 ins_cost(DEFAULT_COST*2); 9283 9284 expand %{ 9285 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9286 iRegIdst tmpI; 9287 maskI_reg_imm(tmpI, src2, mask); 9288 urShiftI_reg_reg(dst, src1, tmpI); 9289 %} 9290 %} 9291 9292 // Register Shift Right Immediate 9293 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9294 match(Set dst (URShiftI src1 src2)); 9295 9296 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9297 size(4); 9298 ins_encode %{ 9299 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9300 %} 9301 ins_pipe(pipe_class_default); 9302 %} 9303 9304 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9305 // no match-rule, false predicate 9306 effect(DEF dst, USE src1, USE src2); 9307 predicate(false); 9308 9309 format %{ "SRD $dst, $src1, $src2" %} 9310 size(4); 9311 ins_encode %{ 9312 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9313 %} 9314 ins_pipe(pipe_class_default); 9315 %} 9316 9317 // Register Shift Right 9318 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9319 match(Set dst (URShiftL src1 src2)); 9320 ins_cost(DEFAULT_COST*2); 9321 9322 expand %{ 9323 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9324 iRegIdst tmpI; 9325 maskI_reg_imm(tmpI, src2, mask); 9326 urShiftL_regL_regI(dst, src1, tmpI); 9327 %} 9328 %} 9329 9330 // Register Shift Right Immediate 9331 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9332 match(Set dst (URShiftL src1 src2)); 9333 9334 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9335 size(4); 9336 ins_encode %{ 9337 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9338 %} 9339 ins_pipe(pipe_class_default); 9340 %} 9341 9342 // URShiftL + ConvL2I. 9343 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9344 match(Set dst (ConvL2I (URShiftL src1 src2))); 9345 9346 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9347 size(4); 9348 ins_encode %{ 9349 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9350 %} 9351 ins_pipe(pipe_class_default); 9352 %} 9353 9354 // Register Shift Right Immediate with a CastP2X 9355 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9356 match(Set dst (URShiftL (CastP2X src1) src2)); 9357 9358 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9359 size(4); 9360 ins_encode %{ 9361 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9362 %} 9363 ins_pipe(pipe_class_default); 9364 %} 9365 9366 // Bitfield Extract: URShiftI + AndI 9367 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9368 match(Set dst (AndI (URShiftI src1 src2) src3)); 9369 9370 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9371 size(4); 9372 ins_encode %{ 9373 int rshift = ($src2$$constant) & 0x1f; 9374 int length = log2i_exact((juint)$src3$$constant + 1u); 9375 if (rshift + length > 32) { 9376 // if necessary, adjust mask to omit rotated bits. 9377 length = 32 - rshift; 9378 } 9379 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9380 %} 9381 ins_pipe(pipe_class_default); 9382 %} 9383 9384 // Bitfield Extract: URShiftL + AndL 9385 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9386 match(Set dst (AndL (URShiftL src1 src2) src3)); 9387 9388 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9389 size(4); 9390 ins_encode %{ 9391 int rshift = ($src2$$constant) & 0x3f; 9392 int length = log2i_exact((julong)$src3$$constant + 1ull); 9393 if (rshift + length > 64) { 9394 // if necessary, adjust mask to omit rotated bits. 9395 length = 64 - rshift; 9396 } 9397 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9398 %} 9399 ins_pipe(pipe_class_default); 9400 %} 9401 9402 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9403 match(Set dst (ConvL2I (ConvI2L src))); 9404 9405 format %{ "EXTSW $dst, $src \t// int->int" %} 9406 size(4); 9407 ins_encode %{ 9408 __ extsw($dst$$Register, $src$$Register); 9409 %} 9410 ins_pipe(pipe_class_default); 9411 %} 9412 9413 //----------Rotate Instructions------------------------------------------------ 9414 9415 // Rotate Left by 8-bit immediate 9416 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9417 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9418 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9419 9420 format %{ "ROTLWI $dst, $src, $lshift" %} 9421 size(4); 9422 ins_encode %{ 9423 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9424 %} 9425 ins_pipe(pipe_class_default); 9426 %} 9427 9428 // Rotate Right by 8-bit immediate 9429 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9430 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9431 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9432 9433 format %{ "ROTRWI $dst, $rshift" %} 9434 size(4); 9435 ins_encode %{ 9436 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9437 %} 9438 ins_pipe(pipe_class_default); 9439 %} 9440 9441 //----------Floating Point Arithmetic Instructions----------------------------- 9442 9443 // Add float single precision 9444 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9445 match(Set dst (AddF src1 src2)); 9446 9447 format %{ "FADDS $dst, $src1, $src2" %} 9448 size(4); 9449 ins_encode %{ 9450 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9451 %} 9452 ins_pipe(pipe_class_default); 9453 %} 9454 9455 // Add float double precision 9456 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9457 match(Set dst (AddD src1 src2)); 9458 9459 format %{ "FADD $dst, $src1, $src2" %} 9460 size(4); 9461 ins_encode %{ 9462 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9463 %} 9464 ins_pipe(pipe_class_default); 9465 %} 9466 9467 // Sub float single precision 9468 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9469 match(Set dst (SubF src1 src2)); 9470 9471 format %{ "FSUBS $dst, $src1, $src2" %} 9472 size(4); 9473 ins_encode %{ 9474 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9475 %} 9476 ins_pipe(pipe_class_default); 9477 %} 9478 9479 // Sub float double precision 9480 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9481 match(Set dst (SubD src1 src2)); 9482 format %{ "FSUB $dst, $src1, $src2" %} 9483 size(4); 9484 ins_encode %{ 9485 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9486 %} 9487 ins_pipe(pipe_class_default); 9488 %} 9489 9490 // Mul float single precision 9491 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9492 match(Set dst (MulF src1 src2)); 9493 format %{ "FMULS $dst, $src1, $src2" %} 9494 size(4); 9495 ins_encode %{ 9496 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9497 %} 9498 ins_pipe(pipe_class_default); 9499 %} 9500 9501 // Mul float double precision 9502 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9503 match(Set dst (MulD src1 src2)); 9504 format %{ "FMUL $dst, $src1, $src2" %} 9505 size(4); 9506 ins_encode %{ 9507 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9508 %} 9509 ins_pipe(pipe_class_default); 9510 %} 9511 9512 // Div float single precision 9513 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9514 match(Set dst (DivF src1 src2)); 9515 format %{ "FDIVS $dst, $src1, $src2" %} 9516 size(4); 9517 ins_encode %{ 9518 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9519 %} 9520 ins_pipe(pipe_class_default); 9521 %} 9522 9523 // Div float double precision 9524 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9525 match(Set dst (DivD src1 src2)); 9526 format %{ "FDIV $dst, $src1, $src2" %} 9527 size(4); 9528 ins_encode %{ 9529 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9530 %} 9531 ins_pipe(pipe_class_default); 9532 %} 9533 9534 // Absolute float single precision 9535 instruct absF_reg(regF dst, regF src) %{ 9536 match(Set dst (AbsF src)); 9537 format %{ "FABS $dst, $src \t// float" %} 9538 size(4); 9539 ins_encode %{ 9540 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9541 %} 9542 ins_pipe(pipe_class_default); 9543 %} 9544 9545 // Absolute float double precision 9546 instruct absD_reg(regD dst, regD src) %{ 9547 match(Set dst (AbsD src)); 9548 format %{ "FABS $dst, $src \t// double" %} 9549 size(4); 9550 ins_encode %{ 9551 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9552 %} 9553 ins_pipe(pipe_class_default); 9554 %} 9555 9556 instruct negF_reg(regF dst, regF src) %{ 9557 match(Set dst (NegF src)); 9558 format %{ "FNEG $dst, $src \t// float" %} 9559 size(4); 9560 ins_encode %{ 9561 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9562 %} 9563 ins_pipe(pipe_class_default); 9564 %} 9565 9566 instruct negD_reg(regD dst, regD src) %{ 9567 match(Set dst (NegD src)); 9568 format %{ "FNEG $dst, $src \t// double" %} 9569 size(4); 9570 ins_encode %{ 9571 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9572 %} 9573 ins_pipe(pipe_class_default); 9574 %} 9575 9576 // AbsF + NegF. 9577 instruct negF_absF_reg(regF dst, regF src) %{ 9578 match(Set dst (NegF (AbsF src))); 9579 format %{ "FNABS $dst, $src \t// float" %} 9580 size(4); 9581 ins_encode %{ 9582 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9583 %} 9584 ins_pipe(pipe_class_default); 9585 %} 9586 9587 // AbsD + NegD. 9588 instruct negD_absD_reg(regD dst, regD src) %{ 9589 match(Set dst (NegD (AbsD src))); 9590 format %{ "FNABS $dst, $src \t// double" %} 9591 size(4); 9592 ins_encode %{ 9593 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9594 %} 9595 ins_pipe(pipe_class_default); 9596 %} 9597 9598 // VM_Version::has_fsqrt() decides if this node will be used. 9599 // Sqrt float double precision 9600 instruct sqrtD_reg(regD dst, regD src) %{ 9601 match(Set dst (SqrtD src)); 9602 format %{ "FSQRT $dst, $src" %} 9603 size(4); 9604 ins_encode %{ 9605 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 9606 %} 9607 ins_pipe(pipe_class_default); 9608 %} 9609 9610 // Single-precision sqrt. 9611 instruct sqrtF_reg(regF dst, regF src) %{ 9612 match(Set dst (SqrtF src)); 9613 predicate(VM_Version::has_fsqrts()); 9614 ins_cost(DEFAULT_COST); 9615 9616 format %{ "FSQRTS $dst, $src" %} 9617 size(4); 9618 ins_encode %{ 9619 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 9620 %} 9621 ins_pipe(pipe_class_default); 9622 %} 9623 9624 instruct roundDouble_nop(regD dst) %{ 9625 match(Set dst (RoundDouble dst)); 9626 ins_cost(0); 9627 9628 format %{ " -- \t// RoundDouble not needed - empty" %} 9629 size(0); 9630 // PPC results are already "rounded" (i.e., normal-format IEEE). 9631 ins_encode( /*empty*/ ); 9632 ins_pipe(pipe_class_default); 9633 %} 9634 9635 instruct roundFloat_nop(regF dst) %{ 9636 match(Set dst (RoundFloat dst)); 9637 ins_cost(0); 9638 9639 format %{ " -- \t// RoundFloat not needed - empty" %} 9640 size(0); 9641 // PPC results are already "rounded" (i.e., normal-format IEEE). 9642 ins_encode( /*empty*/ ); 9643 ins_pipe(pipe_class_default); 9644 %} 9645 9646 9647 // Multiply-Accumulate 9648 // src1 * src2 + src3 9649 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9650 match(Set dst (FmaF src3 (Binary src1 src2))); 9651 9652 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 9653 size(4); 9654 ins_encode %{ 9655 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9656 %} 9657 ins_pipe(pipe_class_default); 9658 %} 9659 9660 // src1 * src2 + src3 9661 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9662 match(Set dst (FmaD src3 (Binary src1 src2))); 9663 9664 format %{ "FMADD $dst, $src1, $src2, $src3" %} 9665 size(4); 9666 ins_encode %{ 9667 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9668 %} 9669 ins_pipe(pipe_class_default); 9670 %} 9671 9672 // -src1 * src2 + src3 = -(src1*src2-src3) 9673 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9674 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 9675 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 9676 9677 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 9678 size(4); 9679 ins_encode %{ 9680 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9681 %} 9682 ins_pipe(pipe_class_default); 9683 %} 9684 9685 // -src1 * src2 + src3 = -(src1*src2-src3) 9686 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9687 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 9688 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 9689 9690 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 9691 size(4); 9692 ins_encode %{ 9693 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9694 %} 9695 ins_pipe(pipe_class_default); 9696 %} 9697 9698 // -src1 * src2 - src3 = -(src1*src2+src3) 9699 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9700 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 9701 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 9702 9703 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 9704 size(4); 9705 ins_encode %{ 9706 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9707 %} 9708 ins_pipe(pipe_class_default); 9709 %} 9710 9711 // -src1 * src2 - src3 = -(src1*src2+src3) 9712 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9713 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 9714 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 9715 9716 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 9717 size(4); 9718 ins_encode %{ 9719 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9720 %} 9721 ins_pipe(pipe_class_default); 9722 %} 9723 9724 // src1 * src2 - src3 9725 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9726 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 9727 9728 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 9729 size(4); 9730 ins_encode %{ 9731 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9732 %} 9733 ins_pipe(pipe_class_default); 9734 %} 9735 9736 // src1 * src2 - src3 9737 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9738 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 9739 9740 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 9741 size(4); 9742 ins_encode %{ 9743 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9744 %} 9745 ins_pipe(pipe_class_default); 9746 %} 9747 9748 9749 //----------Logical Instructions----------------------------------------------- 9750 9751 // And Instructions 9752 9753 // Register And 9754 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9755 match(Set dst (AndI src1 src2)); 9756 format %{ "AND $dst, $src1, $src2" %} 9757 size(4); 9758 ins_encode %{ 9759 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9760 %} 9761 ins_pipe(pipe_class_default); 9762 %} 9763 9764 // Left shifted Immediate And 9765 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 9766 match(Set dst (AndI src1 src2)); 9767 effect(KILL cr0); 9768 format %{ "ANDIS $dst, $src1, $src2.hi" %} 9769 size(4); 9770 ins_encode %{ 9771 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 9772 %} 9773 ins_pipe(pipe_class_default); 9774 %} 9775 9776 // Immediate And 9777 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 9778 match(Set dst (AndI src1 src2)); 9779 effect(KILL cr0); 9780 9781 format %{ "ANDI $dst, $src1, $src2" %} 9782 size(4); 9783 ins_encode %{ 9784 // FIXME: avoid andi_ ? 9785 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9786 %} 9787 ins_pipe(pipe_class_default); 9788 %} 9789 9790 // Immediate And where the immediate is a negative power of 2. 9791 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 9792 match(Set dst (AndI src1 src2)); 9793 format %{ "ANDWI $dst, $src1, $src2" %} 9794 size(4); 9795 ins_encode %{ 9796 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(juint)$src2$$constant)); 9797 %} 9798 ins_pipe(pipe_class_default); 9799 %} 9800 9801 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 9802 match(Set dst (AndI src1 src2)); 9803 format %{ "ANDWI $dst, $src1, $src2" %} 9804 size(4); 9805 ins_encode %{ 9806 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((juint)$src2$$constant + 1u)); 9807 %} 9808 ins_pipe(pipe_class_default); 9809 %} 9810 9811 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 9812 match(Set dst (AndI src1 src2)); 9813 predicate(UseRotateAndMaskInstructionsPPC64); 9814 format %{ "ANDWI $dst, $src1, $src2" %} 9815 size(4); 9816 ins_encode %{ 9817 int bitpos = 31 - log2i_exact((juint)$src2$$constant); 9818 __ rlwinm($dst$$Register, $src1$$Register, 0, bitpos, bitpos); 9819 %} 9820 ins_pipe(pipe_class_default); 9821 %} 9822 9823 // Register And Long 9824 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9825 match(Set dst (AndL src1 src2)); 9826 ins_cost(DEFAULT_COST); 9827 9828 format %{ "AND $dst, $src1, $src2 \t// long" %} 9829 size(4); 9830 ins_encode %{ 9831 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9832 %} 9833 ins_pipe(pipe_class_default); 9834 %} 9835 9836 // Immediate And long 9837 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 9838 match(Set dst (AndL src1 src2)); 9839 effect(KILL cr0); 9840 9841 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 9842 size(4); 9843 ins_encode %{ 9844 // FIXME: avoid andi_ ? 9845 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9846 %} 9847 ins_pipe(pipe_class_default); 9848 %} 9849 9850 // Immediate And Long where the immediate is a negative power of 2. 9851 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 9852 match(Set dst (AndL src1 src2)); 9853 format %{ "ANDDI $dst, $src1, $src2" %} 9854 size(4); 9855 ins_encode %{ 9856 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(julong)$src2$$constant)); 9857 %} 9858 ins_pipe(pipe_class_default); 9859 %} 9860 9861 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9862 match(Set dst (AndL src1 src2)); 9863 format %{ "ANDDI $dst, $src1, $src2" %} 9864 size(4); 9865 ins_encode %{ 9866 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull)); 9867 %} 9868 ins_pipe(pipe_class_default); 9869 %} 9870 9871 // AndL + ConvL2I. 9872 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9873 match(Set dst (ConvL2I (AndL src1 src2))); 9874 ins_cost(DEFAULT_COST); 9875 9876 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 9877 size(4); 9878 ins_encode %{ 9879 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull)); 9880 %} 9881 ins_pipe(pipe_class_default); 9882 %} 9883 9884 // Or Instructions 9885 9886 // Register Or 9887 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9888 match(Set dst (OrI src1 src2)); 9889 format %{ "OR $dst, $src1, $src2" %} 9890 size(4); 9891 ins_encode %{ 9892 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9893 %} 9894 ins_pipe(pipe_class_default); 9895 %} 9896 9897 // Expand does not work with above instruct. (??) 9898 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9899 // no match-rule 9900 effect(DEF dst, USE src1, USE src2); 9901 format %{ "OR $dst, $src1, $src2" %} 9902 size(4); 9903 ins_encode %{ 9904 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9905 %} 9906 ins_pipe(pipe_class_default); 9907 %} 9908 9909 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9910 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 9911 ins_cost(DEFAULT_COST*3); 9912 9913 expand %{ 9914 // FIXME: we should do this in the ideal world. 9915 iRegIdst tmp1; 9916 iRegIdst tmp2; 9917 orI_reg_reg(tmp1, src1, src2); 9918 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 9919 orI_reg_reg(dst, tmp1, tmp2); 9920 %} 9921 %} 9922 9923 // Immediate Or 9924 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9925 match(Set dst (OrI src1 src2)); 9926 format %{ "ORI $dst, $src1, $src2" %} 9927 size(4); 9928 ins_encode %{ 9929 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 9930 %} 9931 ins_pipe(pipe_class_default); 9932 %} 9933 9934 // Register Or Long 9935 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9936 match(Set dst (OrL src1 src2)); 9937 ins_cost(DEFAULT_COST); 9938 9939 size(4); 9940 format %{ "OR $dst, $src1, $src2 \t// long" %} 9941 ins_encode %{ 9942 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9943 %} 9944 ins_pipe(pipe_class_default); 9945 %} 9946 9947 // OrL + ConvL2I. 9948 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9949 match(Set dst (ConvL2I (OrL src1 src2))); 9950 ins_cost(DEFAULT_COST); 9951 9952 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 9953 size(4); 9954 ins_encode %{ 9955 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9956 %} 9957 ins_pipe(pipe_class_default); 9958 %} 9959 9960 // Immediate Or long 9961 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 9962 match(Set dst (OrL src1 con)); 9963 ins_cost(DEFAULT_COST); 9964 9965 format %{ "ORI $dst, $src1, $con \t// long" %} 9966 size(4); 9967 ins_encode %{ 9968 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 9969 %} 9970 ins_pipe(pipe_class_default); 9971 %} 9972 9973 // Xor Instructions 9974 9975 // Register Xor 9976 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9977 match(Set dst (XorI src1 src2)); 9978 format %{ "XOR $dst, $src1, $src2" %} 9979 size(4); 9980 ins_encode %{ 9981 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9982 %} 9983 ins_pipe(pipe_class_default); 9984 %} 9985 9986 // Expand does not work with above instruct. (??) 9987 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9988 // no match-rule 9989 effect(DEF dst, USE src1, USE src2); 9990 format %{ "XOR $dst, $src1, $src2" %} 9991 size(4); 9992 ins_encode %{ 9993 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9994 %} 9995 ins_pipe(pipe_class_default); 9996 %} 9997 9998 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9999 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10000 ins_cost(DEFAULT_COST*3); 10001 10002 expand %{ 10003 // FIXME: we should do this in the ideal world. 10004 iRegIdst tmp1; 10005 iRegIdst tmp2; 10006 xorI_reg_reg(tmp1, src1, src2); 10007 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10008 xorI_reg_reg(dst, tmp1, tmp2); 10009 %} 10010 %} 10011 10012 // Immediate Xor 10013 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10014 match(Set dst (XorI src1 src2)); 10015 format %{ "XORI $dst, $src1, $src2" %} 10016 size(4); 10017 ins_encode %{ 10018 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10019 %} 10020 ins_pipe(pipe_class_default); 10021 %} 10022 10023 // Register Xor Long 10024 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10025 match(Set dst (XorL src1 src2)); 10026 ins_cost(DEFAULT_COST); 10027 10028 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10029 size(4); 10030 ins_encode %{ 10031 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10032 %} 10033 ins_pipe(pipe_class_default); 10034 %} 10035 10036 // XorL + ConvL2I. 10037 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10038 match(Set dst (ConvL2I (XorL src1 src2))); 10039 ins_cost(DEFAULT_COST); 10040 10041 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10042 size(4); 10043 ins_encode %{ 10044 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10045 %} 10046 ins_pipe(pipe_class_default); 10047 %} 10048 10049 // Immediate Xor Long 10050 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10051 match(Set dst (XorL src1 src2)); 10052 ins_cost(DEFAULT_COST); 10053 10054 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10055 size(4); 10056 ins_encode %{ 10057 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10058 %} 10059 ins_pipe(pipe_class_default); 10060 %} 10061 10062 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10063 match(Set dst (XorI src1 src2)); 10064 ins_cost(DEFAULT_COST); 10065 10066 format %{ "NOT $dst, $src1 ($src2)" %} 10067 size(4); 10068 ins_encode %{ 10069 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10070 %} 10071 ins_pipe(pipe_class_default); 10072 %} 10073 10074 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10075 match(Set dst (XorL src1 src2)); 10076 ins_cost(DEFAULT_COST); 10077 10078 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10079 size(4); 10080 ins_encode %{ 10081 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10082 %} 10083 ins_pipe(pipe_class_default); 10084 %} 10085 10086 // And-complement 10087 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10088 match(Set dst (AndI (XorI src1 src2) src3)); 10089 ins_cost(DEFAULT_COST); 10090 10091 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10092 size(4); 10093 ins_encode( enc_andc(dst, src3, src1) ); 10094 ins_pipe(pipe_class_default); 10095 %} 10096 10097 // And-complement 10098 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10099 // no match-rule, false predicate 10100 effect(DEF dst, USE src1, USE src2); 10101 predicate(false); 10102 10103 format %{ "ANDC $dst, $src1, $src2" %} 10104 size(4); 10105 ins_encode %{ 10106 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10107 %} 10108 ins_pipe(pipe_class_default); 10109 %} 10110 10111 //----------Moves between int/long and float/double---------------------------- 10112 // 10113 // The following rules move values from int/long registers/stack-locations 10114 // to float/double registers/stack-locations and vice versa, without doing any 10115 // conversions. These rules are used to implement the bit-conversion methods 10116 // of java.lang.Float etc., e.g. 10117 // int floatToIntBits(float value) 10118 // float intBitsToFloat(int bits) 10119 // 10120 // Notes on the implementation on ppc64: 10121 // For Power7 and earlier, the rules are limited to those which move between a 10122 // register and a stack-location, because we always have to go through memory 10123 // when moving between a float register and an integer register. 10124 // This restriction is removed in Power8 with the introduction of the mtfprd 10125 // and mffprd instructions. 10126 10127 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10128 match(Set dst (MoveL2D src)); 10129 predicate(VM_Version::has_mtfprd()); 10130 10131 format %{ "MTFPRD $dst, $src" %} 10132 size(4); 10133 ins_encode %{ 10134 __ mtfprd($dst$$FloatRegister, $src$$Register); 10135 %} 10136 ins_pipe(pipe_class_default); 10137 %} 10138 10139 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10140 // no match-rule, false predicate 10141 effect(DEF dst, USE src); 10142 predicate(false); 10143 10144 format %{ "MTFPRWA $dst, $src" %} 10145 size(4); 10146 ins_encode %{ 10147 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10148 %} 10149 ins_pipe(pipe_class_default); 10150 %} 10151 10152 //---------- Chain stack slots between similar types -------- 10153 10154 // These are needed so that the rules below can match. 10155 10156 // Load integer from stack slot 10157 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10158 match(Set dst src); 10159 ins_cost(MEMORY_REF_COST); 10160 10161 format %{ "LWZ $dst, $src" %} 10162 size(4); 10163 ins_encode( enc_lwz(dst, src) ); 10164 ins_pipe(pipe_class_memory); 10165 %} 10166 10167 // Store integer to stack slot 10168 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10169 match(Set dst src); 10170 ins_cost(MEMORY_REF_COST); 10171 10172 format %{ "STW $src, $dst \t// stk" %} 10173 size(4); 10174 ins_encode( enc_stw(src, dst) ); // rs=rt 10175 ins_pipe(pipe_class_memory); 10176 %} 10177 10178 // Load long from stack slot 10179 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10180 match(Set dst src); 10181 ins_cost(MEMORY_REF_COST); 10182 10183 format %{ "LD $dst, $src \t// long" %} 10184 size(4); 10185 ins_encode( enc_ld(dst, src) ); 10186 ins_pipe(pipe_class_memory); 10187 %} 10188 10189 // Store long to stack slot 10190 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10191 match(Set dst src); 10192 ins_cost(MEMORY_REF_COST); 10193 10194 format %{ "STD $src, $dst \t// long" %} 10195 size(4); 10196 ins_encode( enc_std(src, dst) ); // rs=rt 10197 ins_pipe(pipe_class_memory); 10198 %} 10199 10200 //----------Moves between int and float 10201 10202 // Move float value from float stack-location to integer register. 10203 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10204 match(Set dst (MoveF2I src)); 10205 ins_cost(MEMORY_REF_COST); 10206 10207 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10208 size(4); 10209 ins_encode( enc_lwz(dst, src) ); 10210 ins_pipe(pipe_class_memory); 10211 %} 10212 10213 // Move float value from float register to integer stack-location. 10214 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10215 match(Set dst (MoveF2I src)); 10216 ins_cost(MEMORY_REF_COST); 10217 10218 format %{ "STFS $src, $dst \t// MoveF2I" %} 10219 size(4); 10220 ins_encode( enc_stfs(src, dst) ); 10221 ins_pipe(pipe_class_memory); 10222 %} 10223 10224 // Move integer value from integer stack-location to float register. 10225 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10226 match(Set dst (MoveI2F src)); 10227 ins_cost(MEMORY_REF_COST); 10228 10229 format %{ "LFS $dst, $src \t// MoveI2F" %} 10230 size(4); 10231 ins_encode %{ 10232 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10233 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10234 %} 10235 ins_pipe(pipe_class_memory); 10236 %} 10237 10238 // Move integer value from integer register to float stack-location. 10239 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10240 match(Set dst (MoveI2F src)); 10241 ins_cost(MEMORY_REF_COST); 10242 10243 format %{ "STW $src, $dst \t// MoveI2F" %} 10244 size(4); 10245 ins_encode( enc_stw(src, dst) ); 10246 ins_pipe(pipe_class_memory); 10247 %} 10248 10249 //----------Moves between long and float 10250 10251 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10252 // no match-rule, false predicate 10253 effect(DEF dst, USE src); 10254 predicate(false); 10255 10256 format %{ "storeD $src, $dst \t// STACK" %} 10257 size(4); 10258 ins_encode( enc_stfd(src, dst) ); 10259 ins_pipe(pipe_class_default); 10260 %} 10261 10262 //----------Moves between long and double 10263 10264 // Move double value from double stack-location to long register. 10265 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10266 match(Set dst (MoveD2L src)); 10267 ins_cost(MEMORY_REF_COST); 10268 size(4); 10269 format %{ "LD $dst, $src \t// MoveD2L" %} 10270 ins_encode( enc_ld(dst, src) ); 10271 ins_pipe(pipe_class_memory); 10272 %} 10273 10274 // Move double value from double register to long stack-location. 10275 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10276 match(Set dst (MoveD2L src)); 10277 effect(DEF dst, USE src); 10278 ins_cost(MEMORY_REF_COST); 10279 10280 format %{ "STFD $src, $dst \t// MoveD2L" %} 10281 size(4); 10282 ins_encode( enc_stfd(src, dst) ); 10283 ins_pipe(pipe_class_memory); 10284 %} 10285 10286 // Move long value from long stack-location to double register. 10287 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10288 match(Set dst (MoveL2D src)); 10289 ins_cost(MEMORY_REF_COST); 10290 10291 format %{ "LFD $dst, $src \t// MoveL2D" %} 10292 size(4); 10293 ins_encode( enc_lfd(dst, src) ); 10294 ins_pipe(pipe_class_memory); 10295 %} 10296 10297 // Move long value from long register to double stack-location. 10298 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10299 match(Set dst (MoveL2D src)); 10300 ins_cost(MEMORY_REF_COST); 10301 10302 format %{ "STD $src, $dst \t// MoveL2D" %} 10303 size(4); 10304 ins_encode( enc_std(src, dst) ); 10305 ins_pipe(pipe_class_memory); 10306 %} 10307 10308 //----------Register Move Instructions----------------------------------------- 10309 10310 // Replicate for Superword 10311 10312 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10313 predicate(false); 10314 effect(DEF dst, USE src); 10315 10316 format %{ "MR $dst, $src \t// replicate " %} 10317 // variable size, 0 or 4. 10318 ins_encode %{ 10319 __ mr_if_needed($dst$$Register, $src$$Register); 10320 %} 10321 ins_pipe(pipe_class_default); 10322 %} 10323 10324 //----------Cast instructions (Java-level type cast)--------------------------- 10325 10326 // Cast Long to Pointer for unsafe natives. 10327 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10328 match(Set dst (CastX2P src)); 10329 10330 format %{ "MR $dst, $src \t// Long->Ptr" %} 10331 // variable size, 0 or 4. 10332 ins_encode %{ 10333 __ mr_if_needed($dst$$Register, $src$$Register); 10334 %} 10335 ins_pipe(pipe_class_default); 10336 %} 10337 10338 // Cast Pointer to Long for unsafe natives. 10339 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10340 match(Set dst (CastP2X src)); 10341 10342 format %{ "MR $dst, $src \t// Ptr->Long" %} 10343 // variable size, 0 or 4. 10344 ins_encode %{ 10345 __ mr_if_needed($dst$$Register, $src$$Register); 10346 %} 10347 ins_pipe(pipe_class_default); 10348 %} 10349 10350 instruct castPP(iRegPdst dst) %{ 10351 match(Set dst (CastPP dst)); 10352 format %{ " -- \t// castPP of $dst" %} 10353 size(0); 10354 ins_encode( /*empty*/ ); 10355 ins_pipe(pipe_class_default); 10356 %} 10357 10358 instruct castII(iRegIdst dst) %{ 10359 match(Set dst (CastII dst)); 10360 format %{ " -- \t// castII of $dst" %} 10361 size(0); 10362 ins_encode( /*empty*/ ); 10363 ins_pipe(pipe_class_default); 10364 %} 10365 10366 instruct castLL(iRegLdst dst) %{ 10367 match(Set dst (CastLL dst)); 10368 format %{ " -- \t// castLL of $dst" %} 10369 size(0); 10370 ins_encode( /*empty*/ ); 10371 ins_pipe(pipe_class_default); 10372 %} 10373 10374 instruct castFF(regF dst) %{ 10375 match(Set dst (CastFF dst)); 10376 format %{ " -- \t// castFF of $dst" %} 10377 size(0); 10378 ins_encode( /*empty*/ ); 10379 ins_pipe(pipe_class_default); 10380 %} 10381 10382 instruct castDD(regD dst) %{ 10383 match(Set dst (CastDD dst)); 10384 format %{ " -- \t// castDD of $dst" %} 10385 size(0); 10386 ins_encode( /*empty*/ ); 10387 ins_pipe(pipe_class_default); 10388 %} 10389 10390 instruct castVV8(iRegLdst 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 castVV16(vecX dst) %{ 10399 match(Set dst (CastVV dst)); 10400 format %{ " -- \t// castVV of $dst" %} 10401 size(0); 10402 ins_encode( /*empty*/ ); 10403 ins_pipe(pipe_class_default); 10404 %} 10405 10406 instruct checkCastPP(iRegPdst dst) %{ 10407 match(Set dst (CheckCastPP dst)); 10408 format %{ " -- \t// checkcastPP of $dst" %} 10409 size(0); 10410 ins_encode( /*empty*/ ); 10411 ins_pipe(pipe_class_default); 10412 %} 10413 10414 //----------Convert instructions----------------------------------------------- 10415 10416 // Convert to boolean. 10417 10418 // int_to_bool(src) : { 1 if src != 0 10419 // { 0 else 10420 // 10421 // strategy: 10422 // 1) Count leading zeros of 32 bit-value src, 10423 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10424 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10425 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10426 10427 // convI2Bool 10428 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10429 match(Set dst (Conv2B src)); 10430 predicate(UseCountLeadingZerosInstructionsPPC64); 10431 ins_cost(DEFAULT_COST); 10432 10433 expand %{ 10434 immI shiftAmount %{ 0x5 %} 10435 uimmI16 mask %{ 0x1 %} 10436 iRegIdst tmp1; 10437 iRegIdst tmp2; 10438 countLeadingZerosI(tmp1, src); 10439 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10440 xorI_reg_uimm16(dst, tmp2, mask); 10441 %} 10442 %} 10443 10444 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10445 match(Set dst (Conv2B src)); 10446 effect(TEMP crx); 10447 predicate(!UseCountLeadingZerosInstructionsPPC64); 10448 ins_cost(DEFAULT_COST); 10449 10450 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10451 "LI $dst, #0\n\t" 10452 "BEQ $crx, done\n\t" 10453 "LI $dst, #1\n" 10454 "done:" %} 10455 size(16); 10456 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10457 ins_pipe(pipe_class_compare); 10458 %} 10459 10460 // ConvI2B + XorI 10461 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10462 match(Set dst (XorI (Conv2B src) mask)); 10463 predicate(UseCountLeadingZerosInstructionsPPC64); 10464 ins_cost(DEFAULT_COST); 10465 10466 expand %{ 10467 immI shiftAmount %{ 0x5 %} 10468 iRegIdst tmp1; 10469 countLeadingZerosI(tmp1, src); 10470 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10471 %} 10472 %} 10473 10474 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10475 match(Set dst (XorI (Conv2B src) mask)); 10476 effect(TEMP crx); 10477 predicate(!UseCountLeadingZerosInstructionsPPC64); 10478 ins_cost(DEFAULT_COST); 10479 10480 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10481 "LI $dst, #1\n\t" 10482 "BEQ $crx, done\n\t" 10483 "LI $dst, #0\n" 10484 "done:" %} 10485 size(16); 10486 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10487 ins_pipe(pipe_class_compare); 10488 %} 10489 10490 // AndI 0b0..010..0 + ConvI2B 10491 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10492 match(Set dst (Conv2B (AndI src mask))); 10493 predicate(UseRotateAndMaskInstructionsPPC64); 10494 ins_cost(DEFAULT_COST); 10495 10496 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10497 size(4); 10498 ins_encode %{ 10499 __ rlwinm($dst$$Register, $src$$Register, 32 - log2i_exact((juint)($mask$$constant)), 31, 31); 10500 %} 10501 ins_pipe(pipe_class_default); 10502 %} 10503 10504 // Convert pointer to boolean. 10505 // 10506 // ptr_to_bool(src) : { 1 if src != 0 10507 // { 0 else 10508 // 10509 // strategy: 10510 // 1) Count leading zeros of 64 bit-value src, 10511 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10512 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10513 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10514 10515 // ConvP2B 10516 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10517 match(Set dst (Conv2B src)); 10518 predicate(UseCountLeadingZerosInstructionsPPC64); 10519 ins_cost(DEFAULT_COST); 10520 10521 expand %{ 10522 immI shiftAmount %{ 0x6 %} 10523 uimmI16 mask %{ 0x1 %} 10524 iRegIdst tmp1; 10525 iRegIdst tmp2; 10526 countLeadingZerosP(tmp1, src); 10527 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10528 xorI_reg_uimm16(dst, tmp2, mask); 10529 %} 10530 %} 10531 10532 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10533 match(Set dst (Conv2B src)); 10534 effect(TEMP crx); 10535 predicate(!UseCountLeadingZerosInstructionsPPC64); 10536 ins_cost(DEFAULT_COST); 10537 10538 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10539 "LI $dst, #0\n\t" 10540 "BEQ $crx, done\n\t" 10541 "LI $dst, #1\n" 10542 "done:" %} 10543 size(16); 10544 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10545 ins_pipe(pipe_class_compare); 10546 %} 10547 10548 // ConvP2B + XorI 10549 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10550 match(Set dst (XorI (Conv2B src) mask)); 10551 predicate(UseCountLeadingZerosInstructionsPPC64); 10552 ins_cost(DEFAULT_COST); 10553 10554 expand %{ 10555 immI shiftAmount %{ 0x6 %} 10556 iRegIdst tmp1; 10557 countLeadingZerosP(tmp1, src); 10558 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10559 %} 10560 %} 10561 10562 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10563 match(Set dst (XorI (Conv2B src) mask)); 10564 effect(TEMP crx); 10565 predicate(!UseCountLeadingZerosInstructionsPPC64); 10566 ins_cost(DEFAULT_COST); 10567 10568 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10569 "LI $dst, #1\n\t" 10570 "BEQ $crx, done\n\t" 10571 "LI $dst, #0\n" 10572 "done:" %} 10573 size(16); 10574 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10575 ins_pipe(pipe_class_compare); 10576 %} 10577 10578 // if src1 < src2, return -1 else return 0 10579 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10580 match(Set dst (CmpLTMask src1 src2)); 10581 ins_cost(DEFAULT_COST*4); 10582 10583 expand %{ 10584 iRegLdst src1s; 10585 iRegLdst src2s; 10586 iRegLdst diff; 10587 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10588 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10589 subL_reg_reg(diff, src1s, src2s); 10590 // Need to consider >=33 bit result, therefore we need signmaskL. 10591 signmask64I_regL(dst, diff); 10592 %} 10593 %} 10594 10595 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 10596 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 10597 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 10598 size(4); 10599 ins_encode %{ 10600 __ srawi($dst$$Register, $src1$$Register, 0x1f); 10601 %} 10602 ins_pipe(pipe_class_default); 10603 %} 10604 10605 //----------Arithmetic Conversion Instructions--------------------------------- 10606 10607 // Convert to Byte -- nop 10608 // Convert to Short -- nop 10609 10610 // Convert to Int 10611 10612 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 10613 match(Set dst (RShiftI (LShiftI src amount) amount)); 10614 format %{ "EXTSB $dst, $src \t// byte->int" %} 10615 size(4); 10616 ins_encode %{ 10617 __ extsb($dst$$Register, $src$$Register); 10618 %} 10619 ins_pipe(pipe_class_default); 10620 %} 10621 10622 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 10623 effect(DEF dst, USE src); 10624 10625 size(4); 10626 ins_encode %{ 10627 __ extsh($dst$$Register, $src$$Register); 10628 %} 10629 ins_pipe(pipe_class_default); 10630 %} 10631 10632 // LShiftI 16 + RShiftI 16 converts short to int. 10633 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 10634 match(Set dst (RShiftI (LShiftI src amount) amount)); 10635 format %{ "EXTSH $dst, $src \t// short->int" %} 10636 size(4); 10637 ins_encode %{ 10638 __ extsh($dst$$Register, $src$$Register); 10639 %} 10640 ins_pipe(pipe_class_default); 10641 %} 10642 10643 // ConvL2I + ConvI2L: Sign extend int in long register. 10644 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 10645 match(Set dst (ConvI2L (ConvL2I src))); 10646 10647 format %{ "EXTSW $dst, $src \t// long->long" %} 10648 size(4); 10649 ins_encode %{ 10650 __ extsw($dst$$Register, $src$$Register); 10651 %} 10652 ins_pipe(pipe_class_default); 10653 %} 10654 10655 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 10656 match(Set dst (ConvL2I src)); 10657 format %{ "MR $dst, $src \t// long->int" %} 10658 // variable size, 0 or 4 10659 ins_encode %{ 10660 __ mr_if_needed($dst$$Register, $src$$Register); 10661 %} 10662 ins_pipe(pipe_class_default); 10663 %} 10664 10665 instruct convD2IRaw_regD(regD dst, regD src) %{ 10666 // no match-rule, false predicate 10667 effect(DEF dst, USE src); 10668 predicate(false); 10669 10670 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 10671 size(4); 10672 ins_encode %{ 10673 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10674 %} 10675 ins_pipe(pipe_class_default); 10676 %} 10677 10678 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 10679 // no match-rule, false predicate 10680 effect(DEF dst, USE crx, USE src); 10681 predicate(false); 10682 10683 ins_variable_size_depending_on_alignment(true); 10684 10685 format %{ "cmovI $crx, $dst, $src" %} 10686 // Worst case is branch + move + stop, no stop without scheduler. 10687 size(8); 10688 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10689 ins_pipe(pipe_class_default); 10690 %} 10691 10692 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 10693 // no match-rule, false predicate 10694 effect(DEF dst, USE crx, USE src); 10695 predicate(false); 10696 10697 ins_variable_size_depending_on_alignment(true); 10698 10699 format %{ "cmovI $crx, $dst, $src" %} 10700 // Worst case is branch + move + stop, no stop without scheduler. 10701 size(8); 10702 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 10703 ins_pipe(pipe_class_default); 10704 %} 10705 10706 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10707 // no match-rule, false predicate 10708 effect(DEF dst, USE crx, USE mem); 10709 predicate(false); 10710 10711 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 10712 postalloc_expand %{ 10713 // 10714 // replaces 10715 // 10716 // region dst crx mem 10717 // \ | | / 10718 // dst=cmovI_bso_stackSlotL_conLvalue0 10719 // 10720 // with 10721 // 10722 // region dst 10723 // \ / 10724 // dst=loadConI16(0) 10725 // | 10726 // ^ region dst crx mem 10727 // | \ | | / 10728 // dst=cmovI_bso_stackSlotL 10729 // 10730 10731 // Create new nodes. 10732 MachNode *m1 = new loadConI16Node(); 10733 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 10734 10735 // inputs for new nodes 10736 m1->add_req(n_region); 10737 m2->add_req(n_region, n_crx, n_mem); 10738 10739 // precedences for new nodes 10740 m2->add_prec(m1); 10741 10742 // operands for new nodes 10743 m1->_opnds[0] = op_dst; 10744 m1->_opnds[1] = new immI16Oper(0); 10745 10746 m2->_opnds[0] = op_dst; 10747 m2->_opnds[1] = op_crx; 10748 m2->_opnds[2] = op_mem; 10749 10750 // registers for new nodes 10751 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10752 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10753 10754 // Insert new nodes. 10755 nodes->push(m1); 10756 nodes->push(m2); 10757 %} 10758 %} 10759 10760 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 10761 // no match-rule, false predicate 10762 effect(DEF dst, USE crx, USE src); 10763 predicate(false); 10764 10765 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 10766 postalloc_expand %{ 10767 // 10768 // replaces 10769 // 10770 // region dst crx src 10771 // \ | | / 10772 // dst=cmovI_bso_reg_conLvalue0 10773 // 10774 // with 10775 // 10776 // region dst 10777 // \ / 10778 // dst=loadConI16(0) 10779 // | 10780 // ^ region dst crx src 10781 // | \ | | / 10782 // dst=cmovI_bso_reg 10783 // 10784 10785 // Create new nodes. 10786 MachNode *m1 = new loadConI16Node(); 10787 MachNode *m2 = new cmovI_bso_regNode(); 10788 10789 // inputs for new nodes 10790 m1->add_req(n_region); 10791 m2->add_req(n_region, n_crx, n_src); 10792 10793 // precedences for new nodes 10794 m2->add_prec(m1); 10795 10796 // operands for new nodes 10797 m1->_opnds[0] = op_dst; 10798 m1->_opnds[1] = new immI16Oper(0); 10799 10800 m2->_opnds[0] = op_dst; 10801 m2->_opnds[1] = op_crx; 10802 m2->_opnds[2] = op_src; 10803 10804 // registers for new nodes 10805 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10806 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10807 10808 // Insert new nodes. 10809 nodes->push(m1); 10810 nodes->push(m2); 10811 %} 10812 %} 10813 10814 // Double to Int conversion, NaN is mapped to 0. 10815 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 10816 match(Set dst (ConvD2I src)); 10817 predicate(!VM_Version::has_mtfprd()); 10818 ins_cost(DEFAULT_COST); 10819 10820 expand %{ 10821 regD tmpD; 10822 stackSlotL tmpS; 10823 flagsReg crx; 10824 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10825 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10826 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10827 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10828 %} 10829 %} 10830 10831 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 10832 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 10833 match(Set dst (ConvD2I src)); 10834 predicate(VM_Version::has_mtfprd()); 10835 ins_cost(DEFAULT_COST); 10836 10837 expand %{ 10838 regD tmpD; 10839 flagsReg crx; 10840 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10841 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10842 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 10843 %} 10844 %} 10845 10846 instruct convF2IRaw_regF(regF dst, regF src) %{ 10847 // no match-rule, false predicate 10848 effect(DEF dst, USE src); 10849 predicate(false); 10850 10851 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 10852 size(4); 10853 ins_encode %{ 10854 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10855 %} 10856 ins_pipe(pipe_class_default); 10857 %} 10858 10859 // Float to Int conversion, NaN is mapped to 0. 10860 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 10861 match(Set dst (ConvF2I src)); 10862 predicate(!VM_Version::has_mtfprd()); 10863 ins_cost(DEFAULT_COST); 10864 10865 expand %{ 10866 regF tmpF; 10867 stackSlotL tmpS; 10868 flagsReg crx; 10869 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10870 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10871 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10872 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10873 %} 10874 %} 10875 10876 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 10877 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 10878 match(Set dst (ConvF2I src)); 10879 predicate(VM_Version::has_mtfprd()); 10880 ins_cost(DEFAULT_COST); 10881 10882 expand %{ 10883 regF tmpF; 10884 flagsReg crx; 10885 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10886 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10887 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 10888 %} 10889 %} 10890 10891 // Convert to Long 10892 10893 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 10894 match(Set dst (ConvI2L src)); 10895 format %{ "EXTSW $dst, $src \t// int->long" %} 10896 size(4); 10897 ins_encode %{ 10898 __ extsw($dst$$Register, $src$$Register); 10899 %} 10900 ins_pipe(pipe_class_default); 10901 %} 10902 10903 // Zero-extend: convert unsigned int to long (convUI2L). 10904 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 10905 match(Set dst (AndL (ConvI2L src) mask)); 10906 ins_cost(DEFAULT_COST); 10907 10908 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10909 size(4); 10910 ins_encode %{ 10911 __ clrldi($dst$$Register, $src$$Register, 32); 10912 %} 10913 ins_pipe(pipe_class_default); 10914 %} 10915 10916 // Zero-extend: convert unsigned int to long in long register. 10917 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 10918 match(Set dst (AndL src mask)); 10919 ins_cost(DEFAULT_COST); 10920 10921 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10922 size(4); 10923 ins_encode %{ 10924 __ clrldi($dst$$Register, $src$$Register, 32); 10925 %} 10926 ins_pipe(pipe_class_default); 10927 %} 10928 10929 instruct convF2LRaw_regF(regF dst, regF src) %{ 10930 // no match-rule, false predicate 10931 effect(DEF dst, USE src); 10932 predicate(false); 10933 10934 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 10935 size(4); 10936 ins_encode %{ 10937 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10938 %} 10939 ins_pipe(pipe_class_default); 10940 %} 10941 10942 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 10943 // no match-rule, false predicate 10944 effect(DEF dst, USE crx, USE src); 10945 predicate(false); 10946 10947 ins_variable_size_depending_on_alignment(true); 10948 10949 format %{ "cmovL $crx, $dst, $src" %} 10950 // Worst case is branch + move + stop, no stop without scheduler. 10951 size(8); 10952 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10953 ins_pipe(pipe_class_default); 10954 %} 10955 10956 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 10957 // no match-rule, false predicate 10958 effect(DEF dst, USE crx, USE src); 10959 predicate(false); 10960 10961 ins_variable_size_depending_on_alignment(true); 10962 10963 format %{ "cmovL $crx, $dst, $src" %} 10964 // Worst case is branch + move + stop, no stop without scheduler. 10965 size(8); 10966 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 10967 ins_pipe(pipe_class_default); 10968 %} 10969 10970 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10971 // no match-rule, false predicate 10972 effect(DEF dst, USE crx, USE mem); 10973 predicate(false); 10974 10975 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 10976 postalloc_expand %{ 10977 // 10978 // replaces 10979 // 10980 // region dst crx mem 10981 // \ | | / 10982 // dst=cmovL_bso_stackSlotL_conLvalue0 10983 // 10984 // with 10985 // 10986 // region dst 10987 // \ / 10988 // dst=loadConL16(0) 10989 // | 10990 // ^ region dst crx mem 10991 // | \ | | / 10992 // dst=cmovL_bso_stackSlotL 10993 // 10994 10995 // Create new nodes. 10996 MachNode *m1 = new loadConL16Node(); 10997 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 10998 10999 // inputs for new nodes 11000 m1->add_req(n_region); 11001 m2->add_req(n_region, n_crx, n_mem); 11002 m2->add_prec(m1); 11003 11004 // operands for new nodes 11005 m1->_opnds[0] = op_dst; 11006 m1->_opnds[1] = new immL16Oper(0); 11007 m2->_opnds[0] = op_dst; 11008 m2->_opnds[1] = op_crx; 11009 m2->_opnds[2] = op_mem; 11010 11011 // registers for new nodes 11012 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11013 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11014 11015 // Insert new nodes. 11016 nodes->push(m1); 11017 nodes->push(m2); 11018 %} 11019 %} 11020 11021 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11022 // no match-rule, false predicate 11023 effect(DEF dst, USE crx, USE src); 11024 predicate(false); 11025 11026 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11027 postalloc_expand %{ 11028 // 11029 // replaces 11030 // 11031 // region dst crx src 11032 // \ | | / 11033 // dst=cmovL_bso_reg_conLvalue0 11034 // 11035 // with 11036 // 11037 // region dst 11038 // \ / 11039 // dst=loadConL16(0) 11040 // | 11041 // ^ region dst crx src 11042 // | \ | | / 11043 // dst=cmovL_bso_reg 11044 // 11045 11046 // Create new nodes. 11047 MachNode *m1 = new loadConL16Node(); 11048 MachNode *m2 = new cmovL_bso_regNode(); 11049 11050 // inputs for new nodes 11051 m1->add_req(n_region); 11052 m2->add_req(n_region, n_crx, n_src); 11053 m2->add_prec(m1); 11054 11055 // operands for new nodes 11056 m1->_opnds[0] = op_dst; 11057 m1->_opnds[1] = new immL16Oper(0); 11058 m2->_opnds[0] = op_dst; 11059 m2->_opnds[1] = op_crx; 11060 m2->_opnds[2] = op_src; 11061 11062 // registers for new nodes 11063 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11064 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11065 11066 // Insert new nodes. 11067 nodes->push(m1); 11068 nodes->push(m2); 11069 %} 11070 %} 11071 11072 // Float to Long conversion, NaN is mapped to 0. 11073 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11074 match(Set dst (ConvF2L src)); 11075 predicate(!VM_Version::has_mtfprd()); 11076 ins_cost(DEFAULT_COST); 11077 11078 expand %{ 11079 regF tmpF; 11080 stackSlotL tmpS; 11081 flagsReg crx; 11082 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11083 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11084 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11085 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11086 %} 11087 %} 11088 11089 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11090 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11091 match(Set dst (ConvF2L src)); 11092 predicate(VM_Version::has_mtfprd()); 11093 ins_cost(DEFAULT_COST); 11094 11095 expand %{ 11096 regF tmpF; 11097 flagsReg crx; 11098 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11099 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11100 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11101 %} 11102 %} 11103 11104 instruct convD2LRaw_regD(regD dst, regD src) %{ 11105 // no match-rule, false predicate 11106 effect(DEF dst, USE src); 11107 predicate(false); 11108 11109 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11110 size(4); 11111 ins_encode %{ 11112 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11113 %} 11114 ins_pipe(pipe_class_default); 11115 %} 11116 11117 // Double to Long conversion, NaN is mapped to 0. 11118 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11119 match(Set dst (ConvD2L src)); 11120 predicate(!VM_Version::has_mtfprd()); 11121 ins_cost(DEFAULT_COST); 11122 11123 expand %{ 11124 regD tmpD; 11125 stackSlotL tmpS; 11126 flagsReg crx; 11127 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11128 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11129 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11130 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11131 %} 11132 %} 11133 11134 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11135 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11136 match(Set dst (ConvD2L src)); 11137 predicate(VM_Version::has_mtfprd()); 11138 ins_cost(DEFAULT_COST); 11139 11140 expand %{ 11141 regD tmpD; 11142 flagsReg crx; 11143 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11144 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11145 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11146 %} 11147 %} 11148 11149 // Convert to Float 11150 11151 // Placed here as needed in expand. 11152 instruct convL2DRaw_regD(regD dst, regD src) %{ 11153 // no match-rule, false predicate 11154 effect(DEF dst, USE src); 11155 predicate(false); 11156 11157 format %{ "FCFID $dst, $src \t// convL2D" %} 11158 size(4); 11159 ins_encode %{ 11160 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11161 %} 11162 ins_pipe(pipe_class_default); 11163 %} 11164 11165 // Placed here as needed in expand. 11166 instruct convD2F_reg(regF dst, regD src) %{ 11167 match(Set dst (ConvD2F src)); 11168 format %{ "FRSP $dst, $src \t// convD2F" %} 11169 size(4); 11170 ins_encode %{ 11171 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11172 %} 11173 ins_pipe(pipe_class_default); 11174 %} 11175 11176 // Integer to Float conversion. 11177 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11178 match(Set dst (ConvI2F src)); 11179 predicate(!VM_Version::has_fcfids()); 11180 ins_cost(DEFAULT_COST); 11181 11182 expand %{ 11183 iRegLdst tmpL; 11184 stackSlotL tmpS; 11185 regD tmpD; 11186 regD tmpD2; 11187 convI2L_reg(tmpL, src); // Sign-extension int to long. 11188 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11189 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11190 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11191 convD2F_reg(dst, tmpD2); // Convert double to float. 11192 %} 11193 %} 11194 11195 instruct convL2FRaw_regF(regF dst, regD src) %{ 11196 // no match-rule, false predicate 11197 effect(DEF dst, USE src); 11198 predicate(false); 11199 11200 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11201 size(4); 11202 ins_encode %{ 11203 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11204 %} 11205 ins_pipe(pipe_class_default); 11206 %} 11207 11208 // Integer to Float conversion. Special version for Power7. 11209 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11210 match(Set dst (ConvI2F src)); 11211 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11212 ins_cost(DEFAULT_COST); 11213 11214 expand %{ 11215 iRegLdst tmpL; 11216 stackSlotL tmpS; 11217 regD tmpD; 11218 convI2L_reg(tmpL, src); // Sign-extension int to long. 11219 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11220 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11221 convL2FRaw_regF(dst, tmpD); // Convert to float. 11222 %} 11223 %} 11224 11225 // Integer to Float conversion. Special version for Power8. 11226 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11227 match(Set dst (ConvI2F src)); 11228 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11229 ins_cost(DEFAULT_COST); 11230 11231 expand %{ 11232 regD tmpD; 11233 moveI2D_reg(tmpD, src); 11234 convL2FRaw_regF(dst, tmpD); // Convert to float. 11235 %} 11236 %} 11237 11238 // L2F to avoid runtime call. 11239 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11240 match(Set dst (ConvL2F src)); 11241 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11242 ins_cost(DEFAULT_COST); 11243 11244 expand %{ 11245 stackSlotL tmpS; 11246 regD tmpD; 11247 regL_to_stkL(tmpS, src); // Store long to stack. 11248 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11249 convL2FRaw_regF(dst, tmpD); // Convert to float. 11250 %} 11251 %} 11252 11253 // L2F to avoid runtime call. Special version for Power8. 11254 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11255 match(Set dst (ConvL2F src)); 11256 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11257 ins_cost(DEFAULT_COST); 11258 11259 expand %{ 11260 regD tmpD; 11261 moveL2D_reg(tmpD, src); 11262 convL2FRaw_regF(dst, tmpD); // Convert to float. 11263 %} 11264 %} 11265 11266 // Moved up as used in expand. 11267 //instruct convD2F_reg(regF dst, regD src) %{%} 11268 11269 // Convert to Double 11270 11271 // Integer to Double conversion. 11272 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11273 match(Set dst (ConvI2D src)); 11274 predicate(!VM_Version::has_mtfprd()); 11275 ins_cost(DEFAULT_COST); 11276 11277 expand %{ 11278 iRegLdst tmpL; 11279 stackSlotL tmpS; 11280 regD tmpD; 11281 convI2L_reg(tmpL, src); // Sign-extension int to long. 11282 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11283 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11284 convL2DRaw_regD(dst, tmpD); // Convert to double. 11285 %} 11286 %} 11287 11288 // Integer to Double conversion. Special version for Power8. 11289 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11290 match(Set dst (ConvI2D src)); 11291 predicate(VM_Version::has_mtfprd()); 11292 ins_cost(DEFAULT_COST); 11293 11294 expand %{ 11295 regD tmpD; 11296 moveI2D_reg(tmpD, src); 11297 convL2DRaw_regD(dst, tmpD); // Convert to double. 11298 %} 11299 %} 11300 11301 // Long to Double conversion 11302 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11303 match(Set dst (ConvL2D src)); 11304 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11305 11306 expand %{ 11307 regD tmpD; 11308 moveL2D_stack_reg(tmpD, src); 11309 convL2DRaw_regD(dst, tmpD); 11310 %} 11311 %} 11312 11313 // Long to Double conversion. Special version for Power8. 11314 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11315 match(Set dst (ConvL2D src)); 11316 predicate(VM_Version::has_mtfprd()); 11317 ins_cost(DEFAULT_COST); 11318 11319 expand %{ 11320 regD tmpD; 11321 moveL2D_reg(tmpD, src); 11322 convL2DRaw_regD(dst, tmpD); // Convert to double. 11323 %} 11324 %} 11325 11326 instruct convF2D_reg(regD dst, regF src) %{ 11327 match(Set dst (ConvF2D src)); 11328 format %{ "FMR $dst, $src \t// float->double" %} 11329 // variable size, 0 or 4 11330 ins_encode %{ 11331 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11332 %} 11333 ins_pipe(pipe_class_default); 11334 %} 11335 11336 //----------Control Flow Instructions------------------------------------------ 11337 // Compare Instructions 11338 11339 // Compare Integers 11340 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11341 match(Set crx (CmpI src1 src2)); 11342 size(4); 11343 format %{ "CMPW $crx, $src1, $src2" %} 11344 ins_encode %{ 11345 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11346 %} 11347 ins_pipe(pipe_class_compare); 11348 %} 11349 11350 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11351 match(Set crx (CmpI src1 src2)); 11352 format %{ "CMPWI $crx, $src1, $src2" %} 11353 size(4); 11354 ins_encode %{ 11355 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11356 %} 11357 ins_pipe(pipe_class_compare); 11358 %} 11359 11360 // (src1 & src2) == 0? 11361 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11362 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11363 // r0 is killed 11364 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11365 size(4); 11366 ins_encode %{ 11367 __ andi_(R0, $src1$$Register, $src2$$constant); 11368 %} 11369 ins_pipe(pipe_class_compare); 11370 %} 11371 11372 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11373 match(Set crx (CmpL src1 src2)); 11374 format %{ "CMPD $crx, $src1, $src2" %} 11375 size(4); 11376 ins_encode %{ 11377 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11378 %} 11379 ins_pipe(pipe_class_compare); 11380 %} 11381 11382 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11383 match(Set crx (CmpL src1 src2)); 11384 format %{ "CMPDI $crx, $src1, $src2" %} 11385 size(4); 11386 ins_encode %{ 11387 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11388 %} 11389 ins_pipe(pipe_class_compare); 11390 %} 11391 11392 // Added CmpUL for LoopPredicate. 11393 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11394 match(Set crx (CmpUL src1 src2)); 11395 format %{ "CMPLD $crx, $src1, $src2" %} 11396 size(4); 11397 ins_encode %{ 11398 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11399 %} 11400 ins_pipe(pipe_class_compare); 11401 %} 11402 11403 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11404 match(Set crx (CmpUL src1 src2)); 11405 format %{ "CMPLDI $crx, $src1, $src2" %} 11406 size(4); 11407 ins_encode %{ 11408 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11409 %} 11410 ins_pipe(pipe_class_compare); 11411 %} 11412 11413 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11414 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11415 // r0 is killed 11416 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11417 size(4); 11418 ins_encode %{ 11419 __ and_(R0, $src1$$Register, $src2$$Register); 11420 %} 11421 ins_pipe(pipe_class_compare); 11422 %} 11423 11424 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11425 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11426 // r0 is killed 11427 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11428 size(4); 11429 ins_encode %{ 11430 __ andi_(R0, $src1$$Register, $src2$$constant); 11431 %} 11432 ins_pipe(pipe_class_compare); 11433 %} 11434 11435 // Manifest a CmpL3 result in an integer register. 11436 instruct cmpL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 11437 match(Set dst (CmpL3 src1 src2)); 11438 effect(KILL cr0); 11439 ins_cost(DEFAULT_COST * 5); 11440 size((VM_Version::has_brw() ? 16 : 20)); 11441 11442 format %{ "cmpL3_reg_reg $dst, $src1, $src2" %} 11443 11444 ins_encode %{ 11445 __ cmpd(CCR0, $src1$$Register, $src2$$Register); 11446 __ set_cmp3($dst$$Register); 11447 %} 11448 ins_pipe(pipe_class_default); 11449 %} 11450 11451 // Implicit range checks. 11452 // A range check in the ideal world has one of the following shapes: 11453 // - (If le (CmpU length index)), (IfTrue throw exception) 11454 // - (If lt (CmpU index length)), (IfFalse throw exception) 11455 // 11456 // Match range check 'If le (CmpU length index)'. 11457 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11458 match(If cmp (CmpU src_length index)); 11459 effect(USE labl); 11460 predicate(TrapBasedRangeChecks && 11461 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11462 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11463 (Matcher::branches_to_uncommon_trap(_leaf))); 11464 11465 ins_is_TrapBasedCheckNode(true); 11466 11467 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11468 size(4); 11469 ins_encode %{ 11470 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11471 __ trap_range_check_le($src_length$$Register, $index$$constant); 11472 } else { 11473 // Both successors are uncommon traps, probability is 0. 11474 // Node got flipped during fixup flow. 11475 assert($cmp$$cmpcode == 0x9, "must be greater"); 11476 __ trap_range_check_g($src_length$$Register, $index$$constant); 11477 } 11478 %} 11479 ins_pipe(pipe_class_trap); 11480 %} 11481 11482 // Match range check 'If lt (CmpU index length)'. 11483 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11484 match(If cmp (CmpU src_index src_length)); 11485 effect(USE labl); 11486 predicate(TrapBasedRangeChecks && 11487 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11488 _leaf->as_If()->_prob >= PROB_ALWAYS && 11489 (Matcher::branches_to_uncommon_trap(_leaf))); 11490 11491 ins_is_TrapBasedCheckNode(true); 11492 11493 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 11494 size(4); 11495 ins_encode %{ 11496 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11497 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 11498 } else { 11499 // Both successors are uncommon traps, probability is 0. 11500 // Node got flipped during fixup flow. 11501 assert($cmp$$cmpcode == 0x8, "must be less"); 11502 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 11503 } 11504 %} 11505 ins_pipe(pipe_class_trap); 11506 %} 11507 11508 // Match range check 'If lt (CmpU index length)'. 11509 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 11510 match(If cmp (CmpU src_index length)); 11511 effect(USE labl); 11512 predicate(TrapBasedRangeChecks && 11513 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11514 _leaf->as_If()->_prob >= PROB_ALWAYS && 11515 (Matcher::branches_to_uncommon_trap(_leaf))); 11516 11517 ins_is_TrapBasedCheckNode(true); 11518 11519 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 11520 size(4); 11521 ins_encode %{ 11522 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11523 __ trap_range_check_ge($src_index$$Register, $length$$constant); 11524 } else { 11525 // Both successors are uncommon traps, probability is 0. 11526 // Node got flipped during fixup flow. 11527 assert($cmp$$cmpcode == 0x8, "must be less"); 11528 __ trap_range_check_l($src_index$$Register, $length$$constant); 11529 } 11530 %} 11531 ins_pipe(pipe_class_trap); 11532 %} 11533 11534 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11535 match(Set crx (CmpU src1 src2)); 11536 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 11537 size(4); 11538 ins_encode %{ 11539 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11540 %} 11541 ins_pipe(pipe_class_compare); 11542 %} 11543 11544 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 11545 match(Set crx (CmpU src1 src2)); 11546 size(4); 11547 format %{ "CMPLWI $crx, $src1, $src2" %} 11548 ins_encode %{ 11549 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11550 %} 11551 ins_pipe(pipe_class_compare); 11552 %} 11553 11554 // Implicit zero checks (more implicit null checks). 11555 // No constant pool entries required. 11556 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 11557 match(If cmp (CmpN value zero)); 11558 effect(USE labl); 11559 predicate(TrapBasedNullChecks && 11560 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11561 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11562 Matcher::branches_to_uncommon_trap(_leaf)); 11563 ins_cost(1); 11564 11565 ins_is_TrapBasedCheckNode(true); 11566 11567 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 11568 size(4); 11569 ins_encode %{ 11570 if ($cmp$$cmpcode == 0xA) { 11571 __ trap_null_check($value$$Register); 11572 } else { 11573 // Both successors are uncommon traps, probability is 0. 11574 // Node got flipped during fixup flow. 11575 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11576 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11577 } 11578 %} 11579 ins_pipe(pipe_class_trap); 11580 %} 11581 11582 // Compare narrow oops. 11583 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 11584 match(Set crx (CmpN src1 src2)); 11585 11586 size(4); 11587 ins_cost(2); 11588 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 11589 ins_encode %{ 11590 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11591 %} 11592 ins_pipe(pipe_class_compare); 11593 %} 11594 11595 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 11596 match(Set crx (CmpN src1 src2)); 11597 // Make this more expensive than zeroCheckN_iReg_imm0. 11598 ins_cost(2); 11599 11600 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 11601 size(4); 11602 ins_encode %{ 11603 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11604 %} 11605 ins_pipe(pipe_class_compare); 11606 %} 11607 11608 // Implicit zero checks (more implicit null checks). 11609 // No constant pool entries required. 11610 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 11611 match(If cmp (CmpP value zero)); 11612 effect(USE labl); 11613 predicate(TrapBasedNullChecks && 11614 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11615 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11616 Matcher::branches_to_uncommon_trap(_leaf)); 11617 ins_cost(1); // Should not be cheaper than zeroCheckN. 11618 11619 ins_is_TrapBasedCheckNode(true); 11620 11621 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 11622 size(4); 11623 ins_encode %{ 11624 if ($cmp$$cmpcode == 0xA) { 11625 __ trap_null_check($value$$Register); 11626 } else { 11627 // Both successors are uncommon traps, probability is 0. 11628 // Node got flipped during fixup flow. 11629 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11630 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11631 } 11632 %} 11633 ins_pipe(pipe_class_trap); 11634 %} 11635 11636 // Compare Pointers 11637 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 11638 match(Set crx (CmpP src1 src2)); 11639 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 11640 size(4); 11641 ins_encode %{ 11642 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11643 %} 11644 ins_pipe(pipe_class_compare); 11645 %} 11646 11647 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 11648 match(Set crx (CmpP src1 src2)); 11649 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 11650 size(4); 11651 ins_encode %{ 11652 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 11653 %} 11654 ins_pipe(pipe_class_compare); 11655 %} 11656 11657 // Used in postalloc expand. 11658 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 11659 // This match rule prevents reordering of node before a safepoint. 11660 // This only makes sense if this instructions is used exclusively 11661 // for the expansion of EncodeP! 11662 match(Set crx (CmpP src1 src2)); 11663 predicate(false); 11664 11665 format %{ "CMPDI $crx, $src1, $src2" %} 11666 size(4); 11667 ins_encode %{ 11668 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11669 %} 11670 ins_pipe(pipe_class_compare); 11671 %} 11672 11673 //----------Float Compares---------------------------------------------------- 11674 11675 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 11676 // Needs matchrule, see cmpDUnordered. 11677 match(Set crx (CmpF src1 src2)); 11678 // no match-rule, false predicate 11679 predicate(false); 11680 11681 format %{ "cmpFUrd $crx, $src1, $src2" %} 11682 size(4); 11683 ins_encode %{ 11684 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11685 %} 11686 ins_pipe(pipe_class_default); 11687 %} 11688 11689 instruct cmov_bns_less(flagsReg crx) %{ 11690 // no match-rule, false predicate 11691 effect(DEF crx); 11692 predicate(false); 11693 11694 ins_variable_size_depending_on_alignment(true); 11695 11696 format %{ "cmov $crx" %} 11697 // Worst case is branch + move + stop, no stop without scheduler. 11698 size(12); 11699 ins_encode %{ 11700 Label done; 11701 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 11702 __ li(R0, 0); 11703 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 11704 __ bind(done); 11705 %} 11706 ins_pipe(pipe_class_default); 11707 %} 11708 11709 // Compare floating, generate condition code. 11710 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 11711 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 11712 // 11713 // The following code sequence occurs a lot in mpegaudio: 11714 // 11715 // block BXX: 11716 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 11717 // cmpFUrd CCR6, F11, F9 11718 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 11719 // cmov CCR6 11720 // 8: instruct branchConSched: 11721 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 11722 match(Set crx (CmpF src1 src2)); 11723 ins_cost(DEFAULT_COST+BRANCH_COST); 11724 11725 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 11726 postalloc_expand %{ 11727 // 11728 // replaces 11729 // 11730 // region src1 src2 11731 // \ | | 11732 // crx=cmpF_reg_reg 11733 // 11734 // with 11735 // 11736 // region src1 src2 11737 // \ | | 11738 // crx=cmpFUnordered_reg_reg 11739 // | 11740 // ^ region 11741 // | \ 11742 // crx=cmov_bns_less 11743 // 11744 11745 // Create new nodes. 11746 MachNode *m1 = new cmpFUnordered_reg_regNode(); 11747 MachNode *m2 = new cmov_bns_lessNode(); 11748 11749 // inputs for new nodes 11750 m1->add_req(n_region, n_src1, n_src2); 11751 m2->add_req(n_region); 11752 m2->add_prec(m1); 11753 11754 // operands for new nodes 11755 m1->_opnds[0] = op_crx; 11756 m1->_opnds[1] = op_src1; 11757 m1->_opnds[2] = op_src2; 11758 m2->_opnds[0] = op_crx; 11759 11760 // registers for new nodes 11761 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11762 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11763 11764 // Insert new nodes. 11765 nodes->push(m1); 11766 nodes->push(m2); 11767 %} 11768 %} 11769 11770 // Compare float, generate -1,0,1 11771 instruct cmpF3_reg_reg(iRegIdst dst, regF src1, regF src2, flagsRegCR0 cr0) %{ 11772 match(Set dst (CmpF3 src1 src2)); 11773 effect(KILL cr0); 11774 ins_cost(DEFAULT_COST * 6); 11775 size((VM_Version::has_brw() ? 20 : 24)); 11776 11777 format %{ "cmpF3_reg_reg $dst, $src1, $src2" %} 11778 11779 ins_encode %{ 11780 __ fcmpu(CCR0, $src1$$FloatRegister, $src2$$FloatRegister); 11781 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less 11782 %} 11783 ins_pipe(pipe_class_default); 11784 %} 11785 11786 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 11787 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 11788 // node right before the conditional move using it. 11789 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 11790 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 11791 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 11792 // conditional move was supposed to be spilled. 11793 match(Set crx (CmpD src1 src2)); 11794 // False predicate, shall not be matched. 11795 predicate(false); 11796 11797 format %{ "cmpFUrd $crx, $src1, $src2" %} 11798 size(4); 11799 ins_encode %{ 11800 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11801 %} 11802 ins_pipe(pipe_class_default); 11803 %} 11804 11805 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 11806 match(Set crx (CmpD src1 src2)); 11807 ins_cost(DEFAULT_COST+BRANCH_COST); 11808 11809 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 11810 postalloc_expand %{ 11811 // 11812 // replaces 11813 // 11814 // region src1 src2 11815 // \ | | 11816 // crx=cmpD_reg_reg 11817 // 11818 // with 11819 // 11820 // region src1 src2 11821 // \ | | 11822 // crx=cmpDUnordered_reg_reg 11823 // | 11824 // ^ region 11825 // | \ 11826 // crx=cmov_bns_less 11827 // 11828 11829 // create new nodes 11830 MachNode *m1 = new cmpDUnordered_reg_regNode(); 11831 MachNode *m2 = new cmov_bns_lessNode(); 11832 11833 // inputs for new nodes 11834 m1->add_req(n_region, n_src1, n_src2); 11835 m2->add_req(n_region); 11836 m2->add_prec(m1); 11837 11838 // operands for new nodes 11839 m1->_opnds[0] = op_crx; 11840 m1->_opnds[1] = op_src1; 11841 m1->_opnds[2] = op_src2; 11842 m2->_opnds[0] = op_crx; 11843 11844 // registers for new nodes 11845 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11846 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11847 11848 // Insert new nodes. 11849 nodes->push(m1); 11850 nodes->push(m2); 11851 %} 11852 %} 11853 11854 // Compare double, generate -1,0,1 11855 instruct cmpD3_reg_reg(iRegIdst dst, regD src1, regD src2, flagsRegCR0 cr0) %{ 11856 match(Set dst (CmpD3 src1 src2)); 11857 effect(KILL cr0); 11858 ins_cost(DEFAULT_COST * 6); 11859 size((VM_Version::has_brw() ? 20 : 24)); 11860 11861 format %{ "cmpD3_reg_reg $dst, $src1, $src2" %} 11862 11863 ins_encode %{ 11864 __ fcmpu(CCR0, $src1$$FloatRegister, $src2$$FloatRegister); 11865 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less 11866 %} 11867 ins_pipe(pipe_class_default); 11868 %} 11869 11870 // Compare char 11871 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 11872 match(Set dst (Digit src1)); 11873 effect(TEMP src2, TEMP crx); 11874 ins_cost(3 * DEFAULT_COST); 11875 11876 format %{ "LI $src2, 0x3930\n\t" 11877 "CMPRB $crx, 0, $src1, $src2\n\t" 11878 "SETB $dst, $crx" %} 11879 size(12); 11880 ins_encode %{ 11881 // 0x30: 0, 0x39: 9 11882 __ li($src2$$Register, 0x3930); 11883 // compare src1 with ranges 0x30 to 0x39 11884 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 11885 __ setb($dst$$Register, $crx$$CondRegister); 11886 %} 11887 ins_pipe(pipe_class_default); 11888 %} 11889 11890 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 11891 match(Set dst (LowerCase src1)); 11892 effect(TEMP src2, TEMP crx); 11893 ins_cost(12 * DEFAULT_COST); 11894 11895 format %{ "LI $src2, 0x7A61\n\t" 11896 "CMPRB $crx, 0, $src1, $src2\n\t" 11897 "BGT $crx, done\n\t" 11898 "LIS $src2, (signed short)0xF6DF\n\t" 11899 "ORI $src2, $src2, 0xFFF8\n\t" 11900 "CMPRB $crx, 1, $src1, $src2\n\t" 11901 "BGT $crx, done\n\t" 11902 "LIS $src2, (signed short)0xAAB5\n\t" 11903 "ORI $src2, $src2, 0xBABA\n\t" 11904 "INSRDI $src2, $src2, 32, 0\n\t" 11905 "CMPEQB $crx, 1, $src1, $src2\n" 11906 "done:\n\t" 11907 "SETB $dst, $crx" %} 11908 11909 size(48); 11910 ins_encode %{ 11911 Label done; 11912 // 0x61: a, 0x7A: z 11913 __ li($src2$$Register, 0x7A61); 11914 // compare src1 with ranges 0x61 to 0x7A 11915 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 11916 __ bgt($crx$$CondRegister, done); 11917 11918 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case 11919 __ lis($src2$$Register, (signed short)0xF6DF); 11920 __ ori($src2$$Register, $src2$$Register, 0xFFF8); 11921 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF 11922 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 11923 __ bgt($crx$$CondRegister, done); 11924 11925 // 0xAA: feminine ordinal indicator 11926 // 0xB5: micro sign 11927 // 0xBA: masculine ordinal indicator 11928 __ lis($src2$$Register, (signed short)0xAAB5); 11929 __ ori($src2$$Register, $src2$$Register, 0xBABA); 11930 __ insrdi($src2$$Register, $src2$$Register, 32, 0); 11931 // compare src1 with 0xAA, 0xB5, and 0xBA 11932 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register); 11933 11934 __ bind(done); 11935 __ setb($dst$$Register, $crx$$CondRegister); 11936 %} 11937 ins_pipe(pipe_class_default); 11938 %} 11939 11940 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 11941 match(Set dst (UpperCase src1)); 11942 effect(TEMP src2, TEMP crx); 11943 ins_cost(7 * DEFAULT_COST); 11944 11945 format %{ "LI $src2, 0x5A41\n\t" 11946 "CMPRB $crx, 0, $src1, $src2\n\t" 11947 "BGT $crx, done\n\t" 11948 "LIS $src2, (signed short)0xD6C0\n\t" 11949 "ORI $src2, $src2, 0xDED8\n\t" 11950 "CMPRB $crx, 1, $src1, $src2\n" 11951 "done:\n\t" 11952 "SETB $dst, $crx" %} 11953 11954 size(28); 11955 ins_encode %{ 11956 Label done; 11957 // 0x41: A, 0x5A: Z 11958 __ li($src2$$Register, 0x5A41); 11959 // compare src1 with a range 0x41 to 0x5A 11960 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 11961 __ bgt($crx$$CondRegister, done); 11962 11963 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case 11964 __ lis($src2$$Register, (signed short)0xD6C0); 11965 __ ori($src2$$Register, $src2$$Register, 0xDED8); 11966 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE 11967 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 11968 11969 __ bind(done); 11970 __ setb($dst$$Register, $crx$$CondRegister); 11971 %} 11972 ins_pipe(pipe_class_default); 11973 %} 11974 11975 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 11976 match(Set dst (Whitespace src1)); 11977 predicate(PowerArchitecturePPC64 <= 9); 11978 effect(TEMP src2, TEMP crx); 11979 ins_cost(4 * DEFAULT_COST); 11980 11981 format %{ "LI $src2, 0x0D09\n\t" 11982 "ADDIS $src2, 0x201C\n\t" 11983 "CMPRB $crx, 1, $src1, $src2\n\t" 11984 "SETB $dst, $crx" %} 11985 size(16); 11986 ins_encode %{ 11987 // 0x09 to 0x0D, 0x1C to 0x20 11988 __ li($src2$$Register, 0x0D09); 11989 __ addis($src2$$Register, $src2$$Register, 0x0201C); 11990 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20 11991 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 11992 __ setb($dst$$Register, $crx$$CondRegister); 11993 %} 11994 ins_pipe(pipe_class_default); 11995 %} 11996 11997 // Power 10 version, using prefixed addi to load 32-bit constant 11998 instruct cmprb_Whitespace_reg_reg_prefixed(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 11999 match(Set dst (Whitespace src1)); 12000 predicate(PowerArchitecturePPC64 >= 10); 12001 effect(TEMP src2, TEMP crx); 12002 ins_cost(3 * DEFAULT_COST); 12003 12004 format %{ "PLI $src2, 0x201C0D09\n\t" 12005 "CMPRB $crx, 1, $src1, $src2\n\t" 12006 "SETB $dst, $crx" %} 12007 size(16); 12008 ins_encode %{ 12009 // 0x09 to 0x0D, 0x1C to 0x20 12010 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 12011 __ pli($src2$$Register, 0x201C0D09); 12012 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20 12013 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12014 __ setb($dst$$Register, $crx$$CondRegister); 12015 %} 12016 ins_pipe(pipe_class_default); 12017 ins_alignment(2); 12018 %} 12019 12020 //----------Branches--------------------------------------------------------- 12021 // Jump 12022 12023 // Direct Branch. 12024 instruct branch(label labl) %{ 12025 match(Goto); 12026 effect(USE labl); 12027 ins_cost(BRANCH_COST); 12028 12029 format %{ "B $labl" %} 12030 size(4); 12031 ins_encode %{ 12032 Label d; // dummy 12033 __ bind(d); 12034 Label* p = $labl$$label; 12035 // `p' is `NULL' when this encoding class is used only to 12036 // determine the size of the encoded instruction. 12037 Label& l = (NULL == p)? d : *(p); 12038 __ b(l); 12039 %} 12040 ins_pipe(pipe_class_default); 12041 %} 12042 12043 // Conditional Near Branch 12044 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12045 // Same match rule as `branchConFar'. 12046 match(If cmp crx); 12047 effect(USE lbl); 12048 ins_cost(BRANCH_COST); 12049 12050 // If set to 1 this indicates that the current instruction is a 12051 // short variant of a long branch. This avoids using this 12052 // instruction in first-pass matching. It will then only be used in 12053 // the `Shorten_branches' pass. 12054 ins_short_branch(1); 12055 12056 format %{ "B$cmp $crx, $lbl" %} 12057 size(4); 12058 ins_encode( enc_bc(crx, cmp, lbl) ); 12059 ins_pipe(pipe_class_default); 12060 %} 12061 12062 // This is for cases when the ppc64 `bc' instruction does not 12063 // reach far enough. So we emit a far branch here, which is more 12064 // expensive. 12065 // 12066 // Conditional Far Branch 12067 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12068 // Same match rule as `branchCon'. 12069 match(If cmp crx); 12070 effect(USE crx, USE lbl); 12071 // Higher cost than `branchCon'. 12072 ins_cost(5*BRANCH_COST); 12073 12074 // This is not a short variant of a branch, but the long variant. 12075 ins_short_branch(0); 12076 12077 format %{ "B_FAR$cmp $crx, $lbl" %} 12078 size(8); 12079 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12080 ins_pipe(pipe_class_default); 12081 %} 12082 12083 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12084 match(CountedLoopEnd cmp crx); 12085 effect(USE labl); 12086 ins_cost(BRANCH_COST); 12087 12088 // short variant. 12089 ins_short_branch(1); 12090 12091 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12092 size(4); 12093 ins_encode( enc_bc(crx, cmp, labl) ); 12094 ins_pipe(pipe_class_default); 12095 %} 12096 12097 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12098 match(CountedLoopEnd cmp crx); 12099 effect(USE labl); 12100 ins_cost(BRANCH_COST); 12101 12102 // Long variant. 12103 ins_short_branch(0); 12104 12105 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12106 size(8); 12107 ins_encode( enc_bc_far(crx, cmp, labl) ); 12108 ins_pipe(pipe_class_default); 12109 %} 12110 12111 // ============================================================================ 12112 // Java runtime operations, intrinsics and other complex operations. 12113 12114 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12115 // array for an instance of the superklass. Set a hidden internal cache on a 12116 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12117 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12118 // 12119 // GL TODO: Improve this. 12120 // - result should not be a TEMP 12121 // - Add match rule as on sparc avoiding additional Cmp. 12122 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12123 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12124 match(Set result (PartialSubtypeCheck subklass superklass)); 12125 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12126 ins_cost(DEFAULT_COST*10); 12127 12128 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12129 ins_encode %{ 12130 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12131 $tmp_klass$$Register, NULL, $result$$Register); 12132 %} 12133 ins_pipe(pipe_class_default); 12134 %} 12135 12136 // inlined locking and unlocking 12137 12138 instruct cmpFastLock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12139 match(Set crx (FastLock oop box)); 12140 effect(TEMP tmp1, TEMP tmp2); 12141 predicate(!Compile::current()->use_rtm()); 12142 12143 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12144 ins_encode %{ 12145 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12146 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0); 12147 // If locking was successful, crx should indicate 'EQ'. 12148 // The compiler generates a branch to the runtime call to 12149 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12150 %} 12151 ins_pipe(pipe_class_compare); 12152 %} 12153 12154 // Separate version for TM. Use bound register for box to enable USE_KILL. 12155 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12156 match(Set crx (FastLock oop box)); 12157 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12158 predicate(Compile::current()->use_rtm()); 12159 12160 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12161 ins_encode %{ 12162 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12163 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12164 _rtm_counters, _stack_rtm_counters, 12165 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12166 /*RTM*/ true, ra_->C->profile_rtm()); 12167 // If locking was successful, crx should indicate 'EQ'. 12168 // The compiler generates a branch to the runtime call to 12169 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12170 %} 12171 ins_pipe(pipe_class_compare); 12172 %} 12173 12174 instruct cmpFastUnlock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12175 match(Set crx (FastUnlock oop box)); 12176 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12177 predicate(!Compile::current()->use_rtm()); 12178 12179 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12180 ins_encode %{ 12181 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12182 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12183 false); 12184 // If unlocking was successful, crx should indicate 'EQ'. 12185 // The compiler generates a branch to the runtime call to 12186 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12187 %} 12188 ins_pipe(pipe_class_compare); 12189 %} 12190 12191 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12192 match(Set crx (FastUnlock oop box)); 12193 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12194 predicate(Compile::current()->use_rtm()); 12195 12196 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12197 ins_encode %{ 12198 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12199 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12200 /*RTM*/ true); 12201 // If unlocking was successful, crx should indicate 'EQ'. 12202 // The compiler generates a branch to the runtime call to 12203 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12204 %} 12205 ins_pipe(pipe_class_compare); 12206 %} 12207 12208 // Align address. 12209 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12210 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12211 12212 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12213 size(4); 12214 ins_encode %{ 12215 __ clrrdi($dst$$Register, $src$$Register, log2i_exact(-(julong)$mask$$constant)); 12216 %} 12217 ins_pipe(pipe_class_default); 12218 %} 12219 12220 // Array size computation. 12221 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12222 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12223 12224 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12225 size(4); 12226 ins_encode %{ 12227 __ subf($dst$$Register, $start$$Register, $end$$Register); 12228 %} 12229 ins_pipe(pipe_class_default); 12230 %} 12231 12232 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12233 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12234 match(Set dummy (ClearArray cnt base)); 12235 effect(USE_KILL base, KILL ctr); 12236 ins_cost(2 * MEMORY_REF_COST); 12237 12238 format %{ "ClearArray $cnt, $base" %} 12239 ins_encode %{ 12240 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12241 %} 12242 ins_pipe(pipe_class_default); 12243 %} 12244 12245 // Clear-array with constant large array length. 12246 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12247 match(Set dummy (ClearArray cnt base)); 12248 effect(USE_KILL base, TEMP tmp, KILL ctr); 12249 ins_cost(3 * MEMORY_REF_COST); 12250 12251 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12252 ins_encode %{ 12253 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12254 %} 12255 ins_pipe(pipe_class_default); 12256 %} 12257 12258 // Clear-array with dynamic array length. 12259 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12260 match(Set dummy (ClearArray cnt base)); 12261 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12262 ins_cost(4 * MEMORY_REF_COST); 12263 12264 format %{ "ClearArray $cnt, $base" %} 12265 ins_encode %{ 12266 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12267 %} 12268 ins_pipe(pipe_class_default); 12269 %} 12270 12271 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12272 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12273 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12274 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12275 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12276 ins_cost(300); 12277 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12278 ins_encode %{ 12279 __ string_compare($str1$$Register, $str2$$Register, 12280 $cnt1$$Register, $cnt2$$Register, 12281 $tmp$$Register, 12282 $result$$Register, StrIntrinsicNode::LL); 12283 %} 12284 ins_pipe(pipe_class_default); 12285 %} 12286 12287 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12288 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12289 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12290 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12291 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12292 ins_cost(300); 12293 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12294 ins_encode %{ 12295 __ string_compare($str1$$Register, $str2$$Register, 12296 $cnt1$$Register, $cnt2$$Register, 12297 $tmp$$Register, 12298 $result$$Register, StrIntrinsicNode::UU); 12299 %} 12300 ins_pipe(pipe_class_default); 12301 %} 12302 12303 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12304 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12305 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12306 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12307 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12308 ins_cost(300); 12309 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12310 ins_encode %{ 12311 __ string_compare($str1$$Register, $str2$$Register, 12312 $cnt1$$Register, $cnt2$$Register, 12313 $tmp$$Register, 12314 $result$$Register, StrIntrinsicNode::LU); 12315 %} 12316 ins_pipe(pipe_class_default); 12317 %} 12318 12319 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12320 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12321 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12322 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12323 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12324 ins_cost(300); 12325 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12326 ins_encode %{ 12327 __ string_compare($str2$$Register, $str1$$Register, 12328 $cnt2$$Register, $cnt1$$Register, 12329 $tmp$$Register, 12330 $result$$Register, StrIntrinsicNode::UL); 12331 %} 12332 ins_pipe(pipe_class_default); 12333 %} 12334 12335 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12336 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12337 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12338 match(Set result (StrEquals (Binary str1 str2) cnt)); 12339 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12340 ins_cost(300); 12341 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12342 ins_encode %{ 12343 __ array_equals(false, $str1$$Register, $str2$$Register, 12344 $cnt$$Register, $tmp$$Register, 12345 $result$$Register, true /* byte */); 12346 %} 12347 ins_pipe(pipe_class_default); 12348 %} 12349 12350 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12351 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12352 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12353 match(Set result (StrEquals (Binary str1 str2) cnt)); 12354 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12355 ins_cost(300); 12356 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12357 ins_encode %{ 12358 __ array_equals(false, $str1$$Register, $str2$$Register, 12359 $cnt$$Register, $tmp$$Register, 12360 $result$$Register, false /* byte */); 12361 %} 12362 ins_pipe(pipe_class_default); 12363 %} 12364 12365 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12366 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12367 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12368 match(Set result (AryEq ary1 ary2)); 12369 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12370 ins_cost(300); 12371 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12372 ins_encode %{ 12373 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12374 $tmp1$$Register, $tmp2$$Register, 12375 $result$$Register, true /* byte */); 12376 %} 12377 ins_pipe(pipe_class_default); 12378 %} 12379 12380 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12381 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12382 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12383 match(Set result (AryEq ary1 ary2)); 12384 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12385 ins_cost(300); 12386 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12387 ins_encode %{ 12388 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12389 $tmp1$$Register, $tmp2$$Register, 12390 $result$$Register, false /* byte */); 12391 %} 12392 ins_pipe(pipe_class_default); 12393 %} 12394 12395 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12396 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12397 iRegIdst tmp1, iRegIdst tmp2, 12398 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12399 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12400 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12401 // Required for EA: check if it is still a type_array. 12402 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12403 ins_cost(150); 12404 12405 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12406 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12407 12408 ins_encode %{ 12409 immPOper *needleOper = (immPOper *)$needleImm; 12410 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12411 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12412 jchar chr; 12413 #ifdef VM_LITTLE_ENDIAN 12414 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12415 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12416 #else 12417 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12418 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12419 #endif 12420 __ string_indexof_char($result$$Register, 12421 $haystack$$Register, $haycnt$$Register, 12422 R0, chr, 12423 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12424 %} 12425 ins_pipe(pipe_class_compare); 12426 %} 12427 12428 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12429 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12430 iRegIdst tmp1, iRegIdst tmp2, 12431 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12432 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12433 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12434 // Required for EA: check if it is still a type_array. 12435 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12436 ins_cost(150); 12437 12438 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12439 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12440 12441 ins_encode %{ 12442 immPOper *needleOper = (immPOper *)$needleImm; 12443 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12444 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12445 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12446 __ string_indexof_char($result$$Register, 12447 $haystack$$Register, $haycnt$$Register, 12448 R0, chr, 12449 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12450 %} 12451 ins_pipe(pipe_class_compare); 12452 %} 12453 12454 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12455 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12456 iRegIdst tmp1, iRegIdst tmp2, 12457 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12458 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12459 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12460 // Required for EA: check if it is still a type_array. 12461 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12462 ins_cost(150); 12463 12464 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12465 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12466 12467 ins_encode %{ 12468 immPOper *needleOper = (immPOper *)$needleImm; 12469 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12470 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12471 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12472 __ string_indexof_char($result$$Register, 12473 $haystack$$Register, $haycnt$$Register, 12474 R0, chr, 12475 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12476 %} 12477 ins_pipe(pipe_class_compare); 12478 %} 12479 12480 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12481 rscratch2RegP needle, immI_1 needlecntImm, 12482 iRegIdst tmp1, iRegIdst tmp2, 12483 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12484 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12485 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12486 // Required for EA: check if it is still a type_array. 12487 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12488 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12489 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12490 ins_cost(180); 12491 12492 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12493 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12494 ins_encode %{ 12495 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12496 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12497 guarantee(needle_values, "sanity"); 12498 jchar chr; 12499 #ifdef VM_LITTLE_ENDIAN 12500 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12501 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12502 #else 12503 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12504 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12505 #endif 12506 __ string_indexof_char($result$$Register, 12507 $haystack$$Register, $haycnt$$Register, 12508 R0, chr, 12509 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12510 %} 12511 ins_pipe(pipe_class_compare); 12512 %} 12513 12514 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12515 rscratch2RegP needle, immI_1 needlecntImm, 12516 iRegIdst tmp1, iRegIdst tmp2, 12517 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12518 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12519 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12520 // Required for EA: check if it is still a type_array. 12521 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12522 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12523 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12524 ins_cost(180); 12525 12526 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12527 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12528 ins_encode %{ 12529 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12530 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12531 guarantee(needle_values, "sanity"); 12532 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12533 __ string_indexof_char($result$$Register, 12534 $haystack$$Register, $haycnt$$Register, 12535 R0, chr, 12536 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12537 %} 12538 ins_pipe(pipe_class_compare); 12539 %} 12540 12541 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12542 rscratch2RegP needle, immI_1 needlecntImm, 12543 iRegIdst tmp1, iRegIdst tmp2, 12544 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12545 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12546 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12547 // Required for EA: check if it is still a type_array. 12548 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12549 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12550 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12551 ins_cost(180); 12552 12553 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12554 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12555 ins_encode %{ 12556 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12557 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12558 guarantee(needle_values, "sanity"); 12559 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12560 __ string_indexof_char($result$$Register, 12561 $haystack$$Register, $haycnt$$Register, 12562 R0, chr, 12563 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12564 %} 12565 ins_pipe(pipe_class_compare); 12566 %} 12567 12568 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12569 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12570 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12571 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12572 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12573 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U); 12574 ins_cost(180); 12575 12576 format %{ "StringUTF16 IndexOfChar $haystack[0..$haycnt], $ch" 12577 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12578 ins_encode %{ 12579 __ string_indexof_char($result$$Register, 12580 $haystack$$Register, $haycnt$$Register, 12581 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12582 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12583 %} 12584 ins_pipe(pipe_class_compare); 12585 %} 12586 12587 instruct indexOfChar_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12588 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12589 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12590 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12591 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12592 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L); 12593 ins_cost(180); 12594 12595 format %{ "StringLatin1 IndexOfChar $haystack[0..$haycnt], $ch" 12596 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12597 ins_encode %{ 12598 __ string_indexof_char($result$$Register, 12599 $haystack$$Register, $haycnt$$Register, 12600 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12601 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12602 %} 12603 ins_pipe(pipe_class_compare); 12604 %} 12605 12606 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12607 iRegPsrc needle, uimmI15 needlecntImm, 12608 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12609 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12610 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12611 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12612 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12613 // Required for EA: check if it is still a type_array. 12614 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12615 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12616 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12617 ins_cost(250); 12618 12619 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12620 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12621 ins_encode %{ 12622 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12623 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12624 12625 __ string_indexof($result$$Register, 12626 $haystack$$Register, $haycnt$$Register, 12627 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12628 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12629 %} 12630 ins_pipe(pipe_class_compare); 12631 %} 12632 12633 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12634 iRegPsrc needle, uimmI15 needlecntImm, 12635 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12636 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12637 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12638 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12639 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12640 // Required for EA: check if it is still a type_array. 12641 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12642 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12643 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12644 ins_cost(250); 12645 12646 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12647 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12648 ins_encode %{ 12649 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12650 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12651 12652 __ string_indexof($result$$Register, 12653 $haystack$$Register, $haycnt$$Register, 12654 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12655 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12656 %} 12657 ins_pipe(pipe_class_compare); 12658 %} 12659 12660 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12661 iRegPsrc needle, uimmI15 needlecntImm, 12662 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12663 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12664 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12665 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12666 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12667 // Required for EA: check if it is still a type_array. 12668 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12669 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12670 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12671 ins_cost(250); 12672 12673 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12674 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12675 ins_encode %{ 12676 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12677 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12678 12679 __ string_indexof($result$$Register, 12680 $haystack$$Register, $haycnt$$Register, 12681 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12682 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12683 %} 12684 ins_pipe(pipe_class_compare); 12685 %} 12686 12687 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12688 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12689 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12690 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12691 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12692 TEMP_DEF result, 12693 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12694 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12695 ins_cost(300); 12696 12697 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12698 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12699 ins_encode %{ 12700 __ string_indexof($result$$Register, 12701 $haystack$$Register, $haycnt$$Register, 12702 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12703 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12704 %} 12705 ins_pipe(pipe_class_compare); 12706 %} 12707 12708 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12709 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12710 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12711 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12712 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12713 TEMP_DEF result, 12714 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12715 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12716 ins_cost(300); 12717 12718 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12719 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12720 ins_encode %{ 12721 __ string_indexof($result$$Register, 12722 $haystack$$Register, $haycnt$$Register, 12723 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12724 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12725 %} 12726 ins_pipe(pipe_class_compare); 12727 %} 12728 12729 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12730 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12731 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12732 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12733 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12734 TEMP_DEF result, 12735 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12736 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12737 ins_cost(300); 12738 12739 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12740 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12741 ins_encode %{ 12742 __ string_indexof($result$$Register, 12743 $haystack$$Register, $haycnt$$Register, 12744 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12745 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12746 %} 12747 ins_pipe(pipe_class_compare); 12748 %} 12749 12750 // char[] to byte[] compression 12751 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12752 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12753 match(Set result (StrCompressedCopy src (Binary dst len))); 12754 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12755 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12756 ins_cost(300); 12757 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12758 ins_encode %{ 12759 Label Lskip, Ldone; 12760 __ li($result$$Register, 0); 12761 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12762 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 12763 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12764 __ beq(CCR0, Lskip); 12765 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 12766 __ bind(Lskip); 12767 __ mr($result$$Register, $len$$Register); 12768 __ bind(Ldone); 12769 %} 12770 ins_pipe(pipe_class_default); 12771 %} 12772 12773 // byte[] to char[] inflation 12774 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 12775 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12776 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12777 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12778 ins_cost(300); 12779 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12780 ins_encode %{ 12781 Label Ldone; 12782 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12783 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 12784 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12785 __ beq(CCR0, Ldone); 12786 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 12787 __ bind(Ldone); 12788 %} 12789 ins_pipe(pipe_class_default); 12790 %} 12791 12792 // StringCoding.java intrinsics 12793 instruct count_positives(iRegPsrc ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 12794 regCTR ctr, flagsRegCR0 cr0) 12795 %{ 12796 match(Set result (CountPositives ary1 len)); 12797 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 12798 ins_cost(300); 12799 format %{ "count positives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 12800 ins_encode %{ 12801 __ count_positives($ary1$$Register, $len$$Register, $result$$Register, 12802 $tmp1$$Register, $tmp2$$Register); 12803 %} 12804 ins_pipe(pipe_class_default); 12805 %} 12806 12807 // encode char[] to byte[] in ISO_8859_1 12808 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12809 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12810 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 12811 match(Set result (EncodeISOArray src (Binary dst len))); 12812 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12813 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12814 ins_cost(300); 12815 format %{ "Encode iso array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12816 ins_encode %{ 12817 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register, 12818 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false); 12819 %} 12820 ins_pipe(pipe_class_default); 12821 %} 12822 12823 // encode char[] to byte[] in ASCII 12824 instruct encode_ascii_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12825 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12826 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 12827 match(Set result (EncodeISOArray src (Binary dst len))); 12828 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12829 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12830 ins_cost(300); 12831 format %{ "Encode ascii array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12832 ins_encode %{ 12833 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register, 12834 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, true); 12835 %} 12836 ins_pipe(pipe_class_default); 12837 %} 12838 12839 12840 //---------- Min/Max Instructions --------------------------------------------- 12841 12842 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12843 match(Set dst (MinI src1 src2)); 12844 ins_cost(DEFAULT_COST*6); 12845 12846 expand %{ 12847 iRegLdst src1s; 12848 iRegLdst src2s; 12849 iRegLdst diff; 12850 iRegLdst sm; 12851 iRegLdst doz; // difference or zero 12852 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12853 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12854 subL_reg_reg(diff, src2s, src1s); 12855 // Need to consider >=33 bit result, therefore we need signmaskL. 12856 signmask64L_regL(sm, diff); 12857 andL_reg_reg(doz, diff, sm); // <=0 12858 addI_regL_regL(dst, doz, src1s); 12859 %} 12860 %} 12861 12862 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12863 match(Set dst (MinI src1 src2)); 12864 effect(KILL cr0); 12865 predicate(VM_Version::has_isel()); 12866 ins_cost(DEFAULT_COST*2); 12867 12868 ins_encode %{ 12869 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12870 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 12871 %} 12872 ins_pipe(pipe_class_default); 12873 %} 12874 12875 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12876 match(Set dst (MaxI src1 src2)); 12877 ins_cost(DEFAULT_COST*6); 12878 12879 expand %{ 12880 iRegLdst src1s; 12881 iRegLdst src2s; 12882 iRegLdst diff; 12883 iRegLdst sm; 12884 iRegLdst doz; // difference or zero 12885 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12886 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12887 subL_reg_reg(diff, src2s, src1s); 12888 // Need to consider >=33 bit result, therefore we need signmaskL. 12889 signmask64L_regL(sm, diff); 12890 andcL_reg_reg(doz, diff, sm); // >=0 12891 addI_regL_regL(dst, doz, src1s); 12892 %} 12893 %} 12894 12895 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12896 match(Set dst (MaxI src1 src2)); 12897 effect(KILL cr0); 12898 predicate(VM_Version::has_isel()); 12899 ins_cost(DEFAULT_COST*2); 12900 12901 ins_encode %{ 12902 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12903 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 12904 %} 12905 ins_pipe(pipe_class_default); 12906 %} 12907 12908 //---------- Population Count Instructions ------------------------------------ 12909 12910 // Popcnt for Power7. 12911 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 12912 match(Set dst (PopCountI src)); 12913 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12914 ins_cost(DEFAULT_COST); 12915 12916 format %{ "POPCNTW $dst, $src" %} 12917 size(4); 12918 ins_encode %{ 12919 __ popcntw($dst$$Register, $src$$Register); 12920 %} 12921 ins_pipe(pipe_class_default); 12922 %} 12923 12924 // Popcnt for Power7. 12925 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 12926 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12927 match(Set dst (PopCountL src)); 12928 ins_cost(DEFAULT_COST); 12929 12930 format %{ "POPCNTD $dst, $src" %} 12931 size(4); 12932 ins_encode %{ 12933 __ popcntd($dst$$Register, $src$$Register); 12934 %} 12935 ins_pipe(pipe_class_default); 12936 %} 12937 12938 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 12939 match(Set dst (CountLeadingZerosI src)); 12940 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12941 ins_cost(DEFAULT_COST); 12942 12943 format %{ "CNTLZW $dst, $src" %} 12944 size(4); 12945 ins_encode %{ 12946 __ cntlzw($dst$$Register, $src$$Register); 12947 %} 12948 ins_pipe(pipe_class_default); 12949 %} 12950 12951 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 12952 match(Set dst (CountLeadingZerosL src)); 12953 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12954 ins_cost(DEFAULT_COST); 12955 12956 format %{ "CNTLZD $dst, $src" %} 12957 size(4); 12958 ins_encode %{ 12959 __ cntlzd($dst$$Register, $src$$Register); 12960 %} 12961 ins_pipe(pipe_class_default); 12962 %} 12963 12964 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 12965 // no match-rule, false predicate 12966 effect(DEF dst, USE src); 12967 predicate(false); 12968 12969 format %{ "CNTLZD $dst, $src" %} 12970 size(4); 12971 ins_encode %{ 12972 __ cntlzd($dst$$Register, $src$$Register); 12973 %} 12974 ins_pipe(pipe_class_default); 12975 %} 12976 12977 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 12978 match(Set dst (CountTrailingZerosI src)); 12979 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 12980 ins_cost(DEFAULT_COST); 12981 12982 expand %{ 12983 immI16 imm1 %{ (int)-1 %} 12984 immI16 imm2 %{ (int)32 %} 12985 immI_minus1 m1 %{ -1 %} 12986 iRegIdst tmpI1; 12987 iRegIdst tmpI2; 12988 iRegIdst tmpI3; 12989 addI_reg_imm16(tmpI1, src, imm1); 12990 andcI_reg_reg(tmpI2, src, m1, tmpI1); 12991 countLeadingZerosI(tmpI3, tmpI2); 12992 subI_imm16_reg(dst, imm2, tmpI3); 12993 %} 12994 %} 12995 12996 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{ 12997 match(Set dst (CountTrailingZerosI src)); 12998 predicate(UseCountTrailingZerosInstructionsPPC64); 12999 ins_cost(DEFAULT_COST); 13000 13001 format %{ "CNTTZW $dst, $src" %} 13002 size(4); 13003 ins_encode %{ 13004 __ cnttzw($dst$$Register, $src$$Register); 13005 %} 13006 ins_pipe(pipe_class_default); 13007 %} 13008 13009 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13010 match(Set dst (CountTrailingZerosL src)); 13011 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13012 ins_cost(DEFAULT_COST); 13013 13014 expand %{ 13015 immL16 imm1 %{ (long)-1 %} 13016 immI16 imm2 %{ (int)64 %} 13017 iRegLdst tmpL1; 13018 iRegLdst tmpL2; 13019 iRegIdst tmpL3; 13020 addL_reg_imm16(tmpL1, src, imm1); 13021 andcL_reg_reg(tmpL2, tmpL1, src); 13022 countLeadingZerosL(tmpL3, tmpL2); 13023 subI_imm16_reg(dst, imm2, tmpL3); 13024 %} 13025 %} 13026 13027 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{ 13028 match(Set dst (CountTrailingZerosL src)); 13029 predicate(UseCountTrailingZerosInstructionsPPC64); 13030 ins_cost(DEFAULT_COST); 13031 13032 format %{ "CNTTZD $dst, $src" %} 13033 size(4); 13034 ins_encode %{ 13035 __ cnttzd($dst$$Register, $src$$Register); 13036 %} 13037 ins_pipe(pipe_class_default); 13038 %} 13039 13040 // Expand nodes for byte_reverse_int. 13041 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13042 effect(DEF dst, USE src, USE pos, USE shift); 13043 predicate(false); 13044 13045 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13046 size(4); 13047 ins_encode %{ 13048 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13049 %} 13050 ins_pipe(pipe_class_default); 13051 %} 13052 13053 // As insrwi_a, but with USE_DEF. 13054 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13055 effect(USE_DEF dst, USE src, USE pos, USE shift); 13056 predicate(false); 13057 13058 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13059 size(4); 13060 ins_encode %{ 13061 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13062 %} 13063 ins_pipe(pipe_class_default); 13064 %} 13065 13066 // Just slightly faster than java implementation. 13067 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13068 match(Set dst (ReverseBytesI src)); 13069 predicate(!UseByteReverseInstructions); 13070 ins_cost(7*DEFAULT_COST); 13071 13072 expand %{ 13073 immI16 imm24 %{ (int) 24 %} 13074 immI16 imm16 %{ (int) 16 %} 13075 immI16 imm8 %{ (int) 8 %} 13076 immI16 imm4 %{ (int) 4 %} 13077 immI16 imm0 %{ (int) 0 %} 13078 iRegLdst tmpI1; 13079 iRegLdst tmpI2; 13080 iRegLdst tmpI3; 13081 13082 urShiftI_reg_imm(tmpI1, src, imm24); 13083 insrwi_a(dst, tmpI1, imm24, imm8); 13084 urShiftI_reg_imm(tmpI2, src, imm16); 13085 insrwi(dst, tmpI2, imm8, imm16); 13086 urShiftI_reg_imm(tmpI3, src, imm8); 13087 insrwi(dst, tmpI3, imm8, imm8); 13088 insrwi(dst, src, imm0, imm8); 13089 %} 13090 %} 13091 13092 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{ 13093 match(Set dst (ReverseBytesI src)); 13094 predicate(UseVectorByteReverseInstructionsPPC64); 13095 effect(TEMP tmpV); 13096 ins_cost(DEFAULT_COST*3); 13097 size(12); 13098 format %{ "MTVSRWZ $tmpV, $src\n" 13099 "\tXXBRW $tmpV, $tmpV\n" 13100 "\tMFVSRWZ $dst, $tmpV" %} 13101 13102 ins_encode %{ 13103 __ mtvsrwz($tmpV$$VectorSRegister, $src$$Register); 13104 __ xxbrw($tmpV$$VectorSRegister, $tmpV$$VectorSRegister); 13105 __ mfvsrwz($dst$$Register, $tmpV$$VectorSRegister); 13106 %} 13107 ins_pipe(pipe_class_default); 13108 %} 13109 13110 instruct bytes_reverse_int(iRegIdst dst, iRegIsrc src) %{ 13111 match(Set dst (ReverseBytesI src)); 13112 predicate(UseByteReverseInstructions); 13113 ins_cost(DEFAULT_COST); 13114 size(4); 13115 13116 format %{ "BRW $dst, $src" %} 13117 13118 ins_encode %{ 13119 __ brw($dst$$Register, $src$$Register); 13120 %} 13121 ins_pipe(pipe_class_default); 13122 %} 13123 13124 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13125 match(Set dst (ReverseBytesL src)); 13126 predicate(!UseByteReverseInstructions); 13127 ins_cost(15*DEFAULT_COST); 13128 13129 expand %{ 13130 immI16 imm56 %{ (int) 56 %} 13131 immI16 imm48 %{ (int) 48 %} 13132 immI16 imm40 %{ (int) 40 %} 13133 immI16 imm32 %{ (int) 32 %} 13134 immI16 imm24 %{ (int) 24 %} 13135 immI16 imm16 %{ (int) 16 %} 13136 immI16 imm8 %{ (int) 8 %} 13137 immI16 imm0 %{ (int) 0 %} 13138 iRegLdst tmpL1; 13139 iRegLdst tmpL2; 13140 iRegLdst tmpL3; 13141 iRegLdst tmpL4; 13142 iRegLdst tmpL5; 13143 iRegLdst tmpL6; 13144 13145 // src : |a|b|c|d|e|f|g|h| 13146 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13147 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13148 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13149 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13150 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13151 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13152 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13153 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13154 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13155 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13156 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13157 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13158 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13159 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13160 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13161 %} 13162 %} 13163 13164 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{ 13165 match(Set dst (ReverseBytesL src)); 13166 predicate(UseVectorByteReverseInstructionsPPC64); 13167 effect(TEMP tmpV); 13168 ins_cost(DEFAULT_COST*3); 13169 size(12); 13170 format %{ "MTVSRD $tmpV, $src\n" 13171 "\tXXBRD $tmpV, $tmpV\n" 13172 "\tMFVSRD $dst, $tmpV" %} 13173 13174 ins_encode %{ 13175 __ mtvsrd($tmpV$$VectorSRegister, $src$$Register); 13176 __ xxbrd($tmpV$$VectorSRegister, $tmpV$$VectorSRegister); 13177 __ mfvsrd($dst$$Register, $tmpV$$VectorSRegister); 13178 %} 13179 ins_pipe(pipe_class_default); 13180 %} 13181 13182 instruct bytes_reverse_long(iRegLdst dst, iRegLsrc src) %{ 13183 match(Set dst (ReverseBytesL src)); 13184 predicate(UseByteReverseInstructions); 13185 ins_cost(DEFAULT_COST); 13186 size(4); 13187 13188 format %{ "BRD $dst, $src" %} 13189 13190 ins_encode %{ 13191 __ brd($dst$$Register, $src$$Register); 13192 %} 13193 ins_pipe(pipe_class_default); 13194 %} 13195 13196 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13197 match(Set dst (ReverseBytesUS src)); 13198 predicate(!UseByteReverseInstructions); 13199 ins_cost(2*DEFAULT_COST); 13200 13201 expand %{ 13202 immI16 imm16 %{ (int) 16 %} 13203 immI16 imm8 %{ (int) 8 %} 13204 13205 urShiftI_reg_imm(dst, src, imm8); 13206 insrwi(dst, src, imm16, imm8); 13207 %} 13208 %} 13209 13210 instruct bytes_reverse_ushort(iRegIdst dst, iRegIsrc src) %{ 13211 match(Set dst (ReverseBytesUS src)); 13212 predicate(UseByteReverseInstructions); 13213 ins_cost(DEFAULT_COST); 13214 size(4); 13215 13216 format %{ "BRH $dst, $src" %} 13217 13218 ins_encode %{ 13219 __ brh($dst$$Register, $src$$Register); 13220 %} 13221 ins_pipe(pipe_class_default); 13222 %} 13223 13224 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13225 match(Set dst (ReverseBytesS src)); 13226 predicate(!UseByteReverseInstructions); 13227 ins_cost(3*DEFAULT_COST); 13228 13229 expand %{ 13230 immI16 imm16 %{ (int) 16 %} 13231 immI16 imm8 %{ (int) 8 %} 13232 iRegLdst tmpI1; 13233 13234 urShiftI_reg_imm(tmpI1, src, imm8); 13235 insrwi(tmpI1, src, imm16, imm8); 13236 extsh(dst, tmpI1); 13237 %} 13238 %} 13239 13240 instruct bytes_reverse_short(iRegIdst dst, iRegIsrc src) %{ 13241 match(Set dst (ReverseBytesS src)); 13242 predicate(UseByteReverseInstructions); 13243 ins_cost(DEFAULT_COST); 13244 size(8); 13245 13246 format %{ "BRH $dst, $src\n\t" 13247 "EXTSH $dst, $dst" %} 13248 13249 ins_encode %{ 13250 __ brh($dst$$Register, $src$$Register); 13251 __ extsh($dst$$Register, $dst$$Register); 13252 %} 13253 ins_pipe(pipe_class_default); 13254 %} 13255 13256 // Load Integer reversed byte order 13257 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13258 match(Set dst (ReverseBytesI (LoadI mem))); 13259 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13260 ins_cost(MEMORY_REF_COST); 13261 13262 size(4); 13263 ins_encode %{ 13264 __ lwbrx($dst$$Register, $mem$$Register); 13265 %} 13266 ins_pipe(pipe_class_default); 13267 %} 13268 13269 instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{ 13270 match(Set dst (ReverseBytesI (LoadI mem))); 13271 ins_cost(2 * MEMORY_REF_COST); 13272 13273 size(12); 13274 ins_encode %{ 13275 __ lwbrx($dst$$Register, $mem$$Register); 13276 __ twi_0($dst$$Register); 13277 __ isync(); 13278 %} 13279 ins_pipe(pipe_class_default); 13280 %} 13281 13282 // Load Long - aligned and reversed 13283 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13284 match(Set dst (ReverseBytesL (LoadL mem))); 13285 predicate(VM_Version::has_ldbrx() && (n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)))); 13286 ins_cost(MEMORY_REF_COST); 13287 13288 size(4); 13289 ins_encode %{ 13290 __ ldbrx($dst$$Register, $mem$$Register); 13291 %} 13292 ins_pipe(pipe_class_default); 13293 %} 13294 13295 instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{ 13296 match(Set dst (ReverseBytesL (LoadL mem))); 13297 predicate(VM_Version::has_ldbrx()); 13298 ins_cost(2 * MEMORY_REF_COST); 13299 13300 size(12); 13301 ins_encode %{ 13302 __ ldbrx($dst$$Register, $mem$$Register); 13303 __ twi_0($dst$$Register); 13304 __ isync(); 13305 %} 13306 ins_pipe(pipe_class_default); 13307 %} 13308 13309 // Load unsigned short / char reversed byte order 13310 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13311 match(Set dst (ReverseBytesUS (LoadUS mem))); 13312 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13313 ins_cost(MEMORY_REF_COST); 13314 13315 size(4); 13316 ins_encode %{ 13317 __ lhbrx($dst$$Register, $mem$$Register); 13318 %} 13319 ins_pipe(pipe_class_default); 13320 %} 13321 13322 instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{ 13323 match(Set dst (ReverseBytesUS (LoadUS mem))); 13324 ins_cost(2 * MEMORY_REF_COST); 13325 13326 size(12); 13327 ins_encode %{ 13328 __ lhbrx($dst$$Register, $mem$$Register); 13329 __ twi_0($dst$$Register); 13330 __ isync(); 13331 %} 13332 ins_pipe(pipe_class_default); 13333 %} 13334 13335 // Load short reversed byte order 13336 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13337 match(Set dst (ReverseBytesS (LoadS mem))); 13338 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13339 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13340 13341 size(8); 13342 ins_encode %{ 13343 __ lhbrx($dst$$Register, $mem$$Register); 13344 __ extsh($dst$$Register, $dst$$Register); 13345 %} 13346 ins_pipe(pipe_class_default); 13347 %} 13348 13349 instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{ 13350 match(Set dst (ReverseBytesS (LoadS mem))); 13351 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13352 13353 size(16); 13354 ins_encode %{ 13355 __ lhbrx($dst$$Register, $mem$$Register); 13356 __ twi_0($dst$$Register); 13357 __ extsh($dst$$Register, $dst$$Register); 13358 __ isync(); 13359 %} 13360 ins_pipe(pipe_class_default); 13361 %} 13362 13363 // Store Integer reversed byte order 13364 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13365 match(Set mem (StoreI mem (ReverseBytesI src))); 13366 ins_cost(MEMORY_REF_COST); 13367 13368 size(4); 13369 ins_encode %{ 13370 __ stwbrx($src$$Register, $mem$$Register); 13371 %} 13372 ins_pipe(pipe_class_default); 13373 %} 13374 13375 // Store Long reversed byte order 13376 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13377 match(Set mem (StoreL mem (ReverseBytesL src))); 13378 predicate(VM_Version::has_stdbrx()); 13379 ins_cost(MEMORY_REF_COST); 13380 13381 size(4); 13382 ins_encode %{ 13383 __ stdbrx($src$$Register, $mem$$Register); 13384 %} 13385 ins_pipe(pipe_class_default); 13386 %} 13387 13388 // Store unsigned short / char reversed byte order 13389 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13390 match(Set mem (StoreC mem (ReverseBytesUS src))); 13391 ins_cost(MEMORY_REF_COST); 13392 13393 size(4); 13394 ins_encode %{ 13395 __ sthbrx($src$$Register, $mem$$Register); 13396 %} 13397 ins_pipe(pipe_class_default); 13398 %} 13399 13400 // Store short reversed byte order 13401 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13402 match(Set mem (StoreC mem (ReverseBytesS src))); 13403 ins_cost(MEMORY_REF_COST); 13404 13405 size(4); 13406 ins_encode %{ 13407 __ sthbrx($src$$Register, $mem$$Register); 13408 %} 13409 ins_pipe(pipe_class_default); 13410 %} 13411 13412 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13413 effect(DEF temp1, USE src); 13414 13415 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %} 13416 size(4); 13417 ins_encode %{ 13418 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13419 %} 13420 ins_pipe(pipe_class_default); 13421 %} 13422 13423 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13424 effect(DEF dst, USE src, USE imm1); 13425 13426 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %} 13427 size(4); 13428 ins_encode %{ 13429 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13430 %} 13431 ins_pipe(pipe_class_default); 13432 %} 13433 13434 instruct xscvdpspn_regF(vecX dst, regF src) %{ 13435 effect(DEF dst, USE src); 13436 13437 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %} 13438 size(4); 13439 ins_encode %{ 13440 __ xscvdpspn($dst$$VectorSRegister, $src$$FloatRegister->to_vsr()); 13441 %} 13442 ins_pipe(pipe_class_default); 13443 %} 13444 13445 //---------- Replicate Vector Instructions ------------------------------------ 13446 13447 // Insrdi does replicate if src == dst. 13448 instruct repl32(iRegLdst dst) %{ 13449 predicate(false); 13450 effect(USE_DEF dst); 13451 13452 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13453 size(4); 13454 ins_encode %{ 13455 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13456 %} 13457 ins_pipe(pipe_class_default); 13458 %} 13459 13460 // Insrdi does replicate if src == dst. 13461 instruct repl48(iRegLdst dst) %{ 13462 predicate(false); 13463 effect(USE_DEF dst); 13464 13465 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13466 size(4); 13467 ins_encode %{ 13468 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13469 %} 13470 ins_pipe(pipe_class_default); 13471 %} 13472 13473 // Insrdi does replicate if src == dst. 13474 instruct repl56(iRegLdst dst) %{ 13475 predicate(false); 13476 effect(USE_DEF dst); 13477 13478 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13479 size(4); 13480 ins_encode %{ 13481 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 13482 %} 13483 ins_pipe(pipe_class_default); 13484 %} 13485 13486 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13487 match(Set dst (ReplicateB src)); 13488 predicate(n->as_Vector()->length() == 8); 13489 expand %{ 13490 moveReg(dst, src); 13491 repl56(dst); 13492 repl48(dst); 13493 repl32(dst); 13494 %} 13495 %} 13496 13497 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 13498 match(Set dst (ReplicateB zero)); 13499 predicate(n->as_Vector()->length() == 8); 13500 format %{ "LI $dst, #0 \t// replicate8B" %} 13501 size(4); 13502 ins_encode %{ 13503 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13504 %} 13505 ins_pipe(pipe_class_default); 13506 %} 13507 13508 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13509 match(Set dst (ReplicateB src)); 13510 predicate(n->as_Vector()->length() == 8); 13511 format %{ "LI $dst, #-1 \t// replicate8B" %} 13512 size(4); 13513 ins_encode %{ 13514 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13515 %} 13516 ins_pipe(pipe_class_default); 13517 %} 13518 13519 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 13520 match(Set dst (ReplicateB src)); 13521 predicate(n->as_Vector()->length() == 16); 13522 13523 expand %{ 13524 iRegLdst tmpL; 13525 vecX tmpV; 13526 immI8 imm1 %{ (int) 1 %} 13527 moveReg(tmpL, src); 13528 repl56(tmpL); 13529 repl48(tmpL); 13530 mtvsrwz(tmpV, tmpL); 13531 xxspltw(dst, tmpV, imm1); 13532 %} 13533 %} 13534 13535 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 13536 match(Set dst (ReplicateB zero)); 13537 predicate(n->as_Vector()->length() == 16); 13538 13539 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 13540 size(4); 13541 ins_encode %{ 13542 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13543 %} 13544 ins_pipe(pipe_class_default); 13545 %} 13546 13547 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 13548 match(Set dst (ReplicateB src)); 13549 predicate(n->as_Vector()->length() == 16); 13550 13551 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13552 size(4); 13553 ins_encode %{ 13554 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13555 %} 13556 ins_pipe(pipe_class_default); 13557 %} 13558 13559 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13560 match(Set dst (ReplicateS src)); 13561 predicate(n->as_Vector()->length() == 4); 13562 expand %{ 13563 moveReg(dst, src); 13564 repl48(dst); 13565 repl32(dst); 13566 %} 13567 %} 13568 13569 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 13570 match(Set dst (ReplicateS zero)); 13571 predicate(n->as_Vector()->length() == 4); 13572 format %{ "LI $dst, #0 \t// replicate4S" %} 13573 size(4); 13574 ins_encode %{ 13575 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13576 %} 13577 ins_pipe(pipe_class_default); 13578 %} 13579 13580 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13581 match(Set dst (ReplicateS src)); 13582 predicate(n->as_Vector()->length() == 4); 13583 format %{ "LI $dst, -1 \t// replicate4S" %} 13584 size(4); 13585 ins_encode %{ 13586 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13587 %} 13588 ins_pipe(pipe_class_default); 13589 %} 13590 13591 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 13592 match(Set dst (ReplicateS src)); 13593 predicate(n->as_Vector()->length() == 8); 13594 13595 expand %{ 13596 iRegLdst tmpL; 13597 vecX tmpV; 13598 immI8 zero %{ (int) 0 %} 13599 moveReg(tmpL, src); 13600 repl48(tmpL); 13601 repl32(tmpL); 13602 mtvsrd(tmpV, tmpL); 13603 xxpermdi(dst, tmpV, tmpV, zero); 13604 %} 13605 %} 13606 13607 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 13608 match(Set dst (ReplicateS zero)); 13609 predicate(n->as_Vector()->length() == 8); 13610 13611 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 13612 size(4); 13613 ins_encode %{ 13614 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13615 %} 13616 ins_pipe(pipe_class_default); 13617 %} 13618 13619 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 13620 match(Set dst (ReplicateS src)); 13621 predicate(n->as_Vector()->length() == 8); 13622 13623 format %{ "XXLEQV $dst, $src \t// replicate8S" %} 13624 size(4); 13625 ins_encode %{ 13626 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13627 %} 13628 ins_pipe(pipe_class_default); 13629 %} 13630 13631 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13632 match(Set dst (ReplicateI src)); 13633 predicate(n->as_Vector()->length() == 2); 13634 ins_cost(2 * DEFAULT_COST); 13635 expand %{ 13636 moveReg(dst, src); 13637 repl32(dst); 13638 %} 13639 %} 13640 13641 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 13642 match(Set dst (ReplicateI zero)); 13643 predicate(n->as_Vector()->length() == 2); 13644 format %{ "LI $dst, #0 \t// replicate2I" %} 13645 size(4); 13646 ins_encode %{ 13647 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13648 %} 13649 ins_pipe(pipe_class_default); 13650 %} 13651 13652 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13653 match(Set dst (ReplicateI src)); 13654 predicate(n->as_Vector()->length() == 2); 13655 format %{ "LI $dst, -1 \t// replicate2I" %} 13656 size(4); 13657 ins_encode %{ 13658 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13659 %} 13660 ins_pipe(pipe_class_default); 13661 %} 13662 13663 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 13664 match(Set dst (ReplicateI src)); 13665 predicate(n->as_Vector()->length() == 4); 13666 ins_cost(2 * DEFAULT_COST); 13667 13668 expand %{ 13669 iRegLdst tmpL; 13670 vecX tmpV; 13671 immI8 zero %{ (int) 0 %} 13672 moveReg(tmpL, src); 13673 repl32(tmpL); 13674 mtvsrd(tmpV, tmpL); 13675 xxpermdi(dst, tmpV, tmpV, zero); 13676 %} 13677 %} 13678 13679 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 13680 match(Set dst (ReplicateI zero)); 13681 predicate(n->as_Vector()->length() == 4); 13682 13683 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 13684 size(4); 13685 ins_encode %{ 13686 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13687 %} 13688 ins_pipe(pipe_class_default); 13689 %} 13690 13691 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 13692 match(Set dst (ReplicateI src)); 13693 predicate(n->as_Vector()->length() == 4); 13694 13695 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 13696 size(4); 13697 ins_encode %{ 13698 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13699 %} 13700 ins_pipe(pipe_class_default); 13701 %} 13702 13703 // Move float to int register via stack, replicate. 13704 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 13705 match(Set dst (ReplicateF src)); 13706 predicate(n->as_Vector()->length() == 2); 13707 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13708 expand %{ 13709 stackSlotL tmpS; 13710 iRegIdst tmpI; 13711 moveF2I_reg_stack(tmpS, src); // Move float to stack. 13712 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 13713 moveReg(dst, tmpI); // Move int to long reg. 13714 repl32(dst); // Replicate bitpattern. 13715 %} 13716 %} 13717 13718 // Replicate scalar constant to packed float values in Double register 13719 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 13720 match(Set dst (ReplicateF src)); 13721 predicate(n->as_Vector()->length() == 2); 13722 ins_cost(5 * DEFAULT_COST); 13723 13724 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 13725 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 13726 %} 13727 13728 // Replicate scalar zero constant to packed float values in Double register 13729 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 13730 match(Set dst (ReplicateF zero)); 13731 predicate(n->as_Vector()->length() == 2); 13732 13733 format %{ "LI $dst, #0 \t// replicate2F" %} 13734 ins_encode %{ 13735 __ li($dst$$Register, 0x0); 13736 %} 13737 ins_pipe(pipe_class_default); 13738 %} 13739 13740 13741 //----------Vector Arithmetic Instructions-------------------------------------- 13742 13743 // Vector Addition Instructions 13744 13745 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{ 13746 match(Set dst (AddVB src1 src2)); 13747 predicate(n->as_Vector()->length() == 16); 13748 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %} 13749 size(4); 13750 ins_encode %{ 13751 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13752 %} 13753 ins_pipe(pipe_class_default); 13754 %} 13755 13756 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{ 13757 match(Set dst (AddVS src1 src2)); 13758 predicate(n->as_Vector()->length() == 8); 13759 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %} 13760 size(4); 13761 ins_encode %{ 13762 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13763 %} 13764 ins_pipe(pipe_class_default); 13765 %} 13766 13767 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{ 13768 match(Set dst (AddVI src1 src2)); 13769 predicate(n->as_Vector()->length() == 4); 13770 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %} 13771 size(4); 13772 ins_encode %{ 13773 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13774 %} 13775 ins_pipe(pipe_class_default); 13776 %} 13777 13778 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{ 13779 match(Set dst (AddVF src1 src2)); 13780 predicate(n->as_Vector()->length() == 4); 13781 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %} 13782 size(4); 13783 ins_encode %{ 13784 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13785 %} 13786 ins_pipe(pipe_class_default); 13787 %} 13788 13789 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{ 13790 match(Set dst (AddVL src1 src2)); 13791 predicate(n->as_Vector()->length() == 2); 13792 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %} 13793 size(4); 13794 ins_encode %{ 13795 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13796 %} 13797 ins_pipe(pipe_class_default); 13798 %} 13799 13800 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{ 13801 match(Set dst (AddVD src1 src2)); 13802 predicate(n->as_Vector()->length() == 2); 13803 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %} 13804 size(4); 13805 ins_encode %{ 13806 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13807 %} 13808 ins_pipe(pipe_class_default); 13809 %} 13810 13811 // Vector Subtraction Instructions 13812 13813 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{ 13814 match(Set dst (SubVB src1 src2)); 13815 predicate(n->as_Vector()->length() == 16); 13816 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %} 13817 size(4); 13818 ins_encode %{ 13819 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13820 %} 13821 ins_pipe(pipe_class_default); 13822 %} 13823 13824 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{ 13825 match(Set dst (SubVS src1 src2)); 13826 predicate(n->as_Vector()->length() == 8); 13827 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %} 13828 size(4); 13829 ins_encode %{ 13830 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13831 %} 13832 ins_pipe(pipe_class_default); 13833 %} 13834 13835 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{ 13836 match(Set dst (SubVI src1 src2)); 13837 predicate(n->as_Vector()->length() == 4); 13838 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %} 13839 size(4); 13840 ins_encode %{ 13841 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13842 %} 13843 ins_pipe(pipe_class_default); 13844 %} 13845 13846 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{ 13847 match(Set dst (SubVF src1 src2)); 13848 predicate(n->as_Vector()->length() == 4); 13849 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %} 13850 size(4); 13851 ins_encode %{ 13852 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13853 %} 13854 ins_pipe(pipe_class_default); 13855 %} 13856 13857 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{ 13858 match(Set dst (SubVL src1 src2)); 13859 predicate(n->as_Vector()->length() == 2); 13860 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %} 13861 size(4); 13862 ins_encode %{ 13863 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13864 %} 13865 ins_pipe(pipe_class_default); 13866 %} 13867 13868 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{ 13869 match(Set dst (SubVD src1 src2)); 13870 predicate(n->as_Vector()->length() == 2); 13871 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %} 13872 size(4); 13873 ins_encode %{ 13874 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13875 %} 13876 ins_pipe(pipe_class_default); 13877 %} 13878 13879 // Vector Multiplication Instructions 13880 13881 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 13882 match(Set dst (MulVS src1 src2)); 13883 predicate(n->as_Vector()->length() == 8); 13884 effect(TEMP tmp); 13885 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %} 13886 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %} 13887 size(8); 13888 ins_encode %{ 13889 __ vspltish($tmp$$VectorSRegister->to_vr(), 0); 13890 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr()); 13891 %} 13892 ins_pipe(pipe_class_default); 13893 %} 13894 13895 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{ 13896 match(Set dst (MulVI src1 src2)); 13897 predicate(n->as_Vector()->length() == 4); 13898 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %} 13899 size(4); 13900 ins_encode %{ 13901 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13902 %} 13903 ins_pipe(pipe_class_default); 13904 %} 13905 13906 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{ 13907 match(Set dst (MulVF src1 src2)); 13908 predicate(n->as_Vector()->length() == 4); 13909 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %} 13910 size(4); 13911 ins_encode %{ 13912 __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13913 %} 13914 ins_pipe(pipe_class_default); 13915 %} 13916 13917 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{ 13918 match(Set dst (MulVD src1 src2)); 13919 predicate(n->as_Vector()->length() == 2); 13920 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %} 13921 size(4); 13922 ins_encode %{ 13923 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13924 %} 13925 ins_pipe(pipe_class_default); 13926 %} 13927 13928 // Vector Division Instructions 13929 13930 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{ 13931 match(Set dst (DivVF src1 src2)); 13932 predicate(n->as_Vector()->length() == 4); 13933 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %} 13934 size(4); 13935 ins_encode %{ 13936 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13937 %} 13938 ins_pipe(pipe_class_default); 13939 %} 13940 13941 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ 13942 match(Set dst (DivVD src1 src2)); 13943 predicate(n->as_Vector()->length() == 2); 13944 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %} 13945 size(4); 13946 ins_encode %{ 13947 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13948 %} 13949 ins_pipe(pipe_class_default); 13950 %} 13951 13952 // Vector Absolute Instructions 13953 13954 instruct vabs4F_reg(vecX dst, vecX src) %{ 13955 match(Set dst (AbsVF src)); 13956 predicate(n->as_Vector()->length() == 4); 13957 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %} 13958 size(4); 13959 ins_encode %{ 13960 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister); 13961 %} 13962 ins_pipe(pipe_class_default); 13963 %} 13964 13965 instruct vabs2D_reg(vecX dst, vecX src) %{ 13966 match(Set dst (AbsVD src)); 13967 predicate(n->as_Vector()->length() == 2); 13968 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %} 13969 size(4); 13970 ins_encode %{ 13971 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister); 13972 %} 13973 ins_pipe(pipe_class_default); 13974 %} 13975 13976 // Round Instructions 13977 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{ 13978 match(Set dst (RoundDoubleMode src rmode)); 13979 format %{ "RoundDoubleMode $src,$rmode" %} 13980 size(4); 13981 ins_encode %{ 13982 switch ($rmode$$constant) { 13983 case RoundDoubleModeNode::rmode_rint: 13984 __ xvrdpic($dst$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr()); 13985 break; 13986 case RoundDoubleModeNode::rmode_floor: 13987 __ frim($dst$$FloatRegister, $src$$FloatRegister); 13988 break; 13989 case RoundDoubleModeNode::rmode_ceil: 13990 __ frip($dst$$FloatRegister, $src$$FloatRegister); 13991 break; 13992 default: 13993 ShouldNotReachHere(); 13994 } 13995 %} 13996 ins_pipe(pipe_class_default); 13997 %} 13998 13999 // Vector Round Instructions 14000 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{ 14001 match(Set dst (RoundDoubleModeV src rmode)); 14002 predicate(n->as_Vector()->length() == 2); 14003 format %{ "RoundDoubleModeV $src,$rmode" %} 14004 size(4); 14005 ins_encode %{ 14006 switch ($rmode$$constant) { 14007 case RoundDoubleModeNode::rmode_rint: 14008 __ xvrdpic($dst$$VectorSRegister, $src$$VectorSRegister); 14009 break; 14010 case RoundDoubleModeNode::rmode_floor: 14011 __ xvrdpim($dst$$VectorSRegister, $src$$VectorSRegister); 14012 break; 14013 case RoundDoubleModeNode::rmode_ceil: 14014 __ xvrdpip($dst$$VectorSRegister, $src$$VectorSRegister); 14015 break; 14016 default: 14017 ShouldNotReachHere(); 14018 } 14019 %} 14020 ins_pipe(pipe_class_default); 14021 %} 14022 14023 // Vector Negate Instructions 14024 14025 instruct vneg4F_reg(vecX dst, vecX src) %{ 14026 match(Set dst (NegVF src)); 14027 predicate(n->as_Vector()->length() == 4); 14028 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %} 14029 size(4); 14030 ins_encode %{ 14031 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister); 14032 %} 14033 ins_pipe(pipe_class_default); 14034 %} 14035 14036 instruct vneg2D_reg(vecX dst, vecX src) %{ 14037 match(Set dst (NegVD src)); 14038 predicate(n->as_Vector()->length() == 2); 14039 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %} 14040 size(4); 14041 ins_encode %{ 14042 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister); 14043 %} 14044 ins_pipe(pipe_class_default); 14045 %} 14046 14047 // Vector Square Root Instructions 14048 14049 instruct vsqrt4F_reg(vecX dst, vecX src) %{ 14050 match(Set dst (SqrtVF src)); 14051 predicate(n->as_Vector()->length() == 4); 14052 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %} 14053 size(4); 14054 ins_encode %{ 14055 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister); 14056 %} 14057 ins_pipe(pipe_class_default); 14058 %} 14059 14060 instruct vsqrt2D_reg(vecX dst, vecX src) %{ 14061 match(Set dst (SqrtVD src)); 14062 predicate(n->as_Vector()->length() == 2); 14063 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %} 14064 size(4); 14065 ins_encode %{ 14066 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister); 14067 %} 14068 ins_pipe(pipe_class_default); 14069 %} 14070 14071 // Vector Population Count Instructions 14072 14073 instruct vpopcnt_reg(vecX dst, vecX src) %{ 14074 match(Set dst (PopCountVI src)); 14075 format %{ "VPOPCNT $dst,$src\t// pop count packed" %} 14076 size(4); 14077 ins_encode %{ 14078 BasicType bt = Matcher::vector_element_basic_type(this); 14079 switch (bt) { 14080 case T_BYTE: 14081 __ vpopcntb($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14082 break; 14083 case T_SHORT: 14084 __ vpopcnth($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14085 break; 14086 case T_INT: 14087 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14088 break; 14089 case T_LONG: 14090 __ vpopcntd($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14091 break; 14092 default: 14093 ShouldNotReachHere(); 14094 } 14095 %} 14096 ins_pipe(pipe_class_default); 14097 %} 14098 14099 // --------------------------------- FMA -------------------------------------- 14100 // dst + src1 * src2 14101 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{ 14102 match(Set dst (FmaVF dst (Binary src1 src2))); 14103 predicate(n->as_Vector()->length() == 4); 14104 14105 format %{ "XVMADDASP $dst, $src1, $src2" %} 14106 14107 size(4); 14108 ins_encode %{ 14109 __ xvmaddasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14110 %} 14111 ins_pipe(pipe_class_default); 14112 %} 14113 14114 // dst - src1 * src2 14115 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{ 14116 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 14117 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 14118 predicate(n->as_Vector()->length() == 4); 14119 14120 format %{ "XVNMSUBASP $dst, $src1, $src2" %} 14121 14122 size(4); 14123 ins_encode %{ 14124 __ xvnmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14125 %} 14126 ins_pipe(pipe_class_default); 14127 %} 14128 14129 // - dst + src1 * src2 14130 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{ 14131 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2))); 14132 predicate(n->as_Vector()->length() == 4); 14133 14134 format %{ "XVMSUBASP $dst, $src1, $src2" %} 14135 14136 size(4); 14137 ins_encode %{ 14138 __ xvmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14139 %} 14140 ins_pipe(pipe_class_default); 14141 %} 14142 14143 // dst + src1 * src2 14144 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{ 14145 match(Set dst (FmaVD dst (Binary src1 src2))); 14146 predicate(n->as_Vector()->length() == 2); 14147 14148 format %{ "XVMADDADP $dst, $src1, $src2" %} 14149 14150 size(4); 14151 ins_encode %{ 14152 __ xvmaddadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14153 %} 14154 ins_pipe(pipe_class_default); 14155 %} 14156 14157 // dst - src1 * src2 14158 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{ 14159 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 14160 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 14161 predicate(n->as_Vector()->length() == 2); 14162 14163 format %{ "XVNMSUBADP $dst, $src1, $src2" %} 14164 14165 size(4); 14166 ins_encode %{ 14167 __ xvnmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14168 %} 14169 ins_pipe(pipe_class_default); 14170 %} 14171 14172 // - dst + src1 * src2 14173 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{ 14174 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2))); 14175 predicate(n->as_Vector()->length() == 2); 14176 14177 format %{ "XVMSUBADP $dst, $src1, $src2" %} 14178 14179 size(4); 14180 ins_encode %{ 14181 __ xvmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14182 %} 14183 ins_pipe(pipe_class_default); 14184 %} 14185 14186 //----------Overflow Math Instructions----------------------------------------- 14187 14188 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 14189 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14190 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14191 14192 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14193 match(Set cr0 (OverflowAddL op1 op2)); 14194 14195 format %{ "add_ $op1, $op2\t# overflow check long" %} 14196 ins_encode %{ 14197 __ li(R0, 0); 14198 __ mtxer(R0); // clear XER.SO 14199 __ addo_(R0, $op1$$Register, $op2$$Register); 14200 %} 14201 ins_pipe(pipe_class_default); 14202 %} 14203 14204 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14205 match(Set cr0 (OverflowSubL op1 op2)); 14206 14207 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14208 ins_encode %{ 14209 __ li(R0, 0); 14210 __ mtxer(R0); // clear XER.SO 14211 __ subfo_(R0, $op2$$Register, $op1$$Register); 14212 %} 14213 ins_pipe(pipe_class_default); 14214 %} 14215 14216 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14217 match(Set cr0 (OverflowSubL zero op2)); 14218 14219 format %{ "nego_ R0, $op2\t# overflow check long" %} 14220 ins_encode %{ 14221 __ li(R0, 0); 14222 __ mtxer(R0); // clear XER.SO 14223 __ nego_(R0, $op2$$Register); 14224 %} 14225 ins_pipe(pipe_class_default); 14226 %} 14227 14228 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14229 match(Set cr0 (OverflowMulL op1 op2)); 14230 14231 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14232 ins_encode %{ 14233 __ li(R0, 0); 14234 __ mtxer(R0); // clear XER.SO 14235 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14236 %} 14237 ins_pipe(pipe_class_default); 14238 %} 14239 14240 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14241 match(Set dst (ReplicateF src)); 14242 predicate(n->as_Vector()->length() == 4); 14243 ins_cost(DEFAULT_COST); 14244 expand %{ 14245 vecX tmpV; 14246 immI8 zero %{ (int) 0 %} 14247 14248 xscvdpspn_regF(tmpV, src); 14249 xxspltw(dst, tmpV, zero); 14250 %} 14251 %} 14252 14253 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14254 match(Set dst (ReplicateF src)); 14255 predicate(n->as_Vector()->length() == 4); 14256 effect(TEMP tmp); 14257 ins_cost(10 * DEFAULT_COST); 14258 14259 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14260 %} 14261 14262 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14263 match(Set dst (ReplicateF zero)); 14264 predicate(n->as_Vector()->length() == 4); 14265 14266 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14267 ins_encode %{ 14268 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14269 %} 14270 ins_pipe(pipe_class_default); 14271 %} 14272 14273 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14274 match(Set dst (ReplicateD src)); 14275 predicate(n->as_Vector()->length() == 2); 14276 14277 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %} 14278 size(4); 14279 ins_encode %{ 14280 __ xxpermdi($dst$$VectorSRegister, $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0); 14281 %} 14282 ins_pipe(pipe_class_default); 14283 %} 14284 14285 instruct repl2D_immD0(vecX dst, immD_0 zero) %{ 14286 match(Set dst (ReplicateD zero)); 14287 predicate(n->as_Vector()->length() == 2); 14288 14289 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14290 size(4); 14291 ins_encode %{ 14292 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14293 %} 14294 ins_pipe(pipe_class_default); 14295 %} 14296 14297 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14298 predicate(false); 14299 effect(DEF dst, USE src); 14300 14301 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %} 14302 size(4); 14303 ins_encode %{ 14304 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14305 %} 14306 ins_pipe(pipe_class_default); 14307 %} 14308 14309 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14310 effect(DEF dst, USE src, USE zero); 14311 14312 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %} 14313 size(4); 14314 ins_encode %{ 14315 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14316 %} 14317 ins_pipe(pipe_class_default); 14318 %} 14319 14320 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14321 effect(DEF dst, USE src1, USE src2, USE zero); 14322 14323 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %} 14324 size(4); 14325 ins_encode %{ 14326 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14327 %} 14328 ins_pipe(pipe_class_default); 14329 %} 14330 14331 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14332 match(Set dst (ReplicateL src)); 14333 predicate(n->as_Vector()->length() == 2); 14334 expand %{ 14335 vecX tmpV; 14336 immI8 zero %{ (int) 0 %} 14337 mtvsrd(tmpV, src); 14338 xxpermdi(dst, tmpV, tmpV, zero); 14339 %} 14340 %} 14341 14342 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14343 match(Set dst (ReplicateL zero)); 14344 predicate(n->as_Vector()->length() == 2); 14345 14346 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14347 size(4); 14348 ins_encode %{ 14349 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14350 %} 14351 ins_pipe(pipe_class_default); 14352 %} 14353 14354 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14355 match(Set dst (ReplicateL src)); 14356 predicate(n->as_Vector()->length() == 2); 14357 14358 format %{ "XXLEQV $dst, $src \t// replicate2L" %} 14359 size(4); 14360 ins_encode %{ 14361 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14362 %} 14363 ins_pipe(pipe_class_default); 14364 %} 14365 14366 // ============================================================================ 14367 // Safepoint Instruction 14368 14369 instruct safePoint_poll(iRegPdst poll) %{ 14370 match(SafePoint poll); 14371 14372 // It caused problems to add the effect that r0 is killed, but this 14373 // effect no longer needs to be mentioned, since r0 is not contained 14374 // in a reg_class. 14375 14376 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14377 size(4); 14378 ins_encode( enc_poll(0x0, poll) ); 14379 ins_pipe(pipe_class_default); 14380 %} 14381 14382 // ============================================================================ 14383 // Call Instructions 14384 14385 // Call Java Static Instruction 14386 14387 source %{ 14388 14389 #include "runtime/continuation.hpp" 14390 14391 %} 14392 14393 // Schedulable version of call static node. 14394 instruct CallStaticJavaDirect(method meth) %{ 14395 match(CallStaticJava); 14396 effect(USE meth); 14397 ins_cost(CALL_COST); 14398 14399 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14400 14401 format %{ "CALL,static $meth \t// ==> " %} 14402 size((Continuations::enabled() ? 8 : 4)); 14403 ins_encode( enc_java_static_call(meth) ); 14404 ins_pipe(pipe_class_call); 14405 %} 14406 14407 // Call Java Dynamic Instruction 14408 14409 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14410 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14411 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14412 // The call destination must still be placed in the constant pool. 14413 instruct CallDynamicJavaDirectSched(method meth) %{ 14414 match(CallDynamicJava); // To get all the data fields we need ... 14415 effect(USE meth); 14416 predicate(false); // ... but never match. 14417 14418 ins_field_load_ic_hi_node(loadConL_hiNode*); 14419 ins_field_load_ic_node(loadConLNode*); 14420 ins_num_consts(1 /* 1 patchable constant: call destination */); 14421 14422 format %{ "BL \t// dynamic $meth ==> " %} 14423 size((Continuations::enabled() ? 8 : 4)); 14424 ins_encode( enc_java_dynamic_call_sched(meth) ); 14425 ins_pipe(pipe_class_call); 14426 %} 14427 14428 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14429 // We use postalloc expanded calls if we use inline caches 14430 // and do not update method data. 14431 // 14432 // This instruction has two constants: inline cache (IC) and call destination. 14433 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14434 // one constant. 14435 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14436 match(CallDynamicJava); 14437 effect(USE meth); 14438 predicate(UseInlineCaches); 14439 ins_cost(CALL_COST); 14440 14441 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14442 14443 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14444 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14445 %} 14446 14447 // Compound version of call dynamic java 14448 // We use postalloc expanded calls if we use inline caches 14449 // and do not update method data. 14450 instruct CallDynamicJavaDirect(method meth) %{ 14451 match(CallDynamicJava); 14452 effect(USE meth); 14453 predicate(!UseInlineCaches); 14454 ins_cost(CALL_COST); 14455 14456 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14457 ins_num_consts(4); 14458 14459 format %{ "CALL,dynamic $meth \t// ==> " %} 14460 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14461 ins_pipe(pipe_class_call); 14462 %} 14463 14464 // Call Runtime Instruction 14465 14466 instruct CallRuntimeDirect(method meth) %{ 14467 match(CallRuntime); 14468 effect(USE meth); 14469 ins_cost(CALL_COST); 14470 14471 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14472 // env for callee, C-toc. 14473 ins_num_consts(3); 14474 14475 format %{ "CALL,runtime" %} 14476 ins_encode( enc_java_to_runtime_call(meth) ); 14477 ins_pipe(pipe_class_call); 14478 %} 14479 14480 // Call Leaf 14481 14482 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14483 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14484 effect(DEF dst, USE src); 14485 14486 ins_num_consts(1); 14487 14488 format %{ "MTCTR $src" %} 14489 size(4); 14490 ins_encode( enc_leaf_call_mtctr(src) ); 14491 ins_pipe(pipe_class_default); 14492 %} 14493 14494 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 14495 instruct CallLeafDirect(method meth) %{ 14496 match(CallLeaf); // To get the data all the data fields we need ... 14497 effect(USE meth); 14498 predicate(false); // but never match. 14499 14500 format %{ "BCTRL \t// leaf call $meth ==> " %} 14501 size((Continuations::enabled() ? 8 : 4)); 14502 ins_encode %{ 14503 __ bctrl(); 14504 __ post_call_nop(); 14505 %} 14506 ins_pipe(pipe_class_call); 14507 %} 14508 14509 // postalloc expand of CallLeafDirect. 14510 // Load address to call from TOC, then bl to it. 14511 instruct CallLeafDirect_Ex(method meth) %{ 14512 match(CallLeaf); 14513 effect(USE meth); 14514 ins_cost(CALL_COST); 14515 14516 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14517 // env for callee, C-toc. 14518 ins_num_consts(3); 14519 14520 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14521 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14522 %} 14523 14524 // Call runtime without safepoint - same as CallLeaf. 14525 // postalloc expand of CallLeafNoFPDirect. 14526 // Load address to call from TOC, then bl to it. 14527 instruct CallLeafNoFPDirect_Ex(method meth) %{ 14528 match(CallLeafNoFP); 14529 effect(USE meth); 14530 ins_cost(CALL_COST); 14531 14532 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14533 // env for callee, C-toc. 14534 ins_num_consts(3); 14535 14536 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14537 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14538 %} 14539 14540 // Tail Call; Jump from runtime stub to Java code. 14541 // Also known as an 'interprocedural jump'. 14542 // Target of jump will eventually return to caller. 14543 // TailJump below removes the return address. 14544 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ptr) %{ 14545 match(TailCall jump_target method_ptr); 14546 ins_cost(CALL_COST); 14547 14548 format %{ "MTCTR $jump_target \t// $method_ptr holds method\n\t" 14549 "BCTR \t// tail call" %} 14550 size(8); 14551 ins_encode %{ 14552 __ mtctr($jump_target$$Register); 14553 __ bctr(); 14554 %} 14555 ins_pipe(pipe_class_call); 14556 %} 14557 14558 // Return Instruction 14559 instruct Ret() %{ 14560 match(Return); 14561 format %{ "BLR \t// branch to link register" %} 14562 size(4); 14563 ins_encode %{ 14564 // LR is restored in MachEpilogNode. Just do the RET here. 14565 __ blr(); 14566 %} 14567 ins_pipe(pipe_class_default); 14568 %} 14569 14570 // Tail Jump; remove the return address; jump to target. 14571 // TailCall above leaves the return address around. 14572 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14573 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14574 // "restore" before this instruction (in Epilogue), we need to materialize it 14575 // in %i0. 14576 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14577 match(TailJump jump_target ex_oop); 14578 ins_cost(CALL_COST); 14579 14580 format %{ "LD R4_ARG2 = LR\n\t" 14581 "MTCTR $jump_target\n\t" 14582 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14583 size(12); 14584 ins_encode %{ 14585 __ ld(R4_ARG2/* issuing pc */, _abi0(lr), R1_SP); 14586 __ mtctr($jump_target$$Register); 14587 __ bctr(); 14588 %} 14589 ins_pipe(pipe_class_call); 14590 %} 14591 14592 // Create exception oop: created by stack-crawling runtime code. 14593 // Created exception is now available to this handler, and is setup 14594 // just prior to jumping to this handler. No code emitted. 14595 instruct CreateException(rarg1RegP ex_oop) %{ 14596 match(Set ex_oop (CreateEx)); 14597 ins_cost(0); 14598 14599 format %{ " -- \t// exception oop; no code emitted" %} 14600 size(0); 14601 ins_encode( /*empty*/ ); 14602 ins_pipe(pipe_class_default); 14603 %} 14604 14605 // Rethrow exception: The exception oop will come in the first 14606 // argument position. Then JUMP (not call) to the rethrow stub code. 14607 instruct RethrowException() %{ 14608 match(Rethrow); 14609 ins_cost(CALL_COST); 14610 14611 format %{ "Jmp rethrow_stub" %} 14612 ins_encode %{ 14613 cbuf.set_insts_mark(); 14614 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 14615 %} 14616 ins_pipe(pipe_class_call); 14617 %} 14618 14619 // Die now. 14620 instruct ShouldNotReachHere() %{ 14621 match(Halt); 14622 ins_cost(CALL_COST); 14623 14624 format %{ "ShouldNotReachHere" %} 14625 ins_encode %{ 14626 if (is_reachable()) { 14627 __ stop(_halt_reason); 14628 } 14629 %} 14630 ins_pipe(pipe_class_default); 14631 %} 14632 14633 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 14634 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 14635 // Get a DEF on threadRegP, no costs, no encoding, use 14636 // 'ins_should_rematerialize(true)' to avoid spilling. 14637 instruct tlsLoadP(threadRegP dst) %{ 14638 match(Set dst (ThreadLocal)); 14639 ins_cost(0); 14640 14641 ins_should_rematerialize(true); 14642 14643 format %{ " -- \t// $dst=Thread::current(), empty" %} 14644 size(0); 14645 ins_encode( /*empty*/ ); 14646 ins_pipe(pipe_class_empty); 14647 %} 14648 14649 //---Some PPC specific nodes--------------------------------------------------- 14650 14651 // Stop a group. 14652 instruct endGroup() %{ 14653 ins_cost(0); 14654 14655 ins_is_nop(true); 14656 14657 format %{ "End Bundle (ori r1, r1, 0)" %} 14658 size(4); 14659 ins_encode %{ 14660 __ endgroup(); 14661 %} 14662 ins_pipe(pipe_class_default); 14663 %} 14664 14665 // Nop instructions 14666 14667 instruct fxNop() %{ 14668 ins_cost(0); 14669 14670 ins_is_nop(true); 14671 14672 format %{ "fxNop" %} 14673 size(4); 14674 ins_encode %{ 14675 __ nop(); 14676 %} 14677 ins_pipe(pipe_class_default); 14678 %} 14679 14680 instruct fpNop0() %{ 14681 ins_cost(0); 14682 14683 ins_is_nop(true); 14684 14685 format %{ "fpNop0" %} 14686 size(4); 14687 ins_encode %{ 14688 __ fpnop0(); 14689 %} 14690 ins_pipe(pipe_class_default); 14691 %} 14692 14693 instruct fpNop1() %{ 14694 ins_cost(0); 14695 14696 ins_is_nop(true); 14697 14698 format %{ "fpNop1" %} 14699 size(4); 14700 ins_encode %{ 14701 __ fpnop1(); 14702 %} 14703 ins_pipe(pipe_class_default); 14704 %} 14705 14706 instruct brNop0() %{ 14707 ins_cost(0); 14708 size(4); 14709 format %{ "brNop0" %} 14710 ins_encode %{ 14711 __ brnop0(); 14712 %} 14713 ins_is_nop(true); 14714 ins_pipe(pipe_class_default); 14715 %} 14716 14717 instruct brNop1() %{ 14718 ins_cost(0); 14719 14720 ins_is_nop(true); 14721 14722 format %{ "brNop1" %} 14723 size(4); 14724 ins_encode %{ 14725 __ brnop1(); 14726 %} 14727 ins_pipe(pipe_class_default); 14728 %} 14729 14730 instruct brNop2() %{ 14731 ins_cost(0); 14732 14733 ins_is_nop(true); 14734 14735 format %{ "brNop2" %} 14736 size(4); 14737 ins_encode %{ 14738 __ brnop2(); 14739 %} 14740 ins_pipe(pipe_class_default); 14741 %} 14742 14743 instruct cacheWB(indirect addr) 14744 %{ 14745 match(CacheWB addr); 14746 14747 ins_cost(100); 14748 format %{ "cache writeback, address = $addr" %} 14749 ins_encode %{ 14750 assert($addr->index_position() < 0, "should be"); 14751 assert($addr$$disp == 0, "should be"); 14752 __ cache_wb(Address($addr$$base$$Register)); 14753 %} 14754 ins_pipe(pipe_class_default); 14755 %} 14756 14757 instruct cacheWBPreSync() 14758 %{ 14759 match(CacheWBPreSync); 14760 14761 ins_cost(0); 14762 format %{ "cache writeback presync" %} 14763 ins_encode %{ 14764 __ cache_wbsync(true); 14765 %} 14766 ins_pipe(pipe_class_default); 14767 %} 14768 14769 instruct cacheWBPostSync() 14770 %{ 14771 match(CacheWBPostSync); 14772 14773 ins_cost(100); 14774 format %{ "cache writeback postsync" %} 14775 ins_encode %{ 14776 __ cache_wbsync(false); 14777 %} 14778 ins_pipe(pipe_class_default); 14779 %} 14780 14781 //----------PEEPHOLE RULES----------------------------------------------------- 14782 // These must follow all instruction definitions as they use the names 14783 // defined in the instructions definitions. 14784 // 14785 // peepmatch ( root_instr_name [preceeding_instruction]* ); 14786 // 14787 // peepconstraint %{ 14788 // (instruction_number.operand_name relational_op instruction_number.operand_name 14789 // [, ...] ); 14790 // // instruction numbers are zero-based using left to right order in peepmatch 14791 // 14792 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14793 // // provide an instruction_number.operand_name for each operand that appears 14794 // // in the replacement instruction's match rule 14795 // 14796 // ---------VM FLAGS--------------------------------------------------------- 14797 // 14798 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14799 // 14800 // Each peephole rule is given an identifying number starting with zero and 14801 // increasing by one in the order seen by the parser. An individual peephole 14802 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14803 // on the command-line. 14804 // 14805 // ---------CURRENT LIMITATIONS---------------------------------------------- 14806 // 14807 // Only match adjacent instructions in same basic block 14808 // Only equality constraints 14809 // Only constraints between operands, not (0.dest_reg == EAX_enc) 14810 // Only one replacement instruction 14811 // 14812 // ---------EXAMPLE---------------------------------------------------------- 14813 // 14814 // // pertinent parts of existing instructions in architecture description 14815 // instruct movI(eRegI dst, eRegI src) %{ 14816 // match(Set dst (CopyI src)); 14817 // %} 14818 // 14819 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 14820 // match(Set dst (AddI dst src)); 14821 // effect(KILL cr); 14822 // %} 14823 // 14824 // // Change (inc mov) to lea 14825 // peephole %{ 14826 // // increment preceded by register-register move 14827 // peepmatch ( incI_eReg movI ); 14828 // // require that the destination register of the increment 14829 // // match the destination register of the move 14830 // peepconstraint ( 0.dst == 1.dst ); 14831 // // construct a replacement instruction that sets 14832 // // the destination to ( move's source register + one ) 14833 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14834 // %} 14835 // 14836 // Implementation no longer uses movX instructions since 14837 // machine-independent system no longer uses CopyX nodes. 14838 // 14839 // peephole %{ 14840 // peepmatch ( incI_eReg movI ); 14841 // peepconstraint ( 0.dst == 1.dst ); 14842 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14843 // %} 14844 // 14845 // peephole %{ 14846 // peepmatch ( decI_eReg movI ); 14847 // peepconstraint ( 0.dst == 1.dst ); 14848 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14849 // %} 14850 // 14851 // peephole %{ 14852 // peepmatch ( addI_eReg_imm movI ); 14853 // peepconstraint ( 0.dst == 1.dst ); 14854 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14855 // %} 14856 // 14857 // peephole %{ 14858 // peepmatch ( addP_eReg_imm movP ); 14859 // peepconstraint ( 0.dst == 1.dst ); 14860 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 14861 // %} 14862 14863 // // Change load of spilled value to only a spill 14864 // instruct storeI(memory mem, eRegI src) %{ 14865 // match(Set mem (StoreI mem src)); 14866 // %} 14867 // 14868 // instruct loadI(eRegI dst, memory mem) %{ 14869 // match(Set dst (LoadI mem)); 14870 // %} 14871 // 14872 peephole %{ 14873 peepmatch ( loadI storeI ); 14874 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14875 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 14876 %} 14877 14878 peephole %{ 14879 peepmatch ( loadL storeL ); 14880 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14881 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 14882 %} 14883 14884 peephole %{ 14885 peepmatch ( loadP storeP ); 14886 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 14887 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 14888 %} 14889 14890 //----------SMARTSPILL RULES--------------------------------------------------- 14891 // These must follow all instruction definitions as they use the names 14892 // defined in the instructions definitions.