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 == nullptr) { 2066 ciEnv::current()->record_failure("CodeCache is full"); 2067 return 0; // CodeBuffer::expand failed 2068 } 2069 2070 int offset = __ offset(); 2071 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2072 relocInfo::runtime_call_type); 2073 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2074 __ end_a_stub(); 2075 2076 return offset; 2077 } 2078 2079 // The deopt_handler is like the exception handler, but it calls to 2080 // the deoptimization blob instead of jumping to the exception blob. 2081 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2082 C2_MacroAssembler _masm(&cbuf); 2083 2084 address base = __ start_a_stub(size_deopt_handler()); 2085 if (base == nullptr) { 2086 ciEnv::current()->record_failure("CodeCache is full"); 2087 return 0; // CodeBuffer::expand failed 2088 } 2089 2090 int offset = __ offset(); 2091 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2092 relocInfo::runtime_call_type); 2093 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2094 __ end_a_stub(); 2095 2096 return offset; 2097 } 2098 2099 //============================================================================= 2100 2101 // Use a frame slots bias for frameless methods if accessing the stack. 2102 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2103 if (as_Register(reg_enc) == R1_SP) { 2104 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2105 } 2106 return 0; 2107 } 2108 2109 const bool Matcher::match_rule_supported(int opcode) { 2110 if (!has_match_rule(opcode)) { 2111 return false; // no match rule present 2112 } 2113 2114 switch (opcode) { 2115 case Op_SqrtD: 2116 return VM_Version::has_fsqrt(); 2117 case Op_RoundDoubleMode: 2118 return VM_Version::has_vsx(); 2119 case Op_CountLeadingZerosI: 2120 case Op_CountLeadingZerosL: 2121 return UseCountLeadingZerosInstructionsPPC64; 2122 case Op_CountTrailingZerosI: 2123 case Op_CountTrailingZerosL: 2124 return (UseCountLeadingZerosInstructionsPPC64 || UseCountTrailingZerosInstructionsPPC64); 2125 case Op_PopCountI: 2126 case Op_PopCountL: 2127 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2128 2129 case Op_AddVB: 2130 case Op_AddVS: 2131 case Op_AddVI: 2132 case Op_AddVF: 2133 case Op_AddVD: 2134 case Op_SubVB: 2135 case Op_SubVS: 2136 case Op_SubVI: 2137 case Op_SubVF: 2138 case Op_SubVD: 2139 case Op_MulVS: 2140 case Op_MulVF: 2141 case Op_MulVD: 2142 case Op_DivVF: 2143 case Op_DivVD: 2144 case Op_AbsVF: 2145 case Op_AbsVD: 2146 case Op_NegVF: 2147 case Op_NegVD: 2148 case Op_SqrtVF: 2149 case Op_SqrtVD: 2150 case Op_AddVL: 2151 case Op_SubVL: 2152 case Op_MulVI: 2153 case Op_RoundDoubleModeV: 2154 return SuperwordUseVSX; 2155 case Op_PopCountVI: 2156 return (SuperwordUseVSX && UsePopCountInstruction); 2157 case Op_FmaVF: 2158 case Op_FmaVD: 2159 return (SuperwordUseVSX && UseFMA); 2160 2161 case Op_Digit: 2162 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isDigit); 2163 case Op_LowerCase: 2164 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isLowerCase); 2165 case Op_UpperCase: 2166 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isUpperCase); 2167 case Op_Whitespace: 2168 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isWhitespace); 2169 2170 case Op_CacheWB: 2171 case Op_CacheWBPreSync: 2172 case Op_CacheWBPostSync: 2173 return VM_Version::supports_data_cache_line_flush(); 2174 } 2175 2176 return true; // Per default match rules are supported. 2177 } 2178 2179 const bool Matcher::match_rule_supported_superword(int opcode, int vlen, BasicType bt) { 2180 return match_rule_supported_vector(opcode, vlen, bt); 2181 } 2182 2183 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { 2184 if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) { 2185 return false; 2186 } 2187 return true; // Per default match rules are supported. 2188 } 2189 2190 const bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) { 2191 return false; 2192 } 2193 2194 const bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) { 2195 return false; 2196 } 2197 2198 const RegMask* Matcher::predicate_reg_mask(void) { 2199 return NULL; 2200 } 2201 2202 const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) { 2203 return NULL; 2204 } 2205 2206 // Vector calling convention not yet implemented. 2207 const bool Matcher::supports_vector_calling_convention(void) { 2208 return false; 2209 } 2210 2211 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 2212 Unimplemented(); 2213 return OptoRegPair(0, 0); 2214 } 2215 2216 // Vector width in bytes. 2217 const int Matcher::vector_width_in_bytes(BasicType bt) { 2218 if (SuperwordUseVSX) { 2219 assert(MaxVectorSize == 16, ""); 2220 return 16; 2221 } else { 2222 assert(MaxVectorSize == 8, ""); 2223 return 8; 2224 } 2225 } 2226 2227 // Vector ideal reg. 2228 const uint Matcher::vector_ideal_reg(int size) { 2229 if (SuperwordUseVSX) { 2230 assert(MaxVectorSize == 16 && size == 16, ""); 2231 return Op_VecX; 2232 } else { 2233 assert(MaxVectorSize == 8 && size == 8, ""); 2234 return Op_RegL; 2235 } 2236 } 2237 2238 // Limits on vector size (number of elements) loaded into vector. 2239 const int Matcher::max_vector_size(const BasicType bt) { 2240 assert(is_java_primitive(bt), "only primitive type vectors"); 2241 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2242 } 2243 2244 const int Matcher::min_vector_size(const BasicType bt) { 2245 return max_vector_size(bt); // Same as max. 2246 } 2247 2248 const int Matcher::superword_max_vector_size(const BasicType bt) { 2249 return Matcher::max_vector_size(bt); 2250 } 2251 2252 const int Matcher::scalable_vector_reg_size(const BasicType bt) { 2253 return -1; 2254 } 2255 2256 // RETURNS: whether this branch offset is short enough that a short 2257 // branch can be used. 2258 // 2259 // If the platform does not provide any short branch variants, then 2260 // this method should return `false' for offset 0. 2261 // 2262 // `Compile::Fill_buffer' will decide on basis of this information 2263 // whether to do the pass `Compile::Shorten_branches' at all. 2264 // 2265 // And `Compile::Shorten_branches' will decide on basis of this 2266 // information whether to replace particular branch sites by short 2267 // ones. 2268 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2269 // Is the offset within the range of a ppc64 pc relative branch? 2270 bool b; 2271 2272 const int safety_zone = 3 * BytesPerInstWord; 2273 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2274 29 - 16 + 1 + 2); 2275 return b; 2276 } 2277 2278 /* TODO: PPC port 2279 // Make a new machine dependent decode node (with its operands). 2280 MachTypeNode *Matcher::make_decode_node() { 2281 assert(CompressedOops::base() == NULL && CompressedOops::shift() == 0, 2282 "This method is only implemented for unscaled cOops mode so far"); 2283 MachTypeNode *decode = new decodeN_unscaledNode(); 2284 decode->set_opnd_array(0, new iRegPdstOper()); 2285 decode->set_opnd_array(1, new iRegNsrcOper()); 2286 return decode; 2287 } 2288 */ 2289 2290 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { 2291 ShouldNotReachHere(); // generic vector operands not supported 2292 return NULL; 2293 } 2294 2295 bool Matcher::is_reg2reg_move(MachNode* m) { 2296 ShouldNotReachHere(); // generic vector operands not supported 2297 return false; 2298 } 2299 2300 bool Matcher::is_generic_vector(MachOper* opnd) { 2301 ShouldNotReachHere(); // generic vector operands not supported 2302 return false; 2303 } 2304 2305 // Constants for c2c and c calling conventions. 2306 2307 const MachRegisterNumbers iarg_reg[8] = { 2308 R3_num, R4_num, R5_num, R6_num, 2309 R7_num, R8_num, R9_num, R10_num 2310 }; 2311 2312 const MachRegisterNumbers farg_reg[13] = { 2313 F1_num, F2_num, F3_num, F4_num, 2314 F5_num, F6_num, F7_num, F8_num, 2315 F9_num, F10_num, F11_num, F12_num, 2316 F13_num 2317 }; 2318 2319 const MachRegisterNumbers vsarg_reg[64] = { 2320 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2321 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2322 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2323 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2324 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2325 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2326 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2327 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2328 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2329 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2330 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2331 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2332 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2333 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2334 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2335 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2336 }; 2337 2338 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2339 2340 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2341 2342 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2343 2344 // Return whether or not this register is ever used as an argument. This 2345 // function is used on startup to build the trampoline stubs in generateOptoStub. 2346 // Registers not mentioned will be killed by the VM call in the trampoline, and 2347 // arguments in those registers not be available to the callee. 2348 bool Matcher::can_be_java_arg(int reg) { 2349 // We return true for all registers contained in iarg_reg[] and 2350 // farg_reg[] and their virtual halves. 2351 // We must include the virtual halves in order to get STDs and LDs 2352 // instead of STWs and LWs in the trampoline stubs. 2353 2354 if ( reg == R3_num || reg == R3_H_num 2355 || reg == R4_num || reg == R4_H_num 2356 || reg == R5_num || reg == R5_H_num 2357 || reg == R6_num || reg == R6_H_num 2358 || reg == R7_num || reg == R7_H_num 2359 || reg == R8_num || reg == R8_H_num 2360 || reg == R9_num || reg == R9_H_num 2361 || reg == R10_num || reg == R10_H_num) 2362 return true; 2363 2364 if ( reg == F1_num || reg == F1_H_num 2365 || reg == F2_num || reg == F2_H_num 2366 || reg == F3_num || reg == F3_H_num 2367 || reg == F4_num || reg == F4_H_num 2368 || reg == F5_num || reg == F5_H_num 2369 || reg == F6_num || reg == F6_H_num 2370 || reg == F7_num || reg == F7_H_num 2371 || reg == F8_num || reg == F8_H_num 2372 || reg == F9_num || reg == F9_H_num 2373 || reg == F10_num || reg == F10_H_num 2374 || reg == F11_num || reg == F11_H_num 2375 || reg == F12_num || reg == F12_H_num 2376 || reg == F13_num || reg == F13_H_num) 2377 return true; 2378 2379 return false; 2380 } 2381 2382 bool Matcher::is_spillable_arg(int reg) { 2383 return can_be_java_arg(reg); 2384 } 2385 2386 uint Matcher::int_pressure_limit() 2387 { 2388 return (INTPRESSURE == -1) ? 26 : INTPRESSURE; 2389 } 2390 2391 uint Matcher::float_pressure_limit() 2392 { 2393 return (FLOATPRESSURE == -1) ? 28 : FLOATPRESSURE; 2394 } 2395 2396 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2397 return false; 2398 } 2399 2400 // Register for DIVI projection of divmodI. 2401 RegMask Matcher::divI_proj_mask() { 2402 ShouldNotReachHere(); 2403 return RegMask(); 2404 } 2405 2406 // Register for MODI projection of divmodI. 2407 RegMask Matcher::modI_proj_mask() { 2408 ShouldNotReachHere(); 2409 return RegMask(); 2410 } 2411 2412 // Register for DIVL projection of divmodL. 2413 RegMask Matcher::divL_proj_mask() { 2414 ShouldNotReachHere(); 2415 return RegMask(); 2416 } 2417 2418 // Register for MODL projection of divmodL. 2419 RegMask Matcher::modL_proj_mask() { 2420 ShouldNotReachHere(); 2421 return RegMask(); 2422 } 2423 2424 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2425 return RegMask(); 2426 } 2427 2428 %} 2429 2430 //----------ENCODING BLOCK----------------------------------------------------- 2431 // This block specifies the encoding classes used by the compiler to output 2432 // byte streams. Encoding classes are parameterized macros used by 2433 // Machine Instruction Nodes in order to generate the bit encoding of the 2434 // instruction. Operands specify their base encoding interface with the 2435 // interface keyword. There are currently supported four interfaces, 2436 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2437 // operand to generate a function which returns its register number when 2438 // queried. CONST_INTER causes an operand to generate a function which 2439 // returns the value of the constant when queried. MEMORY_INTER causes an 2440 // operand to generate four functions which return the Base Register, the 2441 // Index Register, the Scale Value, and the Offset Value of the operand when 2442 // queried. COND_INTER causes an operand to generate six functions which 2443 // return the encoding code (ie - encoding bits for the instruction) 2444 // associated with each basic boolean condition for a conditional instruction. 2445 // 2446 // Instructions specify two basic values for encoding. Again, a function 2447 // is available to check if the constant displacement is an oop. They use the 2448 // ins_encode keyword to specify their encoding classes (which must be 2449 // a sequence of enc_class names, and their parameters, specified in 2450 // the encoding block), and they use the 2451 // opcode keyword to specify, in order, their primary, secondary, and 2452 // tertiary opcode. Only the opcode sections which a particular instruction 2453 // needs for encoding need to be specified. 2454 encode %{ 2455 enc_class enc_unimplemented %{ 2456 C2_MacroAssembler _masm(&cbuf); 2457 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2458 %} 2459 2460 enc_class enc_untested %{ 2461 #ifdef ASSERT 2462 C2_MacroAssembler _masm(&cbuf); 2463 __ untested("Untested mach node encoding in AD file."); 2464 #else 2465 #endif 2466 %} 2467 2468 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2469 C2_MacroAssembler _masm(&cbuf); 2470 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2471 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2472 %} 2473 2474 // Load acquire. 2475 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2476 C2_MacroAssembler _masm(&cbuf); 2477 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2478 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2479 __ twi_0($dst$$Register); 2480 __ isync(); 2481 %} 2482 2483 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2484 2485 C2_MacroAssembler _masm(&cbuf); 2486 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2487 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2488 %} 2489 2490 // Load acquire. 2491 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2492 2493 C2_MacroAssembler _masm(&cbuf); 2494 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2495 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2496 __ twi_0($dst$$Register); 2497 __ isync(); 2498 %} 2499 2500 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2501 2502 C2_MacroAssembler _masm(&cbuf); 2503 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2504 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2505 %} 2506 2507 // Load acquire. 2508 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2509 2510 C2_MacroAssembler _masm(&cbuf); 2511 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2512 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2513 __ twi_0($dst$$Register); 2514 __ isync(); 2515 %} 2516 2517 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2518 C2_MacroAssembler _masm(&cbuf); 2519 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2520 // Operand 'ds' requires 4-alignment. 2521 assert((Idisp & 0x3) == 0, "unaligned offset"); 2522 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2523 %} 2524 2525 // Load acquire. 2526 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2527 C2_MacroAssembler _masm(&cbuf); 2528 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2529 // Operand 'ds' requires 4-alignment. 2530 assert((Idisp & 0x3) == 0, "unaligned offset"); 2531 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2532 __ twi_0($dst$$Register); 2533 __ isync(); 2534 %} 2535 2536 enc_class enc_lfd(RegF dst, memory mem) %{ 2537 C2_MacroAssembler _masm(&cbuf); 2538 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2539 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2540 %} 2541 2542 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2543 2544 C2_MacroAssembler _masm(&cbuf); 2545 int toc_offset = 0; 2546 2547 address const_toc_addr; 2548 // Create a non-oop constant, no relocation needed. 2549 // If it is an IC, it has a virtual_call_Relocation. 2550 const_toc_addr = __ long_constant((jlong)$src$$constant); 2551 if (const_toc_addr == NULL) { 2552 ciEnv::current()->record_out_of_memory_failure(); 2553 return; 2554 } 2555 2556 // Get the constant's TOC offset. 2557 toc_offset = __ offset_to_method_toc(const_toc_addr); 2558 2559 // Keep the current instruction offset in mind. 2560 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2561 2562 __ ld($dst$$Register, toc_offset, $toc$$Register); 2563 %} 2564 2565 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2566 2567 C2_MacroAssembler _masm(&cbuf); 2568 2569 if (!ra_->C->output()->in_scratch_emit_size()) { 2570 address const_toc_addr; 2571 // Create a non-oop constant, no relocation needed. 2572 // If it is an IC, it has a virtual_call_Relocation. 2573 const_toc_addr = __ long_constant((jlong)$src$$constant); 2574 if (const_toc_addr == NULL) { 2575 ciEnv::current()->record_out_of_memory_failure(); 2576 return; 2577 } 2578 2579 // Get the constant's TOC offset. 2580 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2581 // Store the toc offset of the constant. 2582 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2583 2584 // Also keep the current instruction offset in mind. 2585 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2586 } 2587 2588 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2589 %} 2590 2591 %} // encode 2592 2593 source %{ 2594 2595 typedef struct { 2596 loadConL_hiNode *_large_hi; 2597 loadConL_loNode *_large_lo; 2598 loadConLNode *_small; 2599 MachNode *_last; 2600 } loadConLNodesTuple; 2601 2602 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2603 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2604 loadConLNodesTuple nodes; 2605 2606 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2607 if (large_constant_pool) { 2608 // Create new nodes. 2609 loadConL_hiNode *m1 = new loadConL_hiNode(); 2610 loadConL_loNode *m2 = new loadConL_loNode(); 2611 2612 // inputs for new nodes 2613 m1->add_req(NULL, toc); 2614 m2->add_req(NULL, m1); 2615 2616 // operands for new nodes 2617 m1->_opnds[0] = new iRegLdstOper(); // dst 2618 m1->_opnds[1] = immSrc; // src 2619 m1->_opnds[2] = new iRegPdstOper(); // toc 2620 m2->_opnds[0] = new iRegLdstOper(); // dst 2621 m2->_opnds[1] = immSrc; // src 2622 m2->_opnds[2] = new iRegLdstOper(); // base 2623 2624 // Initialize ins_attrib TOC fields. 2625 m1->_const_toc_offset = -1; 2626 m2->_const_toc_offset_hi_node = m1; 2627 2628 // Initialize ins_attrib instruction offset. 2629 m1->_cbuf_insts_offset = -1; 2630 2631 // register allocation for new nodes 2632 ra_->set_pair(m1->_idx, reg_second, reg_first); 2633 ra_->set_pair(m2->_idx, reg_second, reg_first); 2634 2635 // Create result. 2636 nodes._large_hi = m1; 2637 nodes._large_lo = m2; 2638 nodes._small = NULL; 2639 nodes._last = nodes._large_lo; 2640 assert(m2->bottom_type()->isa_long(), "must be long"); 2641 } else { 2642 loadConLNode *m2 = new loadConLNode(); 2643 2644 // inputs for new nodes 2645 m2->add_req(NULL, toc); 2646 2647 // operands for new nodes 2648 m2->_opnds[0] = new iRegLdstOper(); // dst 2649 m2->_opnds[1] = immSrc; // src 2650 m2->_opnds[2] = new iRegPdstOper(); // toc 2651 2652 // Initialize ins_attrib instruction offset. 2653 m2->_cbuf_insts_offset = -1; 2654 2655 // register allocation for new nodes 2656 ra_->set_pair(m2->_idx, reg_second, reg_first); 2657 2658 // Create result. 2659 nodes._large_hi = NULL; 2660 nodes._large_lo = NULL; 2661 nodes._small = m2; 2662 nodes._last = nodes._small; 2663 assert(m2->bottom_type()->isa_long(), "must be long"); 2664 } 2665 2666 return nodes; 2667 } 2668 2669 typedef struct { 2670 loadConL_hiNode *_large_hi; 2671 loadConL_loNode *_large_lo; 2672 mtvsrdNode *_moved; 2673 xxspltdNode *_replicated; 2674 loadConLNode *_small; 2675 MachNode *_last; 2676 } loadConLReplicatedNodesTuple; 2677 2678 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2679 vecXOper *dst, immI_0Oper *zero, 2680 OptoReg::Name reg_second, OptoReg::Name reg_first, 2681 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2682 loadConLReplicatedNodesTuple nodes; 2683 2684 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2685 if (large_constant_pool) { 2686 // Create new nodes. 2687 loadConL_hiNode *m1 = new loadConL_hiNode(); 2688 loadConL_loNode *m2 = new loadConL_loNode(); 2689 mtvsrdNode *m3 = new mtvsrdNode(); 2690 xxspltdNode *m4 = new xxspltdNode(); 2691 2692 // inputs for new nodes 2693 m1->add_req(NULL, toc); 2694 m2->add_req(NULL, m1); 2695 m3->add_req(NULL, m2); 2696 m4->add_req(NULL, m3); 2697 2698 // operands for new nodes 2699 m1->_opnds[0] = new iRegLdstOper(); // dst 2700 m1->_opnds[1] = immSrc; // src 2701 m1->_opnds[2] = new iRegPdstOper(); // toc 2702 2703 m2->_opnds[0] = new iRegLdstOper(); // dst 2704 m2->_opnds[1] = immSrc; // src 2705 m2->_opnds[2] = new iRegLdstOper(); // base 2706 2707 m3->_opnds[0] = new vecXOper(); // dst 2708 m3->_opnds[1] = new iRegLdstOper(); // src 2709 2710 m4->_opnds[0] = new vecXOper(); // dst 2711 m4->_opnds[1] = new vecXOper(); // src 2712 m4->_opnds[2] = zero; 2713 2714 // Initialize ins_attrib TOC fields. 2715 m1->_const_toc_offset = -1; 2716 m2->_const_toc_offset_hi_node = m1; 2717 2718 // Initialize ins_attrib instruction offset. 2719 m1->_cbuf_insts_offset = -1; 2720 2721 // register allocation for new nodes 2722 ra_->set_pair(m1->_idx, reg_second, reg_first); 2723 ra_->set_pair(m2->_idx, reg_second, reg_first); 2724 ra_->set1(m3->_idx, reg_second); 2725 ra_->set2(m3->_idx, reg_vec_first); 2726 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2727 2728 // Create result. 2729 nodes._large_hi = m1; 2730 nodes._large_lo = m2; 2731 nodes._moved = m3; 2732 nodes._replicated = m4; 2733 nodes._small = NULL; 2734 nodes._last = nodes._replicated; 2735 assert(m2->bottom_type()->isa_long(), "must be long"); 2736 } else { 2737 loadConLNode *m2 = new loadConLNode(); 2738 mtvsrdNode *m3 = new mtvsrdNode(); 2739 xxspltdNode *m4 = new xxspltdNode(); 2740 2741 // inputs for new nodes 2742 m2->add_req(NULL, toc); 2743 2744 // operands for new nodes 2745 m2->_opnds[0] = new iRegLdstOper(); // dst 2746 m2->_opnds[1] = immSrc; // src 2747 m2->_opnds[2] = new iRegPdstOper(); // toc 2748 2749 m3->_opnds[0] = new vecXOper(); // dst 2750 m3->_opnds[1] = new iRegLdstOper(); // src 2751 2752 m4->_opnds[0] = new vecXOper(); // dst 2753 m4->_opnds[1] = new vecXOper(); // src 2754 m4->_opnds[2] = zero; 2755 2756 // Initialize ins_attrib instruction offset. 2757 m2->_cbuf_insts_offset = -1; 2758 ra_->set1(m3->_idx, reg_second); 2759 ra_->set2(m3->_idx, reg_vec_first); 2760 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2761 2762 // register allocation for new nodes 2763 ra_->set_pair(m2->_idx, reg_second, reg_first); 2764 2765 // Create result. 2766 nodes._large_hi = NULL; 2767 nodes._large_lo = NULL; 2768 nodes._small = m2; 2769 nodes._moved = m3; 2770 nodes._replicated = m4; 2771 nodes._last = nodes._replicated; 2772 assert(m2->bottom_type()->isa_long(), "must be long"); 2773 } 2774 2775 return nodes; 2776 } 2777 2778 %} // source 2779 2780 encode %{ 2781 // Postalloc expand emitter for loading a long constant from the method's TOC. 2782 // Enc_class needed as consttanttablebase is not supported by postalloc 2783 // expand. 2784 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2785 // Create new nodes. 2786 loadConLNodesTuple loadConLNodes = 2787 loadConLNodesTuple_create(ra_, n_toc, op_src, 2788 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2789 2790 // Push new nodes. 2791 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2792 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2793 2794 // some asserts 2795 assert(nodes->length() >= 1, "must have created at least 1 node"); 2796 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2797 %} 2798 2799 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2800 2801 C2_MacroAssembler _masm(&cbuf); 2802 int toc_offset = 0; 2803 2804 intptr_t val = $src$$constant; 2805 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2806 address const_toc_addr; 2807 RelocationHolder r; // Initializes type to none. 2808 if (constant_reloc == relocInfo::oop_type) { 2809 // Create an oop constant and a corresponding relocation. 2810 AddressLiteral a = __ constant_oop_address((jobject)val); 2811 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2812 r = a.rspec(); 2813 } else if (constant_reloc == relocInfo::metadata_type) { 2814 // Notify OOP recorder (don't need the relocation) 2815 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2816 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2817 } else { 2818 // Create a non-oop constant, no relocation needed. 2819 const_toc_addr = __ long_constant((jlong)$src$$constant); 2820 } 2821 2822 if (const_toc_addr == NULL) { 2823 ciEnv::current()->record_out_of_memory_failure(); 2824 return; 2825 } 2826 __ relocate(r); // If set above. 2827 // Get the constant's TOC offset. 2828 toc_offset = __ offset_to_method_toc(const_toc_addr); 2829 2830 __ ld($dst$$Register, toc_offset, $toc$$Register); 2831 %} 2832 2833 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2834 2835 C2_MacroAssembler _masm(&cbuf); 2836 if (!ra_->C->output()->in_scratch_emit_size()) { 2837 intptr_t val = $src$$constant; 2838 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2839 address const_toc_addr; 2840 RelocationHolder r; // Initializes type to none. 2841 if (constant_reloc == relocInfo::oop_type) { 2842 // Create an oop constant and a corresponding relocation. 2843 AddressLiteral a = __ constant_oop_address((jobject)val); 2844 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2845 r = a.rspec(); 2846 } else if (constant_reloc == relocInfo::metadata_type) { 2847 // Notify OOP recorder (don't need the relocation) 2848 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2849 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2850 } else { // non-oop pointers, e.g. card mark base, heap top 2851 // Create a non-oop constant, no relocation needed. 2852 const_toc_addr = __ long_constant((jlong)$src$$constant); 2853 } 2854 2855 if (const_toc_addr == NULL) { 2856 ciEnv::current()->record_out_of_memory_failure(); 2857 return; 2858 } 2859 __ relocate(r); // If set above. 2860 // Get the constant's TOC offset. 2861 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2862 // Store the toc offset of the constant. 2863 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 2864 } 2865 2866 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2867 %} 2868 2869 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 2870 // Enc_class needed as consttanttablebase is not supported by postalloc 2871 // expand. 2872 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 2873 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2874 if (large_constant_pool) { 2875 // Create new nodes. 2876 loadConP_hiNode *m1 = new loadConP_hiNode(); 2877 loadConP_loNode *m2 = new loadConP_loNode(); 2878 2879 // inputs for new nodes 2880 m1->add_req(NULL, n_toc); 2881 m2->add_req(NULL, m1); 2882 2883 // operands for new nodes 2884 m1->_opnds[0] = new iRegPdstOper(); // dst 2885 m1->_opnds[1] = op_src; // src 2886 m1->_opnds[2] = new iRegPdstOper(); // toc 2887 m2->_opnds[0] = new iRegPdstOper(); // dst 2888 m2->_opnds[1] = op_src; // src 2889 m2->_opnds[2] = new iRegLdstOper(); // base 2890 2891 // Initialize ins_attrib TOC fields. 2892 m1->_const_toc_offset = -1; 2893 m2->_const_toc_offset_hi_node = m1; 2894 2895 // Register allocation for new nodes. 2896 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2897 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2898 2899 nodes->push(m1); 2900 nodes->push(m2); 2901 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2902 } else { 2903 loadConPNode *m2 = new loadConPNode(); 2904 2905 // inputs for new nodes 2906 m2->add_req(NULL, n_toc); 2907 2908 // operands for new nodes 2909 m2->_opnds[0] = new iRegPdstOper(); // dst 2910 m2->_opnds[1] = op_src; // src 2911 m2->_opnds[2] = new iRegPdstOper(); // toc 2912 2913 // Register allocation for new nodes. 2914 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2915 2916 nodes->push(m2); 2917 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2918 } 2919 %} 2920 2921 // Enc_class needed as consttanttablebase is not supported by postalloc 2922 // expand. 2923 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 2924 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2925 2926 MachNode *m2; 2927 if (large_constant_pool) { 2928 m2 = new loadConFCompNode(); 2929 } else { 2930 m2 = new loadConFNode(); 2931 } 2932 // inputs for new nodes 2933 m2->add_req(NULL, n_toc); 2934 2935 // operands for new nodes 2936 m2->_opnds[0] = op_dst; 2937 m2->_opnds[1] = op_src; 2938 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2939 2940 // register allocation for new nodes 2941 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2942 nodes->push(m2); 2943 %} 2944 2945 // Enc_class needed as consttanttablebase is not supported by postalloc 2946 // expand. 2947 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 2948 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2949 2950 MachNode *m2; 2951 if (large_constant_pool) { 2952 m2 = new loadConDCompNode(); 2953 } else { 2954 m2 = new loadConDNode(); 2955 } 2956 // inputs for new nodes 2957 m2->add_req(NULL, n_toc); 2958 2959 // operands for new nodes 2960 m2->_opnds[0] = op_dst; 2961 m2->_opnds[1] = op_src; 2962 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2963 2964 // register allocation for new nodes 2965 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2966 nodes->push(m2); 2967 %} 2968 2969 enc_class enc_stw(iRegIsrc src, memory mem) %{ 2970 C2_MacroAssembler _masm(&cbuf); 2971 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2972 __ stw($src$$Register, Idisp, $mem$$base$$Register); 2973 %} 2974 2975 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 2976 C2_MacroAssembler _masm(&cbuf); 2977 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2978 // Operand 'ds' requires 4-alignment. 2979 assert((Idisp & 0x3) == 0, "unaligned offset"); 2980 __ std($src$$Register, Idisp, $mem$$base$$Register); 2981 %} 2982 2983 enc_class enc_stfs(RegF src, memory mem) %{ 2984 C2_MacroAssembler _masm(&cbuf); 2985 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2986 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 2987 %} 2988 2989 enc_class enc_stfd(RegF src, memory mem) %{ 2990 C2_MacroAssembler _masm(&cbuf); 2991 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2992 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 2993 %} 2994 2995 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 2996 2997 if (VM_Version::has_isel()) { 2998 // use isel instruction with Power 7 2999 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3000 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3001 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3002 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3003 3004 n_compare->add_req(n_region, n_src); 3005 n_compare->_opnds[0] = op_crx; 3006 n_compare->_opnds[1] = op_src; 3007 n_compare->_opnds[2] = new immL16Oper(0); 3008 3009 n_sub_base->add_req(n_region, n_src); 3010 n_sub_base->_opnds[0] = op_dst; 3011 n_sub_base->_opnds[1] = op_src; 3012 n_sub_base->_bottom_type = _bottom_type; 3013 3014 n_shift->add_req(n_region, n_sub_base); 3015 n_shift->_opnds[0] = op_dst; 3016 n_shift->_opnds[1] = op_dst; 3017 n_shift->_bottom_type = _bottom_type; 3018 3019 n_cond_set->add_req(n_region, n_compare, n_shift); 3020 n_cond_set->_opnds[0] = op_dst; 3021 n_cond_set->_opnds[1] = op_crx; 3022 n_cond_set->_opnds[2] = op_dst; 3023 n_cond_set->_bottom_type = _bottom_type; 3024 3025 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3026 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3027 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3028 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3029 3030 nodes->push(n_compare); 3031 nodes->push(n_sub_base); 3032 nodes->push(n_shift); 3033 nodes->push(n_cond_set); 3034 3035 } else { 3036 // before Power 7 3037 moveRegNode *n_move = new moveRegNode(); 3038 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3039 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3040 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3041 3042 n_move->add_req(n_region, n_src); 3043 n_move->_opnds[0] = op_dst; 3044 n_move->_opnds[1] = op_src; 3045 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3046 3047 n_compare->add_req(n_region, n_src); 3048 n_compare->add_prec(n_move); 3049 3050 n_compare->_opnds[0] = op_crx; 3051 n_compare->_opnds[1] = op_src; 3052 n_compare->_opnds[2] = new immL16Oper(0); 3053 3054 n_sub_base->add_req(n_region, n_compare, n_src); 3055 n_sub_base->_opnds[0] = op_dst; 3056 n_sub_base->_opnds[1] = op_crx; 3057 n_sub_base->_opnds[2] = op_src; 3058 n_sub_base->_bottom_type = _bottom_type; 3059 3060 n_shift->add_req(n_region, n_sub_base); 3061 n_shift->_opnds[0] = op_dst; 3062 n_shift->_opnds[1] = op_dst; 3063 n_shift->_bottom_type = _bottom_type; 3064 3065 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3066 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3067 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3068 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3069 3070 nodes->push(n_move); 3071 nodes->push(n_compare); 3072 nodes->push(n_sub_base); 3073 nodes->push(n_shift); 3074 } 3075 3076 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3077 %} 3078 3079 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3080 3081 encodeP_subNode *n1 = new encodeP_subNode(); 3082 n1->add_req(n_region, n_src); 3083 n1->_opnds[0] = op_dst; 3084 n1->_opnds[1] = op_src; 3085 n1->_bottom_type = _bottom_type; 3086 3087 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3088 n2->add_req(n_region, n1); 3089 n2->_opnds[0] = op_dst; 3090 n2->_opnds[1] = op_dst; 3091 n2->_bottom_type = _bottom_type; 3092 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3093 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3094 3095 nodes->push(n1); 3096 nodes->push(n2); 3097 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3098 %} 3099 3100 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3101 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3102 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3103 3104 n_compare->add_req(n_region, n_src); 3105 n_compare->_opnds[0] = op_crx; 3106 n_compare->_opnds[1] = op_src; 3107 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3108 3109 n_shift->add_req(n_region, n_src); 3110 n_shift->_opnds[0] = op_dst; 3111 n_shift->_opnds[1] = op_src; 3112 n_shift->_bottom_type = _bottom_type; 3113 3114 if (VM_Version::has_isel()) { 3115 // use isel instruction with Power 7 3116 3117 decodeN_addNode *n_add_base = new decodeN_addNode(); 3118 n_add_base->add_req(n_region, n_shift); 3119 n_add_base->_opnds[0] = op_dst; 3120 n_add_base->_opnds[1] = op_dst; 3121 n_add_base->_bottom_type = _bottom_type; 3122 3123 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3124 n_cond_set->add_req(n_region, n_compare, n_add_base); 3125 n_cond_set->_opnds[0] = op_dst; 3126 n_cond_set->_opnds[1] = op_crx; 3127 n_cond_set->_opnds[2] = op_dst; 3128 n_cond_set->_bottom_type = _bottom_type; 3129 3130 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3131 ra_->set_oop(n_cond_set, true); 3132 3133 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3134 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3135 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3136 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3137 3138 nodes->push(n_compare); 3139 nodes->push(n_shift); 3140 nodes->push(n_add_base); 3141 nodes->push(n_cond_set); 3142 3143 } else { 3144 // before Power 7 3145 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3146 3147 n_add_base->add_req(n_region, n_compare, n_shift); 3148 n_add_base->_opnds[0] = op_dst; 3149 n_add_base->_opnds[1] = op_crx; 3150 n_add_base->_opnds[2] = op_dst; 3151 n_add_base->_bottom_type = _bottom_type; 3152 3153 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3154 ra_->set_oop(n_add_base, true); 3155 3156 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3157 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3158 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3159 3160 nodes->push(n_compare); 3161 nodes->push(n_shift); 3162 nodes->push(n_add_base); 3163 } 3164 %} 3165 3166 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3167 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3168 n1->add_req(n_region, n_src); 3169 n1->_opnds[0] = op_dst; 3170 n1->_opnds[1] = op_src; 3171 n1->_bottom_type = _bottom_type; 3172 3173 decodeN_addNode *n2 = new decodeN_addNode(); 3174 n2->add_req(n_region, n1); 3175 n2->_opnds[0] = op_dst; 3176 n2->_opnds[1] = op_dst; 3177 n2->_bottom_type = _bottom_type; 3178 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3179 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3180 3181 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3182 ra_->set_oop(n2, true); 3183 3184 nodes->push(n1); 3185 nodes->push(n2); 3186 %} 3187 3188 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3189 3190 C2_MacroAssembler _masm(&cbuf); 3191 int cc = $cmp$$cmpcode; 3192 int flags_reg = $crx$$reg; 3193 Label done; 3194 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3195 // Branch if not (cmp crx). 3196 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3197 __ mr($dst$$Register, $src$$Register); 3198 __ bind(done); 3199 %} 3200 3201 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3202 3203 C2_MacroAssembler _masm(&cbuf); 3204 Label done; 3205 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3206 // Branch if not (cmp crx). 3207 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3208 __ li($dst$$Register, $src$$constant); 3209 __ bind(done); 3210 %} 3211 3212 // This enc_class is needed so that scheduler gets proper 3213 // input mapping for latency computation. 3214 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3215 C2_MacroAssembler _masm(&cbuf); 3216 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3217 %} 3218 3219 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3220 3221 C2_MacroAssembler _masm(&cbuf); 3222 3223 Label done; 3224 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3225 __ li($dst$$Register, $zero$$constant); 3226 __ beq($crx$$CondRegister, done); 3227 __ li($dst$$Register, $notzero$$constant); 3228 __ bind(done); 3229 %} 3230 3231 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3232 3233 C2_MacroAssembler _masm(&cbuf); 3234 3235 Label done; 3236 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3237 __ li($dst$$Register, $zero$$constant); 3238 __ beq($crx$$CondRegister, done); 3239 __ li($dst$$Register, $notzero$$constant); 3240 __ bind(done); 3241 %} 3242 3243 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3244 3245 C2_MacroAssembler _masm(&cbuf); 3246 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3247 Label done; 3248 __ bso($crx$$CondRegister, done); 3249 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3250 __ bind(done); 3251 %} 3252 3253 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3254 3255 C2_MacroAssembler _masm(&cbuf); 3256 Label done; 3257 __ bso($crx$$CondRegister, done); 3258 __ mffprd($dst$$Register, $src$$FloatRegister); 3259 __ bind(done); 3260 %} 3261 3262 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3263 3264 C2_MacroAssembler _masm(&cbuf); 3265 Label d; // dummy 3266 __ bind(d); 3267 Label* p = ($lbl$$label); 3268 // `p' is `NULL' when this encoding class is used only to 3269 // determine the size of the encoded instruction. 3270 Label& l = (NULL == p)? d : *(p); 3271 int cc = $cmp$$cmpcode; 3272 int flags_reg = $crx$$reg; 3273 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3274 int bhint = Assembler::bhintNoHint; 3275 3276 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3277 if (_prob <= PROB_NEVER) { 3278 bhint = Assembler::bhintIsNotTaken; 3279 } else if (_prob >= PROB_ALWAYS) { 3280 bhint = Assembler::bhintIsTaken; 3281 } 3282 } 3283 3284 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3285 cc_to_biint(cc, flags_reg), 3286 l); 3287 %} 3288 3289 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3290 // The scheduler doesn't know about branch shortening, so we set the opcode 3291 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3292 3293 C2_MacroAssembler _masm(&cbuf); 3294 Label d; // dummy 3295 __ bind(d); 3296 Label* p = ($lbl$$label); 3297 // `p' is `NULL' when this encoding class is used only to 3298 // determine the size of the encoded instruction. 3299 Label& l = (NULL == p)? d : *(p); 3300 int cc = $cmp$$cmpcode; 3301 int flags_reg = $crx$$reg; 3302 int bhint = Assembler::bhintNoHint; 3303 3304 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3305 if (_prob <= PROB_NEVER) { 3306 bhint = Assembler::bhintIsNotTaken; 3307 } else if (_prob >= PROB_ALWAYS) { 3308 bhint = Assembler::bhintIsTaken; 3309 } 3310 } 3311 3312 // Tell the conditional far branch to optimize itself when being relocated. 3313 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3314 cc_to_biint(cc, flags_reg), 3315 l, 3316 MacroAssembler::bc_far_optimize_on_relocate); 3317 %} 3318 3319 // Postalloc expand emitter for loading a replicatef float constant from 3320 // the method's TOC. 3321 // Enc_class needed as consttanttablebase is not supported by postalloc 3322 // expand. 3323 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3324 // Create new nodes. 3325 3326 // Make an operand with the bit pattern to load as float. 3327 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3328 3329 loadConLNodesTuple loadConLNodes = 3330 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3331 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3332 3333 // Push new nodes. 3334 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3335 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3336 3337 assert(nodes->length() >= 1, "must have created at least 1 node"); 3338 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3339 %} 3340 3341 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3342 // Create new nodes. 3343 3344 // Make an operand with the bit pattern to load as float. 3345 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3346 immI_0Oper *op_zero = new immI_0Oper(0); 3347 3348 loadConLReplicatedNodesTuple loadConLNodes = 3349 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3350 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3351 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3352 3353 // Push new nodes. 3354 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3355 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3356 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3357 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3358 3359 assert(nodes->length() >= 1, "must have created at least 1 node"); 3360 %} 3361 3362 // This enc_class is needed so that scheduler gets proper 3363 // input mapping for latency computation. 3364 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3365 // Fake operand dst needed for PPC scheduler. 3366 assert($dst$$constant == 0x0, "dst must be 0x0"); 3367 3368 C2_MacroAssembler _masm(&cbuf); 3369 // Mark the code position where the load from the safepoint 3370 // polling page was emitted as relocInfo::poll_type. 3371 __ relocate(relocInfo::poll_type); 3372 __ load_from_polling_page($poll$$Register); 3373 %} 3374 3375 // A Java static call or a runtime call. 3376 // 3377 // Branch-and-link relative to a trampoline. 3378 // The trampoline loads the target address and does a long branch to there. 3379 // In case we call java, the trampoline branches to a interpreter_stub 3380 // which loads the inline cache and the real call target from the constant pool. 3381 // 3382 // This basically looks like this: 3383 // 3384 // >>>> consts -+ -+ 3385 // | |- offset1 3386 // [call target1] | <-+ 3387 // [IC cache] |- offset2 3388 // [call target2] <--+ 3389 // 3390 // <<<< consts 3391 // >>>> insts 3392 // 3393 // bl offset16 -+ -+ ??? // How many bits available? 3394 // | | 3395 // <<<< insts | | 3396 // >>>> stubs | | 3397 // | |- trampoline_stub_Reloc 3398 // trampoline stub: | <-+ 3399 // r2 = toc | 3400 // r2 = [r2 + offset1] | // Load call target1 from const section 3401 // mtctr r2 | 3402 // bctr |- static_stub_Reloc 3403 // comp_to_interp_stub: <---+ 3404 // r1 = toc 3405 // ICreg = [r1 + IC_offset] // Load IC from const section 3406 // r1 = [r1 + offset2] // Load call target2 from const section 3407 // mtctr r1 3408 // bctr 3409 // 3410 // <<<< stubs 3411 // 3412 // The call instruction in the code either 3413 // - Branches directly to a compiled method if the offset is encodable in instruction. 3414 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3415 // - Branches to the compiled_to_interp stub if the target is interpreted. 3416 // 3417 // Further there are three relocations from the loads to the constants in 3418 // the constant section. 3419 // 3420 // Usage of r1 and r2 in the stubs allows to distinguish them. 3421 enc_class enc_java_static_call(method meth) %{ 3422 3423 C2_MacroAssembler _masm(&cbuf); 3424 address entry_point = (address)$meth$$method; 3425 3426 if (!_method) { 3427 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3428 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3429 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3430 } else { 3431 // Remember the offset not the address. 3432 const int start_offset = __ offset(); 3433 3434 // The trampoline stub. 3435 // No entry point given, use the current pc. 3436 // Make sure branch fits into 3437 if (entry_point == 0) entry_point = __ pc(); 3438 3439 // Put the entry point as a constant into the constant pool. 3440 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3441 if (entry_point_toc_addr == NULL) { 3442 ciEnv::current()->record_out_of_memory_failure(); 3443 return; 3444 } 3445 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3446 3447 // Emit the trampoline stub which will be related to the branch-and-link below. 3448 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3449 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3450 int method_index = resolved_method_index(cbuf); 3451 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3452 : static_call_Relocation::spec(method_index)); 3453 3454 // The real call. 3455 // Note: At this point we do not have the address of the trampoline 3456 // stub, and the entry point might be too far away for bl, so __ pc() 3457 // serves as dummy and the bl will be patched later. 3458 cbuf.set_insts_mark(); 3459 __ bl(__ pc()); // Emits a relocation. 3460 3461 // The stub for call to interpreter. 3462 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3463 if (stub == NULL) { 3464 ciEnv::current()->record_failure("CodeCache is full"); 3465 return; 3466 } 3467 } 3468 __ post_call_nop(); 3469 %} 3470 3471 // Second node of expanded dynamic call - the call. 3472 enc_class enc_java_dynamic_call_sched(method meth) %{ 3473 3474 C2_MacroAssembler _masm(&cbuf); 3475 3476 if (!ra_->C->output()->in_scratch_emit_size()) { 3477 // Create a call trampoline stub for the given method. 3478 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3479 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3480 if (entry_point_const == NULL) { 3481 ciEnv::current()->record_out_of_memory_failure(); 3482 return; 3483 } 3484 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3485 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3486 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3487 3488 // Build relocation at call site with ic position as data. 3489 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3490 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3491 "must have one, but can't have both"); 3492 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3493 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3494 "must contain instruction offset"); 3495 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3496 ? _load_ic_hi_node->_cbuf_insts_offset 3497 : _load_ic_node->_cbuf_insts_offset; 3498 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3499 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3500 "should be load from TOC"); 3501 int method_index = resolved_method_index(cbuf); 3502 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3503 } 3504 3505 // At this point I do not have the address of the trampoline stub, 3506 // and the entry point might be too far away for bl. Pc() serves 3507 // as dummy and bl will be patched later. 3508 __ bl((address) __ pc()); 3509 __ post_call_nop(); 3510 %} 3511 3512 // postalloc expand emitter for virtual calls. 3513 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3514 3515 // Create the nodes for loading the IC from the TOC. 3516 loadConLNodesTuple loadConLNodes_IC = 3517 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3518 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3519 3520 // Create the call node. 3521 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3522 call->_method_handle_invoke = _method_handle_invoke; 3523 call->_vtable_index = _vtable_index; 3524 call->_method = _method; 3525 call->_optimized_virtual = _optimized_virtual; 3526 call->_tf = _tf; 3527 call->_entry_point = _entry_point; 3528 call->_cnt = _cnt; 3529 call->_guaranteed_safepoint = true; 3530 call->_oop_map = _oop_map; 3531 call->_jvms = _jvms; 3532 call->_jvmadj = _jvmadj; 3533 call->_in_rms = _in_rms; 3534 call->_nesting = _nesting; 3535 call->_override_symbolic_info = _override_symbolic_info; 3536 call->_arg_escape = _arg_escape; 3537 3538 // New call needs all inputs of old call. 3539 // Req... 3540 for (uint i = 0; i < req(); ++i) { 3541 // The expanded node does not need toc any more. 3542 // Add the inline cache constant here instead. This expresses the 3543 // register of the inline cache must be live at the call. 3544 // Else we would have to adapt JVMState by -1. 3545 if (i == mach_constant_base_node_input()) { 3546 call->add_req(loadConLNodes_IC._last); 3547 } else { 3548 call->add_req(in(i)); 3549 } 3550 } 3551 // ...as well as prec 3552 for (uint i = req(); i < len(); ++i) { 3553 call->add_prec(in(i)); 3554 } 3555 3556 // Remember nodes loading the inline cache into r19. 3557 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3558 call->_load_ic_node = loadConLNodes_IC._small; 3559 3560 // Operands for new nodes. 3561 call->_opnds[0] = _opnds[0]; 3562 call->_opnds[1] = _opnds[1]; 3563 3564 // Only the inline cache is associated with a register. 3565 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3566 3567 // Push new nodes. 3568 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3569 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3570 nodes->push(call); 3571 %} 3572 3573 // Compound version of call dynamic 3574 // Toc is only passed so that it can be used in ins_encode statement. 3575 // In the code we have to use $constanttablebase. 3576 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3577 C2_MacroAssembler _masm(&cbuf); 3578 int start_offset = __ offset(); 3579 3580 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3581 3582 int vtable_index = this->_vtable_index; 3583 if (vtable_index < 0) { 3584 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3585 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3586 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3587 3588 // Virtual call relocation will point to ic load. 3589 address virtual_call_meta_addr = __ pc(); 3590 // Load a clear inline cache. 3591 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3592 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3593 if (!success) { 3594 ciEnv::current()->record_out_of_memory_failure(); 3595 return; 3596 } 3597 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3598 // to determine who we intended to call. 3599 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3600 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3601 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3602 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3603 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset); 3604 } else { 3605 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3606 // Go thru the vtable. Get receiver klass. Receiver already 3607 // checked for non-null. If we'll go thru a C2I adapter, the 3608 // interpreter expects method in R19_method. 3609 3610 __ load_klass(R11_scratch1, R3); 3611 3612 int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index * vtableEntry::size_in_bytes(); 3613 int v_off = entry_offset + in_bytes(vtableEntry::method_offset()); 3614 __ li(R19_method, v_off); 3615 __ ldx(R19_method/*method*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3616 // NOTE: for vtable dispatches, the vtable entry will never be 3617 // null. However it may very well end up in handle_wrong_method 3618 // if the method is abstract for the particular class. 3619 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3620 // Call target. Either compiled code or C2I adapter. 3621 __ mtctr(R11_scratch1); 3622 __ bctrl(); 3623 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3624 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset); 3625 } 3626 __ post_call_nop(); 3627 %} 3628 3629 // a runtime call 3630 enc_class enc_java_to_runtime_call (method meth) %{ 3631 3632 C2_MacroAssembler _masm(&cbuf); 3633 const address start_pc = __ pc(); 3634 3635 #if defined(ABI_ELFv2) 3636 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3637 __ call_c(entry, relocInfo::runtime_call_type); 3638 __ post_call_nop(); 3639 #else 3640 // The function we're going to call. 3641 FunctionDescriptor fdtemp; 3642 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3643 3644 Register Rtoc = R12_scratch2; 3645 // Calculate the method's TOC. 3646 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3647 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3648 // pool entries; call_c_using_toc will optimize the call. 3649 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3650 if (!success) { 3651 ciEnv::current()->record_out_of_memory_failure(); 3652 return; 3653 } 3654 __ post_call_nop(); 3655 #endif 3656 3657 // Check the ret_addr_offset. 3658 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3659 "Fix constant in ret_addr_offset()"); 3660 %} 3661 3662 // Move to ctr for leaf call. 3663 // This enc_class is needed so that scheduler gets proper 3664 // input mapping for latency computation. 3665 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3666 C2_MacroAssembler _masm(&cbuf); 3667 __ mtctr($src$$Register); 3668 %} 3669 3670 // Postalloc expand emitter for runtime leaf calls. 3671 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3672 loadConLNodesTuple loadConLNodes_Entry; 3673 #if defined(ABI_ELFv2) 3674 jlong entry_address = (jlong) this->entry_point(); 3675 assert(entry_address, "need address here"); 3676 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3677 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3678 #else 3679 // Get the struct that describes the function we are about to call. 3680 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3681 assert(fd, "need fd here"); 3682 jlong entry_address = (jlong) fd->entry(); 3683 // new nodes 3684 loadConLNodesTuple loadConLNodes_Env; 3685 loadConLNodesTuple loadConLNodes_Toc; 3686 3687 // Create nodes and operands for loading the entry point. 3688 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3689 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3690 3691 3692 // Create nodes and operands for loading the env pointer. 3693 if (fd->env() != NULL) { 3694 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3695 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3696 } else { 3697 loadConLNodes_Env._large_hi = NULL; 3698 loadConLNodes_Env._large_lo = NULL; 3699 loadConLNodes_Env._small = NULL; 3700 loadConLNodes_Env._last = new loadConL16Node(); 3701 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3702 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3703 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3704 } 3705 3706 // Create nodes and operands for loading the Toc point. 3707 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3708 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3709 #endif // ABI_ELFv2 3710 // mtctr node 3711 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3712 3713 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3714 mtctr->add_req(0, loadConLNodes_Entry._last); 3715 3716 mtctr->_opnds[0] = new iRegLdstOper(); 3717 mtctr->_opnds[1] = new iRegLdstOper(); 3718 3719 // call node 3720 MachCallLeafNode *call = new CallLeafDirectNode(); 3721 3722 call->_opnds[0] = _opnds[0]; 3723 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3724 3725 // Make the new call node look like the old one. 3726 call->_name = _name; 3727 call->_tf = _tf; 3728 call->_entry_point = _entry_point; 3729 call->_cnt = _cnt; 3730 call->_guaranteed_safepoint = false; 3731 call->_oop_map = _oop_map; 3732 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3733 call->_jvms = NULL; 3734 call->_jvmadj = _jvmadj; 3735 call->_in_rms = _in_rms; 3736 call->_nesting = _nesting; 3737 3738 // New call needs all inputs of old call. 3739 // Req... 3740 for (uint i = 0; i < req(); ++i) { 3741 if (i != mach_constant_base_node_input()) { 3742 call->add_req(in(i)); 3743 } 3744 } 3745 3746 // These must be reqired edges, as the registers are live up to 3747 // the call. Else the constants are handled as kills. 3748 call->add_req(mtctr); 3749 #if !defined(ABI_ELFv2) 3750 call->add_req(loadConLNodes_Env._last); 3751 call->add_req(loadConLNodes_Toc._last); 3752 #endif 3753 3754 // ...as well as prec 3755 for (uint i = req(); i < len(); ++i) { 3756 call->add_prec(in(i)); 3757 } 3758 3759 // registers 3760 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 3761 3762 // Insert the new nodes. 3763 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 3764 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 3765 #if !defined(ABI_ELFv2) 3766 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 3767 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 3768 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 3769 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 3770 #endif 3771 nodes->push(mtctr); 3772 nodes->push(call); 3773 %} 3774 %} 3775 3776 //----------FRAME-------------------------------------------------------------- 3777 // Definition of frame structure and management information. 3778 3779 frame %{ 3780 // These two registers define part of the calling convention between 3781 // compiled code and the interpreter. 3782 3783 // Inline Cache Register or method for I2C. 3784 inline_cache_reg(R19); // R19_method 3785 3786 // Optional: name the operand used by cisc-spilling to access 3787 // [stack_pointer + offset]. 3788 cisc_spilling_operand_name(indOffset); 3789 3790 // Number of stack slots consumed by a Monitor enter. 3791 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 3792 3793 // Compiled code's Frame Pointer. 3794 frame_pointer(R1); // R1_SP 3795 3796 // Interpreter stores its frame pointer in a register which is 3797 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 3798 // interpreted java to compiled java. 3799 // 3800 // R14_state holds pointer to caller's cInterpreter. 3801 interpreter_frame_pointer(R14); // R14_state 3802 3803 stack_alignment(frame::alignment_in_bytes); 3804 3805 // Number of outgoing stack slots killed above the 3806 // out_preserve_stack_slots for calls to C. Supports the var-args 3807 // backing area for register parms. 3808 // 3809 varargs_C_out_slots_killed(((frame::native_abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 3810 3811 // The after-PROLOG location of the return address. Location of 3812 // return address specifies a type (REG or STACK) and a number 3813 // representing the register number (i.e. - use a register name) or 3814 // stack slot. 3815 // 3816 // A: Link register is stored in stack slot ... 3817 // M: ... but it's in the caller's frame according to PPC-64 ABI. 3818 // J: Therefore, we make sure that the link register is also in R11_scratch1 3819 // at the end of the prolog. 3820 // B: We use R20, now. 3821 //return_addr(REG R20); 3822 3823 // G: After reading the comments made by all the luminaries on their 3824 // failure to tell the compiler where the return address really is, 3825 // I hardly dare to try myself. However, I'm convinced it's in slot 3826 // 4 what apparently works and saves us some spills. 3827 return_addr(STACK 4); 3828 3829 // Location of native (C/C++) and interpreter return values. This 3830 // is specified to be the same as Java. In the 32-bit VM, long 3831 // values are actually returned from native calls in O0:O1 and 3832 // returned to the interpreter in I0:I1. The copying to and from 3833 // the register pairs is done by the appropriate call and epilog 3834 // opcodes. This simplifies the register allocator. 3835 c_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 // Location of compiled Java return values. Same as C 3846 return_value %{ 3847 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3848 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0), 3849 "only return normal values"); 3850 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3851 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3852 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3853 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3854 %} 3855 %} 3856 3857 3858 //----------ATTRIBUTES--------------------------------------------------------- 3859 3860 //----------Operand Attributes------------------------------------------------- 3861 op_attrib op_cost(1); // Required cost attribute. 3862 3863 //----------Instruction Attributes--------------------------------------------- 3864 3865 // Cost attribute. required. 3866 ins_attrib ins_cost(DEFAULT_COST); 3867 3868 // Is this instruction a non-matching short branch variant of some 3869 // long branch? Not required. 3870 ins_attrib ins_short_branch(0); 3871 3872 ins_attrib ins_is_TrapBasedCheckNode(true); 3873 3874 // Number of constants. 3875 // This instruction uses the given number of constants 3876 // (optional attribute). 3877 // This is needed to determine in time whether the constant pool will 3878 // exceed 4000 entries. Before postalloc_expand the overall number of constants 3879 // is determined. It's also used to compute the constant pool size 3880 // in Output(). 3881 ins_attrib ins_num_consts(0); 3882 3883 // Required alignment attribute (must be a power of 2) specifies the 3884 // alignment that some part of the instruction (not necessarily the 3885 // start) requires. If > 1, a compute_padding() function must be 3886 // provided for the instruction. 3887 ins_attrib ins_alignment(1); 3888 3889 // Enforce/prohibit rematerializations. 3890 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 3891 // then rematerialization of that instruction is prohibited and the 3892 // instruction's value will be spilled if necessary. 3893 // Causes that MachNode::rematerialize() returns false. 3894 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 3895 // then rematerialization should be enforced and a copy of the instruction 3896 // should be inserted if possible; rematerialization is not guaranteed. 3897 // Note: this may result in rematerializations in front of every use. 3898 // Causes that MachNode::rematerialize() can return true. 3899 // (optional attribute) 3900 ins_attrib ins_cannot_rematerialize(false); 3901 ins_attrib ins_should_rematerialize(false); 3902 3903 // Instruction has variable size depending on alignment. 3904 ins_attrib ins_variable_size_depending_on_alignment(false); 3905 3906 // Instruction is a nop. 3907 ins_attrib ins_is_nop(false); 3908 3909 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 3910 ins_attrib ins_use_mach_if_fast_lock_node(false); 3911 3912 // Field for the toc offset of a constant. 3913 // 3914 // This is needed if the toc offset is not encodable as an immediate in 3915 // the PPC load instruction. If so, the upper (hi) bits of the offset are 3916 // added to the toc, and from this a load with immediate is performed. 3917 // With postalloc expand, we get two nodes that require the same offset 3918 // but which don't know about each other. The offset is only known 3919 // when the constant is added to the constant pool during emitting. 3920 // It is generated in the 'hi'-node adding the upper bits, and saved 3921 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 3922 // the offset from there when it gets encoded. 3923 ins_attrib ins_field_const_toc_offset(0); 3924 ins_attrib ins_field_const_toc_offset_hi_node(0); 3925 3926 // A field that can hold the instructions offset in the code buffer. 3927 // Set in the nodes emitter. 3928 ins_attrib ins_field_cbuf_insts_offset(-1); 3929 3930 // Fields for referencing a call's load-IC-node. 3931 // If the toc offset can not be encoded as an immediate in a load, we 3932 // use two nodes. 3933 ins_attrib ins_field_load_ic_hi_node(0); 3934 ins_attrib ins_field_load_ic_node(0); 3935 3936 //----------OPERANDS----------------------------------------------------------- 3937 // Operand definitions must precede instruction definitions for correct 3938 // parsing in the ADLC because operands constitute user defined types 3939 // which are used in instruction definitions. 3940 // 3941 // Formats are generated automatically for constants and base registers. 3942 3943 operand vecX() %{ 3944 constraint(ALLOC_IN_RC(vs_reg)); 3945 match(VecX); 3946 3947 format %{ %} 3948 interface(REG_INTER); 3949 %} 3950 3951 //----------Simple Operands---------------------------------------------------- 3952 // Immediate Operands 3953 3954 // Integer Immediate: 32-bit 3955 operand immI() %{ 3956 match(ConI); 3957 op_cost(40); 3958 format %{ %} 3959 interface(CONST_INTER); 3960 %} 3961 3962 operand immI8() %{ 3963 predicate(Assembler::is_simm(n->get_int(), 8)); 3964 op_cost(0); 3965 match(ConI); 3966 format %{ %} 3967 interface(CONST_INTER); 3968 %} 3969 3970 // Integer Immediate: 16-bit 3971 operand immI16() %{ 3972 predicate(Assembler::is_simm(n->get_int(), 16)); 3973 op_cost(0); 3974 match(ConI); 3975 format %{ %} 3976 interface(CONST_INTER); 3977 %} 3978 3979 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 3980 operand immIhi16() %{ 3981 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 3982 match(ConI); 3983 op_cost(0); 3984 format %{ %} 3985 interface(CONST_INTER); 3986 %} 3987 3988 // Integer Immediate: 32-bit immediate for prefixed addi and load/store. 3989 operand immI32() %{ 3990 predicate(PowerArchitecturePPC64 >= 10); 3991 op_cost(0); 3992 match(ConI); 3993 format %{ %} 3994 interface(CONST_INTER); 3995 %} 3996 3997 operand immInegpow2() %{ 3998 predicate(is_power_of_2(-(juint)(n->get_int()))); 3999 match(ConI); 4000 op_cost(0); 4001 format %{ %} 4002 interface(CONST_INTER); 4003 %} 4004 4005 operand immIpow2minus1() %{ 4006 predicate(is_power_of_2((juint)(n->get_int()) + 1u)); 4007 match(ConI); 4008 op_cost(0); 4009 format %{ %} 4010 interface(CONST_INTER); 4011 %} 4012 4013 operand immIpowerOf2() %{ 4014 predicate(is_power_of_2((juint)(n->get_int()))); 4015 match(ConI); 4016 op_cost(0); 4017 format %{ %} 4018 interface(CONST_INTER); 4019 %} 4020 4021 // Unsigned Integer Immediate: the values 0-31 4022 operand uimmI5() %{ 4023 predicate(Assembler::is_uimm(n->get_int(), 5)); 4024 match(ConI); 4025 op_cost(0); 4026 format %{ %} 4027 interface(CONST_INTER); 4028 %} 4029 4030 // Unsigned Integer Immediate: 6-bit 4031 operand uimmI6() %{ 4032 predicate(Assembler::is_uimm(n->get_int(), 6)); 4033 match(ConI); 4034 op_cost(0); 4035 format %{ %} 4036 interface(CONST_INTER); 4037 %} 4038 4039 // Unsigned Integer Immediate: 6-bit int, greater than 32 4040 operand uimmI6_ge32() %{ 4041 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4042 match(ConI); 4043 op_cost(0); 4044 format %{ %} 4045 interface(CONST_INTER); 4046 %} 4047 4048 // Unsigned Integer Immediate: 15-bit 4049 operand uimmI15() %{ 4050 predicate(Assembler::is_uimm(n->get_int(), 15)); 4051 match(ConI); 4052 op_cost(0); 4053 format %{ %} 4054 interface(CONST_INTER); 4055 %} 4056 4057 // Unsigned Integer Immediate: 16-bit 4058 operand uimmI16() %{ 4059 predicate(Assembler::is_uimm(n->get_int(), 16)); 4060 match(ConI); 4061 op_cost(0); 4062 format %{ %} 4063 interface(CONST_INTER); 4064 %} 4065 4066 // constant 'int 0'. 4067 operand immI_0() %{ 4068 predicate(n->get_int() == 0); 4069 match(ConI); 4070 op_cost(0); 4071 format %{ %} 4072 interface(CONST_INTER); 4073 %} 4074 4075 // constant 'int 1'. 4076 operand immI_1() %{ 4077 predicate(n->get_int() == 1); 4078 match(ConI); 4079 op_cost(0); 4080 format %{ %} 4081 interface(CONST_INTER); 4082 %} 4083 4084 // constant 'int -1'. 4085 operand immI_minus1() %{ 4086 predicate(n->get_int() == -1); 4087 match(ConI); 4088 op_cost(0); 4089 format %{ %} 4090 interface(CONST_INTER); 4091 %} 4092 4093 // int value 16. 4094 operand immI_16() %{ 4095 predicate(n->get_int() == 16); 4096 match(ConI); 4097 op_cost(0); 4098 format %{ %} 4099 interface(CONST_INTER); 4100 %} 4101 4102 // int value 24. 4103 operand immI_24() %{ 4104 predicate(n->get_int() == 24); 4105 match(ConI); 4106 op_cost(0); 4107 format %{ %} 4108 interface(CONST_INTER); 4109 %} 4110 4111 // Compressed oops constants 4112 // Pointer Immediate 4113 operand immN() %{ 4114 match(ConN); 4115 4116 op_cost(10); 4117 format %{ %} 4118 interface(CONST_INTER); 4119 %} 4120 4121 // NULL Pointer Immediate 4122 operand immN_0() %{ 4123 predicate(n->get_narrowcon() == 0); 4124 match(ConN); 4125 4126 op_cost(0); 4127 format %{ %} 4128 interface(CONST_INTER); 4129 %} 4130 4131 // Compressed klass constants 4132 operand immNKlass() %{ 4133 match(ConNKlass); 4134 4135 op_cost(0); 4136 format %{ %} 4137 interface(CONST_INTER); 4138 %} 4139 4140 // This operand can be used to avoid matching of an instruct 4141 // with chain rule. 4142 operand immNKlass_NM() %{ 4143 match(ConNKlass); 4144 predicate(false); 4145 op_cost(0); 4146 format %{ %} 4147 interface(CONST_INTER); 4148 %} 4149 4150 // Pointer Immediate: 64-bit 4151 operand immP() %{ 4152 match(ConP); 4153 op_cost(0); 4154 format %{ %} 4155 interface(CONST_INTER); 4156 %} 4157 4158 // Operand to avoid match of loadConP. 4159 // This operand can be used to avoid matching of an instruct 4160 // with chain rule. 4161 operand immP_NM() %{ 4162 match(ConP); 4163 predicate(false); 4164 op_cost(0); 4165 format %{ %} 4166 interface(CONST_INTER); 4167 %} 4168 4169 // constant 'pointer 0'. 4170 operand immP_0() %{ 4171 predicate(n->get_ptr() == 0); 4172 match(ConP); 4173 op_cost(0); 4174 format %{ %} 4175 interface(CONST_INTER); 4176 %} 4177 4178 // pointer 0x0 or 0x1 4179 operand immP_0or1() %{ 4180 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4181 match(ConP); 4182 op_cost(0); 4183 format %{ %} 4184 interface(CONST_INTER); 4185 %} 4186 4187 operand immL() %{ 4188 match(ConL); 4189 op_cost(40); 4190 format %{ %} 4191 interface(CONST_INTER); 4192 %} 4193 4194 operand immLmax30() %{ 4195 predicate((n->get_long() <= 30)); 4196 match(ConL); 4197 op_cost(0); 4198 format %{ %} 4199 interface(CONST_INTER); 4200 %} 4201 4202 // Long Immediate: 16-bit 4203 operand immL16() %{ 4204 predicate(Assembler::is_simm(n->get_long(), 16)); 4205 match(ConL); 4206 op_cost(0); 4207 format %{ %} 4208 interface(CONST_INTER); 4209 %} 4210 4211 // Long Immediate: 16-bit, 4-aligned 4212 operand immL16Alg4() %{ 4213 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4214 match(ConL); 4215 op_cost(0); 4216 format %{ %} 4217 interface(CONST_INTER); 4218 %} 4219 4220 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4221 operand immL32hi16() %{ 4222 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4223 match(ConL); 4224 op_cost(0); 4225 format %{ %} 4226 interface(CONST_INTER); 4227 %} 4228 4229 // Long Immediate: 32-bit 4230 operand immL32() %{ 4231 predicate(Assembler::is_simm(n->get_long(), 32)); 4232 match(ConL); 4233 op_cost(0); 4234 format %{ %} 4235 interface(CONST_INTER); 4236 %} 4237 4238 // Long Immediate: 34-bit, immediate field in prefixed addi and load/store. 4239 operand immL34() %{ 4240 predicate(PowerArchitecturePPC64 >= 10 && Assembler::is_simm(n->get_long(), 34)); 4241 match(ConL); 4242 op_cost(0); 4243 format %{ %} 4244 interface(CONST_INTER); 4245 %} 4246 4247 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4248 operand immLhighest16() %{ 4249 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4250 match(ConL); 4251 op_cost(0); 4252 format %{ %} 4253 interface(CONST_INTER); 4254 %} 4255 4256 operand immLnegpow2() %{ 4257 predicate(is_power_of_2(-(julong)(n->get_long()))); 4258 match(ConL); 4259 op_cost(0); 4260 format %{ %} 4261 interface(CONST_INTER); 4262 %} 4263 4264 operand immLpow2minus1() %{ 4265 predicate(is_power_of_2((julong)(n->get_long()) + 1ull)); 4266 match(ConL); 4267 op_cost(0); 4268 format %{ %} 4269 interface(CONST_INTER); 4270 %} 4271 4272 // constant 'long 0'. 4273 operand immL_0() %{ 4274 predicate(n->get_long() == 0L); 4275 match(ConL); 4276 op_cost(0); 4277 format %{ %} 4278 interface(CONST_INTER); 4279 %} 4280 4281 // constat ' long -1'. 4282 operand immL_minus1() %{ 4283 predicate(n->get_long() == -1L); 4284 match(ConL); 4285 op_cost(0); 4286 format %{ %} 4287 interface(CONST_INTER); 4288 %} 4289 4290 // Long Immediate: low 32-bit mask 4291 operand immL_32bits() %{ 4292 predicate(n->get_long() == 0xFFFFFFFFL); 4293 match(ConL); 4294 op_cost(0); 4295 format %{ %} 4296 interface(CONST_INTER); 4297 %} 4298 4299 // Unsigned Long Immediate: 16-bit 4300 operand uimmL16() %{ 4301 predicate(Assembler::is_uimm(n->get_long(), 16)); 4302 match(ConL); 4303 op_cost(0); 4304 format %{ %} 4305 interface(CONST_INTER); 4306 %} 4307 4308 // Float Immediate 4309 operand immF() %{ 4310 match(ConF); 4311 op_cost(40); 4312 format %{ %} 4313 interface(CONST_INTER); 4314 %} 4315 4316 // Float Immediate: +0.0f. 4317 operand immF_0() %{ 4318 predicate(jint_cast(n->getf()) == 0); 4319 match(ConF); 4320 4321 op_cost(0); 4322 format %{ %} 4323 interface(CONST_INTER); 4324 %} 4325 4326 // Double Immediate 4327 operand immD() %{ 4328 match(ConD); 4329 op_cost(40); 4330 format %{ %} 4331 interface(CONST_INTER); 4332 %} 4333 4334 // Double Immediate: +0.0d. 4335 operand immD_0() %{ 4336 predicate(jlong_cast(n->getd()) == 0); 4337 match(ConD); 4338 4339 op_cost(0); 4340 format %{ %} 4341 interface(CONST_INTER); 4342 %} 4343 4344 // Integer Register Operands 4345 // Integer Destination Register 4346 // See definition of reg_class bits32_reg_rw. 4347 operand iRegIdst() %{ 4348 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4349 match(RegI); 4350 match(rscratch1RegI); 4351 match(rscratch2RegI); 4352 match(rarg1RegI); 4353 match(rarg2RegI); 4354 match(rarg3RegI); 4355 match(rarg4RegI); 4356 format %{ %} 4357 interface(REG_INTER); 4358 %} 4359 4360 // Integer Source Register 4361 // See definition of reg_class bits32_reg_ro. 4362 operand iRegIsrc() %{ 4363 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4364 match(RegI); 4365 match(rscratch1RegI); 4366 match(rscratch2RegI); 4367 match(rarg1RegI); 4368 match(rarg2RegI); 4369 match(rarg3RegI); 4370 match(rarg4RegI); 4371 format %{ %} 4372 interface(REG_INTER); 4373 %} 4374 4375 operand rscratch1RegI() %{ 4376 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4377 match(iRegIdst); 4378 format %{ %} 4379 interface(REG_INTER); 4380 %} 4381 4382 operand rscratch2RegI() %{ 4383 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4384 match(iRegIdst); 4385 format %{ %} 4386 interface(REG_INTER); 4387 %} 4388 4389 operand rarg1RegI() %{ 4390 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4391 match(iRegIdst); 4392 format %{ %} 4393 interface(REG_INTER); 4394 %} 4395 4396 operand rarg2RegI() %{ 4397 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4398 match(iRegIdst); 4399 format %{ %} 4400 interface(REG_INTER); 4401 %} 4402 4403 operand rarg3RegI() %{ 4404 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4405 match(iRegIdst); 4406 format %{ %} 4407 interface(REG_INTER); 4408 %} 4409 4410 operand rarg4RegI() %{ 4411 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4412 match(iRegIdst); 4413 format %{ %} 4414 interface(REG_INTER); 4415 %} 4416 4417 operand rarg1RegL() %{ 4418 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4419 match(iRegLdst); 4420 format %{ %} 4421 interface(REG_INTER); 4422 %} 4423 4424 operand rarg2RegL() %{ 4425 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4426 match(iRegLdst); 4427 format %{ %} 4428 interface(REG_INTER); 4429 %} 4430 4431 operand rarg3RegL() %{ 4432 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4433 match(iRegLdst); 4434 format %{ %} 4435 interface(REG_INTER); 4436 %} 4437 4438 operand rarg4RegL() %{ 4439 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4440 match(iRegLdst); 4441 format %{ %} 4442 interface(REG_INTER); 4443 %} 4444 4445 // Pointer Destination Register 4446 // See definition of reg_class bits64_reg_rw. 4447 operand iRegPdst() %{ 4448 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4449 match(RegP); 4450 match(rscratch1RegP); 4451 match(rscratch2RegP); 4452 match(rarg1RegP); 4453 match(rarg2RegP); 4454 match(rarg3RegP); 4455 match(rarg4RegP); 4456 format %{ %} 4457 interface(REG_INTER); 4458 %} 4459 4460 // Pointer Destination Register 4461 // Operand not using r11 and r12 (killed in epilog). 4462 operand iRegPdstNoScratch() %{ 4463 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4464 match(RegP); 4465 match(rarg1RegP); 4466 match(rarg2RegP); 4467 match(rarg3RegP); 4468 match(rarg4RegP); 4469 format %{ %} 4470 interface(REG_INTER); 4471 %} 4472 4473 // Pointer Source Register 4474 // See definition of reg_class bits64_reg_ro. 4475 operand iRegPsrc() %{ 4476 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4477 match(RegP); 4478 match(iRegPdst); 4479 match(rscratch1RegP); 4480 match(rscratch2RegP); 4481 match(rarg1RegP); 4482 match(rarg2RegP); 4483 match(rarg3RegP); 4484 match(rarg4RegP); 4485 match(threadRegP); 4486 format %{ %} 4487 interface(REG_INTER); 4488 %} 4489 4490 // Thread operand. 4491 operand threadRegP() %{ 4492 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4493 match(iRegPdst); 4494 format %{ "R16" %} 4495 interface(REG_INTER); 4496 %} 4497 4498 operand rscratch1RegP() %{ 4499 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4500 match(iRegPdst); 4501 format %{ "R11" %} 4502 interface(REG_INTER); 4503 %} 4504 4505 operand rscratch2RegP() %{ 4506 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4507 match(iRegPdst); 4508 format %{ %} 4509 interface(REG_INTER); 4510 %} 4511 4512 operand rarg1RegP() %{ 4513 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4514 match(iRegPdst); 4515 format %{ %} 4516 interface(REG_INTER); 4517 %} 4518 4519 operand rarg2RegP() %{ 4520 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4521 match(iRegPdst); 4522 format %{ %} 4523 interface(REG_INTER); 4524 %} 4525 4526 operand rarg3RegP() %{ 4527 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4528 match(iRegPdst); 4529 format %{ %} 4530 interface(REG_INTER); 4531 %} 4532 4533 operand rarg4RegP() %{ 4534 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4535 match(iRegPdst); 4536 format %{ %} 4537 interface(REG_INTER); 4538 %} 4539 4540 operand iRegNsrc() %{ 4541 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4542 match(RegN); 4543 match(iRegNdst); 4544 4545 format %{ %} 4546 interface(REG_INTER); 4547 %} 4548 4549 operand iRegNdst() %{ 4550 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4551 match(RegN); 4552 4553 format %{ %} 4554 interface(REG_INTER); 4555 %} 4556 4557 // Long Destination Register 4558 // See definition of reg_class bits64_reg_rw. 4559 operand iRegLdst() %{ 4560 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4561 match(RegL); 4562 match(rscratch1RegL); 4563 match(rscratch2RegL); 4564 format %{ %} 4565 interface(REG_INTER); 4566 %} 4567 4568 // Long Source Register 4569 // See definition of reg_class bits64_reg_ro. 4570 operand iRegLsrc() %{ 4571 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4572 match(RegL); 4573 match(iRegLdst); 4574 match(rscratch1RegL); 4575 match(rscratch2RegL); 4576 format %{ %} 4577 interface(REG_INTER); 4578 %} 4579 4580 // Special operand for ConvL2I. 4581 operand iRegL2Isrc(iRegLsrc reg) %{ 4582 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4583 match(ConvL2I reg); 4584 format %{ "ConvL2I($reg)" %} 4585 interface(REG_INTER) 4586 %} 4587 4588 operand rscratch1RegL() %{ 4589 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4590 match(RegL); 4591 format %{ %} 4592 interface(REG_INTER); 4593 %} 4594 4595 operand rscratch2RegL() %{ 4596 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4597 match(RegL); 4598 format %{ %} 4599 interface(REG_INTER); 4600 %} 4601 4602 // Condition Code Flag Registers 4603 operand flagsReg() %{ 4604 constraint(ALLOC_IN_RC(int_flags)); 4605 match(RegFlags); 4606 format %{ %} 4607 interface(REG_INTER); 4608 %} 4609 4610 operand flagsRegSrc() %{ 4611 constraint(ALLOC_IN_RC(int_flags_ro)); 4612 match(RegFlags); 4613 match(flagsReg); 4614 match(flagsRegCR0); 4615 format %{ %} 4616 interface(REG_INTER); 4617 %} 4618 4619 // Condition Code Flag Register CR0 4620 operand flagsRegCR0() %{ 4621 constraint(ALLOC_IN_RC(int_flags_CR0)); 4622 match(RegFlags); 4623 format %{ "CR0" %} 4624 interface(REG_INTER); 4625 %} 4626 4627 operand flagsRegCR1() %{ 4628 constraint(ALLOC_IN_RC(int_flags_CR1)); 4629 match(RegFlags); 4630 format %{ "CR1" %} 4631 interface(REG_INTER); 4632 %} 4633 4634 operand flagsRegCR6() %{ 4635 constraint(ALLOC_IN_RC(int_flags_CR6)); 4636 match(RegFlags); 4637 format %{ "CR6" %} 4638 interface(REG_INTER); 4639 %} 4640 4641 operand regCTR() %{ 4642 constraint(ALLOC_IN_RC(ctr_reg)); 4643 // RegFlags should work. Introducing a RegSpecial type would cause a 4644 // lot of changes. 4645 match(RegFlags); 4646 format %{"SR_CTR" %} 4647 interface(REG_INTER); 4648 %} 4649 4650 operand regD() %{ 4651 constraint(ALLOC_IN_RC(dbl_reg)); 4652 match(RegD); 4653 format %{ %} 4654 interface(REG_INTER); 4655 %} 4656 4657 operand regF() %{ 4658 constraint(ALLOC_IN_RC(flt_reg)); 4659 match(RegF); 4660 format %{ %} 4661 interface(REG_INTER); 4662 %} 4663 4664 // Special Registers 4665 4666 // Method Register 4667 operand inline_cache_regP(iRegPdst reg) %{ 4668 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4669 match(reg); 4670 format %{ %} 4671 interface(REG_INTER); 4672 %} 4673 4674 // Operands to remove register moves in unscaled mode. 4675 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4676 operand iRegP2N(iRegPsrc reg) %{ 4677 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0); 4678 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4679 match(EncodeP reg); 4680 format %{ "$reg" %} 4681 interface(REG_INTER) 4682 %} 4683 4684 operand iRegN2P(iRegNsrc reg) %{ 4685 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4686 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4687 match(DecodeN reg); 4688 format %{ "$reg" %} 4689 interface(REG_INTER) 4690 %} 4691 4692 operand iRegN2P_klass(iRegNsrc reg) %{ 4693 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 4694 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4695 match(DecodeNKlass reg); 4696 format %{ "$reg" %} 4697 interface(REG_INTER) 4698 %} 4699 4700 //----------Complex Operands--------------------------------------------------- 4701 // Indirect Memory Reference 4702 operand indirect(iRegPsrc reg) %{ 4703 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4704 match(reg); 4705 op_cost(100); 4706 format %{ "[$reg]" %} 4707 interface(MEMORY_INTER) %{ 4708 base($reg); 4709 index(0x0); 4710 scale(0x0); 4711 disp(0x0); 4712 %} 4713 %} 4714 4715 // Indirect with Offset 4716 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 4717 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4718 match(AddP reg offset); 4719 op_cost(100); 4720 format %{ "[$reg + $offset]" %} 4721 interface(MEMORY_INTER) %{ 4722 base($reg); 4723 index(0x0); 4724 scale(0x0); 4725 disp($offset); 4726 %} 4727 %} 4728 4729 // Indirect with 4-aligned Offset 4730 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 4731 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4732 match(AddP reg offset); 4733 op_cost(100); 4734 format %{ "[$reg + $offset]" %} 4735 interface(MEMORY_INTER) %{ 4736 base($reg); 4737 index(0x0); 4738 scale(0x0); 4739 disp($offset); 4740 %} 4741 %} 4742 4743 //----------Complex Operands for Compressed OOPs------------------------------- 4744 // Compressed OOPs with narrow_oop_shift == 0. 4745 4746 // Indirect Memory Reference, compressed OOP 4747 operand indirectNarrow(iRegNsrc reg) %{ 4748 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4749 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4750 match(DecodeN reg); 4751 op_cost(100); 4752 format %{ "[$reg]" %} 4753 interface(MEMORY_INTER) %{ 4754 base($reg); 4755 index(0x0); 4756 scale(0x0); 4757 disp(0x0); 4758 %} 4759 %} 4760 4761 operand indirectNarrow_klass(iRegNsrc reg) %{ 4762 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 4763 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4764 match(DecodeNKlass reg); 4765 op_cost(100); 4766 format %{ "[$reg]" %} 4767 interface(MEMORY_INTER) %{ 4768 base($reg); 4769 index(0x0); 4770 scale(0x0); 4771 disp(0x0); 4772 %} 4773 %} 4774 4775 // Indirect with Offset, compressed OOP 4776 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 4777 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4778 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4779 match(AddP (DecodeN reg) offset); 4780 op_cost(100); 4781 format %{ "[$reg + $offset]" %} 4782 interface(MEMORY_INTER) %{ 4783 base($reg); 4784 index(0x0); 4785 scale(0x0); 4786 disp($offset); 4787 %} 4788 %} 4789 4790 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 4791 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 4792 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4793 match(AddP (DecodeNKlass reg) offset); 4794 op_cost(100); 4795 format %{ "[$reg + $offset]" %} 4796 interface(MEMORY_INTER) %{ 4797 base($reg); 4798 index(0x0); 4799 scale(0x0); 4800 disp($offset); 4801 %} 4802 %} 4803 4804 // Indirect with 4-aligned Offset, compressed OOP 4805 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 4806 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4807 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4808 match(AddP (DecodeN reg) offset); 4809 op_cost(100); 4810 format %{ "[$reg + $offset]" %} 4811 interface(MEMORY_INTER) %{ 4812 base($reg); 4813 index(0x0); 4814 scale(0x0); 4815 disp($offset); 4816 %} 4817 %} 4818 4819 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 4820 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 4821 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4822 match(AddP (DecodeNKlass reg) offset); 4823 op_cost(100); 4824 format %{ "[$reg + $offset]" %} 4825 interface(MEMORY_INTER) %{ 4826 base($reg); 4827 index(0x0); 4828 scale(0x0); 4829 disp($offset); 4830 %} 4831 %} 4832 4833 //----------Special Memory Operands-------------------------------------------- 4834 // Stack Slot Operand 4835 // 4836 // This operand is used for loading and storing temporary values on 4837 // the stack where a match requires a value to flow through memory. 4838 operand stackSlotI(sRegI reg) %{ 4839 constraint(ALLOC_IN_RC(stack_slots)); 4840 op_cost(100); 4841 //match(RegI); 4842 format %{ "[sp+$reg]" %} 4843 interface(MEMORY_INTER) %{ 4844 base(0x1); // R1_SP 4845 index(0x0); 4846 scale(0x0); 4847 disp($reg); // Stack Offset 4848 %} 4849 %} 4850 4851 operand stackSlotL(sRegL reg) %{ 4852 constraint(ALLOC_IN_RC(stack_slots)); 4853 op_cost(100); 4854 //match(RegL); 4855 format %{ "[sp+$reg]" %} 4856 interface(MEMORY_INTER) %{ 4857 base(0x1); // R1_SP 4858 index(0x0); 4859 scale(0x0); 4860 disp($reg); // Stack Offset 4861 %} 4862 %} 4863 4864 operand stackSlotP(sRegP reg) %{ 4865 constraint(ALLOC_IN_RC(stack_slots)); 4866 op_cost(100); 4867 //match(RegP); 4868 format %{ "[sp+$reg]" %} 4869 interface(MEMORY_INTER) %{ 4870 base(0x1); // R1_SP 4871 index(0x0); 4872 scale(0x0); 4873 disp($reg); // Stack Offset 4874 %} 4875 %} 4876 4877 operand stackSlotF(sRegF reg) %{ 4878 constraint(ALLOC_IN_RC(stack_slots)); 4879 op_cost(100); 4880 //match(RegF); 4881 format %{ "[sp+$reg]" %} 4882 interface(MEMORY_INTER) %{ 4883 base(0x1); // R1_SP 4884 index(0x0); 4885 scale(0x0); 4886 disp($reg); // Stack Offset 4887 %} 4888 %} 4889 4890 operand stackSlotD(sRegD reg) %{ 4891 constraint(ALLOC_IN_RC(stack_slots)); 4892 op_cost(100); 4893 //match(RegD); 4894 format %{ "[sp+$reg]" %} 4895 interface(MEMORY_INTER) %{ 4896 base(0x1); // R1_SP 4897 index(0x0); 4898 scale(0x0); 4899 disp($reg); // Stack Offset 4900 %} 4901 %} 4902 4903 // Operands for expressing Control Flow 4904 // NOTE: Label is a predefined operand which should not be redefined in 4905 // the AD file. It is generically handled within the ADLC. 4906 4907 //----------Conditional Branch Operands---------------------------------------- 4908 // Comparison Op 4909 // 4910 // This is the operation of the comparison, and is limited to the 4911 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 4912 // (!=). 4913 // 4914 // Other attributes of the comparison, such as unsignedness, are specified 4915 // by the comparison instruction that sets a condition code flags register. 4916 // That result is represented by a flags operand whose subtype is appropriate 4917 // to the unsignedness (etc.) of the comparison. 4918 // 4919 // Later, the instruction which matches both the Comparison Op (a Bool) and 4920 // the flags (produced by the Cmp) specifies the coding of the comparison op 4921 // by matching a specific subtype of Bool operand below. 4922 4923 // When used for floating point comparisons: unordered same as less. 4924 operand cmpOp() %{ 4925 match(Bool); 4926 format %{ "" %} 4927 interface(COND_INTER) %{ 4928 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 4929 // BO & BI 4930 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 4931 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 4932 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 4933 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 4934 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 4935 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 4936 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 4937 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 4938 %} 4939 %} 4940 4941 //----------OPERAND CLASSES---------------------------------------------------- 4942 // Operand Classes are groups of operands that are used to simplify 4943 // instruction definitions by not requiring the AD writer to specify 4944 // separate instructions for every form of operand when the 4945 // instruction accepts multiple operand types with the same basic 4946 // encoding and format. The classic case of this is memory operands. 4947 // Indirect is not included since its use is limited to Compare & Swap. 4948 4949 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 4950 // Memory operand where offsets are 4-aligned. Required for ld, std. 4951 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 4952 opclass indirectMemory(indirect, indirectNarrow); 4953 4954 // Special opclass for I and ConvL2I. 4955 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 4956 4957 // Operand classes to match encode and decode. iRegN_P2N is only used 4958 // for storeN. I have never seen an encode node elsewhere. 4959 opclass iRegN_P2N(iRegNsrc, iRegP2N); 4960 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 4961 4962 //----------PIPELINE----------------------------------------------------------- 4963 4964 pipeline %{ 4965 4966 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 4967 // J. Res. & Dev., No. 1, Jan. 2002. 4968 4969 //----------ATTRIBUTES--------------------------------------------------------- 4970 attributes %{ 4971 4972 // Power4 instructions are of fixed length. 4973 fixed_size_instructions; 4974 4975 // TODO: if `bundle' means number of instructions fetched 4976 // per cycle, this is 8. If `bundle' means Power4 `group', that is 4977 // max instructions issued per cycle, this is 5. 4978 max_instructions_per_bundle = 8; 4979 4980 // A Power4 instruction is 4 bytes long. 4981 instruction_unit_size = 4; 4982 4983 // The Power4 processor fetches 64 bytes... 4984 instruction_fetch_unit_size = 64; 4985 4986 // ...in one line 4987 instruction_fetch_units = 1 4988 4989 // Unused, list one so that array generated by adlc is not empty. 4990 // Aix compiler chokes if _nop_count = 0. 4991 nops(fxNop); 4992 %} 4993 4994 //----------RESOURCES---------------------------------------------------------- 4995 // Resources are the functional units available to the machine 4996 resources( 4997 PPC_BR, // branch unit 4998 PPC_CR, // condition unit 4999 PPC_FX1, // integer arithmetic unit 1 5000 PPC_FX2, // integer arithmetic unit 2 5001 PPC_LDST1, // load/store unit 1 5002 PPC_LDST2, // load/store unit 2 5003 PPC_FP1, // float arithmetic unit 1 5004 PPC_FP2, // float arithmetic unit 2 5005 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5006 PPC_FX = PPC_FX1 | PPC_FX2, 5007 PPC_FP = PPC_FP1 | PPC_FP2 5008 ); 5009 5010 //----------PIPELINE DESCRIPTION----------------------------------------------- 5011 // Pipeline Description specifies the stages in the machine's pipeline 5012 pipe_desc( 5013 // Power4 longest pipeline path 5014 PPC_IF, // instruction fetch 5015 PPC_IC, 5016 //PPC_BP, // branch prediction 5017 PPC_D0, // decode 5018 PPC_D1, // decode 5019 PPC_D2, // decode 5020 PPC_D3, // decode 5021 PPC_Xfer1, 5022 PPC_GD, // group definition 5023 PPC_MP, // map 5024 PPC_ISS, // issue 5025 PPC_RF, // resource fetch 5026 PPC_EX1, // execute (all units) 5027 PPC_EX2, // execute (FP, LDST) 5028 PPC_EX3, // execute (FP, LDST) 5029 PPC_EX4, // execute (FP) 5030 PPC_EX5, // execute (FP) 5031 PPC_EX6, // execute (FP) 5032 PPC_WB, // write back 5033 PPC_Xfer2, 5034 PPC_CP 5035 ); 5036 5037 //----------PIPELINE CLASSES--------------------------------------------------- 5038 // Pipeline Classes describe the stages in which input and output are 5039 // referenced by the hardware pipeline. 5040 5041 // Simple pipeline classes. 5042 5043 // Default pipeline class. 5044 pipe_class pipe_class_default() %{ 5045 single_instruction; 5046 fixed_latency(2); 5047 %} 5048 5049 // Pipeline class for empty instructions. 5050 pipe_class pipe_class_empty() %{ 5051 single_instruction; 5052 fixed_latency(0); 5053 %} 5054 5055 // Pipeline class for compares. 5056 pipe_class pipe_class_compare() %{ 5057 single_instruction; 5058 fixed_latency(16); 5059 %} 5060 5061 // Pipeline class for traps. 5062 pipe_class pipe_class_trap() %{ 5063 single_instruction; 5064 fixed_latency(100); 5065 %} 5066 5067 // Pipeline class for memory operations. 5068 pipe_class pipe_class_memory() %{ 5069 single_instruction; 5070 fixed_latency(16); 5071 %} 5072 5073 // Pipeline class for call. 5074 pipe_class pipe_class_call() %{ 5075 single_instruction; 5076 fixed_latency(100); 5077 %} 5078 5079 // Define the class for the Nop node. 5080 define %{ 5081 MachNop = pipe_class_default; 5082 %} 5083 5084 %} 5085 5086 //----------INSTRUCTIONS------------------------------------------------------- 5087 5088 // Naming of instructions: 5089 // opA_operB / opA_operB_operC: 5090 // Operation 'op' with one or two source operands 'oper'. Result 5091 // type is A, source operand types are B and C. 5092 // Iff A == B == C, B and C are left out. 5093 // 5094 // The instructions are ordered according to the following scheme: 5095 // - loads 5096 // - load constants 5097 // - prefetch 5098 // - store 5099 // - encode/decode 5100 // - membar 5101 // - conditional moves 5102 // - compare & swap 5103 // - arithmetic and logic operations 5104 // * int: Add, Sub, Mul, Div, Mod 5105 // * int: lShift, arShift, urShift, rot 5106 // * float: Add, Sub, Mul, Div 5107 // * and, or, xor ... 5108 // - register moves: float <-> int, reg <-> stack, repl 5109 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5110 // - conv (low level type cast requiring bit changes (sign extend etc) 5111 // - compares, range & zero checks. 5112 // - branches 5113 // - complex operations, intrinsics, min, max, replicate 5114 // - lock 5115 // - Calls 5116 // 5117 // If there are similar instructions with different types they are sorted: 5118 // int before float 5119 // small before big 5120 // signed before unsigned 5121 // e.g., loadS before loadUS before loadI before loadF. 5122 5123 5124 //----------Load/Store Instructions-------------------------------------------- 5125 5126 //----------Load Instructions-------------------------------------------------- 5127 5128 // Converts byte to int. 5129 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5130 // reuses the 'amount' operand, but adlc expects that operand specification 5131 // and operands in match rule are equivalent. 5132 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5133 effect(DEF dst, USE src); 5134 format %{ "EXTSB $dst, $src \t// byte->int" %} 5135 size(4); 5136 ins_encode %{ 5137 __ extsb($dst$$Register, $src$$Register); 5138 %} 5139 ins_pipe(pipe_class_default); 5140 %} 5141 5142 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5143 // match-rule, false predicate 5144 match(Set dst (LoadB mem)); 5145 predicate(false); 5146 5147 format %{ "LBZ $dst, $mem" %} 5148 size(4); 5149 ins_encode( enc_lbz(dst, mem) ); 5150 ins_pipe(pipe_class_memory); 5151 %} 5152 5153 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5154 // match-rule, false predicate 5155 match(Set dst (LoadB mem)); 5156 predicate(false); 5157 5158 format %{ "LBZ $dst, $mem\n\t" 5159 "TWI $dst\n\t" 5160 "ISYNC" %} 5161 size(12); 5162 ins_encode( enc_lbz_ac(dst, mem) ); 5163 ins_pipe(pipe_class_memory); 5164 %} 5165 5166 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5167 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5168 match(Set dst (LoadB mem)); 5169 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5170 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5171 expand %{ 5172 iRegIdst tmp; 5173 loadUB_indirect(tmp, mem); 5174 convB2I_reg_2(dst, tmp); 5175 %} 5176 %} 5177 5178 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5179 match(Set dst (LoadB mem)); 5180 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5181 expand %{ 5182 iRegIdst tmp; 5183 loadUB_indirect_ac(tmp, mem); 5184 convB2I_reg_2(dst, tmp); 5185 %} 5186 %} 5187 5188 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5189 // match-rule, false predicate 5190 match(Set dst (LoadB mem)); 5191 predicate(false); 5192 5193 format %{ "LBZ $dst, $mem" %} 5194 size(4); 5195 ins_encode( enc_lbz(dst, mem) ); 5196 ins_pipe(pipe_class_memory); 5197 %} 5198 5199 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5200 // match-rule, false predicate 5201 match(Set dst (LoadB mem)); 5202 predicate(false); 5203 5204 format %{ "LBZ $dst, $mem\n\t" 5205 "TWI $dst\n\t" 5206 "ISYNC" %} 5207 size(12); 5208 ins_encode( enc_lbz_ac(dst, mem) ); 5209 ins_pipe(pipe_class_memory); 5210 %} 5211 5212 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5213 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5214 match(Set dst (LoadB mem)); 5215 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5216 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5217 5218 expand %{ 5219 iRegIdst tmp; 5220 loadUB_indOffset16(tmp, mem); 5221 convB2I_reg_2(dst, tmp); 5222 %} 5223 %} 5224 5225 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5226 match(Set dst (LoadB mem)); 5227 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5228 5229 expand %{ 5230 iRegIdst tmp; 5231 loadUB_indOffset16_ac(tmp, mem); 5232 convB2I_reg_2(dst, tmp); 5233 %} 5234 %} 5235 5236 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5237 instruct loadUB(iRegIdst dst, memory mem) %{ 5238 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5239 match(Set dst (LoadUB mem)); 5240 ins_cost(MEMORY_REF_COST); 5241 5242 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5243 size(4); 5244 ins_encode( enc_lbz(dst, mem) ); 5245 ins_pipe(pipe_class_memory); 5246 %} 5247 5248 // Load Unsigned Byte (8bit UNsigned) acquire. 5249 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5250 match(Set dst (LoadUB mem)); 5251 ins_cost(3*MEMORY_REF_COST); 5252 5253 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5254 "TWI $dst\n\t" 5255 "ISYNC" %} 5256 size(12); 5257 ins_encode( enc_lbz_ac(dst, mem) ); 5258 ins_pipe(pipe_class_memory); 5259 %} 5260 5261 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5262 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5263 match(Set dst (ConvI2L (LoadUB mem))); 5264 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5265 ins_cost(MEMORY_REF_COST); 5266 5267 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5268 size(4); 5269 ins_encode( enc_lbz(dst, mem) ); 5270 ins_pipe(pipe_class_memory); 5271 %} 5272 5273 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5274 match(Set dst (ConvI2L (LoadUB mem))); 5275 ins_cost(3*MEMORY_REF_COST); 5276 5277 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5278 "TWI $dst\n\t" 5279 "ISYNC" %} 5280 size(12); 5281 ins_encode( enc_lbz_ac(dst, mem) ); 5282 ins_pipe(pipe_class_memory); 5283 %} 5284 5285 // Load Short (16bit signed) 5286 instruct loadS(iRegIdst dst, memory mem) %{ 5287 match(Set dst (LoadS mem)); 5288 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5289 ins_cost(MEMORY_REF_COST); 5290 5291 format %{ "LHA $dst, $mem" %} 5292 size(4); 5293 ins_encode %{ 5294 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5295 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5296 %} 5297 ins_pipe(pipe_class_memory); 5298 %} 5299 5300 // Load Short (16bit signed) acquire. 5301 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5302 match(Set dst (LoadS mem)); 5303 ins_cost(3*MEMORY_REF_COST); 5304 5305 format %{ "LHA $dst, $mem\t acquire\n\t" 5306 "TWI $dst\n\t" 5307 "ISYNC" %} 5308 size(12); 5309 ins_encode %{ 5310 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5311 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5312 __ twi_0($dst$$Register); 5313 __ isync(); 5314 %} 5315 ins_pipe(pipe_class_memory); 5316 %} 5317 5318 // Load Char (16bit unsigned) 5319 instruct loadUS(iRegIdst dst, memory mem) %{ 5320 match(Set dst (LoadUS mem)); 5321 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5322 ins_cost(MEMORY_REF_COST); 5323 5324 format %{ "LHZ $dst, $mem" %} 5325 size(4); 5326 ins_encode( enc_lhz(dst, mem) ); 5327 ins_pipe(pipe_class_memory); 5328 %} 5329 5330 // Load Char (16bit unsigned) acquire. 5331 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5332 match(Set dst (LoadUS mem)); 5333 ins_cost(3*MEMORY_REF_COST); 5334 5335 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5336 "TWI $dst\n\t" 5337 "ISYNC" %} 5338 size(12); 5339 ins_encode( enc_lhz_ac(dst, mem) ); 5340 ins_pipe(pipe_class_memory); 5341 %} 5342 5343 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5344 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5345 match(Set dst (ConvI2L (LoadUS mem))); 5346 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5347 ins_cost(MEMORY_REF_COST); 5348 5349 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5350 size(4); 5351 ins_encode( enc_lhz(dst, mem) ); 5352 ins_pipe(pipe_class_memory); 5353 %} 5354 5355 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5356 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5357 match(Set dst (ConvI2L (LoadUS mem))); 5358 ins_cost(3*MEMORY_REF_COST); 5359 5360 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5361 "TWI $dst\n\t" 5362 "ISYNC" %} 5363 size(12); 5364 ins_encode( enc_lhz_ac(dst, mem) ); 5365 ins_pipe(pipe_class_memory); 5366 %} 5367 5368 // Load Integer. 5369 instruct loadI(iRegIdst dst, memory mem) %{ 5370 match(Set dst (LoadI mem)); 5371 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5372 ins_cost(MEMORY_REF_COST); 5373 5374 format %{ "LWZ $dst, $mem" %} 5375 size(4); 5376 ins_encode( enc_lwz(dst, mem) ); 5377 ins_pipe(pipe_class_memory); 5378 %} 5379 5380 // Load Integer acquire. 5381 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5382 match(Set dst (LoadI mem)); 5383 ins_cost(3*MEMORY_REF_COST); 5384 5385 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5386 "TWI $dst\n\t" 5387 "ISYNC" %} 5388 size(12); 5389 ins_encode( enc_lwz_ac(dst, mem) ); 5390 ins_pipe(pipe_class_memory); 5391 %} 5392 5393 // Match loading integer and casting it to unsigned int in 5394 // long register. 5395 // LoadI + ConvI2L + AndL 0xffffffff. 5396 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5397 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5398 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5399 ins_cost(MEMORY_REF_COST); 5400 5401 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5402 size(4); 5403 ins_encode( enc_lwz(dst, mem) ); 5404 ins_pipe(pipe_class_memory); 5405 %} 5406 5407 // Match loading integer and casting it to long. 5408 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5409 match(Set dst (ConvI2L (LoadI mem))); 5410 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5411 ins_cost(MEMORY_REF_COST); 5412 5413 format %{ "LWA $dst, $mem \t// loadI2L" %} 5414 size(4); 5415 ins_encode %{ 5416 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5417 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5418 %} 5419 ins_pipe(pipe_class_memory); 5420 %} 5421 5422 // Match loading integer and casting it to long - acquire. 5423 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5424 match(Set dst (ConvI2L (LoadI mem))); 5425 ins_cost(3*MEMORY_REF_COST); 5426 5427 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5428 "TWI $dst\n\t" 5429 "ISYNC" %} 5430 size(12); 5431 ins_encode %{ 5432 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5433 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5434 __ twi_0($dst$$Register); 5435 __ isync(); 5436 %} 5437 ins_pipe(pipe_class_memory); 5438 %} 5439 5440 // Load Long - aligned 5441 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5442 match(Set dst (LoadL mem)); 5443 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5444 ins_cost(MEMORY_REF_COST); 5445 5446 format %{ "LD $dst, $mem \t// long" %} 5447 size(4); 5448 ins_encode( enc_ld(dst, mem) ); 5449 ins_pipe(pipe_class_memory); 5450 %} 5451 5452 // Load Long - aligned acquire. 5453 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5454 match(Set dst (LoadL mem)); 5455 ins_cost(3*MEMORY_REF_COST); 5456 5457 format %{ "LD $dst, $mem \t// long acquire\n\t" 5458 "TWI $dst\n\t" 5459 "ISYNC" %} 5460 size(12); 5461 ins_encode( enc_ld_ac(dst, mem) ); 5462 ins_pipe(pipe_class_memory); 5463 %} 5464 5465 // Load Long - UNaligned 5466 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5467 match(Set dst (LoadL_unaligned mem)); 5468 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5469 ins_cost(MEMORY_REF_COST); 5470 5471 format %{ "LD $dst, $mem \t// unaligned long" %} 5472 size(4); 5473 ins_encode( enc_ld(dst, mem) ); 5474 ins_pipe(pipe_class_memory); 5475 %} 5476 5477 // Load nodes for superwords 5478 5479 // Load Aligned Packed Byte 5480 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5481 predicate(n->as_LoadVector()->memory_size() == 8); 5482 match(Set dst (LoadVector mem)); 5483 ins_cost(MEMORY_REF_COST); 5484 5485 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5486 size(4); 5487 ins_encode( enc_ld(dst, mem) ); 5488 ins_pipe(pipe_class_memory); 5489 %} 5490 5491 // Load Aligned Packed Byte 5492 instruct loadV16(vecX dst, indirect mem) %{ 5493 predicate(n->as_LoadVector()->memory_size() == 16); 5494 match(Set dst (LoadVector mem)); 5495 ins_cost(MEMORY_REF_COST); 5496 5497 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5498 size(4); 5499 ins_encode %{ 5500 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5501 %} 5502 ins_pipe(pipe_class_default); 5503 %} 5504 5505 // Load Range, range = array length (=jint) 5506 instruct loadRange(iRegIdst dst, memory mem) %{ 5507 match(Set dst (LoadRange mem)); 5508 ins_cost(MEMORY_REF_COST); 5509 5510 format %{ "LWZ $dst, $mem \t// range" %} 5511 size(4); 5512 ins_encode( enc_lwz(dst, mem) ); 5513 ins_pipe(pipe_class_memory); 5514 %} 5515 5516 // Load Compressed Pointer 5517 instruct loadN(iRegNdst dst, memory mem) %{ 5518 match(Set dst (LoadN mem)); 5519 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5520 ins_cost(MEMORY_REF_COST); 5521 5522 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5523 size(4); 5524 ins_encode( enc_lwz(dst, mem) ); 5525 ins_pipe(pipe_class_memory); 5526 %} 5527 5528 // Load Compressed Pointer acquire. 5529 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5530 match(Set dst (LoadN mem)); 5531 ins_cost(3*MEMORY_REF_COST); 5532 5533 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5534 "TWI $dst\n\t" 5535 "ISYNC" %} 5536 size(12); 5537 ins_encode( enc_lwz_ac(dst, mem) ); 5538 ins_pipe(pipe_class_memory); 5539 %} 5540 5541 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5542 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5543 match(Set dst (DecodeN (LoadN mem))); 5544 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0); 5545 ins_cost(MEMORY_REF_COST); 5546 5547 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5548 size(4); 5549 ins_encode( enc_lwz(dst, mem) ); 5550 ins_pipe(pipe_class_memory); 5551 %} 5552 5553 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5554 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5555 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0 && 5556 _kids[0]->_leaf->as_Load()->is_unordered()); 5557 ins_cost(MEMORY_REF_COST); 5558 5559 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5560 size(4); 5561 ins_encode( enc_lwz(dst, mem) ); 5562 ins_pipe(pipe_class_memory); 5563 %} 5564 5565 // Load Pointer 5566 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5567 match(Set dst (LoadP mem)); 5568 predicate((n->as_Load()->is_unordered() || followed_by_acquire(n)) && n->as_Load()->barrier_data() == 0); 5569 ins_cost(MEMORY_REF_COST); 5570 5571 format %{ "LD $dst, $mem \t// ptr" %} 5572 size(4); 5573 ins_encode( enc_ld(dst, mem) ); 5574 ins_pipe(pipe_class_memory); 5575 %} 5576 5577 // Load Pointer acquire. 5578 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5579 match(Set dst (LoadP mem)); 5580 ins_cost(3*MEMORY_REF_COST); 5581 5582 predicate(n->as_Load()->barrier_data() == 0); 5583 5584 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5585 "TWI $dst\n\t" 5586 "ISYNC" %} 5587 size(12); 5588 ins_encode( enc_ld_ac(dst, mem) ); 5589 ins_pipe(pipe_class_memory); 5590 %} 5591 5592 // LoadP + CastP2L 5593 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5594 match(Set dst (CastP2X (LoadP mem))); 5595 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && _kids[0]->_leaf->as_Load()->barrier_data() == 0); 5596 ins_cost(MEMORY_REF_COST); 5597 5598 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5599 size(4); 5600 ins_encode( enc_ld(dst, mem) ); 5601 ins_pipe(pipe_class_memory); 5602 %} 5603 5604 // Load compressed klass pointer. 5605 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5606 match(Set dst (LoadNKlass mem)); 5607 ins_cost(MEMORY_REF_COST); 5608 5609 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5610 size(4); 5611 ins_encode( enc_lwz(dst, mem) ); 5612 ins_pipe(pipe_class_memory); 5613 %} 5614 5615 // Load Klass Pointer 5616 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5617 match(Set dst (LoadKlass mem)); 5618 ins_cost(MEMORY_REF_COST); 5619 5620 format %{ "LD $dst, $mem \t// klass ptr" %} 5621 size(4); 5622 ins_encode( enc_ld(dst, mem) ); 5623 ins_pipe(pipe_class_memory); 5624 %} 5625 5626 // Load Float 5627 instruct loadF(regF dst, memory mem) %{ 5628 match(Set dst (LoadF mem)); 5629 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5630 ins_cost(MEMORY_REF_COST); 5631 5632 format %{ "LFS $dst, $mem" %} 5633 size(4); 5634 ins_encode %{ 5635 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5636 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5637 %} 5638 ins_pipe(pipe_class_memory); 5639 %} 5640 5641 // Load Float acquire. 5642 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5643 match(Set dst (LoadF mem)); 5644 effect(TEMP cr0); 5645 ins_cost(3*MEMORY_REF_COST); 5646 5647 format %{ "LFS $dst, $mem \t// acquire\n\t" 5648 "FCMPU cr0, $dst, $dst\n\t" 5649 "BNE cr0, next\n" 5650 "next:\n\t" 5651 "ISYNC" %} 5652 size(16); 5653 ins_encode %{ 5654 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5655 Label next; 5656 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5657 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5658 __ bne(CCR0, next); 5659 __ bind(next); 5660 __ isync(); 5661 %} 5662 ins_pipe(pipe_class_memory); 5663 %} 5664 5665 // Load Double - aligned 5666 instruct loadD(regD dst, memory mem) %{ 5667 match(Set dst (LoadD mem)); 5668 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5669 ins_cost(MEMORY_REF_COST); 5670 5671 format %{ "LFD $dst, $mem" %} 5672 size(4); 5673 ins_encode( enc_lfd(dst, mem) ); 5674 ins_pipe(pipe_class_memory); 5675 %} 5676 5677 // Load Double - aligned acquire. 5678 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5679 match(Set dst (LoadD mem)); 5680 effect(TEMP cr0); 5681 ins_cost(3*MEMORY_REF_COST); 5682 5683 format %{ "LFD $dst, $mem \t// acquire\n\t" 5684 "FCMPU cr0, $dst, $dst\n\t" 5685 "BNE cr0, next\n" 5686 "next:\n\t" 5687 "ISYNC" %} 5688 size(16); 5689 ins_encode %{ 5690 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5691 Label next; 5692 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5693 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5694 __ bne(CCR0, next); 5695 __ bind(next); 5696 __ isync(); 5697 %} 5698 ins_pipe(pipe_class_memory); 5699 %} 5700 5701 // Load Double - UNaligned 5702 instruct loadD_unaligned(regD dst, memory mem) %{ 5703 match(Set dst (LoadD_unaligned mem)); 5704 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5705 ins_cost(MEMORY_REF_COST); 5706 5707 format %{ "LFD $dst, $mem" %} 5708 size(4); 5709 ins_encode( enc_lfd(dst, mem) ); 5710 ins_pipe(pipe_class_memory); 5711 %} 5712 5713 //----------Constants-------------------------------------------------------- 5714 5715 // Load MachConstantTableBase: add hi offset to global toc. 5716 // TODO: Handle hidden register r29 in bundler! 5717 instruct loadToc_hi(iRegLdst dst) %{ 5718 effect(DEF dst); 5719 ins_cost(DEFAULT_COST); 5720 5721 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 5722 size(4); 5723 ins_encode %{ 5724 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 5725 %} 5726 ins_pipe(pipe_class_default); 5727 %} 5728 5729 // Load MachConstantTableBase: add lo offset to global toc. 5730 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 5731 effect(DEF dst, USE src); 5732 ins_cost(DEFAULT_COST); 5733 5734 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 5735 size(4); 5736 ins_encode %{ 5737 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 5738 %} 5739 ins_pipe(pipe_class_default); 5740 %} 5741 5742 // Load 16-bit integer constant 0xssss???? 5743 instruct loadConI16(iRegIdst dst, immI16 src) %{ 5744 match(Set dst src); 5745 5746 format %{ "LI $dst, $src" %} 5747 size(4); 5748 ins_encode %{ 5749 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 5750 %} 5751 ins_pipe(pipe_class_default); 5752 %} 5753 5754 // Load integer constant 0x????0000 5755 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 5756 match(Set dst src); 5757 ins_cost(DEFAULT_COST); 5758 5759 format %{ "LIS $dst, $src.hi" %} 5760 size(4); 5761 ins_encode %{ 5762 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 5763 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5764 %} 5765 ins_pipe(pipe_class_default); 5766 %} 5767 5768 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 5769 // and sign extended), this adds the low 16 bits. 5770 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 5771 // no match-rule, false predicate 5772 effect(DEF dst, USE src1, USE src2); 5773 predicate(false); 5774 5775 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 5776 size(4); 5777 ins_encode %{ 5778 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5779 %} 5780 ins_pipe(pipe_class_default); 5781 %} 5782 5783 instruct loadConI32(iRegIdst dst, immI32 src) %{ 5784 match(Set dst src); 5785 // This macro is valid only in Power 10 and up, but adding the following predicate here 5786 // caused a build error, so we comment it out for now. 5787 // predicate(PowerArchitecturePPC64 >= 10); 5788 ins_cost(DEFAULT_COST+1); 5789 5790 format %{ "PLI $dst, $src" %} 5791 size(8); 5792 ins_encode %{ 5793 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 5794 __ pli($dst$$Register, $src$$constant); 5795 %} 5796 ins_pipe(pipe_class_default); 5797 ins_alignment(2); 5798 %} 5799 5800 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 5801 match(Set dst src); 5802 ins_cost(DEFAULT_COST*2); 5803 5804 expand %{ 5805 // Would like to use $src$$constant. 5806 immI16 srcLo %{ _opnds[1]->constant() %} 5807 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5808 immIhi16 srcHi %{ _opnds[1]->constant() %} 5809 iRegIdst tmpI; 5810 loadConIhi16(tmpI, srcHi); 5811 loadConI32_lo16(dst, tmpI, srcLo); 5812 %} 5813 %} 5814 5815 // No constant pool entries required. 5816 instruct loadConL16(iRegLdst dst, immL16 src) %{ 5817 match(Set dst src); 5818 5819 format %{ "LI $dst, $src \t// long" %} 5820 size(4); 5821 ins_encode %{ 5822 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 5823 %} 5824 ins_pipe(pipe_class_default); 5825 %} 5826 5827 // Load long constant 0xssssssss????0000 5828 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 5829 match(Set dst src); 5830 ins_cost(DEFAULT_COST); 5831 5832 format %{ "LIS $dst, $src.hi \t// long" %} 5833 size(4); 5834 ins_encode %{ 5835 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5836 %} 5837 ins_pipe(pipe_class_default); 5838 %} 5839 5840 // To load a 32 bit constant: merge lower 16 bits into already loaded 5841 // high 16 bits. 5842 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 5843 // no match-rule, false predicate 5844 effect(DEF dst, USE src1, USE src2); 5845 predicate(false); 5846 5847 format %{ "ORI $dst, $src1, $src2.lo" %} 5848 size(4); 5849 ins_encode %{ 5850 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5851 %} 5852 ins_pipe(pipe_class_default); 5853 %} 5854 5855 // Load 32-bit long constant 5856 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 5857 match(Set dst src); 5858 ins_cost(DEFAULT_COST*2); 5859 5860 expand %{ 5861 // Would like to use $src$$constant. 5862 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 5863 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5864 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 5865 iRegLdst tmpL; 5866 loadConL32hi16(tmpL, srcHi); 5867 loadConL32_lo16(dst, tmpL, srcLo); 5868 %} 5869 %} 5870 5871 // Load 34-bit long constant using prefixed addi. No constant pool entries required. 5872 instruct loadConL34(iRegLdst dst, immL34 src) %{ 5873 match(Set dst src); 5874 // This macro is valid only in Power 10 and up, but adding the following predicate here 5875 // caused a build error, so we comment it out for now. 5876 // predicate(PowerArchitecturePPC64 >= 10); 5877 ins_cost(DEFAULT_COST+1); 5878 5879 format %{ "PLI $dst, $src \t// long" %} 5880 size(8); 5881 ins_encode %{ 5882 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 5883 __ pli($dst$$Register, $src$$constant); 5884 %} 5885 ins_pipe(pipe_class_default); 5886 ins_alignment(2); 5887 %} 5888 5889 // Load long constant 0x????000000000000. 5890 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 5891 match(Set dst src); 5892 ins_cost(DEFAULT_COST); 5893 5894 expand %{ 5895 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 5896 immI shift32 %{ 32 %} 5897 iRegLdst tmpL; 5898 loadConL32hi16(tmpL, srcHi); 5899 lshiftL_regL_immI(dst, tmpL, shift32); 5900 %} 5901 %} 5902 5903 // Expand node for constant pool load: small offset. 5904 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 5905 effect(DEF dst, USE src, USE toc); 5906 ins_cost(MEMORY_REF_COST); 5907 5908 ins_num_consts(1); 5909 // Needed so that CallDynamicJavaDirect can compute the address of this 5910 // instruction for relocation. 5911 ins_field_cbuf_insts_offset(int); 5912 5913 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 5914 size(4); 5915 ins_encode( enc_load_long_constL(dst, src, toc) ); 5916 ins_pipe(pipe_class_memory); 5917 %} 5918 5919 // Expand node for constant pool load: large offset. 5920 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 5921 effect(DEF dst, USE src, USE toc); 5922 predicate(false); 5923 5924 ins_num_consts(1); 5925 ins_field_const_toc_offset(int); 5926 // Needed so that CallDynamicJavaDirect can compute the address of this 5927 // instruction for relocation. 5928 ins_field_cbuf_insts_offset(int); 5929 5930 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 5931 size(4); 5932 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 5933 ins_pipe(pipe_class_default); 5934 %} 5935 5936 // Expand node for constant pool load: large offset. 5937 // No constant pool entries required. 5938 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 5939 effect(DEF dst, USE src, USE base); 5940 predicate(false); 5941 5942 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 5943 5944 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 5945 size(4); 5946 ins_encode %{ 5947 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 5948 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 5949 %} 5950 ins_pipe(pipe_class_memory); 5951 %} 5952 5953 // Load long constant from constant table. Expand in case of 5954 // offset > 16 bit is needed. 5955 // Adlc adds toc node MachConstantTableBase. 5956 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 5957 match(Set dst src); 5958 ins_cost(MEMORY_REF_COST); 5959 5960 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 5961 // We can not inline the enc_class for the expand as that does not support constanttablebase. 5962 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 5963 %} 5964 5965 // Load NULL as compressed oop. 5966 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 5967 match(Set dst src); 5968 ins_cost(DEFAULT_COST); 5969 5970 format %{ "LI $dst, $src \t// compressed ptr" %} 5971 size(4); 5972 ins_encode %{ 5973 __ li($dst$$Register, 0); 5974 %} 5975 ins_pipe(pipe_class_default); 5976 %} 5977 5978 // Load hi part of compressed oop constant. 5979 instruct loadConN_hi(iRegNdst dst, immN src) %{ 5980 effect(DEF dst, USE src); 5981 ins_cost(DEFAULT_COST); 5982 5983 format %{ "LIS $dst, $src \t// narrow oop hi" %} 5984 size(4); 5985 ins_encode %{ 5986 __ lis($dst$$Register, 0); // Will get patched. 5987 %} 5988 ins_pipe(pipe_class_default); 5989 %} 5990 5991 // Add lo part of compressed oop constant to already loaded hi part. 5992 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 5993 effect(DEF dst, USE src1, USE src2); 5994 ins_cost(DEFAULT_COST); 5995 5996 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 5997 size(4); 5998 ins_encode %{ 5999 AddressLiteral addrlit = __ constant_oop_address((jobject)$src2$$constant); 6000 __ relocate(addrlit.rspec(), /*compressed format*/ 1); 6001 __ ori($dst$$Register, $src1$$Register, 0); // Will get patched. 6002 %} 6003 ins_pipe(pipe_class_default); 6004 %} 6005 6006 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6007 effect(DEF dst, USE src, USE shift, USE mask_begin); 6008 6009 size(4); 6010 ins_encode %{ 6011 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6012 %} 6013 ins_pipe(pipe_class_default); 6014 %} 6015 6016 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6017 // leaving the upper 32 bits with sign-extension bits. 6018 // This clears these bits: dst = src & 0xFFFFFFFF. 6019 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6020 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6021 effect(DEF dst, USE src); 6022 predicate(false); 6023 6024 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6025 size(4); 6026 ins_encode %{ 6027 __ clrldi($dst$$Register, $src$$Register, 0x20); 6028 %} 6029 ins_pipe(pipe_class_default); 6030 %} 6031 6032 // Optimize DecodeN for disjoint base. 6033 // Load base of compressed oops into a register 6034 instruct loadBase(iRegLdst dst) %{ 6035 effect(DEF dst); 6036 6037 format %{ "LoadConst $dst, heapbase" %} 6038 ins_encode %{ 6039 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0); 6040 %} 6041 ins_pipe(pipe_class_default); 6042 %} 6043 6044 // Loading ConN must be postalloc expanded so that edges between 6045 // the nodes are safe. They may not interfere with a safepoint. 6046 // GL TODO: This needs three instructions: better put this into the constant pool. 6047 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6048 match(Set dst src); 6049 ins_cost(DEFAULT_COST*2); 6050 6051 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6052 postalloc_expand %{ 6053 MachNode *m1 = new loadConN_hiNode(); 6054 MachNode *m2 = new loadConN_loNode(); 6055 MachNode *m3 = new clearMs32bNode(); 6056 m1->add_req(NULL); 6057 m2->add_req(NULL, m1); 6058 m3->add_req(NULL, m2); 6059 m1->_opnds[0] = op_dst; 6060 m1->_opnds[1] = op_src; 6061 m2->_opnds[0] = op_dst; 6062 m2->_opnds[1] = op_dst; 6063 m2->_opnds[2] = op_src; 6064 m3->_opnds[0] = op_dst; 6065 m3->_opnds[1] = op_dst; 6066 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6067 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6068 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6069 nodes->push(m1); 6070 nodes->push(m2); 6071 nodes->push(m3); 6072 %} 6073 %} 6074 6075 // We have seen a safepoint between the hi and lo parts, and this node was handled 6076 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6077 // not a narrow oop. 6078 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6079 match(Set dst src); 6080 effect(DEF dst, USE src); 6081 ins_cost(DEFAULT_COST); 6082 6083 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6084 size(4); 6085 ins_encode %{ 6086 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant); 6087 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6088 %} 6089 ins_pipe(pipe_class_default); 6090 %} 6091 6092 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6093 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6094 match(Set dst src1); 6095 effect(TEMP src2); 6096 ins_cost(DEFAULT_COST); 6097 6098 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6099 size(4); 6100 ins_encode %{ 6101 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6102 %} 6103 ins_pipe(pipe_class_default); 6104 %} 6105 6106 // This needs a match rule so that build_oop_map knows this is 6107 // not a narrow oop. 6108 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6109 match(Set dst src1); 6110 effect(TEMP src2); 6111 ins_cost(DEFAULT_COST); 6112 6113 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6114 size(4); 6115 ins_encode %{ 6116 // Notify OOP recorder (don't need the relocation) 6117 AddressLiteral md = __ constant_metadata_address((Klass*)$src1$$constant); 6118 intptr_t Csrc = CompressedKlassPointers::encode((Klass*)md.value()); 6119 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6120 %} 6121 ins_pipe(pipe_class_default); 6122 %} 6123 6124 // Loading ConNKlass must be postalloc expanded so that edges between 6125 // the nodes are safe. They may not interfere with a safepoint. 6126 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6127 match(Set dst src); 6128 ins_cost(DEFAULT_COST*2); 6129 6130 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6131 postalloc_expand %{ 6132 // Load high bits into register. Sign extended. 6133 MachNode *m1 = new loadConNKlass_hiNode(); 6134 m1->add_req(NULL); 6135 m1->_opnds[0] = op_dst; 6136 m1->_opnds[1] = op_src; 6137 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6138 nodes->push(m1); 6139 6140 MachNode *m2 = m1; 6141 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) { 6142 // Value might be 1-extended. Mask out these bits. 6143 m2 = new loadConNKlass_maskNode(); 6144 m2->add_req(NULL, m1); 6145 m2->_opnds[0] = op_dst; 6146 m2->_opnds[1] = op_src; 6147 m2->_opnds[2] = op_dst; 6148 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6149 nodes->push(m2); 6150 } 6151 6152 MachNode *m3 = new loadConNKlass_loNode(); 6153 m3->add_req(NULL, m2); 6154 m3->_opnds[0] = op_dst; 6155 m3->_opnds[1] = op_src; 6156 m3->_opnds[2] = op_dst; 6157 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6158 nodes->push(m3); 6159 %} 6160 %} 6161 6162 // 0x1 is used in object initialization (initial object header). 6163 // No constant pool entries required. 6164 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6165 match(Set dst src); 6166 6167 format %{ "LI $dst, $src \t// ptr" %} 6168 size(4); 6169 ins_encode %{ 6170 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6171 %} 6172 ins_pipe(pipe_class_default); 6173 %} 6174 6175 // Expand node for constant pool load: small offset. 6176 // The match rule is needed to generate the correct bottom_type(), 6177 // however this node should never match. The use of predicate is not 6178 // possible since ADLC forbids predicates for chain rules. The higher 6179 // costs do not prevent matching in this case. For that reason the 6180 // operand immP_NM with predicate(false) is used. 6181 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6182 match(Set dst src); 6183 effect(TEMP toc); 6184 6185 ins_num_consts(1); 6186 6187 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6188 size(4); 6189 ins_encode( enc_load_long_constP(dst, src, toc) ); 6190 ins_pipe(pipe_class_memory); 6191 %} 6192 6193 // Expand node for constant pool load: large offset. 6194 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6195 effect(DEF dst, USE src, USE toc); 6196 predicate(false); 6197 6198 ins_num_consts(1); 6199 ins_field_const_toc_offset(int); 6200 6201 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6202 size(4); 6203 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6204 ins_pipe(pipe_class_default); 6205 %} 6206 6207 // Expand node for constant pool load: large offset. 6208 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6209 match(Set dst src); 6210 effect(TEMP base); 6211 6212 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6213 6214 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6215 size(4); 6216 ins_encode %{ 6217 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6218 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6219 %} 6220 ins_pipe(pipe_class_memory); 6221 %} 6222 6223 // Load pointer constant from constant table. Expand in case an 6224 // offset > 16 bit is needed. 6225 // Adlc adds toc node MachConstantTableBase. 6226 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6227 match(Set dst src); 6228 ins_cost(MEMORY_REF_COST); 6229 6230 // This rule does not use "expand" because then 6231 // the result type is not known to be an Oop. An ADLC 6232 // enhancement will be needed to make that work - not worth it! 6233 6234 // If this instruction rematerializes, it prolongs the live range 6235 // of the toc node, causing illegal graphs. 6236 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6237 ins_cannot_rematerialize(true); 6238 6239 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6240 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6241 %} 6242 6243 // Expand node for constant pool load: small offset. 6244 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6245 effect(DEF dst, USE src, USE toc); 6246 ins_cost(MEMORY_REF_COST); 6247 6248 ins_num_consts(1); 6249 6250 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6251 size(4); 6252 ins_encode %{ 6253 address float_address = __ float_constant($src$$constant); 6254 if (float_address == NULL) { 6255 ciEnv::current()->record_out_of_memory_failure(); 6256 return; 6257 } 6258 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6259 %} 6260 ins_pipe(pipe_class_memory); 6261 %} 6262 6263 // Expand node for constant pool load: large offset. 6264 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6265 effect(DEF dst, USE src, USE toc); 6266 ins_cost(MEMORY_REF_COST); 6267 6268 ins_num_consts(1); 6269 6270 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6271 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6272 "ADDIS $toc, $toc, -offset_hi"%} 6273 size(12); 6274 ins_encode %{ 6275 FloatRegister Rdst = $dst$$FloatRegister; 6276 Register Rtoc = $toc$$Register; 6277 address float_address = __ float_constant($src$$constant); 6278 if (float_address == NULL) { 6279 ciEnv::current()->record_out_of_memory_failure(); 6280 return; 6281 } 6282 int offset = __ offset_to_method_toc(float_address); 6283 int hi = (offset + (1<<15))>>16; 6284 int lo = offset - hi * (1<<16); 6285 6286 __ addis(Rtoc, Rtoc, hi); 6287 __ lfs(Rdst, lo, Rtoc); 6288 __ addis(Rtoc, Rtoc, -hi); 6289 %} 6290 ins_pipe(pipe_class_memory); 6291 %} 6292 6293 // Adlc adds toc node MachConstantTableBase. 6294 instruct loadConF_Ex(regF dst, immF src) %{ 6295 match(Set dst src); 6296 ins_cost(MEMORY_REF_COST); 6297 6298 // See loadConP. 6299 ins_cannot_rematerialize(true); 6300 6301 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6302 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6303 %} 6304 6305 // Expand node for constant pool load: small offset. 6306 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6307 effect(DEF dst, USE src, USE toc); 6308 ins_cost(MEMORY_REF_COST); 6309 6310 ins_num_consts(1); 6311 6312 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6313 size(4); 6314 ins_encode %{ 6315 address float_address = __ double_constant($src$$constant); 6316 if (float_address == NULL) { 6317 ciEnv::current()->record_out_of_memory_failure(); 6318 return; 6319 } 6320 int offset = __ offset_to_method_toc(float_address); 6321 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6322 %} 6323 ins_pipe(pipe_class_memory); 6324 %} 6325 6326 // Expand node for constant pool load: large offset. 6327 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6328 effect(DEF dst, USE src, USE toc); 6329 ins_cost(MEMORY_REF_COST); 6330 6331 ins_num_consts(1); 6332 6333 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6334 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6335 "ADDIS $toc, $toc, -offset_hi" %} 6336 size(12); 6337 ins_encode %{ 6338 FloatRegister Rdst = $dst$$FloatRegister; 6339 Register Rtoc = $toc$$Register; 6340 address float_address = __ double_constant($src$$constant); 6341 if (float_address == NULL) { 6342 ciEnv::current()->record_out_of_memory_failure(); 6343 return; 6344 } 6345 int offset = __ offset_to_method_toc(float_address); 6346 int hi = (offset + (1<<15))>>16; 6347 int lo = offset - hi * (1<<16); 6348 6349 __ addis(Rtoc, Rtoc, hi); 6350 __ lfd(Rdst, lo, Rtoc); 6351 __ addis(Rtoc, Rtoc, -hi); 6352 %} 6353 ins_pipe(pipe_class_memory); 6354 %} 6355 6356 // Adlc adds toc node MachConstantTableBase. 6357 instruct loadConD_Ex(regD dst, immD src) %{ 6358 match(Set dst src); 6359 ins_cost(MEMORY_REF_COST); 6360 6361 // See loadConP. 6362 ins_cannot_rematerialize(true); 6363 6364 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6365 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6366 %} 6367 6368 // Prefetch instructions. 6369 // Must be safe to execute with invalid address (cannot fault). 6370 6371 // Special prefetch versions which use the dcbz instruction. 6372 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6373 match(PrefetchAllocation (AddP mem src)); 6374 predicate(AllocatePrefetchStyle == 3); 6375 ins_cost(MEMORY_REF_COST); 6376 6377 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6378 size(4); 6379 ins_encode %{ 6380 __ dcbz($src$$Register, $mem$$base$$Register); 6381 %} 6382 ins_pipe(pipe_class_memory); 6383 %} 6384 6385 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6386 match(PrefetchAllocation mem); 6387 predicate(AllocatePrefetchStyle == 3); 6388 ins_cost(MEMORY_REF_COST); 6389 6390 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6391 size(4); 6392 ins_encode %{ 6393 __ dcbz($mem$$base$$Register); 6394 %} 6395 ins_pipe(pipe_class_memory); 6396 %} 6397 6398 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6399 match(PrefetchAllocation (AddP mem src)); 6400 predicate(AllocatePrefetchStyle != 3); 6401 ins_cost(MEMORY_REF_COST); 6402 6403 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6404 size(4); 6405 ins_encode %{ 6406 __ dcbtst($src$$Register, $mem$$base$$Register); 6407 %} 6408 ins_pipe(pipe_class_memory); 6409 %} 6410 6411 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6412 match(PrefetchAllocation mem); 6413 predicate(AllocatePrefetchStyle != 3); 6414 ins_cost(MEMORY_REF_COST); 6415 6416 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6417 size(4); 6418 ins_encode %{ 6419 __ dcbtst($mem$$base$$Register); 6420 %} 6421 ins_pipe(pipe_class_memory); 6422 %} 6423 6424 //----------Store Instructions------------------------------------------------- 6425 6426 // Store Byte 6427 instruct storeB(memory mem, iRegIsrc src) %{ 6428 match(Set mem (StoreB mem src)); 6429 ins_cost(MEMORY_REF_COST); 6430 6431 format %{ "STB $src, $mem \t// byte" %} 6432 size(4); 6433 ins_encode %{ 6434 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6435 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6436 %} 6437 ins_pipe(pipe_class_memory); 6438 %} 6439 6440 // Store Char/Short 6441 instruct storeC(memory mem, iRegIsrc src) %{ 6442 match(Set mem (StoreC mem src)); 6443 ins_cost(MEMORY_REF_COST); 6444 6445 format %{ "STH $src, $mem \t// short" %} 6446 size(4); 6447 ins_encode %{ 6448 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6449 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6450 %} 6451 ins_pipe(pipe_class_memory); 6452 %} 6453 6454 // Store Integer 6455 instruct storeI(memory mem, iRegIsrc src) %{ 6456 match(Set mem (StoreI mem src)); 6457 ins_cost(MEMORY_REF_COST); 6458 6459 format %{ "STW $src, $mem" %} 6460 size(4); 6461 ins_encode( enc_stw(src, mem) ); 6462 ins_pipe(pipe_class_memory); 6463 %} 6464 6465 // ConvL2I + StoreI. 6466 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6467 match(Set mem (StoreI mem (ConvL2I src))); 6468 ins_cost(MEMORY_REF_COST); 6469 6470 format %{ "STW l2i($src), $mem" %} 6471 size(4); 6472 ins_encode( enc_stw(src, mem) ); 6473 ins_pipe(pipe_class_memory); 6474 %} 6475 6476 // Store Long 6477 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6478 match(Set mem (StoreL mem src)); 6479 ins_cost(MEMORY_REF_COST); 6480 6481 format %{ "STD $src, $mem \t// long" %} 6482 size(4); 6483 ins_encode( enc_std(src, mem) ); 6484 ins_pipe(pipe_class_memory); 6485 %} 6486 6487 // Store super word nodes. 6488 6489 // Store Aligned Packed Byte long register to memory 6490 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6491 predicate(n->as_StoreVector()->memory_size() == 8); 6492 match(Set mem (StoreVector mem src)); 6493 ins_cost(MEMORY_REF_COST); 6494 6495 format %{ "STD $mem, $src \t// packed8B" %} 6496 size(4); 6497 ins_encode( enc_std(src, mem) ); 6498 ins_pipe(pipe_class_memory); 6499 %} 6500 6501 // Store Packed Byte long register to memory 6502 instruct storeV16(indirect mem, vecX src) %{ 6503 predicate(n->as_StoreVector()->memory_size() == 16); 6504 match(Set mem (StoreVector mem src)); 6505 ins_cost(MEMORY_REF_COST); 6506 6507 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6508 size(4); 6509 ins_encode %{ 6510 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6511 %} 6512 ins_pipe(pipe_class_default); 6513 %} 6514 6515 // Reinterpret: only one vector size used: either L or X 6516 instruct reinterpretL(iRegLdst dst) %{ 6517 match(Set dst (VectorReinterpret dst)); 6518 ins_cost(0); 6519 format %{ "reinterpret $dst" %} 6520 ins_encode( /*empty*/ ); 6521 ins_pipe(pipe_class_empty); 6522 %} 6523 6524 instruct reinterpretX(vecX dst) %{ 6525 match(Set dst (VectorReinterpret dst)); 6526 ins_cost(0); 6527 format %{ "reinterpret $dst" %} 6528 ins_encode( /*empty*/ ); 6529 ins_pipe(pipe_class_empty); 6530 %} 6531 6532 // Store Compressed Oop 6533 instruct storeN(memory dst, iRegN_P2N src) %{ 6534 match(Set dst (StoreN dst src)); 6535 ins_cost(MEMORY_REF_COST); 6536 6537 format %{ "STW $src, $dst \t// compressed oop" %} 6538 size(4); 6539 ins_encode( enc_stw(src, dst) ); 6540 ins_pipe(pipe_class_memory); 6541 %} 6542 6543 // Store Compressed KLass 6544 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6545 match(Set dst (StoreNKlass dst src)); 6546 ins_cost(MEMORY_REF_COST); 6547 6548 format %{ "STW $src, $dst \t// compressed klass" %} 6549 size(4); 6550 ins_encode( enc_stw(src, dst) ); 6551 ins_pipe(pipe_class_memory); 6552 %} 6553 6554 // Store Pointer 6555 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6556 match(Set dst (StoreP dst src)); 6557 predicate(n->as_Store()->barrier_data() == 0); 6558 ins_cost(MEMORY_REF_COST); 6559 6560 format %{ "STD $src, $dst \t// ptr" %} 6561 size(4); 6562 ins_encode( enc_std(src, dst) ); 6563 ins_pipe(pipe_class_memory); 6564 %} 6565 6566 // Store Float 6567 instruct storeF(memory mem, regF src) %{ 6568 match(Set mem (StoreF mem src)); 6569 ins_cost(MEMORY_REF_COST); 6570 6571 format %{ "STFS $src, $mem" %} 6572 size(4); 6573 ins_encode( enc_stfs(src, mem) ); 6574 ins_pipe(pipe_class_memory); 6575 %} 6576 6577 // Store Double 6578 instruct storeD(memory mem, regD src) %{ 6579 match(Set mem (StoreD mem src)); 6580 ins_cost(MEMORY_REF_COST); 6581 6582 format %{ "STFD $src, $mem" %} 6583 size(4); 6584 ins_encode( enc_stfd(src, mem) ); 6585 ins_pipe(pipe_class_memory); 6586 %} 6587 6588 //----------Store Instructions With Zeros-------------------------------------- 6589 6590 instruct storeCM(memory mem, immI_0 zero) %{ 6591 match(Set mem (StoreCM mem zero)); 6592 ins_cost(MEMORY_REF_COST); 6593 6594 format %{ "STB #0, $mem \t// CMS card-mark byte store" %} 6595 size(8); 6596 ins_encode %{ 6597 __ li(R0, 0); 6598 // No release barrier: Oops are allowed to get visible after marking. 6599 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6600 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6601 %} 6602 ins_pipe(pipe_class_memory); 6603 %} 6604 6605 // Convert oop pointer into compressed form. 6606 6607 // Nodes for postalloc expand. 6608 6609 // Shift node for expand. 6610 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6611 // The match rule is needed to make it a 'MachTypeNode'! 6612 match(Set dst (EncodeP src)); 6613 predicate(false); 6614 6615 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6616 size(4); 6617 ins_encode %{ 6618 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 6619 %} 6620 ins_pipe(pipe_class_default); 6621 %} 6622 6623 // Add node for expand. 6624 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6625 // The match rule is needed to make it a 'MachTypeNode'! 6626 match(Set dst (EncodeP src)); 6627 predicate(false); 6628 6629 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6630 ins_encode %{ 6631 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 6632 %} 6633 ins_pipe(pipe_class_default); 6634 %} 6635 6636 // Conditional sub base. 6637 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6638 // The match rule is needed to make it a 'MachTypeNode'! 6639 match(Set dst (EncodeP (Binary crx src1))); 6640 predicate(false); 6641 6642 format %{ "BEQ $crx, done\n\t" 6643 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6644 "done:" %} 6645 ins_encode %{ 6646 Label done; 6647 __ beq($crx$$CondRegister, done); 6648 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0); 6649 __ bind(done); 6650 %} 6651 ins_pipe(pipe_class_default); 6652 %} 6653 6654 // Power 7 can use isel instruction 6655 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6656 // The match rule is needed to make it a 'MachTypeNode'! 6657 match(Set dst (EncodeP (Binary crx src1))); 6658 predicate(false); 6659 6660 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6661 size(4); 6662 ins_encode %{ 6663 // This is a Power7 instruction for which no machine description exists. 6664 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6665 %} 6666 ins_pipe(pipe_class_default); 6667 %} 6668 6669 // Disjoint narrow oop base. 6670 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6671 match(Set dst (EncodeP src)); 6672 predicate(CompressedOops::base_disjoint()); 6673 6674 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6675 size(4); 6676 ins_encode %{ 6677 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32); 6678 %} 6679 ins_pipe(pipe_class_default); 6680 %} 6681 6682 // shift != 0, base != 0 6683 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6684 match(Set dst (EncodeP src)); 6685 effect(TEMP crx); 6686 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6687 CompressedOops::shift() != 0 && 6688 CompressedOops::base_overlaps()); 6689 6690 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 6691 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 6692 %} 6693 6694 // shift != 0, base != 0 6695 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 6696 match(Set dst (EncodeP src)); 6697 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 6698 CompressedOops::shift() != 0 && 6699 CompressedOops::base_overlaps()); 6700 6701 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 6702 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 6703 %} 6704 6705 // shift != 0, base == 0 6706 // TODO: This is the same as encodeP_shift. Merge! 6707 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 6708 match(Set dst (EncodeP src)); 6709 predicate(CompressedOops::shift() != 0 && 6710 CompressedOops::base() ==0); 6711 6712 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 6713 size(4); 6714 ins_encode %{ 6715 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 6716 %} 6717 ins_pipe(pipe_class_default); 6718 %} 6719 6720 // Compressed OOPs with narrow_oop_shift == 0. 6721 // shift == 0, base == 0 6722 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 6723 match(Set dst (EncodeP src)); 6724 predicate(CompressedOops::shift() == 0); 6725 6726 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 6727 // variable size, 0 or 4. 6728 ins_encode %{ 6729 __ mr_if_needed($dst$$Register, $src$$Register); 6730 %} 6731 ins_pipe(pipe_class_default); 6732 %} 6733 6734 // Decode nodes. 6735 6736 // Shift node for expand. 6737 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 6738 // The match rule is needed to make it a 'MachTypeNode'! 6739 match(Set dst (DecodeN src)); 6740 predicate(false); 6741 6742 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 6743 size(4); 6744 ins_encode %{ 6745 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 6746 %} 6747 ins_pipe(pipe_class_default); 6748 %} 6749 6750 // Add node for expand. 6751 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 6752 // The match rule is needed to make it a 'MachTypeNode'! 6753 match(Set dst (DecodeN src)); 6754 predicate(false); 6755 6756 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 6757 ins_encode %{ 6758 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 6759 %} 6760 ins_pipe(pipe_class_default); 6761 %} 6762 6763 // conditianal add base for expand 6764 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 6765 // The match rule is needed to make it a 'MachTypeNode'! 6766 // NOTICE that the rule is nonsense - we just have to make sure that: 6767 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6768 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6769 match(Set dst (DecodeN (Binary crx src))); 6770 predicate(false); 6771 6772 format %{ "BEQ $crx, done\n\t" 6773 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 6774 "done:" %} 6775 ins_encode %{ 6776 Label done; 6777 __ beq($crx$$CondRegister, done); 6778 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 6779 __ bind(done); 6780 %} 6781 ins_pipe(pipe_class_default); 6782 %} 6783 6784 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6785 // The match rule is needed to make it a 'MachTypeNode'! 6786 // NOTICE that the rule is nonsense - we just have to make sure that: 6787 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6788 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6789 match(Set dst (DecodeN (Binary crx src1))); 6790 predicate(false); 6791 6792 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 6793 size(4); 6794 ins_encode %{ 6795 // This is a Power7 instruction for which no machine description exists. 6796 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6797 %} 6798 ins_pipe(pipe_class_default); 6799 %} 6800 6801 // shift != 0, base != 0 6802 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6803 match(Set dst (DecodeN src)); 6804 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6805 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6806 CompressedOops::shift() != 0 && 6807 CompressedOops::base() != 0); 6808 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 6809 effect(TEMP crx); 6810 6811 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 6812 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 6813 %} 6814 6815 // shift != 0, base == 0 6816 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 6817 match(Set dst (DecodeN src)); 6818 predicate(CompressedOops::shift() != 0 && 6819 CompressedOops::base() == 0); 6820 6821 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 6822 size(4); 6823 ins_encode %{ 6824 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 6825 %} 6826 ins_pipe(pipe_class_default); 6827 %} 6828 6829 // Optimize DecodeN for disjoint base. 6830 // Shift narrow oop and or it into register that already contains the heap base. 6831 // Base == dst must hold, and is assured by construction in postaloc_expand. 6832 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 6833 match(Set dst (DecodeN src)); 6834 effect(TEMP base); 6835 predicate(false); 6836 6837 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 6838 size(4); 6839 ins_encode %{ 6840 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift()); 6841 %} 6842 ins_pipe(pipe_class_default); 6843 %} 6844 6845 // Optimize DecodeN for disjoint base. 6846 // This node requires only one cycle on the critical path. 6847 // We must postalloc_expand as we can not express use_def effects where 6848 // the used register is L and the def'ed register P. 6849 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 6850 match(Set dst (DecodeN src)); 6851 effect(TEMP_DEF dst); 6852 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6853 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6854 CompressedOops::base_disjoint()); 6855 ins_cost(DEFAULT_COST); 6856 6857 format %{ "MOV $dst, heapbase \t\n" 6858 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 6859 postalloc_expand %{ 6860 loadBaseNode *n1 = new loadBaseNode(); 6861 n1->add_req(NULL); 6862 n1->_opnds[0] = op_dst; 6863 6864 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6865 n2->add_req(n_region, n_src, n1); 6866 n2->_opnds[0] = op_dst; 6867 n2->_opnds[1] = op_src; 6868 n2->_opnds[2] = op_dst; 6869 n2->_bottom_type = _bottom_type; 6870 6871 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 6872 ra_->set_oop(n2, true); 6873 6874 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6875 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6876 6877 nodes->push(n1); 6878 nodes->push(n2); 6879 %} 6880 %} 6881 6882 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6883 match(Set dst (DecodeN src)); 6884 effect(TEMP_DEF dst, TEMP crx); 6885 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6886 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6887 CompressedOops::base_disjoint() && VM_Version::has_isel()); 6888 ins_cost(3 * DEFAULT_COST); 6889 6890 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 6891 postalloc_expand %{ 6892 loadBaseNode *n1 = new loadBaseNode(); 6893 n1->add_req(NULL); 6894 n1->_opnds[0] = op_dst; 6895 6896 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 6897 n_compare->add_req(n_region, n_src); 6898 n_compare->_opnds[0] = op_crx; 6899 n_compare->_opnds[1] = op_src; 6900 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 6901 6902 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6903 n2->add_req(n_region, n_src, n1); 6904 n2->_opnds[0] = op_dst; 6905 n2->_opnds[1] = op_src; 6906 n2->_opnds[2] = op_dst; 6907 n2->_bottom_type = _bottom_type; 6908 6909 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 6910 n_cond_set->add_req(n_region, n_compare, n2); 6911 n_cond_set->_opnds[0] = op_dst; 6912 n_cond_set->_opnds[1] = op_crx; 6913 n_cond_set->_opnds[2] = op_dst; 6914 n_cond_set->_bottom_type = _bottom_type; 6915 6916 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 6917 ra_->set_oop(n_cond_set, true); 6918 6919 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6920 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 6921 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6922 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6923 6924 nodes->push(n1); 6925 nodes->push(n_compare); 6926 nodes->push(n2); 6927 nodes->push(n_cond_set); 6928 %} 6929 %} 6930 6931 // src != 0, shift != 0, base != 0 6932 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 6933 match(Set dst (DecodeN src)); 6934 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6935 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6936 CompressedOops::shift() != 0 && 6937 CompressedOops::base() != 0); 6938 ins_cost(2 * DEFAULT_COST); 6939 6940 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 6941 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 6942 %} 6943 6944 // Compressed OOPs with narrow_oop_shift == 0. 6945 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 6946 match(Set dst (DecodeN src)); 6947 predicate(CompressedOops::shift() == 0); 6948 ins_cost(DEFAULT_COST); 6949 6950 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 6951 // variable size, 0 or 4. 6952 ins_encode %{ 6953 __ mr_if_needed($dst$$Register, $src$$Register); 6954 %} 6955 ins_pipe(pipe_class_default); 6956 %} 6957 6958 // Convert compressed oop into int for vectors alignment masking. 6959 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 6960 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6961 predicate(CompressedOops::shift() == 0); 6962 ins_cost(DEFAULT_COST); 6963 6964 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 6965 // variable size, 0 or 4. 6966 ins_encode %{ 6967 __ mr_if_needed($dst$$Register, $src$$Register); 6968 %} 6969 ins_pipe(pipe_class_default); 6970 %} 6971 6972 // Convert klass pointer into compressed form. 6973 6974 // Nodes for postalloc expand. 6975 6976 // Shift node for expand. 6977 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 6978 // The match rule is needed to make it a 'MachTypeNode'! 6979 match(Set dst (EncodePKlass src)); 6980 predicate(false); 6981 6982 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6983 size(4); 6984 ins_encode %{ 6985 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 6986 %} 6987 ins_pipe(pipe_class_default); 6988 %} 6989 6990 // Add node for expand. 6991 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6992 // The match rule is needed to make it a 'MachTypeNode'! 6993 match(Set dst (EncodePKlass (Binary base src))); 6994 predicate(false); 6995 6996 format %{ "SUB $dst, $base, $src \t// encode" %} 6997 size(4); 6998 ins_encode %{ 6999 __ subf($dst$$Register, $base$$Register, $src$$Register); 7000 %} 7001 ins_pipe(pipe_class_default); 7002 %} 7003 7004 // Disjoint narrow oop base. 7005 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7006 match(Set dst (EncodePKlass src)); 7007 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/); 7008 7009 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7010 size(4); 7011 ins_encode %{ 7012 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32); 7013 %} 7014 ins_pipe(pipe_class_default); 7015 %} 7016 7017 // shift != 0, base != 0 7018 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7019 match(Set dst (EncodePKlass (Binary base src))); 7020 predicate(false); 7021 7022 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7023 postalloc_expand %{ 7024 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7025 n1->add_req(n_region, n_base, n_src); 7026 n1->_opnds[0] = op_dst; 7027 n1->_opnds[1] = op_base; 7028 n1->_opnds[2] = op_src; 7029 n1->_bottom_type = _bottom_type; 7030 7031 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7032 n2->add_req(n_region, n1); 7033 n2->_opnds[0] = op_dst; 7034 n2->_opnds[1] = op_dst; 7035 n2->_bottom_type = _bottom_type; 7036 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7037 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7038 7039 nodes->push(n1); 7040 nodes->push(n2); 7041 %} 7042 %} 7043 7044 // shift != 0, base != 0 7045 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7046 match(Set dst (EncodePKlass src)); 7047 //predicate(CompressedKlassPointers::shift() != 0 && 7048 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/); 7049 7050 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7051 ins_cost(DEFAULT_COST*2); // Don't count constant. 7052 expand %{ 7053 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %} 7054 iRegLdst base; 7055 loadConL_Ex(base, baseImm); 7056 encodePKlass_not_null_Ex(dst, base, src); 7057 %} 7058 %} 7059 7060 // Decode nodes. 7061 7062 // Shift node for expand. 7063 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7064 // The match rule is needed to make it a 'MachTypeNode'! 7065 match(Set dst (DecodeNKlass src)); 7066 predicate(false); 7067 7068 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7069 size(4); 7070 ins_encode %{ 7071 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 7072 %} 7073 ins_pipe(pipe_class_default); 7074 %} 7075 7076 // Add node for expand. 7077 7078 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7079 // The match rule is needed to make it a 'MachTypeNode'! 7080 match(Set dst (DecodeNKlass (Binary base src))); 7081 predicate(false); 7082 7083 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7084 size(4); 7085 ins_encode %{ 7086 __ add($dst$$Register, $base$$Register, $src$$Register); 7087 %} 7088 ins_pipe(pipe_class_default); 7089 %} 7090 7091 // src != 0, shift != 0, base != 0 7092 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7093 match(Set dst (DecodeNKlass (Binary base src))); 7094 //effect(kill src); // We need a register for the immediate result after shifting. 7095 predicate(false); 7096 7097 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7098 postalloc_expand %{ 7099 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7100 n1->add_req(n_region, n_base, n_src); 7101 n1->_opnds[0] = op_dst; 7102 n1->_opnds[1] = op_base; 7103 n1->_opnds[2] = op_src; 7104 n1->_bottom_type = _bottom_type; 7105 7106 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7107 n2->add_req(n_region, n1); 7108 n2->_opnds[0] = op_dst; 7109 n2->_opnds[1] = op_dst; 7110 n2->_bottom_type = _bottom_type; 7111 7112 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7113 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7114 7115 nodes->push(n1); 7116 nodes->push(n2); 7117 %} 7118 %} 7119 7120 // src != 0, shift != 0, base != 0 7121 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7122 match(Set dst (DecodeNKlass src)); 7123 // predicate(CompressedKlassPointers::shift() != 0 && 7124 // CompressedKlassPointers::base() != 0); 7125 7126 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7127 7128 ins_cost(DEFAULT_COST*2); // Don't count constant. 7129 expand %{ 7130 // We add first, then we shift. Like this, we can get along with one register less. 7131 // But we have to load the base pre-shifted. 7132 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %} 7133 iRegLdst base; 7134 loadConL_Ex(base, baseImm); 7135 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7136 %} 7137 %} 7138 7139 //----------MemBar Instructions----------------------------------------------- 7140 // Memory barrier flavors 7141 7142 instruct membar_acquire() %{ 7143 match(LoadFence); 7144 ins_cost(4*MEMORY_REF_COST); 7145 7146 format %{ "MEMBAR-acquire" %} 7147 size(4); 7148 ins_encode %{ 7149 __ acquire(); 7150 %} 7151 ins_pipe(pipe_class_default); 7152 %} 7153 7154 instruct unnecessary_membar_acquire() %{ 7155 match(MemBarAcquire); 7156 ins_cost(0); 7157 7158 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7159 size(0); 7160 ins_encode( /*empty*/ ); 7161 ins_pipe(pipe_class_default); 7162 %} 7163 7164 instruct membar_acquire_lock() %{ 7165 match(MemBarAcquireLock); 7166 ins_cost(0); 7167 7168 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7169 size(0); 7170 ins_encode( /*empty*/ ); 7171 ins_pipe(pipe_class_default); 7172 %} 7173 7174 instruct membar_release() %{ 7175 match(MemBarRelease); 7176 match(StoreFence); 7177 ins_cost(4*MEMORY_REF_COST); 7178 7179 format %{ "MEMBAR-release" %} 7180 size(4); 7181 ins_encode %{ 7182 __ release(); 7183 %} 7184 ins_pipe(pipe_class_default); 7185 %} 7186 7187 instruct membar_storestore() %{ 7188 match(MemBarStoreStore); 7189 match(StoreStoreFence); 7190 ins_cost(4*MEMORY_REF_COST); 7191 7192 format %{ "MEMBAR-store-store" %} 7193 size(4); 7194 ins_encode %{ 7195 __ membar(Assembler::StoreStore); 7196 %} 7197 ins_pipe(pipe_class_default); 7198 %} 7199 7200 instruct membar_release_lock() %{ 7201 match(MemBarReleaseLock); 7202 ins_cost(0); 7203 7204 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7205 size(0); 7206 ins_encode( /*empty*/ ); 7207 ins_pipe(pipe_class_default); 7208 %} 7209 7210 instruct membar_volatile() %{ 7211 match(MemBarVolatile); 7212 ins_cost(4*MEMORY_REF_COST); 7213 7214 format %{ "MEMBAR-volatile" %} 7215 size(4); 7216 ins_encode %{ 7217 __ fence(); 7218 %} 7219 ins_pipe(pipe_class_default); 7220 %} 7221 7222 // This optimization is wrong on PPC. The following pattern is not supported: 7223 // MemBarVolatile 7224 // ^ ^ 7225 // | | 7226 // CtrlProj MemProj 7227 // ^ ^ 7228 // | | 7229 // | Load 7230 // | 7231 // MemBarVolatile 7232 // 7233 // The first MemBarVolatile could get optimized out! According to 7234 // Vladimir, this pattern can not occur on Oracle platforms. 7235 // However, it does occur on PPC64 (because of membars in 7236 // inline_unsafe_load_store). 7237 // 7238 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7239 // Don't forget to look at the implementation of post_store_load_barrier again, 7240 // we did other fixes in that method. 7241 //instruct unnecessary_membar_volatile() %{ 7242 // match(MemBarVolatile); 7243 // predicate(Matcher::post_store_load_barrier(n)); 7244 // ins_cost(0); 7245 // 7246 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7247 // size(0); 7248 // ins_encode( /*empty*/ ); 7249 // ins_pipe(pipe_class_default); 7250 //%} 7251 7252 instruct membar_CPUOrder() %{ 7253 match(MemBarCPUOrder); 7254 ins_cost(0); 7255 7256 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7257 size(0); 7258 ins_encode( /*empty*/ ); 7259 ins_pipe(pipe_class_default); 7260 %} 7261 7262 //----------Conditional Move--------------------------------------------------- 7263 7264 // Cmove using isel. 7265 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7266 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7267 predicate(VM_Version::has_isel()); 7268 ins_cost(DEFAULT_COST); 7269 7270 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7271 size(4); 7272 ins_encode %{ 7273 // This is a Power7 instruction for which no machine description 7274 // exists. Anyways, the scheduler should be off on Power7. 7275 int cc = $cmp$$cmpcode; 7276 __ isel($dst$$Register, $crx$$CondRegister, 7277 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7278 %} 7279 ins_pipe(pipe_class_default); 7280 %} 7281 7282 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7283 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7284 predicate(!VM_Version::has_isel()); 7285 ins_cost(DEFAULT_COST+BRANCH_COST); 7286 7287 ins_variable_size_depending_on_alignment(true); 7288 7289 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7290 // Worst case is branch + move + stop, no stop without scheduler 7291 size(8); 7292 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7293 ins_pipe(pipe_class_default); 7294 %} 7295 7296 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7297 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7298 ins_cost(DEFAULT_COST+BRANCH_COST); 7299 7300 ins_variable_size_depending_on_alignment(true); 7301 7302 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7303 // Worst case is branch + move + stop, no stop without scheduler 7304 size(8); 7305 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7306 ins_pipe(pipe_class_default); 7307 %} 7308 7309 // Cmove using isel. 7310 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7311 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7312 predicate(VM_Version::has_isel()); 7313 ins_cost(DEFAULT_COST); 7314 7315 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7316 size(4); 7317 ins_encode %{ 7318 // This is a Power7 instruction for which no machine description 7319 // exists. Anyways, the scheduler should be off on Power7. 7320 int cc = $cmp$$cmpcode; 7321 __ isel($dst$$Register, $crx$$CondRegister, 7322 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7323 %} 7324 ins_pipe(pipe_class_default); 7325 %} 7326 7327 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7328 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7329 predicate(!VM_Version::has_isel()); 7330 ins_cost(DEFAULT_COST+BRANCH_COST); 7331 7332 ins_variable_size_depending_on_alignment(true); 7333 7334 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7335 // Worst case is branch + move + stop, no stop without scheduler. 7336 size(8); 7337 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7338 ins_pipe(pipe_class_default); 7339 %} 7340 7341 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7342 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7343 ins_cost(DEFAULT_COST+BRANCH_COST); 7344 7345 ins_variable_size_depending_on_alignment(true); 7346 7347 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7348 // Worst case is branch + move + stop, no stop without scheduler. 7349 size(8); 7350 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7351 ins_pipe(pipe_class_default); 7352 %} 7353 7354 // Cmove using isel. 7355 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7356 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7357 predicate(VM_Version::has_isel()); 7358 ins_cost(DEFAULT_COST); 7359 7360 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7361 size(4); 7362 ins_encode %{ 7363 // This is a Power7 instruction for which no machine description 7364 // exists. Anyways, the scheduler should be off on Power7. 7365 int cc = $cmp$$cmpcode; 7366 __ isel($dst$$Register, $crx$$CondRegister, 7367 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7368 %} 7369 ins_pipe(pipe_class_default); 7370 %} 7371 7372 // Conditional move for RegN. Only cmov(reg, reg). 7373 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7374 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7375 predicate(!VM_Version::has_isel()); 7376 ins_cost(DEFAULT_COST+BRANCH_COST); 7377 7378 ins_variable_size_depending_on_alignment(true); 7379 7380 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7381 // Worst case is branch + move + stop, no stop without scheduler. 7382 size(8); 7383 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7384 ins_pipe(pipe_class_default); 7385 %} 7386 7387 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7388 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7389 ins_cost(DEFAULT_COST+BRANCH_COST); 7390 7391 ins_variable_size_depending_on_alignment(true); 7392 7393 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7394 // Worst case is branch + move + stop, no stop without scheduler. 7395 size(8); 7396 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7397 ins_pipe(pipe_class_default); 7398 %} 7399 7400 // Cmove using isel. 7401 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7402 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7403 predicate(VM_Version::has_isel()); 7404 ins_cost(DEFAULT_COST); 7405 7406 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7407 size(4); 7408 ins_encode %{ 7409 // This is a Power7 instruction for which no machine description 7410 // exists. Anyways, the scheduler should be off on Power7. 7411 int cc = $cmp$$cmpcode; 7412 __ isel($dst$$Register, $crx$$CondRegister, 7413 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7414 %} 7415 ins_pipe(pipe_class_default); 7416 %} 7417 7418 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7419 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7420 predicate(!VM_Version::has_isel()); 7421 ins_cost(DEFAULT_COST+BRANCH_COST); 7422 7423 ins_variable_size_depending_on_alignment(true); 7424 7425 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7426 // Worst case is branch + move + stop, no stop without scheduler. 7427 size(8); 7428 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7429 ins_pipe(pipe_class_default); 7430 %} 7431 7432 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7433 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7434 ins_cost(DEFAULT_COST+BRANCH_COST); 7435 7436 ins_variable_size_depending_on_alignment(true); 7437 7438 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7439 // Worst case is branch + move + stop, no stop without scheduler. 7440 size(8); 7441 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7442 ins_pipe(pipe_class_default); 7443 %} 7444 7445 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7446 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7447 ins_cost(DEFAULT_COST+BRANCH_COST); 7448 7449 ins_variable_size_depending_on_alignment(true); 7450 7451 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7452 // Worst case is branch + move + stop, no stop without scheduler. 7453 size(8); 7454 ins_encode %{ 7455 Label done; 7456 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7457 // Branch if not (cmp crx). 7458 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7459 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7460 __ bind(done); 7461 %} 7462 ins_pipe(pipe_class_default); 7463 %} 7464 7465 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7466 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7467 ins_cost(DEFAULT_COST+BRANCH_COST); 7468 7469 ins_variable_size_depending_on_alignment(true); 7470 7471 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7472 // Worst case is branch + move + stop, no stop without scheduler. 7473 size(8); 7474 ins_encode %{ 7475 Label done; 7476 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7477 // Branch if not (cmp crx). 7478 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7479 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7480 __ bind(done); 7481 %} 7482 ins_pipe(pipe_class_default); 7483 %} 7484 7485 //----------Compare-And-Swap--------------------------------------------------- 7486 7487 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7488 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7489 // matched. 7490 7491 // Strong versions: 7492 7493 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7494 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7495 predicate(VM_Version::has_lqarx()); 7496 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7497 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7498 ins_encode %{ 7499 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7500 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7501 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7502 $res$$Register, true); 7503 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7504 __ isync(); 7505 } else { 7506 __ sync(); 7507 } 7508 %} 7509 ins_pipe(pipe_class_default); 7510 %} 7511 7512 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7513 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7514 predicate(!VM_Version::has_lqarx()); 7515 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7516 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7517 ins_encode %{ 7518 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7519 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7520 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7521 $res$$Register, true); 7522 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7523 __ isync(); 7524 } else { 7525 __ sync(); 7526 } 7527 %} 7528 ins_pipe(pipe_class_default); 7529 %} 7530 7531 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7532 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7533 predicate(VM_Version::has_lqarx()); 7534 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7535 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7536 ins_encode %{ 7537 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7538 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7539 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7540 $res$$Register, true); 7541 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7542 __ isync(); 7543 } else { 7544 __ sync(); 7545 } 7546 %} 7547 ins_pipe(pipe_class_default); 7548 %} 7549 7550 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7551 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7552 predicate(!VM_Version::has_lqarx()); 7553 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7554 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7555 ins_encode %{ 7556 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7557 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7558 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7559 $res$$Register, true); 7560 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7561 __ isync(); 7562 } else { 7563 __ sync(); 7564 } 7565 %} 7566 ins_pipe(pipe_class_default); 7567 %} 7568 7569 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7570 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7571 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7572 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7573 ins_encode %{ 7574 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7575 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7576 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7577 $res$$Register, true); 7578 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7579 __ isync(); 7580 } else { 7581 __ sync(); 7582 } 7583 %} 7584 ins_pipe(pipe_class_default); 7585 %} 7586 7587 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7588 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7589 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7590 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7591 ins_encode %{ 7592 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7593 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7594 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7595 $res$$Register, true); 7596 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7597 __ isync(); 7598 } else { 7599 __ sync(); 7600 } 7601 %} 7602 ins_pipe(pipe_class_default); 7603 %} 7604 7605 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7606 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 7607 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7608 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7609 ins_encode %{ 7610 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7611 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7612 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7613 $res$$Register, NULL, true); 7614 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7615 __ isync(); 7616 } else { 7617 __ sync(); 7618 } 7619 %} 7620 ins_pipe(pipe_class_default); 7621 %} 7622 7623 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7624 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 7625 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7626 predicate(n->as_LoadStore()->barrier_data() == 0); 7627 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7628 ins_encode %{ 7629 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7630 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7631 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7632 $res$$Register, NULL, true); 7633 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7634 __ isync(); 7635 } else { 7636 __ sync(); 7637 } 7638 %} 7639 ins_pipe(pipe_class_default); 7640 %} 7641 7642 // Weak versions: 7643 7644 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7645 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7646 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7647 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7648 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7649 ins_encode %{ 7650 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7651 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7652 MacroAssembler::MemBarNone, 7653 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7654 %} 7655 ins_pipe(pipe_class_default); 7656 %} 7657 7658 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7659 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7660 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7661 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7662 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7663 ins_encode %{ 7664 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7665 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7666 MacroAssembler::MemBarNone, 7667 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7668 %} 7669 ins_pipe(pipe_class_default); 7670 %} 7671 7672 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7673 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7674 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7675 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7676 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7677 ins_encode %{ 7678 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7679 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7680 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7681 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7682 %} 7683 ins_pipe(pipe_class_default); 7684 %} 7685 7686 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7687 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7688 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7689 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7690 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7691 ins_encode %{ 7692 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7693 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7694 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7695 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7696 %} 7697 ins_pipe(pipe_class_default); 7698 %} 7699 7700 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7701 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7702 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7703 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7704 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7705 ins_encode %{ 7706 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7707 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7708 MacroAssembler::MemBarNone, 7709 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7710 %} 7711 ins_pipe(pipe_class_default); 7712 %} 7713 7714 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7715 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7716 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7717 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7718 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7719 ins_encode %{ 7720 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7721 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7722 MacroAssembler::MemBarNone, 7723 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7724 %} 7725 ins_pipe(pipe_class_default); 7726 %} 7727 7728 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7729 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7730 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7731 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7732 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7733 ins_encode %{ 7734 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7735 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7736 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7737 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7738 %} 7739 ins_pipe(pipe_class_default); 7740 %} 7741 7742 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7743 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7744 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7745 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7746 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7747 ins_encode %{ 7748 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7749 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7750 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7751 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7752 %} 7753 ins_pipe(pipe_class_default); 7754 %} 7755 7756 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7757 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7758 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7759 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7760 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7761 ins_encode %{ 7762 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7763 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7764 MacroAssembler::MemBarNone, 7765 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7766 %} 7767 ins_pipe(pipe_class_default); 7768 %} 7769 7770 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7771 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7772 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7773 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7774 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7775 ins_encode %{ 7776 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7777 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7778 // value is never passed to caller. 7779 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7780 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7781 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7782 %} 7783 ins_pipe(pipe_class_default); 7784 %} 7785 7786 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7787 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7788 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7789 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7790 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7791 ins_encode %{ 7792 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7793 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7794 MacroAssembler::MemBarNone, 7795 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7796 %} 7797 ins_pipe(pipe_class_default); 7798 %} 7799 7800 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7801 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7802 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7803 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7804 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7805 ins_encode %{ 7806 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7807 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7808 // value is never passed to caller. 7809 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7810 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7811 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7812 %} 7813 ins_pipe(pipe_class_default); 7814 %} 7815 7816 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7817 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7818 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7819 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7820 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7821 ins_encode %{ 7822 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7823 // value is never passed to caller. 7824 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7825 MacroAssembler::MemBarNone, 7826 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7827 %} 7828 ins_pipe(pipe_class_default); 7829 %} 7830 7831 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7832 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7833 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7834 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7835 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 7836 ins_encode %{ 7837 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7838 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7839 // value is never passed to caller. 7840 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7841 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7842 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7843 %} 7844 ins_pipe(pipe_class_default); 7845 %} 7846 7847 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7848 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7849 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0); 7850 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7851 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7852 ins_encode %{ 7853 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7854 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7855 MacroAssembler::MemBarNone, 7856 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7857 %} 7858 ins_pipe(pipe_class_default); 7859 %} 7860 7861 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7862 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7863 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && n->as_LoadStore()->barrier_data() == 0); 7864 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7865 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7866 ins_encode %{ 7867 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7868 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7869 // value is never passed to caller. 7870 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7871 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7872 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7873 %} 7874 ins_pipe(pipe_class_default); 7875 %} 7876 7877 // CompareAndExchange 7878 7879 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7880 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7881 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7882 effect(TEMP_DEF res, TEMP cr0); 7883 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7884 ins_encode %{ 7885 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7886 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7887 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7888 noreg, true); 7889 %} 7890 ins_pipe(pipe_class_default); 7891 %} 7892 7893 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7894 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7895 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7896 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7897 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7898 ins_encode %{ 7899 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7900 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7901 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7902 noreg, true); 7903 %} 7904 ins_pipe(pipe_class_default); 7905 %} 7906 7907 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7908 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7909 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7910 effect(TEMP_DEF res, TEMP cr0); 7911 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7912 ins_encode %{ 7913 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7914 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7915 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7916 noreg, true); 7917 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7918 __ isync(); 7919 } else { 7920 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7921 __ sync(); 7922 } 7923 %} 7924 ins_pipe(pipe_class_default); 7925 %} 7926 7927 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7928 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7929 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7930 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7931 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7932 ins_encode %{ 7933 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7934 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7935 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7936 noreg, true); 7937 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7938 __ isync(); 7939 } else { 7940 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7941 __ sync(); 7942 } 7943 %} 7944 ins_pipe(pipe_class_default); 7945 %} 7946 7947 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7948 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7949 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7950 effect(TEMP_DEF res, TEMP cr0); 7951 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7952 ins_encode %{ 7953 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7954 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7955 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7956 noreg, true); 7957 %} 7958 ins_pipe(pipe_class_default); 7959 %} 7960 7961 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7962 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7963 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7964 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7965 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7966 ins_encode %{ 7967 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7968 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7969 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7970 noreg, true); 7971 %} 7972 ins_pipe(pipe_class_default); 7973 %} 7974 7975 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7976 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7977 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7978 effect(TEMP_DEF res, TEMP cr0); 7979 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7980 ins_encode %{ 7981 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7982 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7983 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7984 noreg, true); 7985 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7986 __ isync(); 7987 } else { 7988 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7989 __ sync(); 7990 } 7991 %} 7992 ins_pipe(pipe_class_default); 7993 %} 7994 7995 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7996 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7997 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7998 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7999 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8000 ins_encode %{ 8001 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8002 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8003 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8004 noreg, true); 8005 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8006 __ isync(); 8007 } else { 8008 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8009 __ sync(); 8010 } 8011 %} 8012 ins_pipe(pipe_class_default); 8013 %} 8014 8015 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8016 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8017 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8018 effect(TEMP_DEF res, TEMP cr0); 8019 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8020 ins_encode %{ 8021 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8022 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8023 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8024 noreg, true); 8025 %} 8026 ins_pipe(pipe_class_default); 8027 %} 8028 8029 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8030 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8031 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8032 effect(TEMP_DEF res, TEMP cr0); 8033 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8034 ins_encode %{ 8035 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8036 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8037 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8038 noreg, true); 8039 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8040 __ isync(); 8041 } else { 8042 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8043 __ sync(); 8044 } 8045 %} 8046 ins_pipe(pipe_class_default); 8047 %} 8048 8049 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8050 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8051 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8052 effect(TEMP_DEF res, TEMP cr0); 8053 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8054 ins_encode %{ 8055 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8056 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8057 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8058 noreg, true); 8059 %} 8060 ins_pipe(pipe_class_default); 8061 %} 8062 8063 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8064 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8065 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8066 effect(TEMP_DEF res, TEMP cr0); 8067 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8068 ins_encode %{ 8069 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8070 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8071 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8072 noreg, true); 8073 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8074 __ isync(); 8075 } else { 8076 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8077 __ sync(); 8078 } 8079 %} 8080 ins_pipe(pipe_class_default); 8081 %} 8082 8083 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8084 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8085 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8086 effect(TEMP_DEF res, TEMP cr0); 8087 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8088 ins_encode %{ 8089 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8090 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8091 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8092 noreg, NULL, true); 8093 %} 8094 ins_pipe(pipe_class_default); 8095 %} 8096 8097 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8098 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8099 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8100 effect(TEMP_DEF res, TEMP cr0); 8101 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8102 ins_encode %{ 8103 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8104 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8105 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8106 noreg, NULL, true); 8107 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8108 __ isync(); 8109 } else { 8110 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8111 __ sync(); 8112 } 8113 %} 8114 ins_pipe(pipe_class_default); 8115 %} 8116 8117 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8118 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8119 predicate((((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst) 8120 && n->as_LoadStore()->barrier_data() == 0); 8121 effect(TEMP_DEF res, TEMP cr0); 8122 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8123 ins_encode %{ 8124 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8125 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8126 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8127 noreg, NULL, true); 8128 %} 8129 ins_pipe(pipe_class_default); 8130 %} 8131 8132 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8133 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8134 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) 8135 && n->as_LoadStore()->barrier_data() == 0); 8136 effect(TEMP_DEF res, TEMP cr0); 8137 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8138 ins_encode %{ 8139 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8140 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8141 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8142 noreg, NULL, true); 8143 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8144 __ isync(); 8145 } else { 8146 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8147 __ sync(); 8148 } 8149 %} 8150 ins_pipe(pipe_class_default); 8151 %} 8152 8153 // Special RMW 8154 8155 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8156 match(Set res (GetAndAddB mem_ptr src)); 8157 predicate(VM_Version::has_lqarx()); 8158 effect(TEMP_DEF res, TEMP cr0); 8159 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8160 ins_encode %{ 8161 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8162 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8163 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8164 __ isync(); 8165 } else { 8166 __ sync(); 8167 } 8168 %} 8169 ins_pipe(pipe_class_default); 8170 %} 8171 8172 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8173 match(Set res (GetAndAddB mem_ptr src)); 8174 predicate(!VM_Version::has_lqarx()); 8175 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8176 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8177 ins_encode %{ 8178 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8179 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8180 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8181 __ isync(); 8182 } else { 8183 __ sync(); 8184 } 8185 %} 8186 ins_pipe(pipe_class_default); 8187 %} 8188 8189 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8190 match(Set res (GetAndAddS mem_ptr src)); 8191 predicate(VM_Version::has_lqarx()); 8192 effect(TEMP_DEF res, TEMP cr0); 8193 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8194 ins_encode %{ 8195 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8196 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8197 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8198 __ isync(); 8199 } else { 8200 __ sync(); 8201 } 8202 %} 8203 ins_pipe(pipe_class_default); 8204 %} 8205 8206 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8207 match(Set res (GetAndAddS mem_ptr src)); 8208 predicate(!VM_Version::has_lqarx()); 8209 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8210 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8211 ins_encode %{ 8212 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8213 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8214 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8215 __ isync(); 8216 } else { 8217 __ sync(); 8218 } 8219 %} 8220 ins_pipe(pipe_class_default); 8221 %} 8222 8223 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8224 match(Set res (GetAndAddI mem_ptr src)); 8225 effect(TEMP_DEF res, TEMP cr0); 8226 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8227 ins_encode %{ 8228 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8229 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8230 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8231 __ isync(); 8232 } else { 8233 __ sync(); 8234 } 8235 %} 8236 ins_pipe(pipe_class_default); 8237 %} 8238 8239 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8240 match(Set res (GetAndAddL mem_ptr src)); 8241 effect(TEMP_DEF res, TEMP cr0); 8242 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8243 ins_encode %{ 8244 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8245 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8246 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8247 __ isync(); 8248 } else { 8249 __ sync(); 8250 } 8251 %} 8252 ins_pipe(pipe_class_default); 8253 %} 8254 8255 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8256 match(Set res (GetAndSetB mem_ptr src)); 8257 predicate(VM_Version::has_lqarx()); 8258 effect(TEMP_DEF res, TEMP cr0); 8259 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8260 ins_encode %{ 8261 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8262 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8263 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8264 __ isync(); 8265 } else { 8266 __ sync(); 8267 } 8268 %} 8269 ins_pipe(pipe_class_default); 8270 %} 8271 8272 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8273 match(Set res (GetAndSetB mem_ptr src)); 8274 predicate(!VM_Version::has_lqarx()); 8275 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8276 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8277 ins_encode %{ 8278 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8279 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8280 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8281 __ isync(); 8282 } else { 8283 __ sync(); 8284 } 8285 %} 8286 ins_pipe(pipe_class_default); 8287 %} 8288 8289 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8290 match(Set res (GetAndSetS mem_ptr src)); 8291 predicate(VM_Version::has_lqarx()); 8292 effect(TEMP_DEF res, TEMP cr0); 8293 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8294 ins_encode %{ 8295 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8296 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8297 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8298 __ isync(); 8299 } else { 8300 __ sync(); 8301 } 8302 %} 8303 ins_pipe(pipe_class_default); 8304 %} 8305 8306 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8307 match(Set res (GetAndSetS mem_ptr src)); 8308 predicate(!VM_Version::has_lqarx()); 8309 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8310 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8311 ins_encode %{ 8312 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8313 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8314 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8315 __ isync(); 8316 } else { 8317 __ sync(); 8318 } 8319 %} 8320 ins_pipe(pipe_class_default); 8321 %} 8322 8323 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8324 match(Set res (GetAndSetI mem_ptr src)); 8325 effect(TEMP_DEF res, TEMP cr0); 8326 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8327 ins_encode %{ 8328 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8329 MacroAssembler::cmpxchgx_hint_atomic_update()); 8330 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8331 __ isync(); 8332 } else { 8333 __ sync(); 8334 } 8335 %} 8336 ins_pipe(pipe_class_default); 8337 %} 8338 8339 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8340 match(Set res (GetAndSetL mem_ptr src)); 8341 effect(TEMP_DEF res, TEMP cr0); 8342 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8343 ins_encode %{ 8344 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8345 MacroAssembler::cmpxchgx_hint_atomic_update()); 8346 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8347 __ isync(); 8348 } else { 8349 __ sync(); 8350 } 8351 %} 8352 ins_pipe(pipe_class_default); 8353 %} 8354 8355 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8356 match(Set res (GetAndSetP mem_ptr src)); 8357 predicate(n->as_LoadStore()->barrier_data() == 0); 8358 effect(TEMP_DEF res, TEMP cr0); 8359 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8360 ins_encode %{ 8361 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8362 MacroAssembler::cmpxchgx_hint_atomic_update()); 8363 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8364 __ isync(); 8365 } else { 8366 __ sync(); 8367 } 8368 %} 8369 ins_pipe(pipe_class_default); 8370 %} 8371 8372 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8373 match(Set res (GetAndSetN mem_ptr src)); 8374 effect(TEMP_DEF res, TEMP cr0); 8375 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8376 ins_encode %{ 8377 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8378 MacroAssembler::cmpxchgx_hint_atomic_update()); 8379 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8380 __ isync(); 8381 } else { 8382 __ sync(); 8383 } 8384 %} 8385 ins_pipe(pipe_class_default); 8386 %} 8387 8388 //----------Arithmetic Instructions-------------------------------------------- 8389 // Addition Instructions 8390 8391 // Register Addition 8392 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8393 match(Set dst (AddI src1 src2)); 8394 format %{ "ADD $dst, $src1, $src2" %} 8395 size(4); 8396 ins_encode %{ 8397 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8398 %} 8399 ins_pipe(pipe_class_default); 8400 %} 8401 8402 // Expand does not work with above instruct. (??) 8403 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8404 // no match-rule 8405 effect(DEF dst, USE src1, USE src2); 8406 format %{ "ADD $dst, $src1, $src2" %} 8407 size(4); 8408 ins_encode %{ 8409 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8410 %} 8411 ins_pipe(pipe_class_default); 8412 %} 8413 8414 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8415 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8416 ins_cost(DEFAULT_COST*3); 8417 8418 expand %{ 8419 // FIXME: we should do this in the ideal world. 8420 iRegIdst tmp1; 8421 iRegIdst tmp2; 8422 addI_reg_reg(tmp1, src1, src2); 8423 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8424 addI_reg_reg(dst, tmp1, tmp2); 8425 %} 8426 %} 8427 8428 // Immediate Addition 8429 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8430 match(Set dst (AddI src1 src2)); 8431 format %{ "ADDI $dst, $src1, $src2" %} 8432 size(4); 8433 ins_encode %{ 8434 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8435 %} 8436 ins_pipe(pipe_class_default); 8437 %} 8438 8439 // Immediate Addition with 16-bit shifted operand 8440 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8441 match(Set dst (AddI src1 src2)); 8442 format %{ "ADDIS $dst, $src1, $src2" %} 8443 size(4); 8444 ins_encode %{ 8445 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8446 %} 8447 ins_pipe(pipe_class_default); 8448 %} 8449 8450 // Immediate Addition using prefixed addi 8451 instruct addI_reg_imm32(iRegIdst dst, iRegIsrc src1, immI32 src2) %{ 8452 match(Set dst (AddI src1 src2)); 8453 predicate(PowerArchitecturePPC64 >= 10); 8454 ins_cost(DEFAULT_COST+1); 8455 format %{ "PADDI $dst, $src1, $src2" %} 8456 size(8); 8457 ins_encode %{ 8458 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 8459 __ paddi($dst$$Register, $src1$$Register, $src2$$constant); 8460 %} 8461 ins_pipe(pipe_class_default); 8462 ins_alignment(2); 8463 %} 8464 8465 // Long Addition 8466 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8467 match(Set dst (AddL src1 src2)); 8468 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8469 size(4); 8470 ins_encode %{ 8471 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8472 %} 8473 ins_pipe(pipe_class_default); 8474 %} 8475 8476 // Expand does not work with above instruct. (??) 8477 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8478 // no match-rule 8479 effect(DEF dst, USE src1, USE src2); 8480 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8481 size(4); 8482 ins_encode %{ 8483 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8484 %} 8485 ins_pipe(pipe_class_default); 8486 %} 8487 8488 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8489 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8490 ins_cost(DEFAULT_COST*3); 8491 8492 expand %{ 8493 // FIXME: we should do this in the ideal world. 8494 iRegLdst tmp1; 8495 iRegLdst tmp2; 8496 addL_reg_reg(tmp1, src1, src2); 8497 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8498 addL_reg_reg(dst, tmp1, tmp2); 8499 %} 8500 %} 8501 8502 // AddL + ConvL2I. 8503 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8504 match(Set dst (ConvL2I (AddL src1 src2))); 8505 8506 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8507 size(4); 8508 ins_encode %{ 8509 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8510 %} 8511 ins_pipe(pipe_class_default); 8512 %} 8513 8514 // No constant pool entries required. 8515 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8516 match(Set dst (AddL src1 src2)); 8517 8518 format %{ "ADDI $dst, $src1, $src2" %} 8519 size(4); 8520 ins_encode %{ 8521 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8522 %} 8523 ins_pipe(pipe_class_default); 8524 %} 8525 8526 // Long Immediate Addition with 16-bit shifted operand. 8527 // No constant pool entries required. 8528 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8529 match(Set dst (AddL src1 src2)); 8530 8531 format %{ "ADDIS $dst, $src1, $src2" %} 8532 size(4); 8533 ins_encode %{ 8534 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8535 %} 8536 ins_pipe(pipe_class_default); 8537 %} 8538 8539 // Long Immediate Addition using prefixed addi 8540 // No constant pool entries required. 8541 instruct addL_reg_imm34(iRegLdst dst, iRegLsrc src1, immL34 src2) %{ 8542 match(Set dst (AddL src1 src2)); 8543 predicate(PowerArchitecturePPC64 >= 10); 8544 ins_cost(DEFAULT_COST+1); 8545 8546 format %{ "PADDI $dst, $src1, $src2" %} 8547 size(8); 8548 ins_encode %{ 8549 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 8550 __ paddi($dst$$Register, $src1$$Register, $src2$$constant); 8551 %} 8552 ins_pipe(pipe_class_default); 8553 ins_alignment(2); 8554 %} 8555 8556 // Pointer Register Addition 8557 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8558 match(Set dst (AddP src1 src2)); 8559 format %{ "ADD $dst, $src1, $src2" %} 8560 size(4); 8561 ins_encode %{ 8562 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8563 %} 8564 ins_pipe(pipe_class_default); 8565 %} 8566 8567 // Pointer Immediate Addition 8568 // No constant pool entries required. 8569 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8570 match(Set dst (AddP src1 src2)); 8571 8572 format %{ "ADDI $dst, $src1, $src2" %} 8573 size(4); 8574 ins_encode %{ 8575 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8576 %} 8577 ins_pipe(pipe_class_default); 8578 %} 8579 8580 // Pointer Immediate Addition with 16-bit shifted operand. 8581 // No constant pool entries required. 8582 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8583 match(Set dst (AddP src1 src2)); 8584 8585 format %{ "ADDIS $dst, $src1, $src2" %} 8586 size(4); 8587 ins_encode %{ 8588 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8589 %} 8590 ins_pipe(pipe_class_default); 8591 %} 8592 8593 // Pointer Immediate Addition using prefixed addi 8594 // No constant pool entries required. 8595 instruct addP_reg_imm34(iRegPdst dst, iRegP_N2P src1, immL34 src2) %{ 8596 match(Set dst (AddP src1 src2)); 8597 predicate(PowerArchitecturePPC64 >= 10); 8598 ins_cost(DEFAULT_COST+1); 8599 8600 format %{ "PADDI $dst, $src1, $src2" %} 8601 size(8); 8602 ins_encode %{ 8603 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 8604 __ paddi($dst$$Register, $src1$$Register, $src2$$constant); 8605 %} 8606 ins_pipe(pipe_class_default); 8607 ins_alignment(2); 8608 %} 8609 8610 //--------------------- 8611 // Subtraction Instructions 8612 8613 // Register Subtraction 8614 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8615 match(Set dst (SubI src1 src2)); 8616 format %{ "SUBF $dst, $src2, $src1" %} 8617 size(4); 8618 ins_encode %{ 8619 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8620 %} 8621 ins_pipe(pipe_class_default); 8622 %} 8623 8624 // Immediate Subtraction 8625 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 8626 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 8627 8628 // SubI from constant (using subfic). 8629 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 8630 match(Set dst (SubI src1 src2)); 8631 format %{ "SUBI $dst, $src1, $src2" %} 8632 8633 size(4); 8634 ins_encode %{ 8635 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 8636 %} 8637 ins_pipe(pipe_class_default); 8638 %} 8639 8640 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 8641 // positive integers and 0xF...F for negative ones. 8642 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 8643 // no match-rule, false predicate 8644 effect(DEF dst, USE src); 8645 predicate(false); 8646 8647 format %{ "SRAWI $dst, $src, #31" %} 8648 size(4); 8649 ins_encode %{ 8650 __ srawi($dst$$Register, $src$$Register, 0x1f); 8651 %} 8652 ins_pipe(pipe_class_default); 8653 %} 8654 8655 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 8656 match(Set dst (AbsI src)); 8657 ins_cost(DEFAULT_COST*3); 8658 8659 expand %{ 8660 iRegIdst tmp1; 8661 iRegIdst tmp2; 8662 signmask32I_regI(tmp1, src); 8663 xorI_reg_reg(tmp2, tmp1, src); 8664 subI_reg_reg(dst, tmp2, tmp1); 8665 %} 8666 %} 8667 8668 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 8669 match(Set dst (SubI zero src2)); 8670 format %{ "NEG $dst, $src2" %} 8671 size(4); 8672 ins_encode %{ 8673 __ neg($dst$$Register, $src2$$Register); 8674 %} 8675 ins_pipe(pipe_class_default); 8676 %} 8677 8678 // Long subtraction 8679 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8680 match(Set dst (SubL src1 src2)); 8681 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 8682 size(4); 8683 ins_encode %{ 8684 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8685 %} 8686 ins_pipe(pipe_class_default); 8687 %} 8688 8689 // SubL + convL2I. 8690 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8691 match(Set dst (ConvL2I (SubL src1 src2))); 8692 8693 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 8694 size(4); 8695 ins_encode %{ 8696 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8697 %} 8698 ins_pipe(pipe_class_default); 8699 %} 8700 8701 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8702 // positive longs and 0xF...F for negative ones. 8703 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 8704 // no match-rule, false predicate 8705 effect(DEF dst, USE src); 8706 predicate(false); 8707 8708 format %{ "SRADI $dst, $src, #63" %} 8709 size(4); 8710 ins_encode %{ 8711 __ sradi($dst$$Register, $src$$Register, 0x3f); 8712 %} 8713 ins_pipe(pipe_class_default); 8714 %} 8715 8716 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8717 // positive longs and 0xF...F for negative ones. 8718 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 8719 // no match-rule, false predicate 8720 effect(DEF dst, USE src); 8721 predicate(false); 8722 8723 format %{ "SRADI $dst, $src, #63" %} 8724 size(4); 8725 ins_encode %{ 8726 __ sradi($dst$$Register, $src$$Register, 0x3f); 8727 %} 8728 ins_pipe(pipe_class_default); 8729 %} 8730 8731 instruct absL_reg_Ex(iRegLdst dst, iRegLsrc src) %{ 8732 match(Set dst (AbsL src)); 8733 ins_cost(DEFAULT_COST*3); 8734 8735 expand %{ 8736 iRegLdst tmp1; 8737 iRegLdst tmp2; 8738 signmask64L_regL(tmp1, src); 8739 xorL_reg_reg(tmp2, tmp1, src); 8740 subL_reg_reg(dst, tmp2, tmp1); 8741 %} 8742 %} 8743 8744 // Long negation 8745 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 8746 match(Set dst (SubL zero src2)); 8747 format %{ "NEG $dst, $src2 \t// long" %} 8748 size(4); 8749 ins_encode %{ 8750 __ neg($dst$$Register, $src2$$Register); 8751 %} 8752 ins_pipe(pipe_class_default); 8753 %} 8754 8755 // NegL + ConvL2I. 8756 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 8757 match(Set dst (ConvL2I (SubL zero src2))); 8758 8759 format %{ "NEG $dst, $src2 \t// long + l2i" %} 8760 size(4); 8761 ins_encode %{ 8762 __ neg($dst$$Register, $src2$$Register); 8763 %} 8764 ins_pipe(pipe_class_default); 8765 %} 8766 8767 // Multiplication Instructions 8768 // Integer Multiplication 8769 8770 // Register Multiplication 8771 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8772 match(Set dst (MulI src1 src2)); 8773 ins_cost(DEFAULT_COST); 8774 8775 format %{ "MULLW $dst, $src1, $src2" %} 8776 size(4); 8777 ins_encode %{ 8778 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 8779 %} 8780 ins_pipe(pipe_class_default); 8781 %} 8782 8783 // Immediate Multiplication 8784 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8785 match(Set dst (MulI src1 src2)); 8786 ins_cost(DEFAULT_COST); 8787 8788 format %{ "MULLI $dst, $src1, $src2" %} 8789 size(4); 8790 ins_encode %{ 8791 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8792 %} 8793 ins_pipe(pipe_class_default); 8794 %} 8795 8796 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8797 match(Set dst (MulL src1 src2)); 8798 ins_cost(DEFAULT_COST); 8799 8800 format %{ "MULLD $dst $src1, $src2 \t// long" %} 8801 size(4); 8802 ins_encode %{ 8803 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 8804 %} 8805 ins_pipe(pipe_class_default); 8806 %} 8807 8808 // Multiply high for optimized long division by constant. 8809 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8810 match(Set dst (MulHiL src1 src2)); 8811 ins_cost(DEFAULT_COST); 8812 8813 format %{ "MULHD $dst $src1, $src2 \t// long" %} 8814 size(4); 8815 ins_encode %{ 8816 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 8817 %} 8818 ins_pipe(pipe_class_default); 8819 %} 8820 8821 // Immediate Multiplication 8822 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8823 match(Set dst (MulL src1 src2)); 8824 ins_cost(DEFAULT_COST); 8825 8826 format %{ "MULLI $dst, $src1, $src2" %} 8827 size(4); 8828 ins_encode %{ 8829 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8830 %} 8831 ins_pipe(pipe_class_default); 8832 %} 8833 8834 // Integer Division with Immediate -1: Negate. 8835 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 8836 match(Set dst (DivI src1 src2)); 8837 ins_cost(DEFAULT_COST); 8838 8839 format %{ "NEG $dst, $src1 \t// /-1" %} 8840 size(4); 8841 ins_encode %{ 8842 __ neg($dst$$Register, $src1$$Register); 8843 %} 8844 ins_pipe(pipe_class_default); 8845 %} 8846 8847 // Integer Division with constant, but not -1. 8848 // We should be able to improve this by checking the type of src2. 8849 // It might well be that src2 is known to be positive. 8850 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8851 match(Set dst (DivI src1 src2)); 8852 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 8853 ins_cost(2*DEFAULT_COST); 8854 8855 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 8856 size(4); 8857 ins_encode %{ 8858 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 8859 %} 8860 ins_pipe(pipe_class_default); 8861 %} 8862 8863 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 8864 effect(USE_DEF dst, USE src1, USE crx); 8865 predicate(false); 8866 8867 ins_variable_size_depending_on_alignment(true); 8868 8869 format %{ "CMOVE $dst, neg($src1), $crx" %} 8870 // Worst case is branch + move + stop, no stop without scheduler. 8871 size(8); 8872 ins_encode %{ 8873 Label done; 8874 __ bne($crx$$CondRegister, done); 8875 __ neg($dst$$Register, $src1$$Register); 8876 __ bind(done); 8877 %} 8878 ins_pipe(pipe_class_default); 8879 %} 8880 8881 // Integer Division with Registers not containing constants. 8882 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8883 match(Set dst (DivI src1 src2)); 8884 ins_cost(10*DEFAULT_COST); 8885 8886 expand %{ 8887 immI16 imm %{ (int)-1 %} 8888 flagsReg tmp1; 8889 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8890 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8891 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8892 %} 8893 %} 8894 8895 // Long Division with Immediate -1: Negate. 8896 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 8897 match(Set dst (DivL src1 src2)); 8898 ins_cost(DEFAULT_COST); 8899 8900 format %{ "NEG $dst, $src1 \t// /-1, long" %} 8901 size(4); 8902 ins_encode %{ 8903 __ neg($dst$$Register, $src1$$Register); 8904 %} 8905 ins_pipe(pipe_class_default); 8906 %} 8907 8908 // Long Division with constant, but not -1. 8909 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8910 match(Set dst (DivL src1 src2)); 8911 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 8912 ins_cost(2*DEFAULT_COST); 8913 8914 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 8915 size(4); 8916 ins_encode %{ 8917 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 8918 %} 8919 ins_pipe(pipe_class_default); 8920 %} 8921 8922 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 8923 effect(USE_DEF dst, USE src1, USE crx); 8924 predicate(false); 8925 8926 ins_variable_size_depending_on_alignment(true); 8927 8928 format %{ "CMOVE $dst, neg($src1), $crx" %} 8929 // Worst case is branch + move + stop, no stop without scheduler. 8930 size(8); 8931 ins_encode %{ 8932 Label done; 8933 __ bne($crx$$CondRegister, done); 8934 __ neg($dst$$Register, $src1$$Register); 8935 __ bind(done); 8936 %} 8937 ins_pipe(pipe_class_default); 8938 %} 8939 8940 // Long Division with Registers not containing constants. 8941 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8942 match(Set dst (DivL src1 src2)); 8943 ins_cost(10*DEFAULT_COST); 8944 8945 expand %{ 8946 immL16 imm %{ (int)-1 %} 8947 flagsReg tmp1; 8948 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8949 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8950 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8951 %} 8952 %} 8953 8954 // Integer Remainder with registers. 8955 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8956 match(Set dst (ModI src1 src2)); 8957 ins_cost(10*DEFAULT_COST); 8958 8959 expand %{ 8960 immI16 imm %{ (int)-1 %} 8961 flagsReg tmp1; 8962 iRegIdst tmp2; 8963 iRegIdst tmp3; 8964 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8965 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8966 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8967 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8968 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8969 %} 8970 %} 8971 8972 // Long Remainder with registers 8973 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8974 match(Set dst (ModL src1 src2)); 8975 ins_cost(10*DEFAULT_COST); 8976 8977 expand %{ 8978 immL16 imm %{ (int)-1 %} 8979 flagsReg tmp1; 8980 iRegLdst tmp2; 8981 iRegLdst tmp3; 8982 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8983 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8984 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8985 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8986 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8987 %} 8988 %} 8989 8990 instruct udivI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8991 match(Set dst (UDivI src1 src2)); 8992 format %{ "DIVWU $dst, $src1, $src2" %} 8993 size(4); 8994 ins_encode %{ 8995 __ divwu($dst$$Register, $src1$$Register, $src2$$Register); 8996 %} 8997 ins_pipe(pipe_class_default); 8998 %} 8999 9000 instruct umodI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9001 match(Set dst (UModI src1 src2)); 9002 expand %{ 9003 iRegIdst tmp1; 9004 iRegIdst tmp2; 9005 udivI_reg_reg(tmp1, src1, src2); 9006 // Compute lower 32 bit result using signed instructions as suggested by ISA. 9007 // Upper 32 bit will contain garbage. 9008 mulI_reg_reg(tmp2, src2, tmp1); 9009 subI_reg_reg(dst, src1, tmp2); 9010 %} 9011 %} 9012 9013 instruct udivL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9014 match(Set dst (UDivL src1 src2)); 9015 format %{ "DIVDU $dst, $src1, $src2" %} 9016 size(4); 9017 ins_encode %{ 9018 __ divdu($dst$$Register, $src1$$Register, $src2$$Register); 9019 %} 9020 ins_pipe(pipe_class_default); 9021 %} 9022 9023 instruct umodL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9024 match(Set dst (UModL src1 src2)); 9025 expand %{ 9026 iRegLdst tmp1; 9027 iRegLdst tmp2; 9028 udivL_reg_reg(tmp1, src1, src2); 9029 mulL_reg_reg(tmp2, src2, tmp1); 9030 subL_reg_reg(dst, src1, tmp2); 9031 %} 9032 %} 9033 9034 // Integer Shift Instructions 9035 9036 // Register Shift Left 9037 9038 // Clear all but the lowest #mask bits. 9039 // Used to normalize shift amounts in registers. 9040 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9041 // no match-rule, false predicate 9042 effect(DEF dst, USE src, USE mask); 9043 predicate(false); 9044 9045 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9046 size(4); 9047 ins_encode %{ 9048 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9049 %} 9050 ins_pipe(pipe_class_default); 9051 %} 9052 9053 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9054 // no match-rule, false predicate 9055 effect(DEF dst, USE src1, USE src2); 9056 predicate(false); 9057 9058 format %{ "SLW $dst, $src1, $src2" %} 9059 size(4); 9060 ins_encode %{ 9061 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9062 %} 9063 ins_pipe(pipe_class_default); 9064 %} 9065 9066 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9067 match(Set dst (LShiftI src1 src2)); 9068 ins_cost(DEFAULT_COST*2); 9069 expand %{ 9070 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9071 iRegIdst tmpI; 9072 maskI_reg_imm(tmpI, src2, mask); 9073 lShiftI_reg_reg(dst, src1, tmpI); 9074 %} 9075 %} 9076 9077 // Register Shift Left Immediate 9078 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9079 match(Set dst (LShiftI src1 src2)); 9080 9081 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9082 size(4); 9083 ins_encode %{ 9084 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9085 %} 9086 ins_pipe(pipe_class_default); 9087 %} 9088 9089 // AndI with negpow2-constant + LShiftI 9090 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9091 match(Set dst (LShiftI (AndI src1 src2) src3)); 9092 predicate(UseRotateAndMaskInstructionsPPC64); 9093 9094 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9095 size(4); 9096 ins_encode %{ 9097 long src3 = $src3$$constant; 9098 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant); 9099 if (maskbits >= 32) { 9100 __ li($dst$$Register, 0); // addi 9101 } else { 9102 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9103 } 9104 %} 9105 ins_pipe(pipe_class_default); 9106 %} 9107 9108 // RShiftI + AndI with negpow2-constant + LShiftI 9109 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9110 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9111 predicate(UseRotateAndMaskInstructionsPPC64); 9112 9113 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9114 size(4); 9115 ins_encode %{ 9116 long src3 = $src3$$constant; 9117 long maskbits = src3 + log2i_exact(-(juint)$src2$$constant); 9118 if (maskbits >= 32) { 9119 __ li($dst$$Register, 0); // addi 9120 } else { 9121 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9122 } 9123 %} 9124 ins_pipe(pipe_class_default); 9125 %} 9126 9127 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9128 // no match-rule, false predicate 9129 effect(DEF dst, USE src1, USE src2); 9130 predicate(false); 9131 9132 format %{ "SLD $dst, $src1, $src2" %} 9133 size(4); 9134 ins_encode %{ 9135 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9136 %} 9137 ins_pipe(pipe_class_default); 9138 %} 9139 9140 // Register Shift Left 9141 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9142 match(Set dst (LShiftL src1 src2)); 9143 ins_cost(DEFAULT_COST*2); 9144 expand %{ 9145 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9146 iRegIdst tmpI; 9147 maskI_reg_imm(tmpI, src2, mask); 9148 lShiftL_regL_regI(dst, src1, tmpI); 9149 %} 9150 %} 9151 9152 // Register Shift Left Immediate 9153 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9154 match(Set dst (LShiftL src1 src2)); 9155 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9156 size(4); 9157 ins_encode %{ 9158 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9159 %} 9160 ins_pipe(pipe_class_default); 9161 %} 9162 9163 // If we shift more than 32 bits, we need not convert I2L. 9164 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9165 match(Set dst (LShiftL (ConvI2L src1) src2)); 9166 ins_cost(DEFAULT_COST); 9167 9168 size(4); 9169 format %{ "SLDI $dst, i2l($src1), $src2" %} 9170 ins_encode %{ 9171 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9172 %} 9173 ins_pipe(pipe_class_default); 9174 %} 9175 9176 // Shift a postivie int to the left. 9177 // Clrlsldi clears the upper 32 bits and shifts. 9178 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9179 match(Set dst (LShiftL (ConvI2L src1) src2)); 9180 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9181 9182 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9183 size(4); 9184 ins_encode %{ 9185 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9186 %} 9187 ins_pipe(pipe_class_default); 9188 %} 9189 9190 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9191 // no match-rule, false predicate 9192 effect(DEF dst, USE src1, USE src2); 9193 predicate(false); 9194 9195 format %{ "SRAW $dst, $src1, $src2" %} 9196 size(4); 9197 ins_encode %{ 9198 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9199 %} 9200 ins_pipe(pipe_class_default); 9201 %} 9202 9203 // Register Arithmetic Shift Right 9204 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9205 match(Set dst (RShiftI src1 src2)); 9206 ins_cost(DEFAULT_COST*2); 9207 expand %{ 9208 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9209 iRegIdst tmpI; 9210 maskI_reg_imm(tmpI, src2, mask); 9211 arShiftI_reg_reg(dst, src1, tmpI); 9212 %} 9213 %} 9214 9215 // Register Arithmetic Shift Right Immediate 9216 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9217 match(Set dst (RShiftI src1 src2)); 9218 9219 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9220 size(4); 9221 ins_encode %{ 9222 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9223 %} 9224 ins_pipe(pipe_class_default); 9225 %} 9226 9227 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9228 // no match-rule, false predicate 9229 effect(DEF dst, USE src1, USE src2); 9230 predicate(false); 9231 9232 format %{ "SRAD $dst, $src1, $src2" %} 9233 size(4); 9234 ins_encode %{ 9235 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9236 %} 9237 ins_pipe(pipe_class_default); 9238 %} 9239 9240 // Register Shift Right Arithmetic Long 9241 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9242 match(Set dst (RShiftL src1 src2)); 9243 ins_cost(DEFAULT_COST*2); 9244 9245 expand %{ 9246 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9247 iRegIdst tmpI; 9248 maskI_reg_imm(tmpI, src2, mask); 9249 arShiftL_regL_regI(dst, src1, tmpI); 9250 %} 9251 %} 9252 9253 // Register Shift Right Immediate 9254 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9255 match(Set dst (RShiftL src1 src2)); 9256 9257 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9258 size(4); 9259 ins_encode %{ 9260 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9261 %} 9262 ins_pipe(pipe_class_default); 9263 %} 9264 9265 // RShiftL + ConvL2I 9266 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9267 match(Set dst (ConvL2I (RShiftL src1 src2))); 9268 9269 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9270 size(4); 9271 ins_encode %{ 9272 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9273 %} 9274 ins_pipe(pipe_class_default); 9275 %} 9276 9277 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9278 // no match-rule, false predicate 9279 effect(DEF dst, USE src1, USE src2); 9280 predicate(false); 9281 9282 format %{ "SRW $dst, $src1, $src2" %} 9283 size(4); 9284 ins_encode %{ 9285 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9286 %} 9287 ins_pipe(pipe_class_default); 9288 %} 9289 9290 // Register Shift Right 9291 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9292 match(Set dst (URShiftI src1 src2)); 9293 ins_cost(DEFAULT_COST*2); 9294 9295 expand %{ 9296 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9297 iRegIdst tmpI; 9298 maskI_reg_imm(tmpI, src2, mask); 9299 urShiftI_reg_reg(dst, src1, tmpI); 9300 %} 9301 %} 9302 9303 // Register Shift Right Immediate 9304 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9305 match(Set dst (URShiftI src1 src2)); 9306 9307 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9308 size(4); 9309 ins_encode %{ 9310 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9311 %} 9312 ins_pipe(pipe_class_default); 9313 %} 9314 9315 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9316 // no match-rule, false predicate 9317 effect(DEF dst, USE src1, USE src2); 9318 predicate(false); 9319 9320 format %{ "SRD $dst, $src1, $src2" %} 9321 size(4); 9322 ins_encode %{ 9323 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9324 %} 9325 ins_pipe(pipe_class_default); 9326 %} 9327 9328 // Register Shift Right 9329 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9330 match(Set dst (URShiftL src1 src2)); 9331 ins_cost(DEFAULT_COST*2); 9332 9333 expand %{ 9334 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9335 iRegIdst tmpI; 9336 maskI_reg_imm(tmpI, src2, mask); 9337 urShiftL_regL_regI(dst, src1, tmpI); 9338 %} 9339 %} 9340 9341 // Register Shift Right Immediate 9342 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9343 match(Set dst (URShiftL src1 src2)); 9344 9345 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9346 size(4); 9347 ins_encode %{ 9348 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9349 %} 9350 ins_pipe(pipe_class_default); 9351 %} 9352 9353 // URShiftL + ConvL2I. 9354 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9355 match(Set dst (ConvL2I (URShiftL src1 src2))); 9356 9357 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9358 size(4); 9359 ins_encode %{ 9360 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9361 %} 9362 ins_pipe(pipe_class_default); 9363 %} 9364 9365 // Register Shift Right Immediate with a CastP2X 9366 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9367 match(Set dst (URShiftL (CastP2X src1) src2)); 9368 9369 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9370 size(4); 9371 ins_encode %{ 9372 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9373 %} 9374 ins_pipe(pipe_class_default); 9375 %} 9376 9377 // Bitfield Extract: URShiftI + AndI 9378 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9379 match(Set dst (AndI (URShiftI src1 src2) src3)); 9380 9381 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9382 size(4); 9383 ins_encode %{ 9384 int rshift = ($src2$$constant) & 0x1f; 9385 int length = log2i_exact((juint)$src3$$constant + 1u); 9386 if (rshift + length > 32) { 9387 // if necessary, adjust mask to omit rotated bits. 9388 length = 32 - rshift; 9389 } 9390 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9391 %} 9392 ins_pipe(pipe_class_default); 9393 %} 9394 9395 // Bitfield Extract: URShiftL + AndL 9396 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9397 match(Set dst (AndL (URShiftL src1 src2) src3)); 9398 9399 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9400 size(4); 9401 ins_encode %{ 9402 int rshift = ($src2$$constant) & 0x3f; 9403 int length = log2i_exact((julong)$src3$$constant + 1ull); 9404 if (rshift + length > 64) { 9405 // if necessary, adjust mask to omit rotated bits. 9406 length = 64 - rshift; 9407 } 9408 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9409 %} 9410 ins_pipe(pipe_class_default); 9411 %} 9412 9413 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9414 match(Set dst (ConvL2I (ConvI2L src))); 9415 9416 format %{ "EXTSW $dst, $src \t// int->int" %} 9417 size(4); 9418 ins_encode %{ 9419 __ extsw($dst$$Register, $src$$Register); 9420 %} 9421 ins_pipe(pipe_class_default); 9422 %} 9423 9424 //----------Rotate Instructions------------------------------------------------ 9425 9426 // Rotate Left by 8-bit immediate 9427 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9428 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9429 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9430 9431 format %{ "ROTLWI $dst, $src, $lshift" %} 9432 size(4); 9433 ins_encode %{ 9434 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9435 %} 9436 ins_pipe(pipe_class_default); 9437 %} 9438 9439 // Rotate Right by 8-bit immediate 9440 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9441 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9442 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9443 9444 format %{ "ROTRWI $dst, $rshift" %} 9445 size(4); 9446 ins_encode %{ 9447 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9448 %} 9449 ins_pipe(pipe_class_default); 9450 %} 9451 9452 //----------Floating Point Arithmetic Instructions----------------------------- 9453 9454 // Add float single precision 9455 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9456 match(Set dst (AddF src1 src2)); 9457 9458 format %{ "FADDS $dst, $src1, $src2" %} 9459 size(4); 9460 ins_encode %{ 9461 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9462 %} 9463 ins_pipe(pipe_class_default); 9464 %} 9465 9466 // Add float double precision 9467 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9468 match(Set dst (AddD src1 src2)); 9469 9470 format %{ "FADD $dst, $src1, $src2" %} 9471 size(4); 9472 ins_encode %{ 9473 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9474 %} 9475 ins_pipe(pipe_class_default); 9476 %} 9477 9478 // Sub float single precision 9479 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9480 match(Set dst (SubF src1 src2)); 9481 9482 format %{ "FSUBS $dst, $src1, $src2" %} 9483 size(4); 9484 ins_encode %{ 9485 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9486 %} 9487 ins_pipe(pipe_class_default); 9488 %} 9489 9490 // Sub float double precision 9491 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9492 match(Set dst (SubD src1 src2)); 9493 format %{ "FSUB $dst, $src1, $src2" %} 9494 size(4); 9495 ins_encode %{ 9496 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9497 %} 9498 ins_pipe(pipe_class_default); 9499 %} 9500 9501 // Mul float single precision 9502 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9503 match(Set dst (MulF src1 src2)); 9504 format %{ "FMULS $dst, $src1, $src2" %} 9505 size(4); 9506 ins_encode %{ 9507 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9508 %} 9509 ins_pipe(pipe_class_default); 9510 %} 9511 9512 // Mul float double precision 9513 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9514 match(Set dst (MulD src1 src2)); 9515 format %{ "FMUL $dst, $src1, $src2" %} 9516 size(4); 9517 ins_encode %{ 9518 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9519 %} 9520 ins_pipe(pipe_class_default); 9521 %} 9522 9523 // Div float single precision 9524 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9525 match(Set dst (DivF src1 src2)); 9526 format %{ "FDIVS $dst, $src1, $src2" %} 9527 size(4); 9528 ins_encode %{ 9529 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9530 %} 9531 ins_pipe(pipe_class_default); 9532 %} 9533 9534 // Div float double precision 9535 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9536 match(Set dst (DivD src1 src2)); 9537 format %{ "FDIV $dst, $src1, $src2" %} 9538 size(4); 9539 ins_encode %{ 9540 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9541 %} 9542 ins_pipe(pipe_class_default); 9543 %} 9544 9545 // Absolute float single precision 9546 instruct absF_reg(regF dst, regF src) %{ 9547 match(Set dst (AbsF src)); 9548 format %{ "FABS $dst, $src \t// float" %} 9549 size(4); 9550 ins_encode %{ 9551 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9552 %} 9553 ins_pipe(pipe_class_default); 9554 %} 9555 9556 // Absolute float double precision 9557 instruct absD_reg(regD dst, regD src) %{ 9558 match(Set dst (AbsD src)); 9559 format %{ "FABS $dst, $src \t// double" %} 9560 size(4); 9561 ins_encode %{ 9562 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9563 %} 9564 ins_pipe(pipe_class_default); 9565 %} 9566 9567 instruct negF_reg(regF dst, regF src) %{ 9568 match(Set dst (NegF src)); 9569 format %{ "FNEG $dst, $src \t// float" %} 9570 size(4); 9571 ins_encode %{ 9572 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9573 %} 9574 ins_pipe(pipe_class_default); 9575 %} 9576 9577 instruct negD_reg(regD dst, regD src) %{ 9578 match(Set dst (NegD src)); 9579 format %{ "FNEG $dst, $src \t// double" %} 9580 size(4); 9581 ins_encode %{ 9582 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9583 %} 9584 ins_pipe(pipe_class_default); 9585 %} 9586 9587 // AbsF + NegF. 9588 instruct negF_absF_reg(regF dst, regF src) %{ 9589 match(Set dst (NegF (AbsF src))); 9590 format %{ "FNABS $dst, $src \t// float" %} 9591 size(4); 9592 ins_encode %{ 9593 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9594 %} 9595 ins_pipe(pipe_class_default); 9596 %} 9597 9598 // AbsD + NegD. 9599 instruct negD_absD_reg(regD dst, regD src) %{ 9600 match(Set dst (NegD (AbsD src))); 9601 format %{ "FNABS $dst, $src \t// double" %} 9602 size(4); 9603 ins_encode %{ 9604 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9605 %} 9606 ins_pipe(pipe_class_default); 9607 %} 9608 9609 // VM_Version::has_fsqrt() decides if this node will be used. 9610 // Sqrt float double precision 9611 instruct sqrtD_reg(regD dst, regD src) %{ 9612 match(Set dst (SqrtD src)); 9613 format %{ "FSQRT $dst, $src" %} 9614 size(4); 9615 ins_encode %{ 9616 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 9617 %} 9618 ins_pipe(pipe_class_default); 9619 %} 9620 9621 // Single-precision sqrt. 9622 instruct sqrtF_reg(regF dst, regF src) %{ 9623 match(Set dst (SqrtF src)); 9624 predicate(VM_Version::has_fsqrts()); 9625 ins_cost(DEFAULT_COST); 9626 9627 format %{ "FSQRTS $dst, $src" %} 9628 size(4); 9629 ins_encode %{ 9630 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 9631 %} 9632 ins_pipe(pipe_class_default); 9633 %} 9634 9635 instruct roundDouble_nop(regD dst) %{ 9636 match(Set dst (RoundDouble dst)); 9637 ins_cost(0); 9638 9639 format %{ " -- \t// RoundDouble 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 instruct roundFloat_nop(regF dst) %{ 9647 match(Set dst (RoundFloat dst)); 9648 ins_cost(0); 9649 9650 format %{ " -- \t// RoundFloat not needed - empty" %} 9651 size(0); 9652 // PPC results are already "rounded" (i.e., normal-format IEEE). 9653 ins_encode( /*empty*/ ); 9654 ins_pipe(pipe_class_default); 9655 %} 9656 9657 9658 // Multiply-Accumulate 9659 // src1 * src2 + src3 9660 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9661 match(Set dst (FmaF src3 (Binary src1 src2))); 9662 9663 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 9664 size(4); 9665 ins_encode %{ 9666 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9667 %} 9668 ins_pipe(pipe_class_default); 9669 %} 9670 9671 // src1 * src2 + src3 9672 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9673 match(Set dst (FmaD src3 (Binary src1 src2))); 9674 9675 format %{ "FMADD $dst, $src1, $src2, $src3" %} 9676 size(4); 9677 ins_encode %{ 9678 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9679 %} 9680 ins_pipe(pipe_class_default); 9681 %} 9682 9683 // -src1 * src2 + src3 = -(src1*src2-src3) 9684 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9685 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 9686 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 9687 9688 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 9689 size(4); 9690 ins_encode %{ 9691 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9692 %} 9693 ins_pipe(pipe_class_default); 9694 %} 9695 9696 // -src1 * src2 + src3 = -(src1*src2-src3) 9697 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9698 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 9699 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 9700 9701 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 9702 size(4); 9703 ins_encode %{ 9704 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9705 %} 9706 ins_pipe(pipe_class_default); 9707 %} 9708 9709 // -src1 * src2 - src3 = -(src1*src2+src3) 9710 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9711 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 9712 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 9713 9714 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 9715 size(4); 9716 ins_encode %{ 9717 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9718 %} 9719 ins_pipe(pipe_class_default); 9720 %} 9721 9722 // -src1 * src2 - src3 = -(src1*src2+src3) 9723 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9724 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 9725 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 9726 9727 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 9728 size(4); 9729 ins_encode %{ 9730 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9731 %} 9732 ins_pipe(pipe_class_default); 9733 %} 9734 9735 // src1 * src2 - src3 9736 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9737 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 9738 9739 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 9740 size(4); 9741 ins_encode %{ 9742 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9743 %} 9744 ins_pipe(pipe_class_default); 9745 %} 9746 9747 // src1 * src2 - src3 9748 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9749 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 9750 9751 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 9752 size(4); 9753 ins_encode %{ 9754 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9755 %} 9756 ins_pipe(pipe_class_default); 9757 %} 9758 9759 9760 //----------Logical Instructions----------------------------------------------- 9761 9762 // And Instructions 9763 9764 // Register And 9765 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9766 match(Set dst (AndI src1 src2)); 9767 format %{ "AND $dst, $src1, $src2" %} 9768 size(4); 9769 ins_encode %{ 9770 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9771 %} 9772 ins_pipe(pipe_class_default); 9773 %} 9774 9775 // Left shifted Immediate And 9776 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 9777 match(Set dst (AndI src1 src2)); 9778 effect(KILL cr0); 9779 format %{ "ANDIS $dst, $src1, $src2.hi" %} 9780 size(4); 9781 ins_encode %{ 9782 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 9783 %} 9784 ins_pipe(pipe_class_default); 9785 %} 9786 9787 // Immediate And 9788 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 9789 match(Set dst (AndI src1 src2)); 9790 effect(KILL cr0); 9791 9792 format %{ "ANDI $dst, $src1, $src2" %} 9793 size(4); 9794 ins_encode %{ 9795 // FIXME: avoid andi_ ? 9796 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9797 %} 9798 ins_pipe(pipe_class_default); 9799 %} 9800 9801 // Immediate And where the immediate is a negative power of 2. 9802 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 9803 match(Set dst (AndI src1 src2)); 9804 format %{ "ANDWI $dst, $src1, $src2" %} 9805 size(4); 9806 ins_encode %{ 9807 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(juint)$src2$$constant)); 9808 %} 9809 ins_pipe(pipe_class_default); 9810 %} 9811 9812 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 9813 match(Set dst (AndI src1 src2)); 9814 format %{ "ANDWI $dst, $src1, $src2" %} 9815 size(4); 9816 ins_encode %{ 9817 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((juint)$src2$$constant + 1u)); 9818 %} 9819 ins_pipe(pipe_class_default); 9820 %} 9821 9822 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 9823 match(Set dst (AndI src1 src2)); 9824 predicate(UseRotateAndMaskInstructionsPPC64); 9825 format %{ "ANDWI $dst, $src1, $src2" %} 9826 size(4); 9827 ins_encode %{ 9828 int bitpos = 31 - log2i_exact((juint)$src2$$constant); 9829 __ rlwinm($dst$$Register, $src1$$Register, 0, bitpos, bitpos); 9830 %} 9831 ins_pipe(pipe_class_default); 9832 %} 9833 9834 // Register And Long 9835 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9836 match(Set dst (AndL src1 src2)); 9837 ins_cost(DEFAULT_COST); 9838 9839 format %{ "AND $dst, $src1, $src2 \t// long" %} 9840 size(4); 9841 ins_encode %{ 9842 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9843 %} 9844 ins_pipe(pipe_class_default); 9845 %} 9846 9847 // Immediate And long 9848 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 9849 match(Set dst (AndL src1 src2)); 9850 effect(KILL cr0); 9851 9852 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 9853 size(4); 9854 ins_encode %{ 9855 // FIXME: avoid andi_ ? 9856 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9857 %} 9858 ins_pipe(pipe_class_default); 9859 %} 9860 9861 // Immediate And Long where the immediate is a negative power of 2. 9862 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 9863 match(Set dst (AndL src1 src2)); 9864 format %{ "ANDDI $dst, $src1, $src2" %} 9865 size(4); 9866 ins_encode %{ 9867 __ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(julong)$src2$$constant)); 9868 %} 9869 ins_pipe(pipe_class_default); 9870 %} 9871 9872 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9873 match(Set dst (AndL src1 src2)); 9874 format %{ "ANDDI $dst, $src1, $src2" %} 9875 size(4); 9876 ins_encode %{ 9877 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull)); 9878 %} 9879 ins_pipe(pipe_class_default); 9880 %} 9881 9882 // AndL + ConvL2I. 9883 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9884 match(Set dst (ConvL2I (AndL src1 src2))); 9885 ins_cost(DEFAULT_COST); 9886 9887 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 9888 size(4); 9889 ins_encode %{ 9890 __ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull)); 9891 %} 9892 ins_pipe(pipe_class_default); 9893 %} 9894 9895 // Or Instructions 9896 9897 // Register Or 9898 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9899 match(Set dst (OrI src1 src2)); 9900 format %{ "OR $dst, $src1, $src2" %} 9901 size(4); 9902 ins_encode %{ 9903 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9904 %} 9905 ins_pipe(pipe_class_default); 9906 %} 9907 9908 // Expand does not work with above instruct. (??) 9909 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9910 // no match-rule 9911 effect(DEF dst, USE src1, USE src2); 9912 format %{ "OR $dst, $src1, $src2" %} 9913 size(4); 9914 ins_encode %{ 9915 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9916 %} 9917 ins_pipe(pipe_class_default); 9918 %} 9919 9920 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9921 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 9922 ins_cost(DEFAULT_COST*3); 9923 9924 expand %{ 9925 // FIXME: we should do this in the ideal world. 9926 iRegIdst tmp1; 9927 iRegIdst tmp2; 9928 orI_reg_reg(tmp1, src1, src2); 9929 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 9930 orI_reg_reg(dst, tmp1, tmp2); 9931 %} 9932 %} 9933 9934 // Immediate Or 9935 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9936 match(Set dst (OrI src1 src2)); 9937 format %{ "ORI $dst, $src1, $src2" %} 9938 size(4); 9939 ins_encode %{ 9940 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 9941 %} 9942 ins_pipe(pipe_class_default); 9943 %} 9944 9945 // Register Or Long 9946 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9947 match(Set dst (OrL src1 src2)); 9948 ins_cost(DEFAULT_COST); 9949 9950 size(4); 9951 format %{ "OR $dst, $src1, $src2 \t// long" %} 9952 ins_encode %{ 9953 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9954 %} 9955 ins_pipe(pipe_class_default); 9956 %} 9957 9958 // OrL + ConvL2I. 9959 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9960 match(Set dst (ConvL2I (OrL src1 src2))); 9961 ins_cost(DEFAULT_COST); 9962 9963 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 9964 size(4); 9965 ins_encode %{ 9966 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9967 %} 9968 ins_pipe(pipe_class_default); 9969 %} 9970 9971 // Immediate Or long 9972 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 9973 match(Set dst (OrL src1 con)); 9974 ins_cost(DEFAULT_COST); 9975 9976 format %{ "ORI $dst, $src1, $con \t// long" %} 9977 size(4); 9978 ins_encode %{ 9979 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 9980 %} 9981 ins_pipe(pipe_class_default); 9982 %} 9983 9984 // Xor Instructions 9985 9986 // Register Xor 9987 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9988 match(Set dst (XorI src1 src2)); 9989 format %{ "XOR $dst, $src1, $src2" %} 9990 size(4); 9991 ins_encode %{ 9992 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9993 %} 9994 ins_pipe(pipe_class_default); 9995 %} 9996 9997 // Expand does not work with above instruct. (??) 9998 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9999 // no match-rule 10000 effect(DEF dst, USE src1, USE src2); 10001 format %{ "XOR $dst, $src1, $src2" %} 10002 size(4); 10003 ins_encode %{ 10004 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10005 %} 10006 ins_pipe(pipe_class_default); 10007 %} 10008 10009 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10010 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10011 ins_cost(DEFAULT_COST*3); 10012 10013 expand %{ 10014 // FIXME: we should do this in the ideal world. 10015 iRegIdst tmp1; 10016 iRegIdst tmp2; 10017 xorI_reg_reg(tmp1, src1, src2); 10018 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10019 xorI_reg_reg(dst, tmp1, tmp2); 10020 %} 10021 %} 10022 10023 // Immediate Xor 10024 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10025 match(Set dst (XorI src1 src2)); 10026 format %{ "XORI $dst, $src1, $src2" %} 10027 size(4); 10028 ins_encode %{ 10029 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10030 %} 10031 ins_pipe(pipe_class_default); 10032 %} 10033 10034 // Register Xor Long 10035 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10036 match(Set dst (XorL src1 src2)); 10037 ins_cost(DEFAULT_COST); 10038 10039 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10040 size(4); 10041 ins_encode %{ 10042 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10043 %} 10044 ins_pipe(pipe_class_default); 10045 %} 10046 10047 // XorL + ConvL2I. 10048 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10049 match(Set dst (ConvL2I (XorL src1 src2))); 10050 ins_cost(DEFAULT_COST); 10051 10052 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10053 size(4); 10054 ins_encode %{ 10055 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10056 %} 10057 ins_pipe(pipe_class_default); 10058 %} 10059 10060 // Immediate Xor Long 10061 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10062 match(Set dst (XorL src1 src2)); 10063 ins_cost(DEFAULT_COST); 10064 10065 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10066 size(4); 10067 ins_encode %{ 10068 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10069 %} 10070 ins_pipe(pipe_class_default); 10071 %} 10072 10073 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10074 match(Set dst (XorI src1 src2)); 10075 ins_cost(DEFAULT_COST); 10076 10077 format %{ "NOT $dst, $src1 ($src2)" %} 10078 size(4); 10079 ins_encode %{ 10080 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10081 %} 10082 ins_pipe(pipe_class_default); 10083 %} 10084 10085 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10086 match(Set dst (XorL src1 src2)); 10087 ins_cost(DEFAULT_COST); 10088 10089 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10090 size(4); 10091 ins_encode %{ 10092 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10093 %} 10094 ins_pipe(pipe_class_default); 10095 %} 10096 10097 // And-complement 10098 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10099 match(Set dst (AndI (XorI src1 src2) src3)); 10100 ins_cost(DEFAULT_COST); 10101 10102 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10103 size(4); 10104 ins_encode( enc_andc(dst, src3, src1) ); 10105 ins_pipe(pipe_class_default); 10106 %} 10107 10108 // And-complement 10109 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10110 // no match-rule, false predicate 10111 effect(DEF dst, USE src1, USE src2); 10112 predicate(false); 10113 10114 format %{ "ANDC $dst, $src1, $src2" %} 10115 size(4); 10116 ins_encode %{ 10117 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10118 %} 10119 ins_pipe(pipe_class_default); 10120 %} 10121 10122 //----------Moves between int/long and float/double---------------------------- 10123 // 10124 // The following rules move values from int/long registers/stack-locations 10125 // to float/double registers/stack-locations and vice versa, without doing any 10126 // conversions. These rules are used to implement the bit-conversion methods 10127 // of java.lang.Float etc., e.g. 10128 // int floatToIntBits(float value) 10129 // float intBitsToFloat(int bits) 10130 // 10131 // Notes on the implementation on ppc64: 10132 // For Power7 and earlier, the rules are limited to those which move between a 10133 // register and a stack-location, because we always have to go through memory 10134 // when moving between a float register and an integer register. 10135 // This restriction is removed in Power8 with the introduction of the mtfprd 10136 // and mffprd instructions. 10137 10138 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10139 match(Set dst (MoveL2D src)); 10140 predicate(VM_Version::has_mtfprd()); 10141 10142 format %{ "MTFPRD $dst, $src" %} 10143 size(4); 10144 ins_encode %{ 10145 __ mtfprd($dst$$FloatRegister, $src$$Register); 10146 %} 10147 ins_pipe(pipe_class_default); 10148 %} 10149 10150 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10151 // no match-rule, false predicate 10152 effect(DEF dst, USE src); 10153 predicate(false); 10154 10155 format %{ "MTFPRWA $dst, $src" %} 10156 size(4); 10157 ins_encode %{ 10158 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10159 %} 10160 ins_pipe(pipe_class_default); 10161 %} 10162 10163 //---------- Chain stack slots between similar types -------- 10164 10165 // These are needed so that the rules below can match. 10166 10167 // Load integer from stack slot 10168 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10169 match(Set dst src); 10170 ins_cost(MEMORY_REF_COST); 10171 10172 format %{ "LWZ $dst, $src" %} 10173 size(4); 10174 ins_encode( enc_lwz(dst, src) ); 10175 ins_pipe(pipe_class_memory); 10176 %} 10177 10178 // Store integer to stack slot 10179 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10180 match(Set dst src); 10181 ins_cost(MEMORY_REF_COST); 10182 10183 format %{ "STW $src, $dst \t// stk" %} 10184 size(4); 10185 ins_encode( enc_stw(src, dst) ); // rs=rt 10186 ins_pipe(pipe_class_memory); 10187 %} 10188 10189 // Load long from stack slot 10190 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10191 match(Set dst src); 10192 ins_cost(MEMORY_REF_COST); 10193 10194 format %{ "LD $dst, $src \t// long" %} 10195 size(4); 10196 ins_encode( enc_ld(dst, src) ); 10197 ins_pipe(pipe_class_memory); 10198 %} 10199 10200 // Store long to stack slot 10201 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10202 match(Set dst src); 10203 ins_cost(MEMORY_REF_COST); 10204 10205 format %{ "STD $src, $dst \t// long" %} 10206 size(4); 10207 ins_encode( enc_std(src, dst) ); // rs=rt 10208 ins_pipe(pipe_class_memory); 10209 %} 10210 10211 //----------Moves between int and float 10212 10213 // Move float value from float stack-location to integer register. 10214 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10215 match(Set dst (MoveF2I src)); 10216 ins_cost(MEMORY_REF_COST); 10217 10218 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10219 size(4); 10220 ins_encode( enc_lwz(dst, src) ); 10221 ins_pipe(pipe_class_memory); 10222 %} 10223 10224 // Move float value from float register to integer stack-location. 10225 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10226 match(Set dst (MoveF2I src)); 10227 ins_cost(MEMORY_REF_COST); 10228 10229 format %{ "STFS $src, $dst \t// MoveF2I" %} 10230 size(4); 10231 ins_encode( enc_stfs(src, dst) ); 10232 ins_pipe(pipe_class_memory); 10233 %} 10234 10235 // Move integer value from integer stack-location to float register. 10236 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10237 match(Set dst (MoveI2F src)); 10238 ins_cost(MEMORY_REF_COST); 10239 10240 format %{ "LFS $dst, $src \t// MoveI2F" %} 10241 size(4); 10242 ins_encode %{ 10243 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10244 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10245 %} 10246 ins_pipe(pipe_class_memory); 10247 %} 10248 10249 // Move integer value from integer register to float stack-location. 10250 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10251 match(Set dst (MoveI2F src)); 10252 ins_cost(MEMORY_REF_COST); 10253 10254 format %{ "STW $src, $dst \t// MoveI2F" %} 10255 size(4); 10256 ins_encode( enc_stw(src, dst) ); 10257 ins_pipe(pipe_class_memory); 10258 %} 10259 10260 //----------Moves between long and float 10261 10262 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10263 // no match-rule, false predicate 10264 effect(DEF dst, USE src); 10265 predicate(false); 10266 10267 format %{ "storeD $src, $dst \t// STACK" %} 10268 size(4); 10269 ins_encode( enc_stfd(src, dst) ); 10270 ins_pipe(pipe_class_default); 10271 %} 10272 10273 //----------Moves between long and double 10274 10275 // Move double value from double stack-location to long register. 10276 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10277 match(Set dst (MoveD2L src)); 10278 ins_cost(MEMORY_REF_COST); 10279 size(4); 10280 format %{ "LD $dst, $src \t// MoveD2L" %} 10281 ins_encode( enc_ld(dst, src) ); 10282 ins_pipe(pipe_class_memory); 10283 %} 10284 10285 // Move double value from double register to long stack-location. 10286 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10287 match(Set dst (MoveD2L src)); 10288 effect(DEF dst, USE src); 10289 ins_cost(MEMORY_REF_COST); 10290 10291 format %{ "STFD $src, $dst \t// MoveD2L" %} 10292 size(4); 10293 ins_encode( enc_stfd(src, dst) ); 10294 ins_pipe(pipe_class_memory); 10295 %} 10296 10297 // Move long value from long stack-location to double register. 10298 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10299 match(Set dst (MoveL2D src)); 10300 ins_cost(MEMORY_REF_COST); 10301 10302 format %{ "LFD $dst, $src \t// MoveL2D" %} 10303 size(4); 10304 ins_encode( enc_lfd(dst, src) ); 10305 ins_pipe(pipe_class_memory); 10306 %} 10307 10308 // Move long value from long register to double stack-location. 10309 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10310 match(Set dst (MoveL2D src)); 10311 ins_cost(MEMORY_REF_COST); 10312 10313 format %{ "STD $src, $dst \t// MoveL2D" %} 10314 size(4); 10315 ins_encode( enc_std(src, dst) ); 10316 ins_pipe(pipe_class_memory); 10317 %} 10318 10319 //----------Register Move Instructions----------------------------------------- 10320 10321 // Replicate for Superword 10322 10323 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10324 predicate(false); 10325 effect(DEF dst, USE src); 10326 10327 format %{ "MR $dst, $src \t// replicate " %} 10328 // variable size, 0 or 4. 10329 ins_encode %{ 10330 __ mr_if_needed($dst$$Register, $src$$Register); 10331 %} 10332 ins_pipe(pipe_class_default); 10333 %} 10334 10335 //----------Cast instructions (Java-level type cast)--------------------------- 10336 10337 // Cast Long to Pointer for unsafe natives. 10338 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10339 match(Set dst (CastX2P src)); 10340 10341 format %{ "MR $dst, $src \t// Long->Ptr" %} 10342 // variable size, 0 or 4. 10343 ins_encode %{ 10344 __ mr_if_needed($dst$$Register, $src$$Register); 10345 %} 10346 ins_pipe(pipe_class_default); 10347 %} 10348 10349 // Cast Pointer to Long for unsafe natives. 10350 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10351 match(Set dst (CastP2X src)); 10352 10353 format %{ "MR $dst, $src \t// Ptr->Long" %} 10354 // variable size, 0 or 4. 10355 ins_encode %{ 10356 __ mr_if_needed($dst$$Register, $src$$Register); 10357 %} 10358 ins_pipe(pipe_class_default); 10359 %} 10360 10361 instruct castPP(iRegPdst dst) %{ 10362 match(Set dst (CastPP dst)); 10363 format %{ " -- \t// castPP of $dst" %} 10364 size(0); 10365 ins_encode( /*empty*/ ); 10366 ins_pipe(pipe_class_default); 10367 %} 10368 10369 instruct castII(iRegIdst dst) %{ 10370 match(Set dst (CastII dst)); 10371 format %{ " -- \t// castII of $dst" %} 10372 size(0); 10373 ins_encode( /*empty*/ ); 10374 ins_pipe(pipe_class_default); 10375 %} 10376 10377 instruct castLL(iRegLdst dst) %{ 10378 match(Set dst (CastLL dst)); 10379 format %{ " -- \t// castLL of $dst" %} 10380 size(0); 10381 ins_encode( /*empty*/ ); 10382 ins_pipe(pipe_class_default); 10383 %} 10384 10385 instruct castFF(regF dst) %{ 10386 match(Set dst (CastFF dst)); 10387 format %{ " -- \t// castFF of $dst" %} 10388 size(0); 10389 ins_encode( /*empty*/ ); 10390 ins_pipe(pipe_class_default); 10391 %} 10392 10393 instruct castDD(regD dst) %{ 10394 match(Set dst (CastDD dst)); 10395 format %{ " -- \t// castDD of $dst" %} 10396 size(0); 10397 ins_encode( /*empty*/ ); 10398 ins_pipe(pipe_class_default); 10399 %} 10400 10401 instruct castVV8(iRegLdst dst) %{ 10402 match(Set dst (CastVV dst)); 10403 format %{ " -- \t// castVV of $dst" %} 10404 size(0); 10405 ins_encode( /*empty*/ ); 10406 ins_pipe(pipe_class_default); 10407 %} 10408 10409 instruct castVV16(vecX dst) %{ 10410 match(Set dst (CastVV dst)); 10411 format %{ " -- \t// castVV of $dst" %} 10412 size(0); 10413 ins_encode( /*empty*/ ); 10414 ins_pipe(pipe_class_default); 10415 %} 10416 10417 instruct checkCastPP(iRegPdst dst) %{ 10418 match(Set dst (CheckCastPP dst)); 10419 format %{ " -- \t// checkcastPP of $dst" %} 10420 size(0); 10421 ins_encode( /*empty*/ ); 10422 ins_pipe(pipe_class_default); 10423 %} 10424 10425 //----------Convert instructions----------------------------------------------- 10426 10427 // Convert to boolean. 10428 10429 // int_to_bool(src) : { 1 if src != 0 10430 // { 0 else 10431 // 10432 // strategy: 10433 // 1) Count leading zeros of 32 bit-value src, 10434 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10435 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10436 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10437 10438 // convI2Bool 10439 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10440 match(Set dst (Conv2B src)); 10441 predicate(UseCountLeadingZerosInstructionsPPC64); 10442 ins_cost(DEFAULT_COST); 10443 10444 expand %{ 10445 immI shiftAmount %{ 0x5 %} 10446 uimmI16 mask %{ 0x1 %} 10447 iRegIdst tmp1; 10448 iRegIdst tmp2; 10449 countLeadingZerosI(tmp1, src); 10450 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10451 xorI_reg_uimm16(dst, tmp2, mask); 10452 %} 10453 %} 10454 10455 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10456 match(Set dst (Conv2B src)); 10457 effect(TEMP crx); 10458 predicate(!UseCountLeadingZerosInstructionsPPC64); 10459 ins_cost(DEFAULT_COST); 10460 10461 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10462 "LI $dst, #0\n\t" 10463 "BEQ $crx, done\n\t" 10464 "LI $dst, #1\n" 10465 "done:" %} 10466 size(16); 10467 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10468 ins_pipe(pipe_class_compare); 10469 %} 10470 10471 // ConvI2B + XorI 10472 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10473 match(Set dst (XorI (Conv2B src) mask)); 10474 predicate(UseCountLeadingZerosInstructionsPPC64); 10475 ins_cost(DEFAULT_COST); 10476 10477 expand %{ 10478 immI shiftAmount %{ 0x5 %} 10479 iRegIdst tmp1; 10480 countLeadingZerosI(tmp1, src); 10481 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10482 %} 10483 %} 10484 10485 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10486 match(Set dst (XorI (Conv2B src) mask)); 10487 effect(TEMP crx); 10488 predicate(!UseCountLeadingZerosInstructionsPPC64); 10489 ins_cost(DEFAULT_COST); 10490 10491 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10492 "LI $dst, #1\n\t" 10493 "BEQ $crx, done\n\t" 10494 "LI $dst, #0\n" 10495 "done:" %} 10496 size(16); 10497 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10498 ins_pipe(pipe_class_compare); 10499 %} 10500 10501 // AndI 0b0..010..0 + ConvI2B 10502 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10503 match(Set dst (Conv2B (AndI src mask))); 10504 predicate(UseRotateAndMaskInstructionsPPC64); 10505 ins_cost(DEFAULT_COST); 10506 10507 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10508 size(4); 10509 ins_encode %{ 10510 __ rlwinm($dst$$Register, $src$$Register, 32 - log2i_exact((juint)($mask$$constant)), 31, 31); 10511 %} 10512 ins_pipe(pipe_class_default); 10513 %} 10514 10515 // Convert pointer to boolean. 10516 // 10517 // ptr_to_bool(src) : { 1 if src != 0 10518 // { 0 else 10519 // 10520 // strategy: 10521 // 1) Count leading zeros of 64 bit-value src, 10522 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10523 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10524 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10525 10526 // ConvP2B 10527 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10528 match(Set dst (Conv2B src)); 10529 predicate(UseCountLeadingZerosInstructionsPPC64); 10530 ins_cost(DEFAULT_COST); 10531 10532 expand %{ 10533 immI shiftAmount %{ 0x6 %} 10534 uimmI16 mask %{ 0x1 %} 10535 iRegIdst tmp1; 10536 iRegIdst tmp2; 10537 countLeadingZerosP(tmp1, src); 10538 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10539 xorI_reg_uimm16(dst, tmp2, mask); 10540 %} 10541 %} 10542 10543 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10544 match(Set dst (Conv2B src)); 10545 effect(TEMP crx); 10546 predicate(!UseCountLeadingZerosInstructionsPPC64); 10547 ins_cost(DEFAULT_COST); 10548 10549 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10550 "LI $dst, #0\n\t" 10551 "BEQ $crx, done\n\t" 10552 "LI $dst, #1\n" 10553 "done:" %} 10554 size(16); 10555 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10556 ins_pipe(pipe_class_compare); 10557 %} 10558 10559 // ConvP2B + XorI 10560 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10561 match(Set dst (XorI (Conv2B src) mask)); 10562 predicate(UseCountLeadingZerosInstructionsPPC64); 10563 ins_cost(DEFAULT_COST); 10564 10565 expand %{ 10566 immI shiftAmount %{ 0x6 %} 10567 iRegIdst tmp1; 10568 countLeadingZerosP(tmp1, src); 10569 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10570 %} 10571 %} 10572 10573 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10574 match(Set dst (XorI (Conv2B src) mask)); 10575 effect(TEMP crx); 10576 predicate(!UseCountLeadingZerosInstructionsPPC64); 10577 ins_cost(DEFAULT_COST); 10578 10579 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10580 "LI $dst, #1\n\t" 10581 "BEQ $crx, done\n\t" 10582 "LI $dst, #0\n" 10583 "done:" %} 10584 size(16); 10585 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10586 ins_pipe(pipe_class_compare); 10587 %} 10588 10589 // if src1 < src2, return -1 else return 0 10590 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10591 match(Set dst (CmpLTMask src1 src2)); 10592 ins_cost(DEFAULT_COST*4); 10593 10594 expand %{ 10595 iRegLdst src1s; 10596 iRegLdst src2s; 10597 iRegLdst diff; 10598 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10599 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10600 subL_reg_reg(diff, src1s, src2s); 10601 // Need to consider >=33 bit result, therefore we need signmaskL. 10602 signmask64I_regL(dst, diff); 10603 %} 10604 %} 10605 10606 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 10607 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 10608 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 10609 size(4); 10610 ins_encode %{ 10611 __ srawi($dst$$Register, $src1$$Register, 0x1f); 10612 %} 10613 ins_pipe(pipe_class_default); 10614 %} 10615 10616 //----------Arithmetic Conversion Instructions--------------------------------- 10617 10618 // Convert to Byte -- nop 10619 // Convert to Short -- nop 10620 10621 // Convert to Int 10622 10623 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 10624 match(Set dst (RShiftI (LShiftI src amount) amount)); 10625 format %{ "EXTSB $dst, $src \t// byte->int" %} 10626 size(4); 10627 ins_encode %{ 10628 __ extsb($dst$$Register, $src$$Register); 10629 %} 10630 ins_pipe(pipe_class_default); 10631 %} 10632 10633 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 10634 effect(DEF dst, USE src); 10635 10636 size(4); 10637 ins_encode %{ 10638 __ extsh($dst$$Register, $src$$Register); 10639 %} 10640 ins_pipe(pipe_class_default); 10641 %} 10642 10643 // LShiftI 16 + RShiftI 16 converts short to int. 10644 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 10645 match(Set dst (RShiftI (LShiftI src amount) amount)); 10646 format %{ "EXTSH $dst, $src \t// short->int" %} 10647 size(4); 10648 ins_encode %{ 10649 __ extsh($dst$$Register, $src$$Register); 10650 %} 10651 ins_pipe(pipe_class_default); 10652 %} 10653 10654 // ConvL2I + ConvI2L: Sign extend int in long register. 10655 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 10656 match(Set dst (ConvI2L (ConvL2I src))); 10657 10658 format %{ "EXTSW $dst, $src \t// long->long" %} 10659 size(4); 10660 ins_encode %{ 10661 __ extsw($dst$$Register, $src$$Register); 10662 %} 10663 ins_pipe(pipe_class_default); 10664 %} 10665 10666 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 10667 match(Set dst (ConvL2I src)); 10668 format %{ "MR $dst, $src \t// long->int" %} 10669 // variable size, 0 or 4 10670 ins_encode %{ 10671 __ mr_if_needed($dst$$Register, $src$$Register); 10672 %} 10673 ins_pipe(pipe_class_default); 10674 %} 10675 10676 instruct convD2IRaw_regD(regD dst, regD src) %{ 10677 // no match-rule, false predicate 10678 effect(DEF dst, USE src); 10679 predicate(false); 10680 10681 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 10682 size(4); 10683 ins_encode %{ 10684 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10685 %} 10686 ins_pipe(pipe_class_default); 10687 %} 10688 10689 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 10690 // no match-rule, false predicate 10691 effect(DEF dst, USE crx, USE src); 10692 predicate(false); 10693 10694 ins_variable_size_depending_on_alignment(true); 10695 10696 format %{ "cmovI $crx, $dst, $src" %} 10697 // Worst case is branch + move + stop, no stop without scheduler. 10698 size(8); 10699 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10700 ins_pipe(pipe_class_default); 10701 %} 10702 10703 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 10704 // no match-rule, false predicate 10705 effect(DEF dst, USE crx, USE src); 10706 predicate(false); 10707 10708 ins_variable_size_depending_on_alignment(true); 10709 10710 format %{ "cmovI $crx, $dst, $src" %} 10711 // Worst case is branch + move + stop, no stop without scheduler. 10712 size(8); 10713 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 10714 ins_pipe(pipe_class_default); 10715 %} 10716 10717 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10718 // no match-rule, false predicate 10719 effect(DEF dst, USE crx, USE mem); 10720 predicate(false); 10721 10722 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 10723 postalloc_expand %{ 10724 // 10725 // replaces 10726 // 10727 // region dst crx mem 10728 // \ | | / 10729 // dst=cmovI_bso_stackSlotL_conLvalue0 10730 // 10731 // with 10732 // 10733 // region dst 10734 // \ / 10735 // dst=loadConI16(0) 10736 // | 10737 // ^ region dst crx mem 10738 // | \ | | / 10739 // dst=cmovI_bso_stackSlotL 10740 // 10741 10742 // Create new nodes. 10743 MachNode *m1 = new loadConI16Node(); 10744 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 10745 10746 // inputs for new nodes 10747 m1->add_req(n_region); 10748 m2->add_req(n_region, n_crx, n_mem); 10749 10750 // precedences for new nodes 10751 m2->add_prec(m1); 10752 10753 // operands for new nodes 10754 m1->_opnds[0] = op_dst; 10755 m1->_opnds[1] = new immI16Oper(0); 10756 10757 m2->_opnds[0] = op_dst; 10758 m2->_opnds[1] = op_crx; 10759 m2->_opnds[2] = op_mem; 10760 10761 // registers for new nodes 10762 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10763 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10764 10765 // Insert new nodes. 10766 nodes->push(m1); 10767 nodes->push(m2); 10768 %} 10769 %} 10770 10771 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 10772 // no match-rule, false predicate 10773 effect(DEF dst, USE crx, USE src); 10774 predicate(false); 10775 10776 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 10777 postalloc_expand %{ 10778 // 10779 // replaces 10780 // 10781 // region dst crx src 10782 // \ | | / 10783 // dst=cmovI_bso_reg_conLvalue0 10784 // 10785 // with 10786 // 10787 // region dst 10788 // \ / 10789 // dst=loadConI16(0) 10790 // | 10791 // ^ region dst crx src 10792 // | \ | | / 10793 // dst=cmovI_bso_reg 10794 // 10795 10796 // Create new nodes. 10797 MachNode *m1 = new loadConI16Node(); 10798 MachNode *m2 = new cmovI_bso_regNode(); 10799 10800 // inputs for new nodes 10801 m1->add_req(n_region); 10802 m2->add_req(n_region, n_crx, n_src); 10803 10804 // precedences for new nodes 10805 m2->add_prec(m1); 10806 10807 // operands for new nodes 10808 m1->_opnds[0] = op_dst; 10809 m1->_opnds[1] = new immI16Oper(0); 10810 10811 m2->_opnds[0] = op_dst; 10812 m2->_opnds[1] = op_crx; 10813 m2->_opnds[2] = op_src; 10814 10815 // registers for new nodes 10816 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10817 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10818 10819 // Insert new nodes. 10820 nodes->push(m1); 10821 nodes->push(m2); 10822 %} 10823 %} 10824 10825 // Double to Int conversion, NaN is mapped to 0. 10826 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 10827 match(Set dst (ConvD2I src)); 10828 predicate(!VM_Version::has_mtfprd()); 10829 ins_cost(DEFAULT_COST); 10830 10831 expand %{ 10832 regD tmpD; 10833 stackSlotL tmpS; 10834 flagsReg crx; 10835 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10836 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10837 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10838 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10839 %} 10840 %} 10841 10842 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 10843 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 10844 match(Set dst (ConvD2I src)); 10845 predicate(VM_Version::has_mtfprd()); 10846 ins_cost(DEFAULT_COST); 10847 10848 expand %{ 10849 regD tmpD; 10850 flagsReg crx; 10851 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10852 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10853 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 10854 %} 10855 %} 10856 10857 instruct convF2IRaw_regF(regF dst, regF src) %{ 10858 // no match-rule, false predicate 10859 effect(DEF dst, USE src); 10860 predicate(false); 10861 10862 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 10863 size(4); 10864 ins_encode %{ 10865 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10866 %} 10867 ins_pipe(pipe_class_default); 10868 %} 10869 10870 // Float to Int conversion, NaN is mapped to 0. 10871 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 10872 match(Set dst (ConvF2I src)); 10873 predicate(!VM_Version::has_mtfprd()); 10874 ins_cost(DEFAULT_COST); 10875 10876 expand %{ 10877 regF tmpF; 10878 stackSlotL tmpS; 10879 flagsReg crx; 10880 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10881 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10882 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10883 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10884 %} 10885 %} 10886 10887 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 10888 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 10889 match(Set dst (ConvF2I src)); 10890 predicate(VM_Version::has_mtfprd()); 10891 ins_cost(DEFAULT_COST); 10892 10893 expand %{ 10894 regF tmpF; 10895 flagsReg crx; 10896 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10897 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10898 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 10899 %} 10900 %} 10901 10902 // Convert to Long 10903 10904 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 10905 match(Set dst (ConvI2L src)); 10906 format %{ "EXTSW $dst, $src \t// int->long" %} 10907 size(4); 10908 ins_encode %{ 10909 __ extsw($dst$$Register, $src$$Register); 10910 %} 10911 ins_pipe(pipe_class_default); 10912 %} 10913 10914 // Zero-extend: convert unsigned int to long (convUI2L). 10915 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 10916 match(Set dst (AndL (ConvI2L src) mask)); 10917 ins_cost(DEFAULT_COST); 10918 10919 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10920 size(4); 10921 ins_encode %{ 10922 __ clrldi($dst$$Register, $src$$Register, 32); 10923 %} 10924 ins_pipe(pipe_class_default); 10925 %} 10926 10927 // Zero-extend: convert unsigned int to long in long register. 10928 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 10929 match(Set dst (AndL src mask)); 10930 ins_cost(DEFAULT_COST); 10931 10932 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10933 size(4); 10934 ins_encode %{ 10935 __ clrldi($dst$$Register, $src$$Register, 32); 10936 %} 10937 ins_pipe(pipe_class_default); 10938 %} 10939 10940 instruct convF2LRaw_regF(regF dst, regF src) %{ 10941 // no match-rule, false predicate 10942 effect(DEF dst, USE src); 10943 predicate(false); 10944 10945 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 10946 size(4); 10947 ins_encode %{ 10948 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10949 %} 10950 ins_pipe(pipe_class_default); 10951 %} 10952 10953 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 10954 // no match-rule, false predicate 10955 effect(DEF dst, USE crx, USE src); 10956 predicate(false); 10957 10958 ins_variable_size_depending_on_alignment(true); 10959 10960 format %{ "cmovL $crx, $dst, $src" %} 10961 // Worst case is branch + move + stop, no stop without scheduler. 10962 size(8); 10963 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10964 ins_pipe(pipe_class_default); 10965 %} 10966 10967 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 10968 // no match-rule, false predicate 10969 effect(DEF dst, USE crx, USE src); 10970 predicate(false); 10971 10972 ins_variable_size_depending_on_alignment(true); 10973 10974 format %{ "cmovL $crx, $dst, $src" %} 10975 // Worst case is branch + move + stop, no stop without scheduler. 10976 size(8); 10977 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 10978 ins_pipe(pipe_class_default); 10979 %} 10980 10981 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10982 // no match-rule, false predicate 10983 effect(DEF dst, USE crx, USE mem); 10984 predicate(false); 10985 10986 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 10987 postalloc_expand %{ 10988 // 10989 // replaces 10990 // 10991 // region dst crx mem 10992 // \ | | / 10993 // dst=cmovL_bso_stackSlotL_conLvalue0 10994 // 10995 // with 10996 // 10997 // region dst 10998 // \ / 10999 // dst=loadConL16(0) 11000 // | 11001 // ^ region dst crx mem 11002 // | \ | | / 11003 // dst=cmovL_bso_stackSlotL 11004 // 11005 11006 // Create new nodes. 11007 MachNode *m1 = new loadConL16Node(); 11008 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11009 11010 // inputs for new nodes 11011 m1->add_req(n_region); 11012 m2->add_req(n_region, n_crx, n_mem); 11013 m2->add_prec(m1); 11014 11015 // operands for new nodes 11016 m1->_opnds[0] = op_dst; 11017 m1->_opnds[1] = new immL16Oper(0); 11018 m2->_opnds[0] = op_dst; 11019 m2->_opnds[1] = op_crx; 11020 m2->_opnds[2] = op_mem; 11021 11022 // registers for new nodes 11023 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11024 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11025 11026 // Insert new nodes. 11027 nodes->push(m1); 11028 nodes->push(m2); 11029 %} 11030 %} 11031 11032 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11033 // no match-rule, false predicate 11034 effect(DEF dst, USE crx, USE src); 11035 predicate(false); 11036 11037 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11038 postalloc_expand %{ 11039 // 11040 // replaces 11041 // 11042 // region dst crx src 11043 // \ | | / 11044 // dst=cmovL_bso_reg_conLvalue0 11045 // 11046 // with 11047 // 11048 // region dst 11049 // \ / 11050 // dst=loadConL16(0) 11051 // | 11052 // ^ region dst crx src 11053 // | \ | | / 11054 // dst=cmovL_bso_reg 11055 // 11056 11057 // Create new nodes. 11058 MachNode *m1 = new loadConL16Node(); 11059 MachNode *m2 = new cmovL_bso_regNode(); 11060 11061 // inputs for new nodes 11062 m1->add_req(n_region); 11063 m2->add_req(n_region, n_crx, n_src); 11064 m2->add_prec(m1); 11065 11066 // operands for new nodes 11067 m1->_opnds[0] = op_dst; 11068 m1->_opnds[1] = new immL16Oper(0); 11069 m2->_opnds[0] = op_dst; 11070 m2->_opnds[1] = op_crx; 11071 m2->_opnds[2] = op_src; 11072 11073 // registers for new nodes 11074 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11075 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11076 11077 // Insert new nodes. 11078 nodes->push(m1); 11079 nodes->push(m2); 11080 %} 11081 %} 11082 11083 // Float to Long conversion, NaN is mapped to 0. 11084 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11085 match(Set dst (ConvF2L src)); 11086 predicate(!VM_Version::has_mtfprd()); 11087 ins_cost(DEFAULT_COST); 11088 11089 expand %{ 11090 regF tmpF; 11091 stackSlotL tmpS; 11092 flagsReg crx; 11093 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11094 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11095 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11096 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11097 %} 11098 %} 11099 11100 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11101 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11102 match(Set dst (ConvF2L src)); 11103 predicate(VM_Version::has_mtfprd()); 11104 ins_cost(DEFAULT_COST); 11105 11106 expand %{ 11107 regF tmpF; 11108 flagsReg crx; 11109 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11110 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11111 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11112 %} 11113 %} 11114 11115 instruct convD2LRaw_regD(regD dst, regD src) %{ 11116 // no match-rule, false predicate 11117 effect(DEF dst, USE src); 11118 predicate(false); 11119 11120 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11121 size(4); 11122 ins_encode %{ 11123 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11124 %} 11125 ins_pipe(pipe_class_default); 11126 %} 11127 11128 // Double to Long conversion, NaN is mapped to 0. 11129 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11130 match(Set dst (ConvD2L src)); 11131 predicate(!VM_Version::has_mtfprd()); 11132 ins_cost(DEFAULT_COST); 11133 11134 expand %{ 11135 regD tmpD; 11136 stackSlotL tmpS; 11137 flagsReg crx; 11138 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11139 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11140 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11141 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11142 %} 11143 %} 11144 11145 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11146 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11147 match(Set dst (ConvD2L src)); 11148 predicate(VM_Version::has_mtfprd()); 11149 ins_cost(DEFAULT_COST); 11150 11151 expand %{ 11152 regD tmpD; 11153 flagsReg crx; 11154 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11155 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11156 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11157 %} 11158 %} 11159 11160 // Convert to Float 11161 11162 // Placed here as needed in expand. 11163 instruct convL2DRaw_regD(regD dst, regD src) %{ 11164 // no match-rule, false predicate 11165 effect(DEF dst, USE src); 11166 predicate(false); 11167 11168 format %{ "FCFID $dst, $src \t// convL2D" %} 11169 size(4); 11170 ins_encode %{ 11171 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11172 %} 11173 ins_pipe(pipe_class_default); 11174 %} 11175 11176 // Placed here as needed in expand. 11177 instruct convD2F_reg(regF dst, regD src) %{ 11178 match(Set dst (ConvD2F src)); 11179 format %{ "FRSP $dst, $src \t// convD2F" %} 11180 size(4); 11181 ins_encode %{ 11182 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11183 %} 11184 ins_pipe(pipe_class_default); 11185 %} 11186 11187 // Integer to Float conversion. 11188 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11189 match(Set dst (ConvI2F src)); 11190 predicate(!VM_Version::has_fcfids()); 11191 ins_cost(DEFAULT_COST); 11192 11193 expand %{ 11194 iRegLdst tmpL; 11195 stackSlotL tmpS; 11196 regD tmpD; 11197 regD tmpD2; 11198 convI2L_reg(tmpL, src); // Sign-extension int to long. 11199 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11200 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11201 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11202 convD2F_reg(dst, tmpD2); // Convert double to float. 11203 %} 11204 %} 11205 11206 instruct convL2FRaw_regF(regF dst, regD src) %{ 11207 // no match-rule, false predicate 11208 effect(DEF dst, USE src); 11209 predicate(false); 11210 11211 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11212 size(4); 11213 ins_encode %{ 11214 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11215 %} 11216 ins_pipe(pipe_class_default); 11217 %} 11218 11219 // Integer to Float conversion. Special version for Power7. 11220 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11221 match(Set dst (ConvI2F src)); 11222 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11223 ins_cost(DEFAULT_COST); 11224 11225 expand %{ 11226 iRegLdst tmpL; 11227 stackSlotL tmpS; 11228 regD tmpD; 11229 convI2L_reg(tmpL, src); // Sign-extension int to long. 11230 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11231 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11232 convL2FRaw_regF(dst, tmpD); // Convert to float. 11233 %} 11234 %} 11235 11236 // Integer to Float conversion. Special version for Power8. 11237 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11238 match(Set dst (ConvI2F src)); 11239 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11240 ins_cost(DEFAULT_COST); 11241 11242 expand %{ 11243 regD tmpD; 11244 moveI2D_reg(tmpD, src); 11245 convL2FRaw_regF(dst, tmpD); // Convert to float. 11246 %} 11247 %} 11248 11249 // L2F to avoid runtime call. 11250 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11251 match(Set dst (ConvL2F src)); 11252 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11253 ins_cost(DEFAULT_COST); 11254 11255 expand %{ 11256 stackSlotL tmpS; 11257 regD tmpD; 11258 regL_to_stkL(tmpS, src); // Store long to stack. 11259 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11260 convL2FRaw_regF(dst, tmpD); // Convert to float. 11261 %} 11262 %} 11263 11264 // L2F to avoid runtime call. Special version for Power8. 11265 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11266 match(Set dst (ConvL2F src)); 11267 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11268 ins_cost(DEFAULT_COST); 11269 11270 expand %{ 11271 regD tmpD; 11272 moveL2D_reg(tmpD, src); 11273 convL2FRaw_regF(dst, tmpD); // Convert to float. 11274 %} 11275 %} 11276 11277 // Moved up as used in expand. 11278 //instruct convD2F_reg(regF dst, regD src) %{%} 11279 11280 // Convert to Double 11281 11282 // Integer to Double conversion. 11283 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11284 match(Set dst (ConvI2D src)); 11285 predicate(!VM_Version::has_mtfprd()); 11286 ins_cost(DEFAULT_COST); 11287 11288 expand %{ 11289 iRegLdst tmpL; 11290 stackSlotL tmpS; 11291 regD tmpD; 11292 convI2L_reg(tmpL, src); // Sign-extension int to long. 11293 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11294 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11295 convL2DRaw_regD(dst, tmpD); // Convert to double. 11296 %} 11297 %} 11298 11299 // Integer to Double conversion. Special version for Power8. 11300 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11301 match(Set dst (ConvI2D src)); 11302 predicate(VM_Version::has_mtfprd()); 11303 ins_cost(DEFAULT_COST); 11304 11305 expand %{ 11306 regD tmpD; 11307 moveI2D_reg(tmpD, src); 11308 convL2DRaw_regD(dst, tmpD); // Convert to double. 11309 %} 11310 %} 11311 11312 // Long to Double conversion 11313 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11314 match(Set dst (ConvL2D src)); 11315 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11316 11317 expand %{ 11318 regD tmpD; 11319 moveL2D_stack_reg(tmpD, src); 11320 convL2DRaw_regD(dst, tmpD); 11321 %} 11322 %} 11323 11324 // Long to Double conversion. Special version for Power8. 11325 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11326 match(Set dst (ConvL2D src)); 11327 predicate(VM_Version::has_mtfprd()); 11328 ins_cost(DEFAULT_COST); 11329 11330 expand %{ 11331 regD tmpD; 11332 moveL2D_reg(tmpD, src); 11333 convL2DRaw_regD(dst, tmpD); // Convert to double. 11334 %} 11335 %} 11336 11337 instruct convF2D_reg(regD dst, regF src) %{ 11338 match(Set dst (ConvF2D src)); 11339 format %{ "FMR $dst, $src \t// float->double" %} 11340 // variable size, 0 or 4 11341 ins_encode %{ 11342 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11343 %} 11344 ins_pipe(pipe_class_default); 11345 %} 11346 11347 //----------Control Flow Instructions------------------------------------------ 11348 // Compare Instructions 11349 11350 // Compare Integers 11351 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11352 match(Set crx (CmpI src1 src2)); 11353 size(4); 11354 format %{ "CMPW $crx, $src1, $src2" %} 11355 ins_encode %{ 11356 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11357 %} 11358 ins_pipe(pipe_class_compare); 11359 %} 11360 11361 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11362 match(Set crx (CmpI src1 src2)); 11363 format %{ "CMPWI $crx, $src1, $src2" %} 11364 size(4); 11365 ins_encode %{ 11366 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11367 %} 11368 ins_pipe(pipe_class_compare); 11369 %} 11370 11371 // (src1 & src2) == 0? 11372 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11373 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11374 // r0 is killed 11375 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11376 size(4); 11377 ins_encode %{ 11378 __ andi_(R0, $src1$$Register, $src2$$constant); 11379 %} 11380 ins_pipe(pipe_class_compare); 11381 %} 11382 11383 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11384 match(Set crx (CmpL src1 src2)); 11385 format %{ "CMPD $crx, $src1, $src2" %} 11386 size(4); 11387 ins_encode %{ 11388 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11389 %} 11390 ins_pipe(pipe_class_compare); 11391 %} 11392 11393 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11394 match(Set crx (CmpL src1 src2)); 11395 format %{ "CMPDI $crx, $src1, $src2" %} 11396 size(4); 11397 ins_encode %{ 11398 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11399 %} 11400 ins_pipe(pipe_class_compare); 11401 %} 11402 11403 // Added CmpUL for LoopPredicate. 11404 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11405 match(Set crx (CmpUL src1 src2)); 11406 format %{ "CMPLD $crx, $src1, $src2" %} 11407 size(4); 11408 ins_encode %{ 11409 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11410 %} 11411 ins_pipe(pipe_class_compare); 11412 %} 11413 11414 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11415 match(Set crx (CmpUL src1 src2)); 11416 format %{ "CMPLDI $crx, $src1, $src2" %} 11417 size(4); 11418 ins_encode %{ 11419 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11420 %} 11421 ins_pipe(pipe_class_compare); 11422 %} 11423 11424 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11425 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11426 // r0 is killed 11427 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11428 size(4); 11429 ins_encode %{ 11430 __ and_(R0, $src1$$Register, $src2$$Register); 11431 %} 11432 ins_pipe(pipe_class_compare); 11433 %} 11434 11435 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11436 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11437 // r0 is killed 11438 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11439 size(4); 11440 ins_encode %{ 11441 __ andi_(R0, $src1$$Register, $src2$$constant); 11442 %} 11443 ins_pipe(pipe_class_compare); 11444 %} 11445 11446 // Manifest a CmpL3 result in an integer register. 11447 instruct cmpL3_reg_reg(iRegIdst dst, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 11448 match(Set dst (CmpL3 src1 src2)); 11449 effect(KILL cr0); 11450 ins_cost(DEFAULT_COST * 5); 11451 size((VM_Version::has_brw() ? 16 : 20)); 11452 11453 format %{ "cmpL3_reg_reg $dst, $src1, $src2" %} 11454 11455 ins_encode %{ 11456 __ cmpd(CCR0, $src1$$Register, $src2$$Register); 11457 __ set_cmp3($dst$$Register); 11458 %} 11459 ins_pipe(pipe_class_default); 11460 %} 11461 11462 // Implicit range checks. 11463 // A range check in the ideal world has one of the following shapes: 11464 // - (If le (CmpU length index)), (IfTrue throw exception) 11465 // - (If lt (CmpU index length)), (IfFalse throw exception) 11466 // 11467 // Match range check 'If le (CmpU length index)'. 11468 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11469 match(If cmp (CmpU src_length index)); 11470 effect(USE labl); 11471 predicate(TrapBasedRangeChecks && 11472 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11473 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11474 (Matcher::branches_to_uncommon_trap(_leaf))); 11475 11476 ins_is_TrapBasedCheckNode(true); 11477 11478 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11479 size(4); 11480 ins_encode %{ 11481 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11482 __ trap_range_check_le($src_length$$Register, $index$$constant); 11483 } else { 11484 // Both successors are uncommon traps, probability is 0. 11485 // Node got flipped during fixup flow. 11486 assert($cmp$$cmpcode == 0x9, "must be greater"); 11487 __ trap_range_check_g($src_length$$Register, $index$$constant); 11488 } 11489 %} 11490 ins_pipe(pipe_class_trap); 11491 %} 11492 11493 // Match range check 'If lt (CmpU index length)'. 11494 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11495 match(If cmp (CmpU src_index src_length)); 11496 effect(USE labl); 11497 predicate(TrapBasedRangeChecks && 11498 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11499 _leaf->as_If()->_prob >= PROB_ALWAYS && 11500 (Matcher::branches_to_uncommon_trap(_leaf))); 11501 11502 ins_is_TrapBasedCheckNode(true); 11503 11504 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 11505 size(4); 11506 ins_encode %{ 11507 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11508 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 11509 } else { 11510 // Both successors are uncommon traps, probability is 0. 11511 // Node got flipped during fixup flow. 11512 assert($cmp$$cmpcode == 0x8, "must be less"); 11513 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 11514 } 11515 %} 11516 ins_pipe(pipe_class_trap); 11517 %} 11518 11519 // Match range check 'If lt (CmpU index length)'. 11520 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 11521 match(If cmp (CmpU src_index length)); 11522 effect(USE labl); 11523 predicate(TrapBasedRangeChecks && 11524 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11525 _leaf->as_If()->_prob >= PROB_ALWAYS && 11526 (Matcher::branches_to_uncommon_trap(_leaf))); 11527 11528 ins_is_TrapBasedCheckNode(true); 11529 11530 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 11531 size(4); 11532 ins_encode %{ 11533 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11534 __ trap_range_check_ge($src_index$$Register, $length$$constant); 11535 } else { 11536 // Both successors are uncommon traps, probability is 0. 11537 // Node got flipped during fixup flow. 11538 assert($cmp$$cmpcode == 0x8, "must be less"); 11539 __ trap_range_check_l($src_index$$Register, $length$$constant); 11540 } 11541 %} 11542 ins_pipe(pipe_class_trap); 11543 %} 11544 11545 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11546 match(Set crx (CmpU src1 src2)); 11547 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 11548 size(4); 11549 ins_encode %{ 11550 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11551 %} 11552 ins_pipe(pipe_class_compare); 11553 %} 11554 11555 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 11556 match(Set crx (CmpU src1 src2)); 11557 size(4); 11558 format %{ "CMPLWI $crx, $src1, $src2" %} 11559 ins_encode %{ 11560 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11561 %} 11562 ins_pipe(pipe_class_compare); 11563 %} 11564 11565 // Implicit zero checks (more implicit null checks). 11566 // No constant pool entries required. 11567 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 11568 match(If cmp (CmpN value zero)); 11569 effect(USE labl); 11570 predicate(TrapBasedNullChecks && 11571 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11572 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11573 Matcher::branches_to_uncommon_trap(_leaf)); 11574 ins_cost(1); 11575 11576 ins_is_TrapBasedCheckNode(true); 11577 11578 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 11579 size(4); 11580 ins_encode %{ 11581 if ($cmp$$cmpcode == 0xA) { 11582 __ trap_null_check($value$$Register); 11583 } else { 11584 // Both successors are uncommon traps, probability is 0. 11585 // Node got flipped during fixup flow. 11586 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11587 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11588 } 11589 %} 11590 ins_pipe(pipe_class_trap); 11591 %} 11592 11593 // Compare narrow oops. 11594 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 11595 match(Set crx (CmpN src1 src2)); 11596 11597 size(4); 11598 ins_cost(2); 11599 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 11600 ins_encode %{ 11601 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11602 %} 11603 ins_pipe(pipe_class_compare); 11604 %} 11605 11606 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 11607 match(Set crx (CmpN src1 src2)); 11608 // Make this more expensive than zeroCheckN_iReg_imm0. 11609 ins_cost(2); 11610 11611 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 11612 size(4); 11613 ins_encode %{ 11614 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11615 %} 11616 ins_pipe(pipe_class_compare); 11617 %} 11618 11619 // Implicit zero checks (more implicit null checks). 11620 // No constant pool entries required. 11621 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 11622 match(If cmp (CmpP value zero)); 11623 effect(USE labl); 11624 predicate(TrapBasedNullChecks && 11625 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11626 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11627 Matcher::branches_to_uncommon_trap(_leaf)); 11628 ins_cost(1); // Should not be cheaper than zeroCheckN. 11629 11630 ins_is_TrapBasedCheckNode(true); 11631 11632 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 11633 size(4); 11634 ins_encode %{ 11635 if ($cmp$$cmpcode == 0xA) { 11636 __ trap_null_check($value$$Register); 11637 } else { 11638 // Both successors are uncommon traps, probability is 0. 11639 // Node got flipped during fixup flow. 11640 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11641 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11642 } 11643 %} 11644 ins_pipe(pipe_class_trap); 11645 %} 11646 11647 // Compare Pointers 11648 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 11649 match(Set crx (CmpP src1 src2)); 11650 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 11651 size(4); 11652 ins_encode %{ 11653 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11654 %} 11655 ins_pipe(pipe_class_compare); 11656 %} 11657 11658 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 11659 match(Set crx (CmpP src1 src2)); 11660 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 11661 size(4); 11662 ins_encode %{ 11663 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 11664 %} 11665 ins_pipe(pipe_class_compare); 11666 %} 11667 11668 // Used in postalloc expand. 11669 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 11670 // This match rule prevents reordering of node before a safepoint. 11671 // This only makes sense if this instructions is used exclusively 11672 // for the expansion of EncodeP! 11673 match(Set crx (CmpP src1 src2)); 11674 predicate(false); 11675 11676 format %{ "CMPDI $crx, $src1, $src2" %} 11677 size(4); 11678 ins_encode %{ 11679 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11680 %} 11681 ins_pipe(pipe_class_compare); 11682 %} 11683 11684 //----------Float Compares---------------------------------------------------- 11685 11686 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 11687 // Needs matchrule, see cmpDUnordered. 11688 match(Set crx (CmpF src1 src2)); 11689 // no match-rule, false predicate 11690 predicate(false); 11691 11692 format %{ "cmpFUrd $crx, $src1, $src2" %} 11693 size(4); 11694 ins_encode %{ 11695 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11696 %} 11697 ins_pipe(pipe_class_default); 11698 %} 11699 11700 instruct cmov_bns_less(flagsReg crx) %{ 11701 // no match-rule, false predicate 11702 effect(DEF crx); 11703 predicate(false); 11704 11705 ins_variable_size_depending_on_alignment(true); 11706 11707 format %{ "cmov $crx" %} 11708 // Worst case is branch + move + stop, no stop without scheduler. 11709 size(12); 11710 ins_encode %{ 11711 Label done; 11712 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 11713 __ li(R0, 0); 11714 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 11715 __ bind(done); 11716 %} 11717 ins_pipe(pipe_class_default); 11718 %} 11719 11720 // Compare floating, generate condition code. 11721 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 11722 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 11723 // 11724 // The following code sequence occurs a lot in mpegaudio: 11725 // 11726 // block BXX: 11727 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 11728 // cmpFUrd CCR6, F11, F9 11729 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 11730 // cmov CCR6 11731 // 8: instruct branchConSched: 11732 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 11733 match(Set crx (CmpF src1 src2)); 11734 ins_cost(DEFAULT_COST+BRANCH_COST); 11735 11736 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 11737 postalloc_expand %{ 11738 // 11739 // replaces 11740 // 11741 // region src1 src2 11742 // \ | | 11743 // crx=cmpF_reg_reg 11744 // 11745 // with 11746 // 11747 // region src1 src2 11748 // \ | | 11749 // crx=cmpFUnordered_reg_reg 11750 // | 11751 // ^ region 11752 // | \ 11753 // crx=cmov_bns_less 11754 // 11755 11756 // Create new nodes. 11757 MachNode *m1 = new cmpFUnordered_reg_regNode(); 11758 MachNode *m2 = new cmov_bns_lessNode(); 11759 11760 // inputs for new nodes 11761 m1->add_req(n_region, n_src1, n_src2); 11762 m2->add_req(n_region); 11763 m2->add_prec(m1); 11764 11765 // operands for new nodes 11766 m1->_opnds[0] = op_crx; 11767 m1->_opnds[1] = op_src1; 11768 m1->_opnds[2] = op_src2; 11769 m2->_opnds[0] = op_crx; 11770 11771 // registers for new nodes 11772 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11773 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11774 11775 // Insert new nodes. 11776 nodes->push(m1); 11777 nodes->push(m2); 11778 %} 11779 %} 11780 11781 // Compare float, generate -1,0,1 11782 instruct cmpF3_reg_reg(iRegIdst dst, regF src1, regF src2, flagsRegCR0 cr0) %{ 11783 match(Set dst (CmpF3 src1 src2)); 11784 effect(KILL cr0); 11785 ins_cost(DEFAULT_COST * 6); 11786 size((VM_Version::has_brw() ? 20 : 24)); 11787 11788 format %{ "cmpF3_reg_reg $dst, $src1, $src2" %} 11789 11790 ins_encode %{ 11791 __ fcmpu(CCR0, $src1$$FloatRegister, $src2$$FloatRegister); 11792 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less 11793 %} 11794 ins_pipe(pipe_class_default); 11795 %} 11796 11797 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 11798 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 11799 // node right before the conditional move using it. 11800 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 11801 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 11802 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 11803 // conditional move was supposed to be spilled. 11804 match(Set crx (CmpD src1 src2)); 11805 // False predicate, shall not be matched. 11806 predicate(false); 11807 11808 format %{ "cmpFUrd $crx, $src1, $src2" %} 11809 size(4); 11810 ins_encode %{ 11811 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11812 %} 11813 ins_pipe(pipe_class_default); 11814 %} 11815 11816 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 11817 match(Set crx (CmpD src1 src2)); 11818 ins_cost(DEFAULT_COST+BRANCH_COST); 11819 11820 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 11821 postalloc_expand %{ 11822 // 11823 // replaces 11824 // 11825 // region src1 src2 11826 // \ | | 11827 // crx=cmpD_reg_reg 11828 // 11829 // with 11830 // 11831 // region src1 src2 11832 // \ | | 11833 // crx=cmpDUnordered_reg_reg 11834 // | 11835 // ^ region 11836 // | \ 11837 // crx=cmov_bns_less 11838 // 11839 11840 // create new nodes 11841 MachNode *m1 = new cmpDUnordered_reg_regNode(); 11842 MachNode *m2 = new cmov_bns_lessNode(); 11843 11844 // inputs for new nodes 11845 m1->add_req(n_region, n_src1, n_src2); 11846 m2->add_req(n_region); 11847 m2->add_prec(m1); 11848 11849 // operands for new nodes 11850 m1->_opnds[0] = op_crx; 11851 m1->_opnds[1] = op_src1; 11852 m1->_opnds[2] = op_src2; 11853 m2->_opnds[0] = op_crx; 11854 11855 // registers for new nodes 11856 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11857 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11858 11859 // Insert new nodes. 11860 nodes->push(m1); 11861 nodes->push(m2); 11862 %} 11863 %} 11864 11865 // Compare double, generate -1,0,1 11866 instruct cmpD3_reg_reg(iRegIdst dst, regD src1, regD src2, flagsRegCR0 cr0) %{ 11867 match(Set dst (CmpD3 src1 src2)); 11868 effect(KILL cr0); 11869 ins_cost(DEFAULT_COST * 6); 11870 size((VM_Version::has_brw() ? 20 : 24)); 11871 11872 format %{ "cmpD3_reg_reg $dst, $src1, $src2" %} 11873 11874 ins_encode %{ 11875 __ fcmpu(CCR0, $src1$$FloatRegister, $src2$$FloatRegister); 11876 __ set_cmpu3($dst$$Register, true); // C2 requires unordered to get treated like less 11877 %} 11878 ins_pipe(pipe_class_default); 11879 %} 11880 11881 // Compare char 11882 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 11883 match(Set dst (Digit src1)); 11884 effect(TEMP src2, TEMP crx); 11885 ins_cost(3 * DEFAULT_COST); 11886 11887 format %{ "LI $src2, 0x3930\n\t" 11888 "CMPRB $crx, 0, $src1, $src2\n\t" 11889 "SETB $dst, $crx" %} 11890 size(12); 11891 ins_encode %{ 11892 // 0x30: 0, 0x39: 9 11893 __ li($src2$$Register, 0x3930); 11894 // compare src1 with ranges 0x30 to 0x39 11895 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 11896 __ setb($dst$$Register, $crx$$CondRegister); 11897 %} 11898 ins_pipe(pipe_class_default); 11899 %} 11900 11901 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 11902 match(Set dst (LowerCase src1)); 11903 effect(TEMP src2, TEMP crx); 11904 ins_cost(12 * DEFAULT_COST); 11905 11906 format %{ "LI $src2, 0x7A61\n\t" 11907 "CMPRB $crx, 0, $src1, $src2\n\t" 11908 "BGT $crx, done\n\t" 11909 "LIS $src2, (signed short)0xF6DF\n\t" 11910 "ORI $src2, $src2, 0xFFF8\n\t" 11911 "CMPRB $crx, 1, $src1, $src2\n\t" 11912 "BGT $crx, done\n\t" 11913 "LIS $src2, (signed short)0xAAB5\n\t" 11914 "ORI $src2, $src2, 0xBABA\n\t" 11915 "INSRDI $src2, $src2, 32, 0\n\t" 11916 "CMPEQB $crx, 1, $src1, $src2\n" 11917 "done:\n\t" 11918 "SETB $dst, $crx" %} 11919 11920 size(48); 11921 ins_encode %{ 11922 Label done; 11923 // 0x61: a, 0x7A: z 11924 __ li($src2$$Register, 0x7A61); 11925 // compare src1 with ranges 0x61 to 0x7A 11926 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 11927 __ bgt($crx$$CondRegister, done); 11928 11929 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case 11930 __ lis($src2$$Register, (signed short)0xF6DF); 11931 __ ori($src2$$Register, $src2$$Register, 0xFFF8); 11932 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF 11933 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 11934 __ bgt($crx$$CondRegister, done); 11935 11936 // 0xAA: feminine ordinal indicator 11937 // 0xB5: micro sign 11938 // 0xBA: masculine ordinal indicator 11939 __ lis($src2$$Register, (signed short)0xAAB5); 11940 __ ori($src2$$Register, $src2$$Register, 0xBABA); 11941 __ insrdi($src2$$Register, $src2$$Register, 32, 0); 11942 // compare src1 with 0xAA, 0xB5, and 0xBA 11943 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register); 11944 11945 __ bind(done); 11946 __ setb($dst$$Register, $crx$$CondRegister); 11947 %} 11948 ins_pipe(pipe_class_default); 11949 %} 11950 11951 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 11952 match(Set dst (UpperCase src1)); 11953 effect(TEMP src2, TEMP crx); 11954 ins_cost(7 * DEFAULT_COST); 11955 11956 format %{ "LI $src2, 0x5A41\n\t" 11957 "CMPRB $crx, 0, $src1, $src2\n\t" 11958 "BGT $crx, done\n\t" 11959 "LIS $src2, (signed short)0xD6C0\n\t" 11960 "ORI $src2, $src2, 0xDED8\n\t" 11961 "CMPRB $crx, 1, $src1, $src2\n" 11962 "done:\n\t" 11963 "SETB $dst, $crx" %} 11964 11965 size(28); 11966 ins_encode %{ 11967 Label done; 11968 // 0x41: A, 0x5A: Z 11969 __ li($src2$$Register, 0x5A41); 11970 // compare src1 with a range 0x41 to 0x5A 11971 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 11972 __ bgt($crx$$CondRegister, done); 11973 11974 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case 11975 __ lis($src2$$Register, (signed short)0xD6C0); 11976 __ ori($src2$$Register, $src2$$Register, 0xDED8); 11977 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE 11978 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 11979 11980 __ bind(done); 11981 __ setb($dst$$Register, $crx$$CondRegister); 11982 %} 11983 ins_pipe(pipe_class_default); 11984 %} 11985 11986 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 11987 match(Set dst (Whitespace src1)); 11988 predicate(PowerArchitecturePPC64 <= 9); 11989 effect(TEMP src2, TEMP crx); 11990 ins_cost(4 * DEFAULT_COST); 11991 11992 format %{ "LI $src2, 0x0D09\n\t" 11993 "ADDIS $src2, 0x201C\n\t" 11994 "CMPRB $crx, 1, $src1, $src2\n\t" 11995 "SETB $dst, $crx" %} 11996 size(16); 11997 ins_encode %{ 11998 // 0x09 to 0x0D, 0x1C to 0x20 11999 __ li($src2$$Register, 0x0D09); 12000 __ addis($src2$$Register, $src2$$Register, 0x0201C); 12001 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20 12002 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12003 __ setb($dst$$Register, $crx$$CondRegister); 12004 %} 12005 ins_pipe(pipe_class_default); 12006 %} 12007 12008 // Power 10 version, using prefixed addi to load 32-bit constant 12009 instruct cmprb_Whitespace_reg_reg_prefixed(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12010 match(Set dst (Whitespace src1)); 12011 predicate(PowerArchitecturePPC64 >= 10); 12012 effect(TEMP src2, TEMP crx); 12013 ins_cost(3 * DEFAULT_COST); 12014 12015 format %{ "PLI $src2, 0x201C0D09\n\t" 12016 "CMPRB $crx, 1, $src1, $src2\n\t" 12017 "SETB $dst, $crx" %} 12018 size(16); 12019 ins_encode %{ 12020 // 0x09 to 0x0D, 0x1C to 0x20 12021 assert( ((intptr_t)(__ pc()) & 0x3c) != 0x3c, "Bad alignment for prefixed instruction at " INTPTR_FORMAT, (intptr_t)(__ pc())); 12022 __ pli($src2$$Register, 0x201C0D09); 12023 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20 12024 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12025 __ setb($dst$$Register, $crx$$CondRegister); 12026 %} 12027 ins_pipe(pipe_class_default); 12028 ins_alignment(2); 12029 %} 12030 12031 //----------Branches--------------------------------------------------------- 12032 // Jump 12033 12034 // Direct Branch. 12035 instruct branch(label labl) %{ 12036 match(Goto); 12037 effect(USE labl); 12038 ins_cost(BRANCH_COST); 12039 12040 format %{ "B $labl" %} 12041 size(4); 12042 ins_encode %{ 12043 Label d; // dummy 12044 __ bind(d); 12045 Label* p = $labl$$label; 12046 // `p' is `NULL' when this encoding class is used only to 12047 // determine the size of the encoded instruction. 12048 Label& l = (NULL == p)? d : *(p); 12049 __ b(l); 12050 %} 12051 ins_pipe(pipe_class_default); 12052 %} 12053 12054 // Conditional Near Branch 12055 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12056 // Same match rule as `branchConFar'. 12057 match(If cmp crx); 12058 effect(USE lbl); 12059 ins_cost(BRANCH_COST); 12060 12061 // If set to 1 this indicates that the current instruction is a 12062 // short variant of a long branch. This avoids using this 12063 // instruction in first-pass matching. It will then only be used in 12064 // the `Shorten_branches' pass. 12065 ins_short_branch(1); 12066 12067 format %{ "B$cmp $crx, $lbl" %} 12068 size(4); 12069 ins_encode( enc_bc(crx, cmp, lbl) ); 12070 ins_pipe(pipe_class_default); 12071 %} 12072 12073 // This is for cases when the ppc64 `bc' instruction does not 12074 // reach far enough. So we emit a far branch here, which is more 12075 // expensive. 12076 // 12077 // Conditional Far Branch 12078 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12079 // Same match rule as `branchCon'. 12080 match(If cmp crx); 12081 effect(USE crx, USE lbl); 12082 // Higher cost than `branchCon'. 12083 ins_cost(5*BRANCH_COST); 12084 12085 // This is not a short variant of a branch, but the long variant. 12086 ins_short_branch(0); 12087 12088 format %{ "B_FAR$cmp $crx, $lbl" %} 12089 size(8); 12090 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12091 ins_pipe(pipe_class_default); 12092 %} 12093 12094 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12095 match(CountedLoopEnd cmp crx); 12096 effect(USE labl); 12097 ins_cost(BRANCH_COST); 12098 12099 // short variant. 12100 ins_short_branch(1); 12101 12102 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12103 size(4); 12104 ins_encode( enc_bc(crx, cmp, labl) ); 12105 ins_pipe(pipe_class_default); 12106 %} 12107 12108 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12109 match(CountedLoopEnd cmp crx); 12110 effect(USE labl); 12111 ins_cost(BRANCH_COST); 12112 12113 // Long variant. 12114 ins_short_branch(0); 12115 12116 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12117 size(8); 12118 ins_encode( enc_bc_far(crx, cmp, labl) ); 12119 ins_pipe(pipe_class_default); 12120 %} 12121 12122 // ============================================================================ 12123 // Java runtime operations, intrinsics and other complex operations. 12124 12125 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12126 // array for an instance of the superklass. Set a hidden internal cache on a 12127 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12128 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12129 // 12130 // GL TODO: Improve this. 12131 // - result should not be a TEMP 12132 // - Add match rule as on sparc avoiding additional Cmp. 12133 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12134 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12135 match(Set result (PartialSubtypeCheck subklass superklass)); 12136 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12137 ins_cost(DEFAULT_COST*10); 12138 12139 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12140 ins_encode %{ 12141 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12142 $tmp_klass$$Register, NULL, $result$$Register); 12143 %} 12144 ins_pipe(pipe_class_default); 12145 %} 12146 12147 // inlined locking and unlocking 12148 12149 instruct cmpFastLock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12150 match(Set crx (FastLock oop box)); 12151 effect(TEMP tmp1, TEMP tmp2); 12152 predicate(!Compile::current()->use_rtm()); 12153 12154 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12155 ins_encode %{ 12156 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12157 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0); 12158 // If locking was successful, crx should indicate 'EQ'. 12159 // The compiler generates a branch to the runtime call to 12160 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12161 %} 12162 ins_pipe(pipe_class_compare); 12163 %} 12164 12165 // Separate version for TM. Use bound register for box to enable USE_KILL. 12166 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12167 match(Set crx (FastLock oop box)); 12168 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12169 predicate(Compile::current()->use_rtm()); 12170 12171 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12172 ins_encode %{ 12173 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12174 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12175 _rtm_counters, _stack_rtm_counters, 12176 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12177 /*RTM*/ true, ra_->C->profile_rtm()); 12178 // If locking was successful, crx should indicate 'EQ'. 12179 // The compiler generates a branch to the runtime call to 12180 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12181 %} 12182 ins_pipe(pipe_class_compare); 12183 %} 12184 12185 instruct cmpFastUnlock(flagsRegCR0 crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12186 match(Set crx (FastUnlock oop box)); 12187 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12188 predicate(!Compile::current()->use_rtm()); 12189 12190 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12191 ins_encode %{ 12192 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12193 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12194 false); 12195 // If unlocking was successful, crx should indicate 'EQ'. 12196 // The compiler generates a branch to the runtime call to 12197 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12198 %} 12199 ins_pipe(pipe_class_compare); 12200 %} 12201 12202 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12203 match(Set crx (FastUnlock oop box)); 12204 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12205 predicate(Compile::current()->use_rtm()); 12206 12207 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12208 ins_encode %{ 12209 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12210 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12211 /*RTM*/ true); 12212 // If unlocking was successful, crx should indicate 'EQ'. 12213 // The compiler generates a branch to the runtime call to 12214 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12215 %} 12216 ins_pipe(pipe_class_compare); 12217 %} 12218 12219 // Align address. 12220 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12221 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12222 12223 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12224 size(4); 12225 ins_encode %{ 12226 __ clrrdi($dst$$Register, $src$$Register, log2i_exact(-(julong)$mask$$constant)); 12227 %} 12228 ins_pipe(pipe_class_default); 12229 %} 12230 12231 // Array size computation. 12232 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12233 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12234 12235 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12236 size(4); 12237 ins_encode %{ 12238 __ subf($dst$$Register, $start$$Register, $end$$Register); 12239 %} 12240 ins_pipe(pipe_class_default); 12241 %} 12242 12243 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12244 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12245 match(Set dummy (ClearArray cnt base)); 12246 effect(USE_KILL base, KILL ctr); 12247 ins_cost(2 * MEMORY_REF_COST); 12248 12249 format %{ "ClearArray $cnt, $base" %} 12250 ins_encode %{ 12251 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12252 %} 12253 ins_pipe(pipe_class_default); 12254 %} 12255 12256 // Clear-array with constant large array length. 12257 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12258 match(Set dummy (ClearArray cnt base)); 12259 effect(USE_KILL base, TEMP tmp, KILL ctr); 12260 ins_cost(3 * MEMORY_REF_COST); 12261 12262 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12263 ins_encode %{ 12264 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12265 %} 12266 ins_pipe(pipe_class_default); 12267 %} 12268 12269 // Clear-array with dynamic array length. 12270 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12271 match(Set dummy (ClearArray cnt base)); 12272 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12273 ins_cost(4 * MEMORY_REF_COST); 12274 12275 format %{ "ClearArray $cnt, $base" %} 12276 ins_encode %{ 12277 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12278 %} 12279 ins_pipe(pipe_class_default); 12280 %} 12281 12282 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12283 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12284 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12285 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12286 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12287 ins_cost(300); 12288 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12289 ins_encode %{ 12290 __ string_compare($str1$$Register, $str2$$Register, 12291 $cnt1$$Register, $cnt2$$Register, 12292 $tmp$$Register, 12293 $result$$Register, StrIntrinsicNode::LL); 12294 %} 12295 ins_pipe(pipe_class_default); 12296 %} 12297 12298 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12299 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12300 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12301 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12302 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12303 ins_cost(300); 12304 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12305 ins_encode %{ 12306 __ string_compare($str1$$Register, $str2$$Register, 12307 $cnt1$$Register, $cnt2$$Register, 12308 $tmp$$Register, 12309 $result$$Register, StrIntrinsicNode::UU); 12310 %} 12311 ins_pipe(pipe_class_default); 12312 %} 12313 12314 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12315 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12316 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12317 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12318 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12319 ins_cost(300); 12320 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12321 ins_encode %{ 12322 __ string_compare($str1$$Register, $str2$$Register, 12323 $cnt1$$Register, $cnt2$$Register, 12324 $tmp$$Register, 12325 $result$$Register, StrIntrinsicNode::LU); 12326 %} 12327 ins_pipe(pipe_class_default); 12328 %} 12329 12330 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12331 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12332 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12333 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12334 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12335 ins_cost(300); 12336 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12337 ins_encode %{ 12338 __ string_compare($str2$$Register, $str1$$Register, 12339 $cnt2$$Register, $cnt1$$Register, 12340 $tmp$$Register, 12341 $result$$Register, StrIntrinsicNode::UL); 12342 %} 12343 ins_pipe(pipe_class_default); 12344 %} 12345 12346 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12347 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12348 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12349 match(Set result (StrEquals (Binary str1 str2) cnt)); 12350 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12351 ins_cost(300); 12352 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12353 ins_encode %{ 12354 __ array_equals(false, $str1$$Register, $str2$$Register, 12355 $cnt$$Register, $tmp$$Register, 12356 $result$$Register, true /* byte */); 12357 %} 12358 ins_pipe(pipe_class_default); 12359 %} 12360 12361 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12362 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12363 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12364 match(Set result (StrEquals (Binary str1 str2) cnt)); 12365 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12366 ins_cost(300); 12367 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12368 ins_encode %{ 12369 __ array_equals(false, $str1$$Register, $str2$$Register, 12370 $cnt$$Register, $tmp$$Register, 12371 $result$$Register, false /* byte */); 12372 %} 12373 ins_pipe(pipe_class_default); 12374 %} 12375 12376 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12377 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12378 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12379 match(Set result (AryEq ary1 ary2)); 12380 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12381 ins_cost(300); 12382 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12383 ins_encode %{ 12384 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12385 $tmp1$$Register, $tmp2$$Register, 12386 $result$$Register, true /* byte */); 12387 %} 12388 ins_pipe(pipe_class_default); 12389 %} 12390 12391 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12392 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12393 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12394 match(Set result (AryEq ary1 ary2)); 12395 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12396 ins_cost(300); 12397 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12398 ins_encode %{ 12399 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12400 $tmp1$$Register, $tmp2$$Register, 12401 $result$$Register, false /* byte */); 12402 %} 12403 ins_pipe(pipe_class_default); 12404 %} 12405 12406 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12407 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12408 iRegIdst tmp1, iRegIdst tmp2, 12409 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12410 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12411 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12412 // Required for EA: check if it is still a type_array. 12413 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12414 ins_cost(150); 12415 12416 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12417 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12418 12419 ins_encode %{ 12420 immPOper *needleOper = (immPOper *)$needleImm; 12421 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12422 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12423 jchar chr; 12424 #ifdef VM_LITTLE_ENDIAN 12425 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12426 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12427 #else 12428 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12429 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12430 #endif 12431 __ string_indexof_char($result$$Register, 12432 $haystack$$Register, $haycnt$$Register, 12433 R0, chr, 12434 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12435 %} 12436 ins_pipe(pipe_class_compare); 12437 %} 12438 12439 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12440 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12441 iRegIdst tmp1, iRegIdst tmp2, 12442 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12443 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12444 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12445 // Required for EA: check if it is still a type_array. 12446 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12447 ins_cost(150); 12448 12449 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12450 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12451 12452 ins_encode %{ 12453 immPOper *needleOper = (immPOper *)$needleImm; 12454 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12455 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12456 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12457 __ string_indexof_char($result$$Register, 12458 $haystack$$Register, $haycnt$$Register, 12459 R0, chr, 12460 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12461 %} 12462 ins_pipe(pipe_class_compare); 12463 %} 12464 12465 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12466 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12467 iRegIdst tmp1, iRegIdst tmp2, 12468 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12469 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12470 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12471 // Required for EA: check if it is still a type_array. 12472 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12473 ins_cost(150); 12474 12475 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12476 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12477 12478 ins_encode %{ 12479 immPOper *needleOper = (immPOper *)$needleImm; 12480 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12481 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12482 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12483 __ string_indexof_char($result$$Register, 12484 $haystack$$Register, $haycnt$$Register, 12485 R0, chr, 12486 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12487 %} 12488 ins_pipe(pipe_class_compare); 12489 %} 12490 12491 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12492 rscratch2RegP needle, immI_1 needlecntImm, 12493 iRegIdst tmp1, iRegIdst tmp2, 12494 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12495 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12496 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12497 // Required for EA: check if it is still a type_array. 12498 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12499 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12500 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12501 ins_cost(180); 12502 12503 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12504 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12505 ins_encode %{ 12506 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12507 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12508 guarantee(needle_values, "sanity"); 12509 jchar chr; 12510 #ifdef VM_LITTLE_ENDIAN 12511 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12512 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12513 #else 12514 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12515 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12516 #endif 12517 __ string_indexof_char($result$$Register, 12518 $haystack$$Register, $haycnt$$Register, 12519 R0, chr, 12520 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12521 %} 12522 ins_pipe(pipe_class_compare); 12523 %} 12524 12525 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12526 rscratch2RegP needle, immI_1 needlecntImm, 12527 iRegIdst tmp1, iRegIdst tmp2, 12528 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12529 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12530 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12531 // Required for EA: check if it is still a type_array. 12532 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12533 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12534 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12535 ins_cost(180); 12536 12537 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12538 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12539 ins_encode %{ 12540 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12541 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12542 guarantee(needle_values, "sanity"); 12543 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12544 __ string_indexof_char($result$$Register, 12545 $haystack$$Register, $haycnt$$Register, 12546 R0, chr, 12547 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12548 %} 12549 ins_pipe(pipe_class_compare); 12550 %} 12551 12552 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12553 rscratch2RegP needle, immI_1 needlecntImm, 12554 iRegIdst tmp1, iRegIdst tmp2, 12555 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12556 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12557 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12558 // Required for EA: check if it is still a type_array. 12559 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12560 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12561 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12562 ins_cost(180); 12563 12564 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12565 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12566 ins_encode %{ 12567 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12568 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12569 guarantee(needle_values, "sanity"); 12570 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12571 __ string_indexof_char($result$$Register, 12572 $haystack$$Register, $haycnt$$Register, 12573 R0, chr, 12574 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12575 %} 12576 ins_pipe(pipe_class_compare); 12577 %} 12578 12579 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12580 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12581 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12582 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12583 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12584 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U); 12585 ins_cost(180); 12586 12587 format %{ "StringUTF16 IndexOfChar $haystack[0..$haycnt], $ch" 12588 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12589 ins_encode %{ 12590 __ string_indexof_char($result$$Register, 12591 $haystack$$Register, $haycnt$$Register, 12592 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12593 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12594 %} 12595 ins_pipe(pipe_class_compare); 12596 %} 12597 12598 instruct indexOfChar_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12599 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12600 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12601 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12602 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12603 predicate(((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L); 12604 ins_cost(180); 12605 12606 format %{ "StringLatin1 IndexOfChar $haystack[0..$haycnt], $ch" 12607 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12608 ins_encode %{ 12609 __ string_indexof_char($result$$Register, 12610 $haystack$$Register, $haycnt$$Register, 12611 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12612 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12613 %} 12614 ins_pipe(pipe_class_compare); 12615 %} 12616 12617 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12618 iRegPsrc needle, uimmI15 needlecntImm, 12619 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12620 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12621 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12622 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12623 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12624 // Required for EA: check if it is still a type_array. 12625 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12626 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12627 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12628 ins_cost(250); 12629 12630 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12631 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12632 ins_encode %{ 12633 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12634 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12635 12636 __ string_indexof($result$$Register, 12637 $haystack$$Register, $haycnt$$Register, 12638 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12639 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12640 %} 12641 ins_pipe(pipe_class_compare); 12642 %} 12643 12644 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12645 iRegPsrc needle, uimmI15 needlecntImm, 12646 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12647 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12648 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12649 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12650 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12651 // Required for EA: check if it is still a type_array. 12652 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12653 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12654 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12655 ins_cost(250); 12656 12657 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12658 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12659 ins_encode %{ 12660 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12661 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12662 12663 __ string_indexof($result$$Register, 12664 $haystack$$Register, $haycnt$$Register, 12665 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12666 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12667 %} 12668 ins_pipe(pipe_class_compare); 12669 %} 12670 12671 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12672 iRegPsrc needle, uimmI15 needlecntImm, 12673 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12674 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12675 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12676 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12677 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12678 // Required for EA: check if it is still a type_array. 12679 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12680 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12681 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12682 ins_cost(250); 12683 12684 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12685 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12686 ins_encode %{ 12687 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12688 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12689 12690 __ string_indexof($result$$Register, 12691 $haystack$$Register, $haycnt$$Register, 12692 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12693 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12694 %} 12695 ins_pipe(pipe_class_compare); 12696 %} 12697 12698 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12699 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12700 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12701 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12702 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12703 TEMP_DEF result, 12704 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12705 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12706 ins_cost(300); 12707 12708 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12709 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12710 ins_encode %{ 12711 __ string_indexof($result$$Register, 12712 $haystack$$Register, $haycnt$$Register, 12713 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12714 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12715 %} 12716 ins_pipe(pipe_class_compare); 12717 %} 12718 12719 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12720 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12721 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12722 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12723 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12724 TEMP_DEF result, 12725 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12726 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12727 ins_cost(300); 12728 12729 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12730 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12731 ins_encode %{ 12732 __ string_indexof($result$$Register, 12733 $haystack$$Register, $haycnt$$Register, 12734 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12735 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12736 %} 12737 ins_pipe(pipe_class_compare); 12738 %} 12739 12740 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12741 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12742 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12743 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12744 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12745 TEMP_DEF result, 12746 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12747 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12748 ins_cost(300); 12749 12750 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12751 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12752 ins_encode %{ 12753 __ string_indexof($result$$Register, 12754 $haystack$$Register, $haycnt$$Register, 12755 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12756 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12757 %} 12758 ins_pipe(pipe_class_compare); 12759 %} 12760 12761 // char[] to byte[] compression 12762 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12763 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12764 match(Set result (StrCompressedCopy src (Binary dst len))); 12765 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12766 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12767 ins_cost(300); 12768 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12769 ins_encode %{ 12770 Label Lskip, Ldone; 12771 __ li($result$$Register, 0); 12772 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12773 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 12774 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12775 __ beq(CCR0, Lskip); 12776 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 12777 __ bind(Lskip); 12778 __ mr($result$$Register, $len$$Register); 12779 __ bind(Ldone); 12780 %} 12781 ins_pipe(pipe_class_default); 12782 %} 12783 12784 // byte[] to char[] inflation 12785 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 12786 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12787 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12788 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12789 ins_cost(300); 12790 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12791 ins_encode %{ 12792 Label Ldone; 12793 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12794 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 12795 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12796 __ beq(CCR0, Ldone); 12797 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 12798 __ bind(Ldone); 12799 %} 12800 ins_pipe(pipe_class_default); 12801 %} 12802 12803 // StringCoding.java intrinsics 12804 instruct count_positives(iRegPsrc ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 12805 regCTR ctr, flagsRegCR0 cr0) 12806 %{ 12807 match(Set result (CountPositives ary1 len)); 12808 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 12809 ins_cost(300); 12810 format %{ "count positives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 12811 ins_encode %{ 12812 __ count_positives($ary1$$Register, $len$$Register, $result$$Register, 12813 $tmp1$$Register, $tmp2$$Register); 12814 %} 12815 ins_pipe(pipe_class_default); 12816 %} 12817 12818 // encode char[] to byte[] in ISO_8859_1 12819 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12820 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12821 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 12822 match(Set result (EncodeISOArray src (Binary dst len))); 12823 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12824 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12825 ins_cost(300); 12826 format %{ "Encode iso array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12827 ins_encode %{ 12828 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register, 12829 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false); 12830 %} 12831 ins_pipe(pipe_class_default); 12832 %} 12833 12834 // encode char[] to byte[] in ASCII 12835 instruct encode_ascii_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12836 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12837 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 12838 match(Set result (EncodeISOArray src (Binary dst len))); 12839 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12840 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12841 ins_cost(300); 12842 format %{ "Encode ascii array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12843 ins_encode %{ 12844 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register, 12845 $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, true); 12846 %} 12847 ins_pipe(pipe_class_default); 12848 %} 12849 12850 12851 //---------- Min/Max Instructions --------------------------------------------- 12852 12853 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12854 match(Set dst (MinI src1 src2)); 12855 ins_cost(DEFAULT_COST*6); 12856 12857 expand %{ 12858 iRegLdst src1s; 12859 iRegLdst src2s; 12860 iRegLdst diff; 12861 iRegLdst sm; 12862 iRegLdst doz; // difference or zero 12863 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12864 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12865 subL_reg_reg(diff, src2s, src1s); 12866 // Need to consider >=33 bit result, therefore we need signmaskL. 12867 signmask64L_regL(sm, diff); 12868 andL_reg_reg(doz, diff, sm); // <=0 12869 addI_regL_regL(dst, doz, src1s); 12870 %} 12871 %} 12872 12873 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12874 match(Set dst (MinI src1 src2)); 12875 effect(KILL cr0); 12876 predicate(VM_Version::has_isel()); 12877 ins_cost(DEFAULT_COST*2); 12878 12879 ins_encode %{ 12880 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12881 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 12882 %} 12883 ins_pipe(pipe_class_default); 12884 %} 12885 12886 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12887 match(Set dst (MaxI src1 src2)); 12888 ins_cost(DEFAULT_COST*6); 12889 12890 expand %{ 12891 iRegLdst src1s; 12892 iRegLdst src2s; 12893 iRegLdst diff; 12894 iRegLdst sm; 12895 iRegLdst doz; // difference or zero 12896 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12897 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12898 subL_reg_reg(diff, src2s, src1s); 12899 // Need to consider >=33 bit result, therefore we need signmaskL. 12900 signmask64L_regL(sm, diff); 12901 andcL_reg_reg(doz, diff, sm); // >=0 12902 addI_regL_regL(dst, doz, src1s); 12903 %} 12904 %} 12905 12906 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12907 match(Set dst (MaxI src1 src2)); 12908 effect(KILL cr0); 12909 predicate(VM_Version::has_isel()); 12910 ins_cost(DEFAULT_COST*2); 12911 12912 ins_encode %{ 12913 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12914 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 12915 %} 12916 ins_pipe(pipe_class_default); 12917 %} 12918 12919 //---------- Population Count Instructions ------------------------------------ 12920 12921 // Popcnt for Power7. 12922 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 12923 match(Set dst (PopCountI src)); 12924 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12925 ins_cost(DEFAULT_COST); 12926 12927 format %{ "POPCNTW $dst, $src" %} 12928 size(4); 12929 ins_encode %{ 12930 __ popcntw($dst$$Register, $src$$Register); 12931 %} 12932 ins_pipe(pipe_class_default); 12933 %} 12934 12935 // Popcnt for Power7. 12936 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 12937 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12938 match(Set dst (PopCountL src)); 12939 ins_cost(DEFAULT_COST); 12940 12941 format %{ "POPCNTD $dst, $src" %} 12942 size(4); 12943 ins_encode %{ 12944 __ popcntd($dst$$Register, $src$$Register); 12945 %} 12946 ins_pipe(pipe_class_default); 12947 %} 12948 12949 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 12950 match(Set dst (CountLeadingZerosI src)); 12951 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12952 ins_cost(DEFAULT_COST); 12953 12954 format %{ "CNTLZW $dst, $src" %} 12955 size(4); 12956 ins_encode %{ 12957 __ cntlzw($dst$$Register, $src$$Register); 12958 %} 12959 ins_pipe(pipe_class_default); 12960 %} 12961 12962 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 12963 match(Set dst (CountLeadingZerosL src)); 12964 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12965 ins_cost(DEFAULT_COST); 12966 12967 format %{ "CNTLZD $dst, $src" %} 12968 size(4); 12969 ins_encode %{ 12970 __ cntlzd($dst$$Register, $src$$Register); 12971 %} 12972 ins_pipe(pipe_class_default); 12973 %} 12974 12975 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 12976 // no match-rule, false predicate 12977 effect(DEF dst, USE src); 12978 predicate(false); 12979 12980 format %{ "CNTLZD $dst, $src" %} 12981 size(4); 12982 ins_encode %{ 12983 __ cntlzd($dst$$Register, $src$$Register); 12984 %} 12985 ins_pipe(pipe_class_default); 12986 %} 12987 12988 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 12989 match(Set dst (CountTrailingZerosI src)); 12990 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 12991 ins_cost(DEFAULT_COST); 12992 12993 expand %{ 12994 immI16 imm1 %{ (int)-1 %} 12995 immI16 imm2 %{ (int)32 %} 12996 immI_minus1 m1 %{ -1 %} 12997 iRegIdst tmpI1; 12998 iRegIdst tmpI2; 12999 iRegIdst tmpI3; 13000 addI_reg_imm16(tmpI1, src, imm1); 13001 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13002 countLeadingZerosI(tmpI3, tmpI2); 13003 subI_imm16_reg(dst, imm2, tmpI3); 13004 %} 13005 %} 13006 13007 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{ 13008 match(Set dst (CountTrailingZerosI src)); 13009 predicate(UseCountTrailingZerosInstructionsPPC64); 13010 ins_cost(DEFAULT_COST); 13011 13012 format %{ "CNTTZW $dst, $src" %} 13013 size(4); 13014 ins_encode %{ 13015 __ cnttzw($dst$$Register, $src$$Register); 13016 %} 13017 ins_pipe(pipe_class_default); 13018 %} 13019 13020 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13021 match(Set dst (CountTrailingZerosL src)); 13022 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13023 ins_cost(DEFAULT_COST); 13024 13025 expand %{ 13026 immL16 imm1 %{ (long)-1 %} 13027 immI16 imm2 %{ (int)64 %} 13028 iRegLdst tmpL1; 13029 iRegLdst tmpL2; 13030 iRegIdst tmpL3; 13031 addL_reg_imm16(tmpL1, src, imm1); 13032 andcL_reg_reg(tmpL2, tmpL1, src); 13033 countLeadingZerosL(tmpL3, tmpL2); 13034 subI_imm16_reg(dst, imm2, tmpL3); 13035 %} 13036 %} 13037 13038 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{ 13039 match(Set dst (CountTrailingZerosL src)); 13040 predicate(UseCountTrailingZerosInstructionsPPC64); 13041 ins_cost(DEFAULT_COST); 13042 13043 format %{ "CNTTZD $dst, $src" %} 13044 size(4); 13045 ins_encode %{ 13046 __ cnttzd($dst$$Register, $src$$Register); 13047 %} 13048 ins_pipe(pipe_class_default); 13049 %} 13050 13051 // Expand nodes for byte_reverse_int. 13052 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13053 effect(DEF dst, USE src, USE pos, USE shift); 13054 predicate(false); 13055 13056 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13057 size(4); 13058 ins_encode %{ 13059 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13060 %} 13061 ins_pipe(pipe_class_default); 13062 %} 13063 13064 // As insrwi_a, but with USE_DEF. 13065 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13066 effect(USE_DEF dst, USE src, USE pos, USE shift); 13067 predicate(false); 13068 13069 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13070 size(4); 13071 ins_encode %{ 13072 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13073 %} 13074 ins_pipe(pipe_class_default); 13075 %} 13076 13077 // Just slightly faster than java implementation. 13078 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13079 match(Set dst (ReverseBytesI src)); 13080 predicate(!UseByteReverseInstructions); 13081 ins_cost(7*DEFAULT_COST); 13082 13083 expand %{ 13084 immI16 imm24 %{ (int) 24 %} 13085 immI16 imm16 %{ (int) 16 %} 13086 immI16 imm8 %{ (int) 8 %} 13087 immI16 imm4 %{ (int) 4 %} 13088 immI16 imm0 %{ (int) 0 %} 13089 iRegLdst tmpI1; 13090 iRegLdst tmpI2; 13091 iRegLdst tmpI3; 13092 13093 urShiftI_reg_imm(tmpI1, src, imm24); 13094 insrwi_a(dst, tmpI1, imm24, imm8); 13095 urShiftI_reg_imm(tmpI2, src, imm16); 13096 insrwi(dst, tmpI2, imm8, imm16); 13097 urShiftI_reg_imm(tmpI3, src, imm8); 13098 insrwi(dst, tmpI3, imm8, imm8); 13099 insrwi(dst, src, imm0, imm8); 13100 %} 13101 %} 13102 13103 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{ 13104 match(Set dst (ReverseBytesI src)); 13105 predicate(UseVectorByteReverseInstructionsPPC64); 13106 effect(TEMP tmpV); 13107 ins_cost(DEFAULT_COST*3); 13108 size(12); 13109 format %{ "MTVSRWZ $tmpV, $src\n" 13110 "\tXXBRW $tmpV, $tmpV\n" 13111 "\tMFVSRWZ $dst, $tmpV" %} 13112 13113 ins_encode %{ 13114 __ mtvsrwz($tmpV$$VectorSRegister, $src$$Register); 13115 __ xxbrw($tmpV$$VectorSRegister, $tmpV$$VectorSRegister); 13116 __ mfvsrwz($dst$$Register, $tmpV$$VectorSRegister); 13117 %} 13118 ins_pipe(pipe_class_default); 13119 %} 13120 13121 instruct bytes_reverse_int(iRegIdst dst, iRegIsrc src) %{ 13122 match(Set dst (ReverseBytesI src)); 13123 predicate(UseByteReverseInstructions); 13124 ins_cost(DEFAULT_COST); 13125 size(4); 13126 13127 format %{ "BRW $dst, $src" %} 13128 13129 ins_encode %{ 13130 __ brw($dst$$Register, $src$$Register); 13131 %} 13132 ins_pipe(pipe_class_default); 13133 %} 13134 13135 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13136 match(Set dst (ReverseBytesL src)); 13137 predicate(!UseByteReverseInstructions); 13138 ins_cost(15*DEFAULT_COST); 13139 13140 expand %{ 13141 immI16 imm56 %{ (int) 56 %} 13142 immI16 imm48 %{ (int) 48 %} 13143 immI16 imm40 %{ (int) 40 %} 13144 immI16 imm32 %{ (int) 32 %} 13145 immI16 imm24 %{ (int) 24 %} 13146 immI16 imm16 %{ (int) 16 %} 13147 immI16 imm8 %{ (int) 8 %} 13148 immI16 imm0 %{ (int) 0 %} 13149 iRegLdst tmpL1; 13150 iRegLdst tmpL2; 13151 iRegLdst tmpL3; 13152 iRegLdst tmpL4; 13153 iRegLdst tmpL5; 13154 iRegLdst tmpL6; 13155 13156 // src : |a|b|c|d|e|f|g|h| 13157 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13158 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13159 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13160 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13161 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13162 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13163 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13164 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13165 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13166 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13167 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13168 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13169 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13170 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13171 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13172 %} 13173 %} 13174 13175 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{ 13176 match(Set dst (ReverseBytesL src)); 13177 predicate(UseVectorByteReverseInstructionsPPC64); 13178 effect(TEMP tmpV); 13179 ins_cost(DEFAULT_COST*3); 13180 size(12); 13181 format %{ "MTVSRD $tmpV, $src\n" 13182 "\tXXBRD $tmpV, $tmpV\n" 13183 "\tMFVSRD $dst, $tmpV" %} 13184 13185 ins_encode %{ 13186 __ mtvsrd($tmpV$$VectorSRegister, $src$$Register); 13187 __ xxbrd($tmpV$$VectorSRegister, $tmpV$$VectorSRegister); 13188 __ mfvsrd($dst$$Register, $tmpV$$VectorSRegister); 13189 %} 13190 ins_pipe(pipe_class_default); 13191 %} 13192 13193 instruct bytes_reverse_long(iRegLdst dst, iRegLsrc src) %{ 13194 match(Set dst (ReverseBytesL src)); 13195 predicate(UseByteReverseInstructions); 13196 ins_cost(DEFAULT_COST); 13197 size(4); 13198 13199 format %{ "BRD $dst, $src" %} 13200 13201 ins_encode %{ 13202 __ brd($dst$$Register, $src$$Register); 13203 %} 13204 ins_pipe(pipe_class_default); 13205 %} 13206 13207 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13208 match(Set dst (ReverseBytesUS src)); 13209 predicate(!UseByteReverseInstructions); 13210 ins_cost(2*DEFAULT_COST); 13211 13212 expand %{ 13213 immI16 imm16 %{ (int) 16 %} 13214 immI16 imm8 %{ (int) 8 %} 13215 13216 urShiftI_reg_imm(dst, src, imm8); 13217 insrwi(dst, src, imm16, imm8); 13218 %} 13219 %} 13220 13221 instruct bytes_reverse_ushort(iRegIdst dst, iRegIsrc src) %{ 13222 match(Set dst (ReverseBytesUS src)); 13223 predicate(UseByteReverseInstructions); 13224 ins_cost(DEFAULT_COST); 13225 size(4); 13226 13227 format %{ "BRH $dst, $src" %} 13228 13229 ins_encode %{ 13230 __ brh($dst$$Register, $src$$Register); 13231 %} 13232 ins_pipe(pipe_class_default); 13233 %} 13234 13235 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13236 match(Set dst (ReverseBytesS src)); 13237 predicate(!UseByteReverseInstructions); 13238 ins_cost(3*DEFAULT_COST); 13239 13240 expand %{ 13241 immI16 imm16 %{ (int) 16 %} 13242 immI16 imm8 %{ (int) 8 %} 13243 iRegLdst tmpI1; 13244 13245 urShiftI_reg_imm(tmpI1, src, imm8); 13246 insrwi(tmpI1, src, imm16, imm8); 13247 extsh(dst, tmpI1); 13248 %} 13249 %} 13250 13251 instruct bytes_reverse_short(iRegIdst dst, iRegIsrc src) %{ 13252 match(Set dst (ReverseBytesS src)); 13253 predicate(UseByteReverseInstructions); 13254 ins_cost(DEFAULT_COST); 13255 size(8); 13256 13257 format %{ "BRH $dst, $src\n\t" 13258 "EXTSH $dst, $dst" %} 13259 13260 ins_encode %{ 13261 __ brh($dst$$Register, $src$$Register); 13262 __ extsh($dst$$Register, $dst$$Register); 13263 %} 13264 ins_pipe(pipe_class_default); 13265 %} 13266 13267 // Load Integer reversed byte order 13268 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13269 match(Set dst (ReverseBytesI (LoadI mem))); 13270 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13271 ins_cost(MEMORY_REF_COST); 13272 13273 size(4); 13274 ins_encode %{ 13275 __ lwbrx($dst$$Register, $mem$$Register); 13276 %} 13277 ins_pipe(pipe_class_default); 13278 %} 13279 13280 instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{ 13281 match(Set dst (ReverseBytesI (LoadI mem))); 13282 ins_cost(2 * MEMORY_REF_COST); 13283 13284 size(12); 13285 ins_encode %{ 13286 __ lwbrx($dst$$Register, $mem$$Register); 13287 __ twi_0($dst$$Register); 13288 __ isync(); 13289 %} 13290 ins_pipe(pipe_class_default); 13291 %} 13292 13293 // Load Long - aligned and reversed 13294 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13295 match(Set dst (ReverseBytesL (LoadL mem))); 13296 predicate(VM_Version::has_ldbrx() && (n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)))); 13297 ins_cost(MEMORY_REF_COST); 13298 13299 size(4); 13300 ins_encode %{ 13301 __ ldbrx($dst$$Register, $mem$$Register); 13302 %} 13303 ins_pipe(pipe_class_default); 13304 %} 13305 13306 instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{ 13307 match(Set dst (ReverseBytesL (LoadL mem))); 13308 predicate(VM_Version::has_ldbrx()); 13309 ins_cost(2 * MEMORY_REF_COST); 13310 13311 size(12); 13312 ins_encode %{ 13313 __ ldbrx($dst$$Register, $mem$$Register); 13314 __ twi_0($dst$$Register); 13315 __ isync(); 13316 %} 13317 ins_pipe(pipe_class_default); 13318 %} 13319 13320 // Load unsigned short / char reversed byte order 13321 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13322 match(Set dst (ReverseBytesUS (LoadUS mem))); 13323 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13324 ins_cost(MEMORY_REF_COST); 13325 13326 size(4); 13327 ins_encode %{ 13328 __ lhbrx($dst$$Register, $mem$$Register); 13329 %} 13330 ins_pipe(pipe_class_default); 13331 %} 13332 13333 instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{ 13334 match(Set dst (ReverseBytesUS (LoadUS mem))); 13335 ins_cost(2 * MEMORY_REF_COST); 13336 13337 size(12); 13338 ins_encode %{ 13339 __ lhbrx($dst$$Register, $mem$$Register); 13340 __ twi_0($dst$$Register); 13341 __ isync(); 13342 %} 13343 ins_pipe(pipe_class_default); 13344 %} 13345 13346 // Load short reversed byte order 13347 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13348 match(Set dst (ReverseBytesS (LoadS mem))); 13349 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13350 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13351 13352 size(8); 13353 ins_encode %{ 13354 __ lhbrx($dst$$Register, $mem$$Register); 13355 __ extsh($dst$$Register, $dst$$Register); 13356 %} 13357 ins_pipe(pipe_class_default); 13358 %} 13359 13360 instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{ 13361 match(Set dst (ReverseBytesS (LoadS mem))); 13362 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13363 13364 size(16); 13365 ins_encode %{ 13366 __ lhbrx($dst$$Register, $mem$$Register); 13367 __ twi_0($dst$$Register); 13368 __ extsh($dst$$Register, $dst$$Register); 13369 __ isync(); 13370 %} 13371 ins_pipe(pipe_class_default); 13372 %} 13373 13374 // Store Integer reversed byte order 13375 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13376 match(Set mem (StoreI mem (ReverseBytesI src))); 13377 ins_cost(MEMORY_REF_COST); 13378 13379 size(4); 13380 ins_encode %{ 13381 __ stwbrx($src$$Register, $mem$$Register); 13382 %} 13383 ins_pipe(pipe_class_default); 13384 %} 13385 13386 // Store Long reversed byte order 13387 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13388 match(Set mem (StoreL mem (ReverseBytesL src))); 13389 predicate(VM_Version::has_stdbrx()); 13390 ins_cost(MEMORY_REF_COST); 13391 13392 size(4); 13393 ins_encode %{ 13394 __ stdbrx($src$$Register, $mem$$Register); 13395 %} 13396 ins_pipe(pipe_class_default); 13397 %} 13398 13399 // Store unsigned short / char reversed byte order 13400 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13401 match(Set mem (StoreC mem (ReverseBytesUS src))); 13402 ins_cost(MEMORY_REF_COST); 13403 13404 size(4); 13405 ins_encode %{ 13406 __ sthbrx($src$$Register, $mem$$Register); 13407 %} 13408 ins_pipe(pipe_class_default); 13409 %} 13410 13411 // Store short reversed byte order 13412 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13413 match(Set mem (StoreC mem (ReverseBytesS src))); 13414 ins_cost(MEMORY_REF_COST); 13415 13416 size(4); 13417 ins_encode %{ 13418 __ sthbrx($src$$Register, $mem$$Register); 13419 %} 13420 ins_pipe(pipe_class_default); 13421 %} 13422 13423 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13424 effect(DEF temp1, USE src); 13425 13426 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %} 13427 size(4); 13428 ins_encode %{ 13429 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13430 %} 13431 ins_pipe(pipe_class_default); 13432 %} 13433 13434 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13435 effect(DEF dst, USE src, USE imm1); 13436 13437 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %} 13438 size(4); 13439 ins_encode %{ 13440 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13441 %} 13442 ins_pipe(pipe_class_default); 13443 %} 13444 13445 instruct xscvdpspn_regF(vecX dst, regF src) %{ 13446 effect(DEF dst, USE src); 13447 13448 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %} 13449 size(4); 13450 ins_encode %{ 13451 __ xscvdpspn($dst$$VectorSRegister, $src$$FloatRegister->to_vsr()); 13452 %} 13453 ins_pipe(pipe_class_default); 13454 %} 13455 13456 //---------- Replicate Vector Instructions ------------------------------------ 13457 13458 // Insrdi does replicate if src == dst. 13459 instruct repl32(iRegLdst dst) %{ 13460 predicate(false); 13461 effect(USE_DEF dst); 13462 13463 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13464 size(4); 13465 ins_encode %{ 13466 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13467 %} 13468 ins_pipe(pipe_class_default); 13469 %} 13470 13471 // Insrdi does replicate if src == dst. 13472 instruct repl48(iRegLdst dst) %{ 13473 predicate(false); 13474 effect(USE_DEF dst); 13475 13476 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13477 size(4); 13478 ins_encode %{ 13479 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13480 %} 13481 ins_pipe(pipe_class_default); 13482 %} 13483 13484 // Insrdi does replicate if src == dst. 13485 instruct repl56(iRegLdst dst) %{ 13486 predicate(false); 13487 effect(USE_DEF dst); 13488 13489 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13490 size(4); 13491 ins_encode %{ 13492 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 13493 %} 13494 ins_pipe(pipe_class_default); 13495 %} 13496 13497 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13498 match(Set dst (ReplicateB src)); 13499 predicate(n->as_Vector()->length() == 8); 13500 expand %{ 13501 moveReg(dst, src); 13502 repl56(dst); 13503 repl48(dst); 13504 repl32(dst); 13505 %} 13506 %} 13507 13508 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 13509 match(Set dst (ReplicateB zero)); 13510 predicate(n->as_Vector()->length() == 8); 13511 format %{ "LI $dst, #0 \t// replicate8B" %} 13512 size(4); 13513 ins_encode %{ 13514 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13515 %} 13516 ins_pipe(pipe_class_default); 13517 %} 13518 13519 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13520 match(Set dst (ReplicateB src)); 13521 predicate(n->as_Vector()->length() == 8); 13522 format %{ "LI $dst, #-1 \t// replicate8B" %} 13523 size(4); 13524 ins_encode %{ 13525 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13526 %} 13527 ins_pipe(pipe_class_default); 13528 %} 13529 13530 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 13531 match(Set dst (ReplicateB src)); 13532 predicate(n->as_Vector()->length() == 16); 13533 13534 expand %{ 13535 iRegLdst tmpL; 13536 vecX tmpV; 13537 immI8 imm1 %{ (int) 1 %} 13538 moveReg(tmpL, src); 13539 repl56(tmpL); 13540 repl48(tmpL); 13541 mtvsrwz(tmpV, tmpL); 13542 xxspltw(dst, tmpV, imm1); 13543 %} 13544 %} 13545 13546 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 13547 match(Set dst (ReplicateB zero)); 13548 predicate(n->as_Vector()->length() == 16); 13549 13550 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 13551 size(4); 13552 ins_encode %{ 13553 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13554 %} 13555 ins_pipe(pipe_class_default); 13556 %} 13557 13558 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 13559 match(Set dst (ReplicateB src)); 13560 predicate(n->as_Vector()->length() == 16); 13561 13562 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13563 size(4); 13564 ins_encode %{ 13565 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13566 %} 13567 ins_pipe(pipe_class_default); 13568 %} 13569 13570 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13571 match(Set dst (ReplicateS src)); 13572 predicate(n->as_Vector()->length() == 4); 13573 expand %{ 13574 moveReg(dst, src); 13575 repl48(dst); 13576 repl32(dst); 13577 %} 13578 %} 13579 13580 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 13581 match(Set dst (ReplicateS zero)); 13582 predicate(n->as_Vector()->length() == 4); 13583 format %{ "LI $dst, #0 \t// replicate4S" %} 13584 size(4); 13585 ins_encode %{ 13586 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13587 %} 13588 ins_pipe(pipe_class_default); 13589 %} 13590 13591 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13592 match(Set dst (ReplicateS src)); 13593 predicate(n->as_Vector()->length() == 4); 13594 format %{ "LI $dst, -1 \t// replicate4S" %} 13595 size(4); 13596 ins_encode %{ 13597 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13598 %} 13599 ins_pipe(pipe_class_default); 13600 %} 13601 13602 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 13603 match(Set dst (ReplicateS src)); 13604 predicate(n->as_Vector()->length() == 8); 13605 13606 expand %{ 13607 iRegLdst tmpL; 13608 vecX tmpV; 13609 immI8 zero %{ (int) 0 %} 13610 moveReg(tmpL, src); 13611 repl48(tmpL); 13612 repl32(tmpL); 13613 mtvsrd(tmpV, tmpL); 13614 xxpermdi(dst, tmpV, tmpV, zero); 13615 %} 13616 %} 13617 13618 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 13619 match(Set dst (ReplicateS zero)); 13620 predicate(n->as_Vector()->length() == 8); 13621 13622 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 13623 size(4); 13624 ins_encode %{ 13625 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13626 %} 13627 ins_pipe(pipe_class_default); 13628 %} 13629 13630 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 13631 match(Set dst (ReplicateS src)); 13632 predicate(n->as_Vector()->length() == 8); 13633 13634 format %{ "XXLEQV $dst, $src \t// replicate8S" %} 13635 size(4); 13636 ins_encode %{ 13637 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13638 %} 13639 ins_pipe(pipe_class_default); 13640 %} 13641 13642 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13643 match(Set dst (ReplicateI src)); 13644 predicate(n->as_Vector()->length() == 2); 13645 ins_cost(2 * DEFAULT_COST); 13646 expand %{ 13647 moveReg(dst, src); 13648 repl32(dst); 13649 %} 13650 %} 13651 13652 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 13653 match(Set dst (ReplicateI zero)); 13654 predicate(n->as_Vector()->length() == 2); 13655 format %{ "LI $dst, #0 \t// replicate2I" %} 13656 size(4); 13657 ins_encode %{ 13658 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13659 %} 13660 ins_pipe(pipe_class_default); 13661 %} 13662 13663 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13664 match(Set dst (ReplicateI src)); 13665 predicate(n->as_Vector()->length() == 2); 13666 format %{ "LI $dst, -1 \t// replicate2I" %} 13667 size(4); 13668 ins_encode %{ 13669 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13670 %} 13671 ins_pipe(pipe_class_default); 13672 %} 13673 13674 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 13675 match(Set dst (ReplicateI src)); 13676 predicate(n->as_Vector()->length() == 4); 13677 ins_cost(2 * DEFAULT_COST); 13678 13679 expand %{ 13680 iRegLdst tmpL; 13681 vecX tmpV; 13682 immI8 zero %{ (int) 0 %} 13683 moveReg(tmpL, src); 13684 repl32(tmpL); 13685 mtvsrd(tmpV, tmpL); 13686 xxpermdi(dst, tmpV, tmpV, zero); 13687 %} 13688 %} 13689 13690 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 13691 match(Set dst (ReplicateI zero)); 13692 predicate(n->as_Vector()->length() == 4); 13693 13694 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 13695 size(4); 13696 ins_encode %{ 13697 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13698 %} 13699 ins_pipe(pipe_class_default); 13700 %} 13701 13702 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 13703 match(Set dst (ReplicateI src)); 13704 predicate(n->as_Vector()->length() == 4); 13705 13706 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 13707 size(4); 13708 ins_encode %{ 13709 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13710 %} 13711 ins_pipe(pipe_class_default); 13712 %} 13713 13714 // Move float to int register via stack, replicate. 13715 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 13716 match(Set dst (ReplicateF src)); 13717 predicate(n->as_Vector()->length() == 2); 13718 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13719 expand %{ 13720 stackSlotL tmpS; 13721 iRegIdst tmpI; 13722 moveF2I_reg_stack(tmpS, src); // Move float to stack. 13723 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 13724 moveReg(dst, tmpI); // Move int to long reg. 13725 repl32(dst); // Replicate bitpattern. 13726 %} 13727 %} 13728 13729 // Replicate scalar constant to packed float values in Double register 13730 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 13731 match(Set dst (ReplicateF src)); 13732 predicate(n->as_Vector()->length() == 2); 13733 ins_cost(5 * DEFAULT_COST); 13734 13735 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 13736 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 13737 %} 13738 13739 // Replicate scalar zero constant to packed float values in Double register 13740 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 13741 match(Set dst (ReplicateF zero)); 13742 predicate(n->as_Vector()->length() == 2); 13743 13744 format %{ "LI $dst, #0 \t// replicate2F" %} 13745 ins_encode %{ 13746 __ li($dst$$Register, 0x0); 13747 %} 13748 ins_pipe(pipe_class_default); 13749 %} 13750 13751 13752 //----------Vector Arithmetic Instructions-------------------------------------- 13753 13754 // Vector Addition Instructions 13755 13756 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{ 13757 match(Set dst (AddVB src1 src2)); 13758 predicate(n->as_Vector()->length() == 16); 13759 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %} 13760 size(4); 13761 ins_encode %{ 13762 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13763 %} 13764 ins_pipe(pipe_class_default); 13765 %} 13766 13767 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{ 13768 match(Set dst (AddVS src1 src2)); 13769 predicate(n->as_Vector()->length() == 8); 13770 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %} 13771 size(4); 13772 ins_encode %{ 13773 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13774 %} 13775 ins_pipe(pipe_class_default); 13776 %} 13777 13778 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{ 13779 match(Set dst (AddVI src1 src2)); 13780 predicate(n->as_Vector()->length() == 4); 13781 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %} 13782 size(4); 13783 ins_encode %{ 13784 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13785 %} 13786 ins_pipe(pipe_class_default); 13787 %} 13788 13789 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{ 13790 match(Set dst (AddVF src1 src2)); 13791 predicate(n->as_Vector()->length() == 4); 13792 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %} 13793 size(4); 13794 ins_encode %{ 13795 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13796 %} 13797 ins_pipe(pipe_class_default); 13798 %} 13799 13800 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{ 13801 match(Set dst (AddVL src1 src2)); 13802 predicate(n->as_Vector()->length() == 2); 13803 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %} 13804 size(4); 13805 ins_encode %{ 13806 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13807 %} 13808 ins_pipe(pipe_class_default); 13809 %} 13810 13811 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{ 13812 match(Set dst (AddVD src1 src2)); 13813 predicate(n->as_Vector()->length() == 2); 13814 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %} 13815 size(4); 13816 ins_encode %{ 13817 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13818 %} 13819 ins_pipe(pipe_class_default); 13820 %} 13821 13822 // Vector Subtraction Instructions 13823 13824 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{ 13825 match(Set dst (SubVB src1 src2)); 13826 predicate(n->as_Vector()->length() == 16); 13827 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %} 13828 size(4); 13829 ins_encode %{ 13830 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13831 %} 13832 ins_pipe(pipe_class_default); 13833 %} 13834 13835 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{ 13836 match(Set dst (SubVS src1 src2)); 13837 predicate(n->as_Vector()->length() == 8); 13838 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %} 13839 size(4); 13840 ins_encode %{ 13841 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13842 %} 13843 ins_pipe(pipe_class_default); 13844 %} 13845 13846 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{ 13847 match(Set dst (SubVI src1 src2)); 13848 predicate(n->as_Vector()->length() == 4); 13849 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %} 13850 size(4); 13851 ins_encode %{ 13852 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13853 %} 13854 ins_pipe(pipe_class_default); 13855 %} 13856 13857 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{ 13858 match(Set dst (SubVF src1 src2)); 13859 predicate(n->as_Vector()->length() == 4); 13860 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %} 13861 size(4); 13862 ins_encode %{ 13863 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13864 %} 13865 ins_pipe(pipe_class_default); 13866 %} 13867 13868 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{ 13869 match(Set dst (SubVL src1 src2)); 13870 predicate(n->as_Vector()->length() == 2); 13871 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %} 13872 size(4); 13873 ins_encode %{ 13874 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13875 %} 13876 ins_pipe(pipe_class_default); 13877 %} 13878 13879 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{ 13880 match(Set dst (SubVD src1 src2)); 13881 predicate(n->as_Vector()->length() == 2); 13882 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %} 13883 size(4); 13884 ins_encode %{ 13885 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13886 %} 13887 ins_pipe(pipe_class_default); 13888 %} 13889 13890 // Vector Multiplication Instructions 13891 13892 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 13893 match(Set dst (MulVS src1 src2)); 13894 predicate(n->as_Vector()->length() == 8); 13895 effect(TEMP tmp); 13896 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %} 13897 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %} 13898 size(8); 13899 ins_encode %{ 13900 __ vspltish($tmp$$VectorSRegister->to_vr(), 0); 13901 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr()); 13902 %} 13903 ins_pipe(pipe_class_default); 13904 %} 13905 13906 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{ 13907 match(Set dst (MulVI src1 src2)); 13908 predicate(n->as_Vector()->length() == 4); 13909 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %} 13910 size(4); 13911 ins_encode %{ 13912 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 13913 %} 13914 ins_pipe(pipe_class_default); 13915 %} 13916 13917 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{ 13918 match(Set dst (MulVF src1 src2)); 13919 predicate(n->as_Vector()->length() == 4); 13920 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %} 13921 size(4); 13922 ins_encode %{ 13923 __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13924 %} 13925 ins_pipe(pipe_class_default); 13926 %} 13927 13928 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{ 13929 match(Set dst (MulVD src1 src2)); 13930 predicate(n->as_Vector()->length() == 2); 13931 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %} 13932 size(4); 13933 ins_encode %{ 13934 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13935 %} 13936 ins_pipe(pipe_class_default); 13937 %} 13938 13939 // Vector Division Instructions 13940 13941 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{ 13942 match(Set dst (DivVF src1 src2)); 13943 predicate(n->as_Vector()->length() == 4); 13944 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %} 13945 size(4); 13946 ins_encode %{ 13947 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13948 %} 13949 ins_pipe(pipe_class_default); 13950 %} 13951 13952 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ 13953 match(Set dst (DivVD src1 src2)); 13954 predicate(n->as_Vector()->length() == 2); 13955 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %} 13956 size(4); 13957 ins_encode %{ 13958 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 13959 %} 13960 ins_pipe(pipe_class_default); 13961 %} 13962 13963 // Vector Absolute Instructions 13964 13965 instruct vabs4F_reg(vecX dst, vecX src) %{ 13966 match(Set dst (AbsVF src)); 13967 predicate(n->as_Vector()->length() == 4); 13968 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %} 13969 size(4); 13970 ins_encode %{ 13971 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister); 13972 %} 13973 ins_pipe(pipe_class_default); 13974 %} 13975 13976 instruct vabs2D_reg(vecX dst, vecX src) %{ 13977 match(Set dst (AbsVD src)); 13978 predicate(n->as_Vector()->length() == 2); 13979 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %} 13980 size(4); 13981 ins_encode %{ 13982 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister); 13983 %} 13984 ins_pipe(pipe_class_default); 13985 %} 13986 13987 // Round Instructions 13988 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{ 13989 match(Set dst (RoundDoubleMode src rmode)); 13990 format %{ "RoundDoubleMode $src,$rmode" %} 13991 size(4); 13992 ins_encode %{ 13993 switch ($rmode$$constant) { 13994 case RoundDoubleModeNode::rmode_rint: 13995 __ xvrdpic($dst$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr()); 13996 break; 13997 case RoundDoubleModeNode::rmode_floor: 13998 __ frim($dst$$FloatRegister, $src$$FloatRegister); 13999 break; 14000 case RoundDoubleModeNode::rmode_ceil: 14001 __ frip($dst$$FloatRegister, $src$$FloatRegister); 14002 break; 14003 default: 14004 ShouldNotReachHere(); 14005 } 14006 %} 14007 ins_pipe(pipe_class_default); 14008 %} 14009 14010 // Vector Round Instructions 14011 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{ 14012 match(Set dst (RoundDoubleModeV src rmode)); 14013 predicate(n->as_Vector()->length() == 2); 14014 format %{ "RoundDoubleModeV $src,$rmode" %} 14015 size(4); 14016 ins_encode %{ 14017 switch ($rmode$$constant) { 14018 case RoundDoubleModeNode::rmode_rint: 14019 __ xvrdpic($dst$$VectorSRegister, $src$$VectorSRegister); 14020 break; 14021 case RoundDoubleModeNode::rmode_floor: 14022 __ xvrdpim($dst$$VectorSRegister, $src$$VectorSRegister); 14023 break; 14024 case RoundDoubleModeNode::rmode_ceil: 14025 __ xvrdpip($dst$$VectorSRegister, $src$$VectorSRegister); 14026 break; 14027 default: 14028 ShouldNotReachHere(); 14029 } 14030 %} 14031 ins_pipe(pipe_class_default); 14032 %} 14033 14034 // Vector Negate Instructions 14035 14036 instruct vneg4F_reg(vecX dst, vecX src) %{ 14037 match(Set dst (NegVF src)); 14038 predicate(n->as_Vector()->length() == 4); 14039 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %} 14040 size(4); 14041 ins_encode %{ 14042 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister); 14043 %} 14044 ins_pipe(pipe_class_default); 14045 %} 14046 14047 instruct vneg2D_reg(vecX dst, vecX src) %{ 14048 match(Set dst (NegVD src)); 14049 predicate(n->as_Vector()->length() == 2); 14050 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %} 14051 size(4); 14052 ins_encode %{ 14053 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister); 14054 %} 14055 ins_pipe(pipe_class_default); 14056 %} 14057 14058 // Vector Square Root Instructions 14059 14060 instruct vsqrt4F_reg(vecX dst, vecX src) %{ 14061 match(Set dst (SqrtVF src)); 14062 predicate(n->as_Vector()->length() == 4); 14063 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %} 14064 size(4); 14065 ins_encode %{ 14066 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister); 14067 %} 14068 ins_pipe(pipe_class_default); 14069 %} 14070 14071 instruct vsqrt2D_reg(vecX dst, vecX src) %{ 14072 match(Set dst (SqrtVD src)); 14073 predicate(n->as_Vector()->length() == 2); 14074 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %} 14075 size(4); 14076 ins_encode %{ 14077 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister); 14078 %} 14079 ins_pipe(pipe_class_default); 14080 %} 14081 14082 // Vector Population Count Instructions 14083 14084 instruct vpopcnt_reg(vecX dst, vecX src) %{ 14085 match(Set dst (PopCountVI src)); 14086 format %{ "VPOPCNT $dst,$src\t// pop count packed" %} 14087 size(4); 14088 ins_encode %{ 14089 BasicType bt = Matcher::vector_element_basic_type(this); 14090 switch (bt) { 14091 case T_BYTE: 14092 __ vpopcntb($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14093 break; 14094 case T_SHORT: 14095 __ vpopcnth($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14096 break; 14097 case T_INT: 14098 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14099 break; 14100 case T_LONG: 14101 __ vpopcntd($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14102 break; 14103 default: 14104 ShouldNotReachHere(); 14105 } 14106 %} 14107 ins_pipe(pipe_class_default); 14108 %} 14109 14110 // --------------------------------- FMA -------------------------------------- 14111 // dst + src1 * src2 14112 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{ 14113 match(Set dst (FmaVF dst (Binary src1 src2))); 14114 predicate(n->as_Vector()->length() == 4); 14115 14116 format %{ "XVMADDASP $dst, $src1, $src2" %} 14117 14118 size(4); 14119 ins_encode %{ 14120 __ xvmaddasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14121 %} 14122 ins_pipe(pipe_class_default); 14123 %} 14124 14125 // dst - src1 * src2 14126 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{ 14127 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 14128 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 14129 predicate(n->as_Vector()->length() == 4); 14130 14131 format %{ "XVNMSUBASP $dst, $src1, $src2" %} 14132 14133 size(4); 14134 ins_encode %{ 14135 __ xvnmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14136 %} 14137 ins_pipe(pipe_class_default); 14138 %} 14139 14140 // - dst + src1 * src2 14141 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{ 14142 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2))); 14143 predicate(n->as_Vector()->length() == 4); 14144 14145 format %{ "XVMSUBASP $dst, $src1, $src2" %} 14146 14147 size(4); 14148 ins_encode %{ 14149 __ xvmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14150 %} 14151 ins_pipe(pipe_class_default); 14152 %} 14153 14154 // dst + src1 * src2 14155 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{ 14156 match(Set dst (FmaVD dst (Binary src1 src2))); 14157 predicate(n->as_Vector()->length() == 2); 14158 14159 format %{ "XVMADDADP $dst, $src1, $src2" %} 14160 14161 size(4); 14162 ins_encode %{ 14163 __ xvmaddadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14164 %} 14165 ins_pipe(pipe_class_default); 14166 %} 14167 14168 // dst - src1 * src2 14169 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{ 14170 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 14171 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 14172 predicate(n->as_Vector()->length() == 2); 14173 14174 format %{ "XVNMSUBADP $dst, $src1, $src2" %} 14175 14176 size(4); 14177 ins_encode %{ 14178 __ xvnmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14179 %} 14180 ins_pipe(pipe_class_default); 14181 %} 14182 14183 // - dst + src1 * src2 14184 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{ 14185 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2))); 14186 predicate(n->as_Vector()->length() == 2); 14187 14188 format %{ "XVMSUBADP $dst, $src1, $src2" %} 14189 14190 size(4); 14191 ins_encode %{ 14192 __ xvmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14193 %} 14194 ins_pipe(pipe_class_default); 14195 %} 14196 14197 //----------Overflow Math Instructions----------------------------------------- 14198 14199 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 14200 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14201 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14202 14203 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14204 match(Set cr0 (OverflowAddL op1 op2)); 14205 14206 format %{ "add_ $op1, $op2\t# overflow check long" %} 14207 ins_encode %{ 14208 __ li(R0, 0); 14209 __ mtxer(R0); // clear XER.SO 14210 __ addo_(R0, $op1$$Register, $op2$$Register); 14211 %} 14212 ins_pipe(pipe_class_default); 14213 %} 14214 14215 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14216 match(Set cr0 (OverflowSubL op1 op2)); 14217 14218 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14219 ins_encode %{ 14220 __ li(R0, 0); 14221 __ mtxer(R0); // clear XER.SO 14222 __ subfo_(R0, $op2$$Register, $op1$$Register); 14223 %} 14224 ins_pipe(pipe_class_default); 14225 %} 14226 14227 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14228 match(Set cr0 (OverflowSubL zero op2)); 14229 14230 format %{ "nego_ R0, $op2\t# overflow check long" %} 14231 ins_encode %{ 14232 __ li(R0, 0); 14233 __ mtxer(R0); // clear XER.SO 14234 __ nego_(R0, $op2$$Register); 14235 %} 14236 ins_pipe(pipe_class_default); 14237 %} 14238 14239 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14240 match(Set cr0 (OverflowMulL op1 op2)); 14241 14242 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14243 ins_encode %{ 14244 __ li(R0, 0); 14245 __ mtxer(R0); // clear XER.SO 14246 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14247 %} 14248 ins_pipe(pipe_class_default); 14249 %} 14250 14251 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14252 match(Set dst (ReplicateF src)); 14253 predicate(n->as_Vector()->length() == 4); 14254 ins_cost(DEFAULT_COST); 14255 expand %{ 14256 vecX tmpV; 14257 immI8 zero %{ (int) 0 %} 14258 14259 xscvdpspn_regF(tmpV, src); 14260 xxspltw(dst, tmpV, zero); 14261 %} 14262 %} 14263 14264 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14265 match(Set dst (ReplicateF src)); 14266 predicate(n->as_Vector()->length() == 4); 14267 effect(TEMP tmp); 14268 ins_cost(10 * DEFAULT_COST); 14269 14270 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14271 %} 14272 14273 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14274 match(Set dst (ReplicateF zero)); 14275 predicate(n->as_Vector()->length() == 4); 14276 14277 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14278 ins_encode %{ 14279 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14280 %} 14281 ins_pipe(pipe_class_default); 14282 %} 14283 14284 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14285 match(Set dst (ReplicateD src)); 14286 predicate(n->as_Vector()->length() == 2); 14287 14288 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %} 14289 size(4); 14290 ins_encode %{ 14291 __ xxpermdi($dst$$VectorSRegister, $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0); 14292 %} 14293 ins_pipe(pipe_class_default); 14294 %} 14295 14296 instruct repl2D_immD0(vecX dst, immD_0 zero) %{ 14297 match(Set dst (ReplicateD zero)); 14298 predicate(n->as_Vector()->length() == 2); 14299 14300 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14301 size(4); 14302 ins_encode %{ 14303 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14304 %} 14305 ins_pipe(pipe_class_default); 14306 %} 14307 14308 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14309 predicate(false); 14310 effect(DEF dst, USE src); 14311 14312 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %} 14313 size(4); 14314 ins_encode %{ 14315 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14316 %} 14317 ins_pipe(pipe_class_default); 14318 %} 14319 14320 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14321 effect(DEF dst, USE src, USE zero); 14322 14323 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %} 14324 size(4); 14325 ins_encode %{ 14326 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14327 %} 14328 ins_pipe(pipe_class_default); 14329 %} 14330 14331 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14332 effect(DEF dst, USE src1, USE src2, USE zero); 14333 14334 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %} 14335 size(4); 14336 ins_encode %{ 14337 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14338 %} 14339 ins_pipe(pipe_class_default); 14340 %} 14341 14342 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14343 match(Set dst (ReplicateL src)); 14344 predicate(n->as_Vector()->length() == 2); 14345 expand %{ 14346 vecX tmpV; 14347 immI8 zero %{ (int) 0 %} 14348 mtvsrd(tmpV, src); 14349 xxpermdi(dst, tmpV, tmpV, zero); 14350 %} 14351 %} 14352 14353 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14354 match(Set dst (ReplicateL zero)); 14355 predicate(n->as_Vector()->length() == 2); 14356 14357 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14358 size(4); 14359 ins_encode %{ 14360 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14361 %} 14362 ins_pipe(pipe_class_default); 14363 %} 14364 14365 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14366 match(Set dst (ReplicateL src)); 14367 predicate(n->as_Vector()->length() == 2); 14368 14369 format %{ "XXLEQV $dst, $src \t// replicate2L" %} 14370 size(4); 14371 ins_encode %{ 14372 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14373 %} 14374 ins_pipe(pipe_class_default); 14375 %} 14376 14377 // ============================================================================ 14378 // Safepoint Instruction 14379 14380 instruct safePoint_poll(iRegPdst poll) %{ 14381 match(SafePoint poll); 14382 14383 // It caused problems to add the effect that r0 is killed, but this 14384 // effect no longer needs to be mentioned, since r0 is not contained 14385 // in a reg_class. 14386 14387 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14388 size(4); 14389 ins_encode( enc_poll(0x0, poll) ); 14390 ins_pipe(pipe_class_default); 14391 %} 14392 14393 // ============================================================================ 14394 // Call Instructions 14395 14396 // Call Java Static Instruction 14397 14398 source %{ 14399 14400 #include "runtime/continuation.hpp" 14401 14402 %} 14403 14404 // Schedulable version of call static node. 14405 instruct CallStaticJavaDirect(method meth) %{ 14406 match(CallStaticJava); 14407 effect(USE meth); 14408 ins_cost(CALL_COST); 14409 14410 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14411 14412 format %{ "CALL,static $meth \t// ==> " %} 14413 size((Continuations::enabled() ? 8 : 4)); 14414 ins_encode( enc_java_static_call(meth) ); 14415 ins_pipe(pipe_class_call); 14416 %} 14417 14418 // Call Java Dynamic Instruction 14419 14420 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14421 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14422 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14423 // The call destination must still be placed in the constant pool. 14424 instruct CallDynamicJavaDirectSched(method meth) %{ 14425 match(CallDynamicJava); // To get all the data fields we need ... 14426 effect(USE meth); 14427 predicate(false); // ... but never match. 14428 14429 ins_field_load_ic_hi_node(loadConL_hiNode*); 14430 ins_field_load_ic_node(loadConLNode*); 14431 ins_num_consts(1 /* 1 patchable constant: call destination */); 14432 14433 format %{ "BL \t// dynamic $meth ==> " %} 14434 size((Continuations::enabled() ? 8 : 4)); 14435 ins_encode( enc_java_dynamic_call_sched(meth) ); 14436 ins_pipe(pipe_class_call); 14437 %} 14438 14439 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14440 // We use postalloc expanded calls if we use inline caches 14441 // and do not update method data. 14442 // 14443 // This instruction has two constants: inline cache (IC) and call destination. 14444 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14445 // one constant. 14446 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14447 match(CallDynamicJava); 14448 effect(USE meth); 14449 predicate(UseInlineCaches); 14450 ins_cost(CALL_COST); 14451 14452 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14453 14454 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14455 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14456 %} 14457 14458 // Compound version of call dynamic java 14459 // We use postalloc expanded calls if we use inline caches 14460 // and do not update method data. 14461 instruct CallDynamicJavaDirect(method meth) %{ 14462 match(CallDynamicJava); 14463 effect(USE meth); 14464 predicate(!UseInlineCaches); 14465 ins_cost(CALL_COST); 14466 14467 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14468 ins_num_consts(4); 14469 14470 format %{ "CALL,dynamic $meth \t// ==> " %} 14471 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14472 ins_pipe(pipe_class_call); 14473 %} 14474 14475 // Call Runtime Instruction 14476 14477 instruct CallRuntimeDirect(method meth) %{ 14478 match(CallRuntime); 14479 effect(USE meth); 14480 ins_cost(CALL_COST); 14481 14482 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14483 // env for callee, C-toc. 14484 ins_num_consts(3); 14485 14486 format %{ "CALL,runtime" %} 14487 ins_encode( enc_java_to_runtime_call(meth) ); 14488 ins_pipe(pipe_class_call); 14489 %} 14490 14491 // Call Leaf 14492 14493 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14494 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14495 effect(DEF dst, USE src); 14496 14497 ins_num_consts(1); 14498 14499 format %{ "MTCTR $src" %} 14500 size(4); 14501 ins_encode( enc_leaf_call_mtctr(src) ); 14502 ins_pipe(pipe_class_default); 14503 %} 14504 14505 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 14506 instruct CallLeafDirect(method meth) %{ 14507 match(CallLeaf); // To get the data all the data fields we need ... 14508 effect(USE meth); 14509 predicate(false); // but never match. 14510 14511 format %{ "BCTRL \t// leaf call $meth ==> " %} 14512 size((Continuations::enabled() ? 8 : 4)); 14513 ins_encode %{ 14514 __ bctrl(); 14515 __ post_call_nop(); 14516 %} 14517 ins_pipe(pipe_class_call); 14518 %} 14519 14520 // postalloc expand of CallLeafDirect. 14521 // Load address to call from TOC, then bl to it. 14522 instruct CallLeafDirect_Ex(method meth) %{ 14523 match(CallLeaf); 14524 effect(USE meth); 14525 ins_cost(CALL_COST); 14526 14527 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14528 // env for callee, C-toc. 14529 ins_num_consts(3); 14530 14531 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14532 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14533 %} 14534 14535 // Call runtime without safepoint - same as CallLeaf. 14536 // postalloc expand of CallLeafNoFPDirect. 14537 // Load address to call from TOC, then bl to it. 14538 instruct CallLeafNoFPDirect_Ex(method meth) %{ 14539 match(CallLeafNoFP); 14540 effect(USE meth); 14541 ins_cost(CALL_COST); 14542 14543 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14544 // env for callee, C-toc. 14545 ins_num_consts(3); 14546 14547 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14548 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14549 %} 14550 14551 // Tail Call; Jump from runtime stub to Java code. 14552 // Also known as an 'interprocedural jump'. 14553 // Target of jump will eventually return to caller. 14554 // TailJump below removes the return address. 14555 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ptr) %{ 14556 match(TailCall jump_target method_ptr); 14557 ins_cost(CALL_COST); 14558 14559 format %{ "MTCTR $jump_target \t// $method_ptr holds method\n\t" 14560 "BCTR \t// tail call" %} 14561 size(8); 14562 ins_encode %{ 14563 __ mtctr($jump_target$$Register); 14564 __ bctr(); 14565 %} 14566 ins_pipe(pipe_class_call); 14567 %} 14568 14569 // Return Instruction 14570 instruct Ret() %{ 14571 match(Return); 14572 format %{ "BLR \t// branch to link register" %} 14573 size(4); 14574 ins_encode %{ 14575 // LR is restored in MachEpilogNode. Just do the RET here. 14576 __ blr(); 14577 %} 14578 ins_pipe(pipe_class_default); 14579 %} 14580 14581 // Tail Jump; remove the return address; jump to target. 14582 // TailCall above leaves the return address around. 14583 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14584 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14585 // "restore" before this instruction (in Epilogue), we need to materialize it 14586 // in %i0. 14587 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14588 match(TailJump jump_target ex_oop); 14589 ins_cost(CALL_COST); 14590 14591 format %{ "LD R4_ARG2 = LR\n\t" 14592 "MTCTR $jump_target\n\t" 14593 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14594 size(12); 14595 ins_encode %{ 14596 __ ld(R4_ARG2/* issuing pc */, _abi0(lr), R1_SP); 14597 __ mtctr($jump_target$$Register); 14598 __ bctr(); 14599 %} 14600 ins_pipe(pipe_class_call); 14601 %} 14602 14603 // Create exception oop: created by stack-crawling runtime code. 14604 // Created exception is now available to this handler, and is setup 14605 // just prior to jumping to this handler. No code emitted. 14606 instruct CreateException(rarg1RegP ex_oop) %{ 14607 match(Set ex_oop (CreateEx)); 14608 ins_cost(0); 14609 14610 format %{ " -- \t// exception oop; no code emitted" %} 14611 size(0); 14612 ins_encode( /*empty*/ ); 14613 ins_pipe(pipe_class_default); 14614 %} 14615 14616 // Rethrow exception: The exception oop will come in the first 14617 // argument position. Then JUMP (not call) to the rethrow stub code. 14618 instruct RethrowException() %{ 14619 match(Rethrow); 14620 ins_cost(CALL_COST); 14621 14622 format %{ "Jmp rethrow_stub" %} 14623 ins_encode %{ 14624 cbuf.set_insts_mark(); 14625 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 14626 %} 14627 ins_pipe(pipe_class_call); 14628 %} 14629 14630 // Die now. 14631 instruct ShouldNotReachHere() %{ 14632 match(Halt); 14633 ins_cost(CALL_COST); 14634 14635 format %{ "ShouldNotReachHere" %} 14636 ins_encode %{ 14637 if (is_reachable()) { 14638 __ stop(_halt_reason); 14639 } 14640 %} 14641 ins_pipe(pipe_class_default); 14642 %} 14643 14644 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 14645 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 14646 // Get a DEF on threadRegP, no costs, no encoding, use 14647 // 'ins_should_rematerialize(true)' to avoid spilling. 14648 instruct tlsLoadP(threadRegP dst) %{ 14649 match(Set dst (ThreadLocal)); 14650 ins_cost(0); 14651 14652 ins_should_rematerialize(true); 14653 14654 format %{ " -- \t// $dst=Thread::current(), empty" %} 14655 size(0); 14656 ins_encode( /*empty*/ ); 14657 ins_pipe(pipe_class_empty); 14658 %} 14659 14660 //---Some PPC specific nodes--------------------------------------------------- 14661 14662 // Stop a group. 14663 instruct endGroup() %{ 14664 ins_cost(0); 14665 14666 ins_is_nop(true); 14667 14668 format %{ "End Bundle (ori r1, r1, 0)" %} 14669 size(4); 14670 ins_encode %{ 14671 __ endgroup(); 14672 %} 14673 ins_pipe(pipe_class_default); 14674 %} 14675 14676 // Nop instructions 14677 14678 instruct fxNop() %{ 14679 ins_cost(0); 14680 14681 ins_is_nop(true); 14682 14683 format %{ "fxNop" %} 14684 size(4); 14685 ins_encode %{ 14686 __ nop(); 14687 %} 14688 ins_pipe(pipe_class_default); 14689 %} 14690 14691 instruct fpNop0() %{ 14692 ins_cost(0); 14693 14694 ins_is_nop(true); 14695 14696 format %{ "fpNop0" %} 14697 size(4); 14698 ins_encode %{ 14699 __ fpnop0(); 14700 %} 14701 ins_pipe(pipe_class_default); 14702 %} 14703 14704 instruct fpNop1() %{ 14705 ins_cost(0); 14706 14707 ins_is_nop(true); 14708 14709 format %{ "fpNop1" %} 14710 size(4); 14711 ins_encode %{ 14712 __ fpnop1(); 14713 %} 14714 ins_pipe(pipe_class_default); 14715 %} 14716 14717 instruct brNop0() %{ 14718 ins_cost(0); 14719 size(4); 14720 format %{ "brNop0" %} 14721 ins_encode %{ 14722 __ brnop0(); 14723 %} 14724 ins_is_nop(true); 14725 ins_pipe(pipe_class_default); 14726 %} 14727 14728 instruct brNop1() %{ 14729 ins_cost(0); 14730 14731 ins_is_nop(true); 14732 14733 format %{ "brNop1" %} 14734 size(4); 14735 ins_encode %{ 14736 __ brnop1(); 14737 %} 14738 ins_pipe(pipe_class_default); 14739 %} 14740 14741 instruct brNop2() %{ 14742 ins_cost(0); 14743 14744 ins_is_nop(true); 14745 14746 format %{ "brNop2" %} 14747 size(4); 14748 ins_encode %{ 14749 __ brnop2(); 14750 %} 14751 ins_pipe(pipe_class_default); 14752 %} 14753 14754 instruct cacheWB(indirect addr) 14755 %{ 14756 match(CacheWB addr); 14757 14758 ins_cost(100); 14759 format %{ "cache writeback, address = $addr" %} 14760 ins_encode %{ 14761 assert($addr->index_position() < 0, "should be"); 14762 assert($addr$$disp == 0, "should be"); 14763 __ cache_wb(Address($addr$$base$$Register)); 14764 %} 14765 ins_pipe(pipe_class_default); 14766 %} 14767 14768 instruct cacheWBPreSync() 14769 %{ 14770 match(CacheWBPreSync); 14771 14772 ins_cost(0); 14773 format %{ "cache writeback presync" %} 14774 ins_encode %{ 14775 __ cache_wbsync(true); 14776 %} 14777 ins_pipe(pipe_class_default); 14778 %} 14779 14780 instruct cacheWBPostSync() 14781 %{ 14782 match(CacheWBPostSync); 14783 14784 ins_cost(100); 14785 format %{ "cache writeback postsync" %} 14786 ins_encode %{ 14787 __ cache_wbsync(false); 14788 %} 14789 ins_pipe(pipe_class_default); 14790 %} 14791 14792 //----------PEEPHOLE RULES----------------------------------------------------- 14793 // These must follow all instruction definitions as they use the names 14794 // defined in the instructions definitions. 14795 // 14796 // peepmatch ( root_instr_name [preceeding_instruction]* ); 14797 // 14798 // peepconstraint %{ 14799 // (instruction_number.operand_name relational_op instruction_number.operand_name 14800 // [, ...] ); 14801 // // instruction numbers are zero-based using left to right order in peepmatch 14802 // 14803 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14804 // // provide an instruction_number.operand_name for each operand that appears 14805 // // in the replacement instruction's match rule 14806 // 14807 // ---------VM FLAGS--------------------------------------------------------- 14808 // 14809 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14810 // 14811 // Each peephole rule is given an identifying number starting with zero and 14812 // increasing by one in the order seen by the parser. An individual peephole 14813 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14814 // on the command-line. 14815 // 14816 // ---------CURRENT LIMITATIONS---------------------------------------------- 14817 // 14818 // Only match adjacent instructions in same basic block 14819 // Only equality constraints 14820 // Only constraints between operands, not (0.dest_reg == EAX_enc) 14821 // Only one replacement instruction 14822 // 14823 // ---------EXAMPLE---------------------------------------------------------- 14824 // 14825 // // pertinent parts of existing instructions in architecture description 14826 // instruct movI(eRegI dst, eRegI src) %{ 14827 // match(Set dst (CopyI src)); 14828 // %} 14829 // 14830 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 14831 // match(Set dst (AddI dst src)); 14832 // effect(KILL cr); 14833 // %} 14834 // 14835 // // Change (inc mov) to lea 14836 // peephole %{ 14837 // // increment preceded by register-register move 14838 // peepmatch ( incI_eReg movI ); 14839 // // require that the destination register of the increment 14840 // // match the destination register of the move 14841 // peepconstraint ( 0.dst == 1.dst ); 14842 // // construct a replacement instruction that sets 14843 // // the destination to ( move's source register + one ) 14844 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14845 // %} 14846 // 14847 // Implementation no longer uses movX instructions since 14848 // machine-independent system no longer uses CopyX nodes. 14849 // 14850 // peephole %{ 14851 // peepmatch ( incI_eReg movI ); 14852 // peepconstraint ( 0.dst == 1.dst ); 14853 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14854 // %} 14855 // 14856 // peephole %{ 14857 // peepmatch ( decI_eReg movI ); 14858 // peepconstraint ( 0.dst == 1.dst ); 14859 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14860 // %} 14861 // 14862 // peephole %{ 14863 // peepmatch ( addI_eReg_imm movI ); 14864 // peepconstraint ( 0.dst == 1.dst ); 14865 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14866 // %} 14867 // 14868 // peephole %{ 14869 // peepmatch ( addP_eReg_imm movP ); 14870 // peepconstraint ( 0.dst == 1.dst ); 14871 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 14872 // %} 14873 14874 // // Change load of spilled value to only a spill 14875 // instruct storeI(memory mem, eRegI src) %{ 14876 // match(Set mem (StoreI mem src)); 14877 // %} 14878 // 14879 // instruct loadI(eRegI dst, memory mem) %{ 14880 // match(Set dst (LoadI mem)); 14881 // %} 14882 // 14883 peephole %{ 14884 peepmatch ( loadI storeI ); 14885 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14886 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 14887 %} 14888 14889 peephole %{ 14890 peepmatch ( loadL storeL ); 14891 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14892 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 14893 %} 14894 14895 peephole %{ 14896 peepmatch ( loadP storeP ); 14897 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 14898 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 14899 %} 14900 14901 //----------SMARTSPILL RULES--------------------------------------------------- 14902 // These must follow all instruction definitions as they use the names 14903 // defined in the instructions definitions.