1 // 2 // Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2020 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 reg_def VSR0 ( SOC, SOC, Op_VecX, 0, NULL); 261 reg_def VSR1 ( SOC, SOC, Op_VecX, 1, NULL); 262 reg_def VSR2 ( SOC, SOC, Op_VecX, 2, NULL); 263 reg_def VSR3 ( SOC, SOC, Op_VecX, 3, NULL); 264 reg_def VSR4 ( SOC, SOC, Op_VecX, 4, NULL); 265 reg_def VSR5 ( SOC, SOC, Op_VecX, 5, NULL); 266 reg_def VSR6 ( SOC, SOC, Op_VecX, 6, NULL); 267 reg_def VSR7 ( SOC, SOC, Op_VecX, 7, NULL); 268 reg_def VSR8 ( SOC, SOC, Op_VecX, 8, NULL); 269 reg_def VSR9 ( SOC, SOC, Op_VecX, 9, NULL); 270 reg_def VSR10 ( SOC, SOC, Op_VecX, 10, NULL); 271 reg_def VSR11 ( SOC, SOC, Op_VecX, 11, NULL); 272 reg_def VSR12 ( SOC, SOC, Op_VecX, 12, NULL); 273 reg_def VSR13 ( SOC, SOC, Op_VecX, 13, NULL); 274 reg_def VSR14 ( SOC, SOC, Op_VecX, 14, NULL); 275 reg_def VSR15 ( SOC, SOC, Op_VecX, 15, NULL); 276 reg_def VSR16 ( SOC, SOC, Op_VecX, 16, NULL); 277 reg_def VSR17 ( SOC, SOC, Op_VecX, 17, NULL); 278 reg_def VSR18 ( SOC, SOC, Op_VecX, 18, NULL); 279 reg_def VSR19 ( SOC, SOC, Op_VecX, 19, NULL); 280 reg_def VSR20 ( SOC, SOC, Op_VecX, 20, NULL); 281 reg_def VSR21 ( SOC, SOC, Op_VecX, 21, NULL); 282 reg_def VSR22 ( SOC, SOC, Op_VecX, 22, NULL); 283 reg_def VSR23 ( SOC, SOC, Op_VecX, 23, NULL); 284 reg_def VSR24 ( SOC, SOC, Op_VecX, 24, NULL); 285 reg_def VSR25 ( SOC, SOC, Op_VecX, 25, NULL); 286 reg_def VSR26 ( SOC, SOC, Op_VecX, 26, NULL); 287 reg_def VSR27 ( SOC, SOC, Op_VecX, 27, NULL); 288 reg_def VSR28 ( SOC, SOC, Op_VecX, 28, NULL); 289 reg_def VSR29 ( SOC, SOC, Op_VecX, 29, NULL); 290 reg_def VSR30 ( SOC, SOC, Op_VecX, 30, NULL); 291 reg_def VSR31 ( SOC, SOC, Op_VecX, 31, NULL); 292 reg_def VSR32 ( SOC, SOC, Op_VecX, 32, NULL); 293 reg_def VSR33 ( SOC, SOC, Op_VecX, 33, NULL); 294 reg_def VSR34 ( SOC, SOC, Op_VecX, 34, NULL); 295 reg_def VSR35 ( SOC, SOC, Op_VecX, 35, NULL); 296 reg_def VSR36 ( SOC, SOC, Op_VecX, 36, NULL); 297 reg_def VSR37 ( SOC, SOC, Op_VecX, 37, NULL); 298 reg_def VSR38 ( SOC, SOC, Op_VecX, 38, NULL); 299 reg_def VSR39 ( SOC, SOC, Op_VecX, 39, NULL); 300 reg_def VSR40 ( SOC, SOC, Op_VecX, 40, NULL); 301 reg_def VSR41 ( SOC, SOC, Op_VecX, 41, NULL); 302 reg_def VSR42 ( SOC, SOC, Op_VecX, 42, NULL); 303 reg_def VSR43 ( SOC, SOC, Op_VecX, 43, NULL); 304 reg_def VSR44 ( SOC, SOC, Op_VecX, 44, NULL); 305 reg_def VSR45 ( SOC, SOC, Op_VecX, 45, NULL); 306 reg_def VSR46 ( SOC, SOC, Op_VecX, 46, NULL); 307 reg_def VSR47 ( SOC, SOC, Op_VecX, 47, NULL); 308 reg_def VSR48 ( SOC, SOC, Op_VecX, 48, NULL); 309 reg_def VSR49 ( SOC, SOC, Op_VecX, 49, NULL); 310 reg_def VSR50 ( SOC, SOC, Op_VecX, 50, NULL); 311 reg_def VSR51 ( SOC, SOC, Op_VecX, 51, NULL); 312 reg_def VSR52 ( SOC, SOC, Op_VecX, 52, NULL); 313 reg_def VSR53 ( SOC, SOC, Op_VecX, 53, NULL); 314 reg_def VSR54 ( SOC, SOC, Op_VecX, 54, NULL); 315 reg_def VSR55 ( SOC, SOC, Op_VecX, 55, NULL); 316 reg_def VSR56 ( SOC, SOC, Op_VecX, 56, NULL); 317 reg_def VSR57 ( SOC, SOC, Op_VecX, 57, NULL); 318 reg_def VSR58 ( SOC, SOC, Op_VecX, 58, NULL); 319 reg_def VSR59 ( SOC, SOC, Op_VecX, 59, NULL); 320 reg_def VSR60 ( SOC, SOC, Op_VecX, 60, NULL); 321 reg_def VSR61 ( SOC, SOC, Op_VecX, 61, NULL); 322 reg_def VSR62 ( SOC, SOC, Op_VecX, 62, NULL); 323 reg_def VSR63 ( SOC, SOC, Op_VecX, 63, NULL); 324 325 // ---------------------------- 326 // Specify priority of register selection within phases of register 327 // allocation. Highest priority is first. A useful heuristic is to 328 // give registers a low priority when they are required by machine 329 // instructions, like EAX and EDX on I486, and choose no-save registers 330 // before save-on-call, & save-on-call before save-on-entry. Registers 331 // which participate in fixed calling sequences should come last. 332 // Registers which are used as pairs must fall on an even boundary. 333 334 // It's worth about 1% on SPEC geomean to get this right. 335 336 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 337 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 338 // R3_num. Therefore, R3_num may not be (and in reality is not) 339 // the same as R3->encoding()! Furthermore, we cannot make any 340 // assumptions on ordering, e.g. R3_num may be less than R2_num. 341 // Additionally, the function 342 // static enum RC rc_class(OptoReg::Name reg ) 343 // maps a given <register>_num value to its chunk type (except for flags) 344 // and its current implementation relies on chunk0 and chunk1 having a 345 // size of 64 each. 346 347 // If you change this allocation class, please have a look at the 348 // default values for the parameters RoundRobinIntegerRegIntervalStart 349 // and RoundRobinFloatRegIntervalStart 350 351 alloc_class chunk0 ( 352 // Chunk0 contains *all* 64 integer registers halves. 353 354 // "non-volatile" registers 355 R14, R14_H, 356 R15, R15_H, 357 R17, R17_H, 358 R18, R18_H, 359 R19, R19_H, 360 R20, R20_H, 361 R21, R21_H, 362 R22, R22_H, 363 R23, R23_H, 364 R24, R24_H, 365 R25, R25_H, 366 R26, R26_H, 367 R27, R27_H, 368 R28, R28_H, 369 R29, R29_H, 370 R30, R30_H, 371 R31, R31_H, 372 373 // scratch/special registers 374 R11, R11_H, 375 R12, R12_H, 376 377 // argument registers 378 R10, R10_H, 379 R9, R9_H, 380 R8, R8_H, 381 R7, R7_H, 382 R6, R6_H, 383 R5, R5_H, 384 R4, R4_H, 385 R3, R3_H, 386 387 // special registers, not available for allocation 388 R16, R16_H, // R16_thread 389 R13, R13_H, // system thread id 390 R2, R2_H, // may be used for TOC 391 R1, R1_H, // SP 392 R0, R0_H // R0 (scratch) 393 ); 394 395 // If you change this allocation class, please have a look at the 396 // default values for the parameters RoundRobinIntegerRegIntervalStart 397 // and RoundRobinFloatRegIntervalStart 398 399 alloc_class chunk1 ( 400 // Chunk1 contains *all* 64 floating-point registers halves. 401 402 // scratch register 403 F0, F0_H, 404 405 // argument registers 406 F13, F13_H, 407 F12, F12_H, 408 F11, F11_H, 409 F10, F10_H, 410 F9, F9_H, 411 F8, F8_H, 412 F7, F7_H, 413 F6, F6_H, 414 F5, F5_H, 415 F4, F4_H, 416 F3, F3_H, 417 F2, F2_H, 418 F1, F1_H, 419 420 // non-volatile registers 421 F14, F14_H, 422 F15, F15_H, 423 F16, F16_H, 424 F17, F17_H, 425 F18, F18_H, 426 F19, F19_H, 427 F20, F20_H, 428 F21, F21_H, 429 F22, F22_H, 430 F23, F23_H, 431 F24, F24_H, 432 F25, F25_H, 433 F26, F26_H, 434 F27, F27_H, 435 F28, F28_H, 436 F29, F29_H, 437 F30, F30_H, 438 F31, F31_H 439 ); 440 441 alloc_class chunk2 ( 442 // Chunk2 contains *all* 8 condition code registers. 443 444 CCR0, 445 CCR1, 446 CCR2, 447 CCR3, 448 CCR4, 449 CCR5, 450 CCR6, 451 CCR7 452 ); 453 454 alloc_class chunk3 ( 455 VSR0, 456 VSR1, 457 VSR2, 458 VSR3, 459 VSR4, 460 VSR5, 461 VSR6, 462 VSR7, 463 VSR8, 464 VSR9, 465 VSR10, 466 VSR11, 467 VSR12, 468 VSR13, 469 VSR14, 470 VSR15, 471 VSR16, 472 VSR17, 473 VSR18, 474 VSR19, 475 VSR20, 476 VSR21, 477 VSR22, 478 VSR23, 479 VSR24, 480 VSR25, 481 VSR26, 482 VSR27, 483 VSR28, 484 VSR29, 485 VSR30, 486 VSR31, 487 VSR32, 488 VSR33, 489 VSR34, 490 VSR35, 491 VSR36, 492 VSR37, 493 VSR38, 494 VSR39, 495 VSR40, 496 VSR41, 497 VSR42, 498 VSR43, 499 VSR44, 500 VSR45, 501 VSR46, 502 VSR47, 503 VSR48, 504 VSR49, 505 VSR50, 506 VSR51, 507 VSR52, 508 VSR53, 509 VSR54, 510 VSR55, 511 VSR56, 512 VSR57, 513 VSR58, 514 VSR59, 515 VSR60, 516 VSR61, 517 VSR62, 518 VSR63 519 ); 520 521 alloc_class chunk4 ( 522 // special registers 523 // These registers are not allocated, but used for nodes generated by postalloc expand. 524 SR_XER, 525 SR_LR, 526 SR_CTR, 527 SR_VRSAVE, 528 SR_SPEFSCR, 529 SR_PPR 530 ); 531 532 //-------Architecture Description Register Classes----------------------- 533 534 // Several register classes are automatically defined based upon 535 // information in this architecture description. 536 537 // 1) reg_class inline_cache_reg ( as defined in frame section ) 538 // 2) reg_class compiler_method_oop_reg ( as defined in frame section ) 539 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 540 // 3) 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 void PhaseOutput::pd_perform_mach_node_analysis() { 986 } 987 988 int MachNode::pd_alignment_required() const { 989 return 1; 990 } 991 992 int MachNode::compute_padding(int current_offset) const { 993 return 0; 994 } 995 996 // Should the matcher clone input 'm' of node 'n'? 997 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { 998 return false; 999 } 1000 1001 // Should the Matcher clone shifts on addressing modes, expecting them 1002 // to be subsumed into complex addressing expressions or compute them 1003 // into registers? 1004 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 1005 return clone_base_plus_offset_address(m, mstack, address_visited); 1006 } 1007 1008 void Compile::reshape_address(AddPNode* addp) { 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) 1106 return 4; 1107 1108 int vtable_index = this->_vtable_index; 1109 if (vtable_index < 0) { 1110 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 1111 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 1112 return 12; 1113 } else { 1114 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 1115 return 24; 1116 } 1117 } 1118 1119 int MachCallRuntimeNode::ret_addr_offset() { 1120 #if defined(ABI_ELFv2) 1121 return 28; 1122 #else 1123 return 40; 1124 #endif 1125 } 1126 1127 //============================================================================= 1128 1129 // condition code conversions 1130 1131 static int cc_to_boint(int cc) { 1132 return Assembler::bcondCRbiIs0 | (cc & 8); 1133 } 1134 1135 static int cc_to_inverse_boint(int cc) { 1136 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 1137 } 1138 1139 static int cc_to_biint(int cc, int flags_reg) { 1140 return (flags_reg << 2) | (cc & 3); 1141 } 1142 1143 //============================================================================= 1144 1145 // Compute padding required for nodes which need alignment. The padding 1146 // is the number of bytes (not instructions) which will be inserted before 1147 // the instruction. The padding must match the size of a NOP instruction. 1148 1149 // Currently not used on this platform. 1150 1151 //============================================================================= 1152 1153 // Indicate if the safepoint node needs the polling page as an input. 1154 bool SafePointNode::needs_polling_address_input() { 1155 // The address is loaded from thread by a seperate node. 1156 return true; 1157 } 1158 1159 //============================================================================= 1160 1161 // Emit an interrupt that is caught by the debugger (for debugging compiler). 1162 void emit_break(CodeBuffer &cbuf) { 1163 C2_MacroAssembler _masm(&cbuf); 1164 __ illtrap(); 1165 } 1166 1167 #ifndef PRODUCT 1168 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1169 st->print("BREAKPOINT"); 1170 } 1171 #endif 1172 1173 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1174 emit_break(cbuf); 1175 } 1176 1177 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1178 return MachNode::size(ra_); 1179 } 1180 1181 //============================================================================= 1182 1183 void emit_nop(CodeBuffer &cbuf) { 1184 C2_MacroAssembler _masm(&cbuf); 1185 __ nop(); 1186 } 1187 1188 static inline void emit_long(CodeBuffer &cbuf, int value) { 1189 *((int*)(cbuf.insts_end())) = value; 1190 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1191 } 1192 1193 //============================================================================= 1194 1195 %} // interrupt source 1196 1197 source_hpp %{ // Header information of the source block. 1198 1199 //-------------------------------------------------------------- 1200 //---< Used for optimization in Compile::Shorten_branches >--- 1201 //-------------------------------------------------------------- 1202 1203 class C2_MacroAssembler; 1204 1205 class CallStubImpl { 1206 1207 public: 1208 1209 // Emit call stub, compiled java to interpreter. 1210 static void emit_trampoline_stub(C2_MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1211 1212 // Size of call trampoline stub. 1213 // This doesn't need to be accurate to the byte, but it 1214 // must be larger than or equal to the real size of the stub. 1215 static uint size_call_trampoline() { 1216 return MacroAssembler::trampoline_stub_size; 1217 } 1218 1219 // number of relocations needed by a call trampoline stub 1220 static uint reloc_call_trampoline() { 1221 return 5; 1222 } 1223 1224 }; 1225 1226 %} // end source_hpp 1227 1228 source %{ 1229 1230 // Emit a trampoline stub for a call to a target which is too far away. 1231 // 1232 // code sequences: 1233 // 1234 // call-site: 1235 // branch-and-link to <destination> or <trampoline stub> 1236 // 1237 // Related trampoline stub for this call-site in the stub section: 1238 // load the call target from the constant pool 1239 // branch via CTR (LR/link still points to the call-site above) 1240 1241 void CallStubImpl::emit_trampoline_stub(C2_MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1242 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1243 if (stub == NULL) { 1244 ciEnv::current()->record_out_of_memory_failure(); 1245 } 1246 } 1247 1248 //============================================================================= 1249 1250 // Emit an inline branch-and-link call and a related trampoline stub. 1251 // 1252 // code sequences: 1253 // 1254 // call-site: 1255 // branch-and-link to <destination> or <trampoline stub> 1256 // 1257 // Related trampoline stub for this call-site in the stub section: 1258 // load the call target from the constant pool 1259 // branch via CTR (LR/link still points to the call-site above) 1260 // 1261 1262 typedef struct { 1263 int insts_call_instruction_offset; 1264 int ret_addr_offset; 1265 } EmitCallOffsets; 1266 1267 // Emit a branch-and-link instruction that branches to a trampoline. 1268 // - Remember the offset of the branch-and-link instruction. 1269 // - Add a relocation at the branch-and-link instruction. 1270 // - Emit a branch-and-link. 1271 // - Remember the return pc offset. 1272 EmitCallOffsets emit_call_with_trampoline_stub(C2_MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1273 EmitCallOffsets offsets = { -1, -1 }; 1274 const int start_offset = __ offset(); 1275 offsets.insts_call_instruction_offset = __ offset(); 1276 1277 // No entry point given, use the current pc. 1278 if (entry_point == NULL) entry_point = __ pc(); 1279 1280 // Put the entry point as a constant into the constant pool. 1281 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1282 if (entry_point_toc_addr == NULL) { 1283 ciEnv::current()->record_out_of_memory_failure(); 1284 return offsets; 1285 } 1286 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1287 1288 // Emit the trampoline stub which will be related to the branch-and-link below. 1289 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1290 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1291 __ relocate(rtype); 1292 1293 // Note: At this point we do not have the address of the trampoline 1294 // stub, and the entry point might be too far away for bl, so __ pc() 1295 // serves as dummy and the bl will be patched later. 1296 __ bl((address) __ pc()); 1297 1298 offsets.ret_addr_offset = __ offset() - start_offset; 1299 1300 return offsets; 1301 } 1302 1303 //============================================================================= 1304 1305 // Factory for creating loadConL* nodes for large/small constant pool. 1306 1307 static inline jlong replicate_immF(float con) { 1308 // Replicate float con 2 times and pack into vector. 1309 int val = *((int*)&con); 1310 jlong lval = val; 1311 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1312 return lval; 1313 } 1314 1315 //============================================================================= 1316 1317 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1318 int ConstantTable::calculate_table_base_offset() const { 1319 return 0; // absolute addressing, no offset 1320 } 1321 1322 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1323 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1324 iRegPdstOper *op_dst = new iRegPdstOper(); 1325 MachNode *m1 = new loadToc_hiNode(); 1326 MachNode *m2 = new loadToc_loNode(); 1327 1328 m1->add_req(NULL); 1329 m2->add_req(NULL, m1); 1330 m1->_opnds[0] = op_dst; 1331 m2->_opnds[0] = op_dst; 1332 m2->_opnds[1] = op_dst; 1333 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1334 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1335 nodes->push(m1); 1336 nodes->push(m2); 1337 } 1338 1339 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1340 // Is postalloc expanded. 1341 ShouldNotReachHere(); 1342 } 1343 1344 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1345 return 0; 1346 } 1347 1348 #ifndef PRODUCT 1349 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1350 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1351 } 1352 #endif 1353 1354 //============================================================================= 1355 1356 #ifndef PRODUCT 1357 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1358 Compile* C = ra_->C; 1359 const long framesize = C->output()->frame_slots() << LogBytesPerInt; 1360 1361 st->print("PROLOG\n\t"); 1362 if (C->output()->need_stack_bang(framesize)) { 1363 st->print("stack_overflow_check\n\t"); 1364 } 1365 1366 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1367 st->print("save return pc\n\t"); 1368 st->print("push frame %ld\n\t", -framesize); 1369 } 1370 } 1371 #endif 1372 1373 // Macro used instead of the common __ to emulate the pipes of PPC. 1374 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1375 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1376 // still no scheduling of this code is possible, the micro scheduler is aware of the 1377 // code and can update its internal data. The following mechanism is used to achieve this: 1378 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1379 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1380 #if 0 // TODO: PPC port 1381 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1382 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1383 _masm. 1384 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1385 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1386 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1387 C->hb_scheduling()->_pdScheduling->advance_offset 1388 #else 1389 #define ___(op) if (UsePower6SchedulerPPC64) \ 1390 Unimplemented(); \ 1391 _masm. 1392 #define ___stop if (UsePower6SchedulerPPC64) \ 1393 Unimplemented() 1394 #define ___advance if (UsePower6SchedulerPPC64) \ 1395 Unimplemented() 1396 #endif 1397 1398 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1399 Compile* C = ra_->C; 1400 C2_MacroAssembler _masm(&cbuf); 1401 1402 const long framesize = C->output()->frame_size_in_bytes(); 1403 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1404 1405 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1406 1407 const Register return_pc = R20; // Must match return_addr() in frame section. 1408 const Register callers_sp = R21; 1409 const Register push_frame_temp = R22; 1410 const Register toc_temp = R23; 1411 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1412 1413 if (method_is_frameless) { 1414 // Add nop at beginning of all frameless methods to prevent any 1415 // oop instructions from getting overwritten by make_not_entrant 1416 // (patching attempt would fail). 1417 ___(nop) nop(); 1418 } else { 1419 // Get return pc. 1420 ___(mflr) mflr(return_pc); 1421 } 1422 1423 if (C->clinit_barrier_on_entry()) { 1424 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1425 1426 Label L_skip_barrier; 1427 Register klass = toc_temp; 1428 1429 // Notify OOP recorder (don't need the relocation) 1430 AddressLiteral md = __ constant_metadata_address(C->method()->holder()->constant_encoding()); 1431 __ load_const_optimized(klass, md.value(), R0); 1432 __ clinit_barrier(klass, R16_thread, &L_skip_barrier /*L_fast_path*/); 1433 1434 __ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub(), R0); 1435 __ mtctr(klass); 1436 __ bctr(); 1437 1438 __ bind(L_skip_barrier); 1439 } 1440 1441 // Calls to C2R adapters often do not accept exceptional returns. 1442 // We require that their callers must bang for them. But be 1443 // careful, because some VM calls (such as call site linkage) can 1444 // use several kilobytes of stack. But the stack safety zone should 1445 // account for that. See bugs 4446381, 4468289, 4497237. 1446 1447 int bangsize = C->output()->bang_size_in_bytes(); 1448 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1449 if (C->output()->need_stack_bang(bangsize) && UseStackBanging) { 1450 // Unfortunately we cannot use the function provided in 1451 // assembler.cpp as we have to emulate the pipes. So I had to 1452 // insert the code of generate_stack_overflow_check(), see 1453 // assembler.cpp for some illuminative comments. 1454 const int page_size = os::vm_page_size(); 1455 int bang_end = JavaThread::stack_shadow_zone_size(); 1456 1457 // This is how far the previous frame's stack banging extended. 1458 const int bang_end_safe = bang_end; 1459 1460 if (bangsize > page_size) { 1461 bang_end += bangsize; 1462 } 1463 1464 int bang_offset = bang_end_safe; 1465 1466 while (bang_offset <= bang_end) { 1467 // Need at least one stack bang at end of shadow zone. 1468 1469 // Again I had to copy code, this time from assembler_ppc.cpp, 1470 // bang_stack_with_offset - see there for comments. 1471 1472 // Stack grows down, caller passes positive offset. 1473 assert(bang_offset > 0, "must bang with positive offset"); 1474 1475 long stdoffset = -bang_offset; 1476 1477 if (Assembler::is_simm(stdoffset, 16)) { 1478 // Signed 16 bit offset, a simple std is ok. 1479 if (UseLoadInstructionsForStackBangingPPC64) { 1480 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1481 } else { 1482 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1483 } 1484 } else if (Assembler::is_simm(stdoffset, 31)) { 1485 // Use largeoffset calculations for addis & ld/std. 1486 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1487 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1488 1489 Register tmp = R11; 1490 ___(addis) addis(tmp, R1_SP, hi); 1491 if (UseLoadInstructionsForStackBangingPPC64) { 1492 ___(ld) ld(R0, lo, tmp); 1493 } else { 1494 ___(std) std(R0, lo, tmp); 1495 } 1496 } else { 1497 ShouldNotReachHere(); 1498 } 1499 1500 bang_offset += page_size; 1501 } 1502 // R11 trashed 1503 } // C->output()->need_stack_bang(framesize) && UseStackBanging 1504 1505 unsigned int bytes = (unsigned int)framesize; 1506 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1507 ciMethod *currMethod = C->method(); 1508 1509 // Optimized version for most common case. 1510 if (UsePower6SchedulerPPC64 && 1511 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1512 !(false /* ConstantsALot TODO: PPC port*/)) { 1513 ___(or) mr(callers_sp, R1_SP); 1514 ___(std) std(return_pc, _abi(lr), R1_SP); 1515 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1516 return; 1517 } 1518 1519 if (!method_is_frameless) { 1520 // Get callers sp. 1521 ___(or) mr(callers_sp, R1_SP); 1522 1523 // Push method's frame, modifies SP. 1524 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1525 // The ABI is already accounted for in 'framesize' via the 1526 // 'out_preserve' area. 1527 Register tmp = push_frame_temp; 1528 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1529 if (Assembler::is_simm(-offset, 16)) { 1530 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1531 } else { 1532 long x = -offset; 1533 // Had to insert load_const(tmp, -offset). 1534 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1535 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1536 ___(rldicr) sldi(tmp, tmp, 32); 1537 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1538 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1539 1540 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1541 } 1542 } 1543 #if 0 // TODO: PPC port 1544 // For testing large constant pools, emit a lot of constants to constant pool. 1545 // "Randomize" const_size. 1546 if (ConstantsALot) { 1547 const int num_consts = const_size(); 1548 for (int i = 0; i < num_consts; i++) { 1549 __ long_constant(0xB0B5B00BBABE); 1550 } 1551 } 1552 #endif 1553 if (!method_is_frameless) { 1554 // Save return pc. 1555 ___(std) std(return_pc, _abi(lr), callers_sp); 1556 } 1557 1558 C->output()->set_frame_complete(cbuf.insts_size()); 1559 } 1560 #undef ___ 1561 #undef ___stop 1562 #undef ___advance 1563 1564 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1565 // Variable size. determine dynamically. 1566 return MachNode::size(ra_); 1567 } 1568 1569 int MachPrologNode::reloc() const { 1570 // Return number of relocatable values contained in this instruction. 1571 return 1; // 1 reloc entry for load_const(toc). 1572 } 1573 1574 //============================================================================= 1575 1576 #ifndef PRODUCT 1577 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1578 Compile* C = ra_->C; 1579 1580 st->print("EPILOG\n\t"); 1581 st->print("restore return pc\n\t"); 1582 st->print("pop frame\n\t"); 1583 1584 if (do_polling() && C->is_method_compilation()) { 1585 st->print("touch polling page\n\t"); 1586 } 1587 } 1588 #endif 1589 1590 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1591 Compile* C = ra_->C; 1592 C2_MacroAssembler _masm(&cbuf); 1593 1594 const long framesize = ((long)C->output()->frame_slots()) << LogBytesPerInt; 1595 assert(framesize >= 0, "negative frame-size?"); 1596 1597 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1598 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1599 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1600 const Register polling_page = R12; 1601 1602 if (!method_is_frameless) { 1603 // Restore return pc relative to callers' sp. 1604 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1605 } 1606 1607 if (method_needs_polling) { 1608 __ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread); 1609 } 1610 1611 if (!method_is_frameless) { 1612 // Move return pc to LR. 1613 __ mtlr(return_pc); 1614 // Pop frame (fixed frame-size). 1615 __ addi(R1_SP, R1_SP, (int)framesize); 1616 } 1617 1618 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1619 __ reserved_stack_check(return_pc); 1620 } 1621 1622 if (method_needs_polling) { 1623 // We need to mark the code position where the load from the safepoint 1624 // polling page was emitted as relocInfo::poll_return_type here. 1625 __ relocate(relocInfo::poll_return_type); 1626 __ load_from_polling_page(polling_page); 1627 } 1628 } 1629 1630 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1631 // Variable size. Determine dynamically. 1632 return MachNode::size(ra_); 1633 } 1634 1635 int MachEpilogNode::reloc() const { 1636 // Return number of relocatable values contained in this instruction. 1637 return 1; // 1 for load_from_polling_page. 1638 } 1639 1640 const Pipeline * MachEpilogNode::pipeline() const { 1641 return MachNode::pipeline_class(); 1642 } 1643 1644 #if 0 // TODO: PPC port 1645 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1646 C2_MacroAssembler _masm(&cbuf); 1647 if (LoadPollAddressFromThread) { 1648 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1649 } else { 1650 _masm.nop(); 1651 } 1652 } 1653 1654 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1655 if (LoadPollAddressFromThread) { 1656 return 4; 1657 } else { 1658 return 4; 1659 } 1660 } 1661 1662 #ifndef PRODUCT 1663 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1664 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1665 } 1666 #endif 1667 1668 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1669 return RSCRATCH1_BITS64_REG_mask(); 1670 } 1671 #endif // PPC port 1672 1673 // ============================================================================= 1674 1675 // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or 1676 // rc_stack. 1677 enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack }; 1678 1679 static enum RC rc_class(OptoReg::Name reg) { 1680 // Return the register class for the given register. The given register 1681 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1682 // enumeration in adGlobals_ppc.hpp. 1683 1684 if (reg == OptoReg::Bad) return rc_bad; 1685 1686 // We have 64 integer register halves, starting at index 0. 1687 if (reg < 64) return rc_int; 1688 1689 // We have 64 floating-point register halves, starting at index 64. 1690 if (reg < 64+64) return rc_float; 1691 1692 // We have 64 vector-scalar registers, starting at index 128. 1693 if (reg < 64+64+64) return rc_vs; 1694 1695 // Between float regs & stack are the flags regs. 1696 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1697 1698 return rc_stack; 1699 } 1700 1701 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1702 bool do_print, Compile* C, outputStream *st) { 1703 1704 assert(opcode == Assembler::LD_OPCODE || 1705 opcode == Assembler::STD_OPCODE || 1706 opcode == Assembler::LWZ_OPCODE || 1707 opcode == Assembler::STW_OPCODE || 1708 opcode == Assembler::LFD_OPCODE || 1709 opcode == Assembler::STFD_OPCODE || 1710 opcode == Assembler::LFS_OPCODE || 1711 opcode == Assembler::STFS_OPCODE, 1712 "opcode not supported"); 1713 1714 if (cbuf) { 1715 int d = 1716 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1717 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1718 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1719 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1720 } 1721 #ifndef PRODUCT 1722 else if (do_print) { 1723 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1724 op_str, 1725 Matcher::regName[reg], 1726 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1727 } 1728 #endif 1729 return 4; // size 1730 } 1731 1732 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1733 Compile* C = ra_->C; 1734 1735 // Get registers to move. 1736 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1737 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1738 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1739 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1740 1741 enum RC src_hi_rc = rc_class(src_hi); 1742 enum RC src_lo_rc = rc_class(src_lo); 1743 enum RC dst_hi_rc = rc_class(dst_hi); 1744 enum RC dst_lo_rc = rc_class(dst_lo); 1745 1746 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1747 if (src_hi != OptoReg::Bad) 1748 assert((src_lo&1)==0 && src_lo+1==src_hi && 1749 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1750 "expected aligned-adjacent pairs"); 1751 // Generate spill code! 1752 int size = 0; 1753 1754 if (src_lo == dst_lo && src_hi == dst_hi) 1755 return size; // Self copy, no move. 1756 1757 if (bottom_type()->isa_vect() != NULL && ideal_reg() == Op_VecX) { 1758 // Memory->Memory Spill. 1759 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1760 int src_offset = ra_->reg2offset(src_lo); 1761 int dst_offset = ra_->reg2offset(dst_lo); 1762 if (cbuf) { 1763 C2_MacroAssembler _masm(cbuf); 1764 __ ld(R0, src_offset, R1_SP); 1765 __ std(R0, dst_offset, R1_SP); 1766 __ ld(R0, src_offset+8, R1_SP); 1767 __ std(R0, dst_offset+8, R1_SP); 1768 } 1769 size += 16; 1770 } 1771 // VectorSRegister->Memory Spill. 1772 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) { 1773 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1774 int dst_offset = ra_->reg2offset(dst_lo); 1775 if (cbuf) { 1776 C2_MacroAssembler _masm(cbuf); 1777 __ addi(R0, R1_SP, dst_offset); 1778 __ stxvd2x(Rsrc, R0); 1779 } 1780 size += 8; 1781 } 1782 // Memory->VectorSRegister Spill. 1783 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) { 1784 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1785 int src_offset = ra_->reg2offset(src_lo); 1786 if (cbuf) { 1787 C2_MacroAssembler _masm(cbuf); 1788 __ addi(R0, R1_SP, src_offset); 1789 __ lxvd2x(Rdst, R0); 1790 } 1791 size += 8; 1792 } 1793 // VectorSRegister->VectorSRegister. 1794 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) { 1795 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1796 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1797 if (cbuf) { 1798 C2_MacroAssembler _masm(cbuf); 1799 __ xxlor(Rdst, Rsrc, Rsrc); 1800 } 1801 size += 4; 1802 } 1803 else { 1804 ShouldNotReachHere(); // No VSR spill. 1805 } 1806 return size; 1807 } 1808 1809 // -------------------------------------- 1810 // Memory->Memory Spill. Use R0 to hold the value. 1811 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1812 int src_offset = ra_->reg2offset(src_lo); 1813 int dst_offset = ra_->reg2offset(dst_lo); 1814 if (src_hi != OptoReg::Bad) { 1815 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1816 "expected same type of move for high parts"); 1817 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1818 if (!cbuf && !do_size) st->print("\n\t"); 1819 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1820 } else { 1821 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1822 if (!cbuf && !do_size) st->print("\n\t"); 1823 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1824 } 1825 return size; 1826 } 1827 1828 // -------------------------------------- 1829 // Check for float->int copy; requires a trip through memory. 1830 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1831 Unimplemented(); 1832 } 1833 1834 // -------------------------------------- 1835 // Check for integer reg-reg copy. 1836 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1837 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1838 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1839 size = (Rsrc != Rdst) ? 4 : 0; 1840 1841 if (cbuf) { 1842 C2_MacroAssembler _masm(cbuf); 1843 if (size) { 1844 __ mr(Rdst, Rsrc); 1845 } 1846 } 1847 #ifndef PRODUCT 1848 else if (!do_size) { 1849 if (size) { 1850 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1851 } else { 1852 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1853 } 1854 } 1855 #endif 1856 return size; 1857 } 1858 1859 // Check for integer store. 1860 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1861 int dst_offset = ra_->reg2offset(dst_lo); 1862 if (src_hi != OptoReg::Bad) { 1863 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1864 "expected same type of move for high parts"); 1865 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1866 } else { 1867 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1868 } 1869 return size; 1870 } 1871 1872 // Check for integer load. 1873 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1874 int src_offset = ra_->reg2offset(src_lo); 1875 if (src_hi != OptoReg::Bad) { 1876 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1877 "expected same type of move for high parts"); 1878 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1879 } else { 1880 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1881 } 1882 return size; 1883 } 1884 1885 // Check for float reg-reg copy. 1886 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1887 if (cbuf) { 1888 C2_MacroAssembler _masm(cbuf); 1889 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1890 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1891 __ fmr(Rdst, Rsrc); 1892 } 1893 #ifndef PRODUCT 1894 else if (!do_size) { 1895 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1896 } 1897 #endif 1898 return 4; 1899 } 1900 1901 // Check for float store. 1902 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1903 int dst_offset = ra_->reg2offset(dst_lo); 1904 if (src_hi != OptoReg::Bad) { 1905 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1906 "expected same type of move for high parts"); 1907 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1908 } else { 1909 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1910 } 1911 return size; 1912 } 1913 1914 // Check for float load. 1915 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1916 int src_offset = ra_->reg2offset(src_lo); 1917 if (src_hi != OptoReg::Bad) { 1918 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1919 "expected same type of move for high parts"); 1920 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1921 } else { 1922 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1923 } 1924 return size; 1925 } 1926 1927 // -------------------------------------------------------------------- 1928 // Check for hi bits still needing moving. Only happens for misaligned 1929 // arguments to native calls. 1930 if (src_hi == dst_hi) 1931 return size; // Self copy; no move. 1932 1933 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1934 ShouldNotReachHere(); // Unimplemented 1935 return 0; 1936 } 1937 1938 #ifndef PRODUCT 1939 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1940 if (!ra_) 1941 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1942 else 1943 implementation(NULL, ra_, false, st); 1944 } 1945 #endif 1946 1947 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1948 implementation(&cbuf, ra_, false, NULL); 1949 } 1950 1951 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1952 return implementation(NULL, ra_, true, NULL); 1953 } 1954 1955 #if 0 // TODO: PPC port 1956 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1957 #ifndef PRODUCT 1958 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1959 #endif 1960 assert(ra_->node_regs_max_index() != 0, ""); 1961 1962 // Get registers to move. 1963 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1964 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1965 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1966 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1967 1968 enum RC src_lo_rc = rc_class(src_lo); 1969 enum RC dst_lo_rc = rc_class(dst_lo); 1970 1971 if (src_lo == dst_lo && src_hi == dst_hi) 1972 return ppc64Opcode_none; // Self copy, no move. 1973 1974 // -------------------------------------- 1975 // Memory->Memory Spill. Use R0 to hold the value. 1976 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1977 return ppc64Opcode_compound; 1978 } 1979 1980 // -------------------------------------- 1981 // Check for float->int copy; requires a trip through memory. 1982 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1983 Unimplemented(); 1984 } 1985 1986 // -------------------------------------- 1987 // Check for integer reg-reg copy. 1988 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1989 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1990 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1991 if (Rsrc == Rdst) { 1992 return ppc64Opcode_none; 1993 } else { 1994 return ppc64Opcode_or; 1995 } 1996 } 1997 1998 // Check for integer store. 1999 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 2000 if (src_hi != OptoReg::Bad) { 2001 return ppc64Opcode_std; 2002 } else { 2003 return ppc64Opcode_stw; 2004 } 2005 } 2006 2007 // Check for integer load. 2008 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 2009 if (src_hi != OptoReg::Bad) { 2010 return ppc64Opcode_ld; 2011 } else { 2012 return ppc64Opcode_lwz; 2013 } 2014 } 2015 2016 // Check for float reg-reg copy. 2017 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 2018 return ppc64Opcode_fmr; 2019 } 2020 2021 // Check for float store. 2022 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 2023 if (src_hi != OptoReg::Bad) { 2024 return ppc64Opcode_stfd; 2025 } else { 2026 return ppc64Opcode_stfs; 2027 } 2028 } 2029 2030 // Check for float load. 2031 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 2032 if (src_hi != OptoReg::Bad) { 2033 return ppc64Opcode_lfd; 2034 } else { 2035 return ppc64Opcode_lfs; 2036 } 2037 } 2038 2039 // -------------------------------------------------------------------- 2040 // Check for hi bits still needing moving. Only happens for misaligned 2041 // arguments to native calls. 2042 if (src_hi == dst_hi) { 2043 return ppc64Opcode_none; // Self copy; no move. 2044 } 2045 2046 ShouldNotReachHere(); 2047 return ppc64Opcode_undefined; 2048 } 2049 #endif // PPC port 2050 2051 #ifndef PRODUCT 2052 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2053 st->print("NOP \t// %d nops to pad for loops.", _count); 2054 } 2055 #endif 2056 2057 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 2058 C2_MacroAssembler _masm(&cbuf); 2059 // _count contains the number of nops needed for padding. 2060 for (int i = 0; i < _count; i++) { 2061 __ nop(); 2062 } 2063 } 2064 2065 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 2066 return _count * 4; 2067 } 2068 2069 #ifndef PRODUCT 2070 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2071 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2072 char reg_str[128]; 2073 ra_->dump_register(this, reg_str); 2074 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 2075 } 2076 #endif 2077 2078 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2079 C2_MacroAssembler _masm(&cbuf); 2080 2081 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2082 int reg = ra_->get_encode(this); 2083 2084 if (Assembler::is_simm(offset, 16)) { 2085 __ addi(as_Register(reg), R1, offset); 2086 } else { 2087 ShouldNotReachHere(); 2088 } 2089 } 2090 2091 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2092 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2093 return 4; 2094 } 2095 2096 #ifndef PRODUCT 2097 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2098 st->print_cr("---- MachUEPNode ----"); 2099 st->print_cr("..."); 2100 } 2101 #endif 2102 2103 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2104 // This is the unverified entry point. 2105 C2_MacroAssembler _masm(&cbuf); 2106 2107 // Inline_cache contains a klass. 2108 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 2109 Register receiver_klass = R12_scratch2; // tmp 2110 2111 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 2112 assert(R11_scratch1 == R11, "need prologue scratch register"); 2113 2114 // Check for NULL argument if we don't have implicit null checks. 2115 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 2116 if (TrapBasedNullChecks) { 2117 __ trap_null_check(R3_ARG1); 2118 } else { 2119 Label valid; 2120 __ cmpdi(CCR0, R3_ARG1, 0); 2121 __ bne_predict_taken(CCR0, valid); 2122 // We have a null argument, branch to ic_miss_stub. 2123 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2124 relocInfo::runtime_call_type); 2125 __ bind(valid); 2126 } 2127 } 2128 // Assume argument is not NULL, load klass from receiver. 2129 __ load_klass(receiver_klass, R3_ARG1); 2130 2131 if (TrapBasedICMissChecks) { 2132 __ trap_ic_miss_check(receiver_klass, ic_klass); 2133 } else { 2134 Label valid; 2135 __ cmpd(CCR0, receiver_klass, ic_klass); 2136 __ beq_predict_taken(CCR0, valid); 2137 // We have an unexpected klass, branch to ic_miss_stub. 2138 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2139 relocInfo::runtime_call_type); 2140 __ bind(valid); 2141 } 2142 2143 // Argument is valid and klass is as expected, continue. 2144 } 2145 2146 #if 0 // TODO: PPC port 2147 // Optimize UEP code on z (save a load_const() call in main path). 2148 int MachUEPNode::ep_offset() { 2149 return 0; 2150 } 2151 #endif 2152 2153 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2154 // Variable size. Determine dynamically. 2155 return MachNode::size(ra_); 2156 } 2157 2158 //============================================================================= 2159 2160 %} // interrupt source 2161 2162 source_hpp %{ // Header information of the source block. 2163 2164 class HandlerImpl { 2165 2166 public: 2167 2168 static int emit_exception_handler(CodeBuffer &cbuf); 2169 static int emit_deopt_handler(CodeBuffer& cbuf); 2170 2171 static uint size_exception_handler() { 2172 // The exception_handler is a b64_patchable. 2173 return MacroAssembler::b64_patchable_size; 2174 } 2175 2176 static uint size_deopt_handler() { 2177 // The deopt_handler is a bl64_patchable. 2178 return MacroAssembler::bl64_patchable_size; 2179 } 2180 2181 }; 2182 2183 class Node::PD { 2184 public: 2185 enum NodeFlags { 2186 _last_flag = Node::_last_flag 2187 }; 2188 }; 2189 2190 %} // end source_hpp 2191 2192 source %{ 2193 2194 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2195 C2_MacroAssembler _masm(&cbuf); 2196 2197 address base = __ start_a_stub(size_exception_handler()); 2198 if (base == NULL) return 0; // CodeBuffer::expand failed 2199 2200 int offset = __ offset(); 2201 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2202 relocInfo::runtime_call_type); 2203 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2204 __ end_a_stub(); 2205 2206 return offset; 2207 } 2208 2209 // The deopt_handler is like the exception handler, but it calls to 2210 // the deoptimization blob instead of jumping to the exception blob. 2211 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2212 C2_MacroAssembler _masm(&cbuf); 2213 2214 address base = __ start_a_stub(size_deopt_handler()); 2215 if (base == NULL) return 0; // CodeBuffer::expand failed 2216 2217 int offset = __ offset(); 2218 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2219 relocInfo::runtime_call_type); 2220 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2221 __ end_a_stub(); 2222 2223 return offset; 2224 } 2225 2226 //============================================================================= 2227 2228 // Use a frame slots bias for frameless methods if accessing the stack. 2229 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2230 if (as_Register(reg_enc) == R1_SP) { 2231 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2232 } 2233 return 0; 2234 } 2235 2236 const bool Matcher::match_rule_supported(int opcode) { 2237 if (!has_match_rule(opcode)) 2238 return false; 2239 2240 bool ret_value = true; 2241 switch (opcode) { 2242 case Op_SqrtD: 2243 return VM_Version::has_fsqrt(); 2244 case Op_CountLeadingZerosI: 2245 case Op_CountLeadingZerosL: 2246 if (!UseCountLeadingZerosInstructionsPPC64) 2247 return false; 2248 break; 2249 case Op_CountTrailingZerosI: 2250 case Op_CountTrailingZerosL: 2251 if (!UseCountLeadingZerosInstructionsPPC64 && 2252 !UseCountTrailingZerosInstructionsPPC64) 2253 return false; 2254 break; 2255 2256 case Op_PopCountI: 2257 case Op_PopCountL: 2258 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2259 2260 case Op_StrComp: 2261 return SpecialStringCompareTo; 2262 case Op_StrEquals: 2263 return SpecialStringEquals; 2264 case Op_StrIndexOf: 2265 case Op_StrIndexOfChar: 2266 return SpecialStringIndexOf; 2267 case Op_AddVB: 2268 case Op_AddVS: 2269 case Op_AddVI: 2270 case Op_AddVF: 2271 case Op_AddVD: 2272 case Op_SubVB: 2273 case Op_SubVS: 2274 case Op_SubVI: 2275 case Op_SubVF: 2276 case Op_SubVD: 2277 case Op_MulVS: 2278 case Op_MulVF: 2279 case Op_MulVD: 2280 case Op_DivVF: 2281 case Op_DivVD: 2282 case Op_AbsVF: 2283 case Op_AbsVD: 2284 case Op_NegVF: 2285 case Op_NegVD: 2286 case Op_SqrtVF: 2287 case Op_SqrtVD: 2288 case Op_AddVL: 2289 case Op_SubVL: 2290 case Op_MulVI: 2291 case Op_RoundDoubleModeV: 2292 return SuperwordUseVSX; 2293 case Op_PopCountVI: 2294 return (SuperwordUseVSX && UsePopCountInstruction); 2295 case Op_FmaVF: 2296 case Op_FmaVD: 2297 return (SuperwordUseVSX && UseFMA); 2298 case Op_Digit: 2299 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isDigit); 2300 case Op_LowerCase: 2301 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isLowerCase); 2302 case Op_UpperCase: 2303 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isUpperCase); 2304 case Op_Whitespace: 2305 return vmIntrinsics::is_intrinsic_available(vmIntrinsics::_isWhitespace); 2306 2307 case Op_CacheWB: 2308 case Op_CacheWBPreSync: 2309 case Op_CacheWBPostSync: 2310 if (!VM_Version::supports_data_cache_line_flush()) { 2311 ret_value = false; 2312 } 2313 break; 2314 } 2315 2316 return ret_value; // Per default match rules are supported. 2317 } 2318 2319 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { 2320 2321 // TODO 2322 // identify extra cases that we might want to provide match rules for 2323 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2324 bool ret_value = match_rule_supported(opcode); 2325 // Add rules here. 2326 2327 return ret_value; // Per default match rules are supported. 2328 } 2329 2330 const bool Matcher::has_predicated_vectors(void) { 2331 return false; 2332 } 2333 2334 const int Matcher::float_pressure(int default_pressure_threshold) { 2335 return default_pressure_threshold; 2336 } 2337 2338 int Matcher::regnum_to_fpu_offset(int regnum) { 2339 // No user for this method? 2340 Unimplemented(); 2341 return 999; 2342 } 2343 2344 const bool Matcher::convL2FSupported(void) { 2345 // fcfids can do the conversion (>= Power7). 2346 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2347 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2348 } 2349 2350 // Vector width in bytes. 2351 const int Matcher::vector_width_in_bytes(BasicType bt) { 2352 if (SuperwordUseVSX) { 2353 assert(MaxVectorSize == 16, ""); 2354 return 16; 2355 } else { 2356 assert(MaxVectorSize == 8, ""); 2357 return 8; 2358 } 2359 } 2360 2361 // Vector ideal reg. 2362 const uint Matcher::vector_ideal_reg(int size) { 2363 if (SuperwordUseVSX) { 2364 assert(MaxVectorSize == 16 && size == 16, ""); 2365 return Op_VecX; 2366 } else { 2367 assert(MaxVectorSize == 8 && size == 8, ""); 2368 return Op_RegL; 2369 } 2370 } 2371 2372 // Limits on vector size (number of elements) loaded into vector. 2373 const int Matcher::max_vector_size(const BasicType bt) { 2374 assert(is_java_primitive(bt), "only primitive type vectors"); 2375 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2376 } 2377 2378 const int Matcher::min_vector_size(const BasicType bt) { 2379 return max_vector_size(bt); // Same as max. 2380 } 2381 2382 // PPC implementation uses VSX load/store instructions (if 2383 // SuperwordUseVSX) which support 4 byte but not arbitrary alignment 2384 const bool Matcher::misaligned_vectors_ok() { 2385 return false; 2386 } 2387 2388 // PPC AES support not yet implemented 2389 const bool Matcher::pass_original_key_for_aes() { 2390 return false; 2391 } 2392 2393 // RETURNS: whether this branch offset is short enough that a short 2394 // branch can be used. 2395 // 2396 // If the platform does not provide any short branch variants, then 2397 // this method should return `false' for offset 0. 2398 // 2399 // `Compile::Fill_buffer' will decide on basis of this information 2400 // whether to do the pass `Compile::Shorten_branches' at all. 2401 // 2402 // And `Compile::Shorten_branches' will decide on basis of this 2403 // information whether to replace particular branch sites by short 2404 // ones. 2405 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2406 // Is the offset within the range of a ppc64 pc relative branch? 2407 bool b; 2408 2409 const int safety_zone = 3 * BytesPerInstWord; 2410 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2411 29 - 16 + 1 + 2); 2412 return b; 2413 } 2414 2415 const bool Matcher::isSimpleConstant64(jlong value) { 2416 // Probably always true, even if a temp register is required. 2417 return true; 2418 } 2419 /* TODO: PPC port 2420 // Make a new machine dependent decode node (with its operands). 2421 MachTypeNode *Matcher::make_decode_node() { 2422 assert(CompressedOops::base() == NULL && CompressedOops::shift() == 0, 2423 "This method is only implemented for unscaled cOops mode so far"); 2424 MachTypeNode *decode = new decodeN_unscaledNode(); 2425 decode->set_opnd_array(0, new iRegPdstOper()); 2426 decode->set_opnd_array(1, new iRegNsrcOper()); 2427 return decode; 2428 } 2429 */ 2430 2431 // false => size gets scaled to BytesPerLong, ok. 2432 const bool Matcher::init_array_count_is_in_bytes = false; 2433 2434 // Use conditional move (CMOVL) on Power7. 2435 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2436 2437 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2438 // fsel doesn't accept a condition register as input, so this would be slightly different. 2439 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2440 2441 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2442 const bool Matcher::require_postalloc_expand = true; 2443 2444 // Do we need to mask the count passed to shift instructions or does 2445 // the cpu only look at the lower 5/6 bits anyway? 2446 // PowerPC requires masked shift counts. 2447 const bool Matcher::need_masked_shift_count = true; 2448 2449 // No support for generic vector operands. 2450 const bool Matcher::supports_generic_vector_operands = false; 2451 2452 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { 2453 ShouldNotReachHere(); // generic vector operands not supported 2454 return NULL; 2455 } 2456 2457 bool Matcher::is_generic_reg2reg_move(MachNode* m) { 2458 ShouldNotReachHere(); // generic vector operands not supported 2459 return false; 2460 } 2461 2462 bool Matcher::is_generic_vector(MachOper* opnd) { 2463 ShouldNotReachHere(); // generic vector operands not supported 2464 return false; 2465 } 2466 2467 // This affects two different things: 2468 // - how Decode nodes are matched 2469 // - how ImplicitNullCheck opportunities are recognized 2470 // If true, the matcher will try to remove all Decodes and match them 2471 // (as operands) into nodes. NullChecks are not prepared to deal with 2472 // Decodes by final_graph_reshaping(). 2473 // If false, final_graph_reshaping() forces the decode behind the Cmp 2474 // for a NullCheck. The matcher matches the Decode node into a register. 2475 // Implicit_null_check optimization moves the Decode along with the 2476 // memory operation back up before the NullCheck. 2477 bool Matcher::narrow_oop_use_complex_address() { 2478 // TODO: PPC port if (MatchDecodeNodes) return true; 2479 return false; 2480 } 2481 2482 bool Matcher::narrow_klass_use_complex_address() { 2483 NOT_LP64(ShouldNotCallThis()); 2484 assert(UseCompressedClassPointers, "only for compressed klass code"); 2485 // TODO: PPC port if (MatchDecodeNodes) return true; 2486 return false; 2487 } 2488 2489 bool Matcher::const_oop_prefer_decode() { 2490 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2491 return CompressedOops::base() == NULL; 2492 } 2493 2494 bool Matcher::const_klass_prefer_decode() { 2495 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2496 return CompressedKlassPointers::base() == NULL; 2497 } 2498 2499 // Is it better to copy float constants, or load them directly from memory? 2500 // Intel can load a float constant from a direct address, requiring no 2501 // extra registers. Most RISCs will have to materialize an address into a 2502 // register first, so they would do better to copy the constant from stack. 2503 const bool Matcher::rematerialize_float_constants = false; 2504 2505 // If CPU can load and store mis-aligned doubles directly then no fixup is 2506 // needed. Else we split the double into 2 integer pieces and move it 2507 // piece-by-piece. Only happens when passing doubles into C code as the 2508 // Java calling convention forces doubles to be aligned. 2509 const bool Matcher::misaligned_doubles_ok = true; 2510 2511 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2512 Unimplemented(); 2513 } 2514 2515 // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. 2516 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2517 2518 // Do floats take an entire double register or just half? 2519 // 2520 // A float occupies a ppc64 double register. For the allocator, a 2521 // ppc64 double register appears as a pair of float registers. 2522 bool Matcher::float_in_double() { return true; } 2523 2524 // Do ints take an entire long register or just half? 2525 // The relevant question is how the int is callee-saved: 2526 // the whole long is written but de-opt'ing will have to extract 2527 // the relevant 32 bits. 2528 const bool Matcher::int_in_long = true; 2529 2530 // Constants for c2c and c calling conventions. 2531 2532 const MachRegisterNumbers iarg_reg[8] = { 2533 R3_num, R4_num, R5_num, R6_num, 2534 R7_num, R8_num, R9_num, R10_num 2535 }; 2536 2537 const MachRegisterNumbers farg_reg[13] = { 2538 F1_num, F2_num, F3_num, F4_num, 2539 F5_num, F6_num, F7_num, F8_num, 2540 F9_num, F10_num, F11_num, F12_num, 2541 F13_num 2542 }; 2543 2544 const MachRegisterNumbers vsarg_reg[64] = { 2545 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2546 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2547 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2548 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2549 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2550 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2551 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2552 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2553 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2554 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2555 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2556 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2557 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2558 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2559 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2560 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2561 }; 2562 2563 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2564 2565 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2566 2567 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2568 2569 // Return whether or not this register is ever used as an argument. This 2570 // function is used on startup to build the trampoline stubs in generateOptoStub. 2571 // Registers not mentioned will be killed by the VM call in the trampoline, and 2572 // arguments in those registers not be available to the callee. 2573 bool Matcher::can_be_java_arg(int reg) { 2574 // We return true for all registers contained in iarg_reg[] and 2575 // farg_reg[] and their virtual halves. 2576 // We must include the virtual halves in order to get STDs and LDs 2577 // instead of STWs and LWs in the trampoline stubs. 2578 2579 if ( reg == R3_num || reg == R3_H_num 2580 || reg == R4_num || reg == R4_H_num 2581 || reg == R5_num || reg == R5_H_num 2582 || reg == R6_num || reg == R6_H_num 2583 || reg == R7_num || reg == R7_H_num 2584 || reg == R8_num || reg == R8_H_num 2585 || reg == R9_num || reg == R9_H_num 2586 || reg == R10_num || reg == R10_H_num) 2587 return true; 2588 2589 if ( reg == F1_num || reg == F1_H_num 2590 || reg == F2_num || reg == F2_H_num 2591 || reg == F3_num || reg == F3_H_num 2592 || reg == F4_num || reg == F4_H_num 2593 || reg == F5_num || reg == F5_H_num 2594 || reg == F6_num || reg == F6_H_num 2595 || reg == F7_num || reg == F7_H_num 2596 || reg == F8_num || reg == F8_H_num 2597 || reg == F9_num || reg == F9_H_num 2598 || reg == F10_num || reg == F10_H_num 2599 || reg == F11_num || reg == F11_H_num 2600 || reg == F12_num || reg == F12_H_num 2601 || reg == F13_num || reg == F13_H_num) 2602 return true; 2603 2604 return false; 2605 } 2606 2607 bool Matcher::is_spillable_arg(int reg) { 2608 return can_be_java_arg(reg); 2609 } 2610 2611 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2612 return false; 2613 } 2614 2615 // Register for DIVI projection of divmodI. 2616 RegMask Matcher::divI_proj_mask() { 2617 ShouldNotReachHere(); 2618 return RegMask(); 2619 } 2620 2621 // Register for MODI projection of divmodI. 2622 RegMask Matcher::modI_proj_mask() { 2623 ShouldNotReachHere(); 2624 return RegMask(); 2625 } 2626 2627 // Register for DIVL projection of divmodL. 2628 RegMask Matcher::divL_proj_mask() { 2629 ShouldNotReachHere(); 2630 return RegMask(); 2631 } 2632 2633 // Register for MODL projection of divmodL. 2634 RegMask Matcher::modL_proj_mask() { 2635 ShouldNotReachHere(); 2636 return RegMask(); 2637 } 2638 2639 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2640 return RegMask(); 2641 } 2642 2643 const bool Matcher::convi2l_type_required = true; 2644 2645 %} 2646 2647 //----------ENCODING BLOCK----------------------------------------------------- 2648 // This block specifies the encoding classes used by the compiler to output 2649 // byte streams. Encoding classes are parameterized macros used by 2650 // Machine Instruction Nodes in order to generate the bit encoding of the 2651 // instruction. Operands specify their base encoding interface with the 2652 // interface keyword. There are currently supported four interfaces, 2653 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2654 // operand to generate a function which returns its register number when 2655 // queried. CONST_INTER causes an operand to generate a function which 2656 // returns the value of the constant when queried. MEMORY_INTER causes an 2657 // operand to generate four functions which return the Base Register, the 2658 // Index Register, the Scale Value, and the Offset Value of the operand when 2659 // queried. COND_INTER causes an operand to generate six functions which 2660 // return the encoding code (ie - encoding bits for the instruction) 2661 // associated with each basic boolean condition for a conditional instruction. 2662 // 2663 // Instructions specify two basic values for encoding. Again, a function 2664 // is available to check if the constant displacement is an oop. They use the 2665 // ins_encode keyword to specify their encoding classes (which must be 2666 // a sequence of enc_class names, and their parameters, specified in 2667 // the encoding block), and they use the 2668 // opcode keyword to specify, in order, their primary, secondary, and 2669 // tertiary opcode. Only the opcode sections which a particular instruction 2670 // needs for encoding need to be specified. 2671 encode %{ 2672 enc_class enc_unimplemented %{ 2673 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2674 C2_MacroAssembler _masm(&cbuf); 2675 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2676 %} 2677 2678 enc_class enc_untested %{ 2679 #ifdef ASSERT 2680 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2681 C2_MacroAssembler _masm(&cbuf); 2682 __ untested("Untested mach node encoding in AD file."); 2683 #else 2684 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2685 #endif 2686 %} 2687 2688 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2689 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2690 C2_MacroAssembler _masm(&cbuf); 2691 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2692 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2693 %} 2694 2695 // Load acquire. 2696 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2697 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2698 C2_MacroAssembler _masm(&cbuf); 2699 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2700 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2701 __ twi_0($dst$$Register); 2702 __ isync(); 2703 %} 2704 2705 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2706 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2707 2708 C2_MacroAssembler _masm(&cbuf); 2709 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2710 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2711 %} 2712 2713 // Load acquire. 2714 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2715 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2716 2717 C2_MacroAssembler _masm(&cbuf); 2718 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2719 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2720 __ twi_0($dst$$Register); 2721 __ isync(); 2722 %} 2723 2724 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2725 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2726 2727 C2_MacroAssembler _masm(&cbuf); 2728 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2729 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2730 %} 2731 2732 // Load acquire. 2733 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2734 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2735 2736 C2_MacroAssembler _masm(&cbuf); 2737 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2738 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2739 __ twi_0($dst$$Register); 2740 __ isync(); 2741 %} 2742 2743 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2744 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2745 C2_MacroAssembler _masm(&cbuf); 2746 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2747 // Operand 'ds' requires 4-alignment. 2748 assert((Idisp & 0x3) == 0, "unaligned offset"); 2749 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2750 %} 2751 2752 // Load acquire. 2753 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2754 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2755 C2_MacroAssembler _masm(&cbuf); 2756 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2757 // Operand 'ds' requires 4-alignment. 2758 assert((Idisp & 0x3) == 0, "unaligned offset"); 2759 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2760 __ twi_0($dst$$Register); 2761 __ isync(); 2762 %} 2763 2764 enc_class enc_lfd(RegF dst, memory mem) %{ 2765 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2766 C2_MacroAssembler _masm(&cbuf); 2767 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2768 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2769 %} 2770 2771 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2772 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2773 2774 C2_MacroAssembler _masm(&cbuf); 2775 int toc_offset = 0; 2776 2777 address const_toc_addr; 2778 // Create a non-oop constant, no relocation needed. 2779 // If it is an IC, it has a virtual_call_Relocation. 2780 const_toc_addr = __ long_constant((jlong)$src$$constant); 2781 if (const_toc_addr == NULL) { 2782 ciEnv::current()->record_out_of_memory_failure(); 2783 return; 2784 } 2785 2786 // Get the constant's TOC offset. 2787 toc_offset = __ offset_to_method_toc(const_toc_addr); 2788 2789 // Keep the current instruction offset in mind. 2790 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2791 2792 __ ld($dst$$Register, toc_offset, $toc$$Register); 2793 %} 2794 2795 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2796 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2797 2798 C2_MacroAssembler _masm(&cbuf); 2799 2800 if (!ra_->C->output()->in_scratch_emit_size()) { 2801 address const_toc_addr; 2802 // Create a non-oop constant, no relocation needed. 2803 // If it is an IC, it has a virtual_call_Relocation. 2804 const_toc_addr = __ long_constant((jlong)$src$$constant); 2805 if (const_toc_addr == NULL) { 2806 ciEnv::current()->record_out_of_memory_failure(); 2807 return; 2808 } 2809 2810 // Get the constant's TOC offset. 2811 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2812 // Store the toc offset of the constant. 2813 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2814 2815 // Also keep the current instruction offset in mind. 2816 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2817 } 2818 2819 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2820 %} 2821 2822 %} // encode 2823 2824 source %{ 2825 2826 typedef struct { 2827 loadConL_hiNode *_large_hi; 2828 loadConL_loNode *_large_lo; 2829 loadConLNode *_small; 2830 MachNode *_last; 2831 } loadConLNodesTuple; 2832 2833 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2834 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2835 loadConLNodesTuple nodes; 2836 2837 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2838 if (large_constant_pool) { 2839 // Create new nodes. 2840 loadConL_hiNode *m1 = new loadConL_hiNode(); 2841 loadConL_loNode *m2 = new loadConL_loNode(); 2842 2843 // inputs for new nodes 2844 m1->add_req(NULL, toc); 2845 m2->add_req(NULL, m1); 2846 2847 // operands for new nodes 2848 m1->_opnds[0] = new iRegLdstOper(); // dst 2849 m1->_opnds[1] = immSrc; // src 2850 m1->_opnds[2] = new iRegPdstOper(); // toc 2851 m2->_opnds[0] = new iRegLdstOper(); // dst 2852 m2->_opnds[1] = immSrc; // src 2853 m2->_opnds[2] = new iRegLdstOper(); // base 2854 2855 // Initialize ins_attrib TOC fields. 2856 m1->_const_toc_offset = -1; 2857 m2->_const_toc_offset_hi_node = m1; 2858 2859 // Initialize ins_attrib instruction offset. 2860 m1->_cbuf_insts_offset = -1; 2861 2862 // register allocation for new nodes 2863 ra_->set_pair(m1->_idx, reg_second, reg_first); 2864 ra_->set_pair(m2->_idx, reg_second, reg_first); 2865 2866 // Create result. 2867 nodes._large_hi = m1; 2868 nodes._large_lo = m2; 2869 nodes._small = NULL; 2870 nodes._last = nodes._large_lo; 2871 assert(m2->bottom_type()->isa_long(), "must be long"); 2872 } else { 2873 loadConLNode *m2 = new loadConLNode(); 2874 2875 // inputs for new nodes 2876 m2->add_req(NULL, toc); 2877 2878 // operands for new nodes 2879 m2->_opnds[0] = new iRegLdstOper(); // dst 2880 m2->_opnds[1] = immSrc; // src 2881 m2->_opnds[2] = new iRegPdstOper(); // toc 2882 2883 // Initialize ins_attrib instruction offset. 2884 m2->_cbuf_insts_offset = -1; 2885 2886 // register allocation for new nodes 2887 ra_->set_pair(m2->_idx, reg_second, reg_first); 2888 2889 // Create result. 2890 nodes._large_hi = NULL; 2891 nodes._large_lo = NULL; 2892 nodes._small = m2; 2893 nodes._last = nodes._small; 2894 assert(m2->bottom_type()->isa_long(), "must be long"); 2895 } 2896 2897 return nodes; 2898 } 2899 2900 typedef struct { 2901 loadConL_hiNode *_large_hi; 2902 loadConL_loNode *_large_lo; 2903 mtvsrdNode *_moved; 2904 xxspltdNode *_replicated; 2905 loadConLNode *_small; 2906 MachNode *_last; 2907 } loadConLReplicatedNodesTuple; 2908 2909 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2910 vecXOper *dst, immI_0Oper *zero, 2911 OptoReg::Name reg_second, OptoReg::Name reg_first, 2912 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2913 loadConLReplicatedNodesTuple nodes; 2914 2915 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2916 if (large_constant_pool) { 2917 // Create new nodes. 2918 loadConL_hiNode *m1 = new loadConL_hiNode(); 2919 loadConL_loNode *m2 = new loadConL_loNode(); 2920 mtvsrdNode *m3 = new mtvsrdNode(); 2921 xxspltdNode *m4 = new xxspltdNode(); 2922 2923 // inputs for new nodes 2924 m1->add_req(NULL, toc); 2925 m2->add_req(NULL, m1); 2926 m3->add_req(NULL, m2); 2927 m4->add_req(NULL, m3); 2928 2929 // operands for new nodes 2930 m1->_opnds[0] = new iRegLdstOper(); // dst 2931 m1->_opnds[1] = immSrc; // src 2932 m1->_opnds[2] = new iRegPdstOper(); // toc 2933 2934 m2->_opnds[0] = new iRegLdstOper(); // dst 2935 m2->_opnds[1] = immSrc; // src 2936 m2->_opnds[2] = new iRegLdstOper(); // base 2937 2938 m3->_opnds[0] = new vecXOper(); // dst 2939 m3->_opnds[1] = new iRegLdstOper(); // src 2940 2941 m4->_opnds[0] = new vecXOper(); // dst 2942 m4->_opnds[1] = new vecXOper(); // src 2943 m4->_opnds[2] = zero; 2944 2945 // Initialize ins_attrib TOC fields. 2946 m1->_const_toc_offset = -1; 2947 m2->_const_toc_offset_hi_node = m1; 2948 2949 // Initialize ins_attrib instruction offset. 2950 m1->_cbuf_insts_offset = -1; 2951 2952 // register allocation for new nodes 2953 ra_->set_pair(m1->_idx, reg_second, reg_first); 2954 ra_->set_pair(m2->_idx, reg_second, reg_first); 2955 ra_->set1(m3->_idx, reg_second); 2956 ra_->set2(m3->_idx, reg_vec_first); 2957 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2958 2959 // Create result. 2960 nodes._large_hi = m1; 2961 nodes._large_lo = m2; 2962 nodes._moved = m3; 2963 nodes._replicated = m4; 2964 nodes._small = NULL; 2965 nodes._last = nodes._replicated; 2966 assert(m2->bottom_type()->isa_long(), "must be long"); 2967 } else { 2968 loadConLNode *m2 = new loadConLNode(); 2969 mtvsrdNode *m3 = new mtvsrdNode(); 2970 xxspltdNode *m4 = new xxspltdNode(); 2971 2972 // inputs for new nodes 2973 m2->add_req(NULL, toc); 2974 2975 // operands for new nodes 2976 m2->_opnds[0] = new iRegLdstOper(); // dst 2977 m2->_opnds[1] = immSrc; // src 2978 m2->_opnds[2] = new iRegPdstOper(); // toc 2979 2980 m3->_opnds[0] = new vecXOper(); // dst 2981 m3->_opnds[1] = new iRegLdstOper(); // src 2982 2983 m4->_opnds[0] = new vecXOper(); // dst 2984 m4->_opnds[1] = new vecXOper(); // src 2985 m4->_opnds[2] = zero; 2986 2987 // Initialize ins_attrib instruction offset. 2988 m2->_cbuf_insts_offset = -1; 2989 ra_->set1(m3->_idx, reg_second); 2990 ra_->set2(m3->_idx, reg_vec_first); 2991 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2992 2993 // register allocation for new nodes 2994 ra_->set_pair(m2->_idx, reg_second, reg_first); 2995 2996 // Create result. 2997 nodes._large_hi = NULL; 2998 nodes._large_lo = NULL; 2999 nodes._small = m2; 3000 nodes._moved = m3; 3001 nodes._replicated = m4; 3002 nodes._last = nodes._replicated; 3003 assert(m2->bottom_type()->isa_long(), "must be long"); 3004 } 3005 3006 return nodes; 3007 } 3008 3009 %} // source 3010 3011 encode %{ 3012 // Postalloc expand emitter for loading a long constant from the method's TOC. 3013 // Enc_class needed as consttanttablebase is not supported by postalloc 3014 // expand. 3015 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 3016 // Create new nodes. 3017 loadConLNodesTuple loadConLNodes = 3018 loadConLNodesTuple_create(ra_, n_toc, op_src, 3019 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3020 3021 // Push new nodes. 3022 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3023 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3024 3025 // some asserts 3026 assert(nodes->length() >= 1, "must have created at least 1 node"); 3027 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3028 %} 3029 3030 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 3031 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3032 3033 C2_MacroAssembler _masm(&cbuf); 3034 int toc_offset = 0; 3035 3036 intptr_t val = $src$$constant; 3037 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 3038 address const_toc_addr; 3039 if (constant_reloc == relocInfo::oop_type) { 3040 // Create an oop constant and a corresponding relocation. 3041 AddressLiteral a = __ allocate_oop_address((jobject)val); 3042 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3043 __ relocate(a.rspec()); 3044 } else if (constant_reloc == relocInfo::metadata_type) { 3045 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 3046 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3047 __ relocate(a.rspec()); 3048 } else { 3049 // Create a non-oop constant, no relocation needed. 3050 const_toc_addr = __ long_constant((jlong)$src$$constant); 3051 } 3052 3053 if (const_toc_addr == NULL) { 3054 ciEnv::current()->record_out_of_memory_failure(); 3055 return; 3056 } 3057 // Get the constant's TOC offset. 3058 toc_offset = __ offset_to_method_toc(const_toc_addr); 3059 3060 __ ld($dst$$Register, toc_offset, $toc$$Register); 3061 %} 3062 3063 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 3064 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 3065 3066 C2_MacroAssembler _masm(&cbuf); 3067 if (!ra_->C->output()->in_scratch_emit_size()) { 3068 intptr_t val = $src$$constant; 3069 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 3070 address const_toc_addr; 3071 if (constant_reloc == relocInfo::oop_type) { 3072 // Create an oop constant and a corresponding relocation. 3073 AddressLiteral a = __ allocate_oop_address((jobject)val); 3074 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3075 __ relocate(a.rspec()); 3076 } else if (constant_reloc == relocInfo::metadata_type) { 3077 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 3078 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3079 __ relocate(a.rspec()); 3080 } else { // non-oop pointers, e.g. card mark base, heap top 3081 // Create a non-oop constant, no relocation needed. 3082 const_toc_addr = __ long_constant((jlong)$src$$constant); 3083 } 3084 3085 if (const_toc_addr == NULL) { 3086 ciEnv::current()->record_out_of_memory_failure(); 3087 return; 3088 } 3089 // Get the constant's TOC offset. 3090 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 3091 // Store the toc offset of the constant. 3092 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 3093 } 3094 3095 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 3096 %} 3097 3098 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 3099 // Enc_class needed as consttanttablebase is not supported by postalloc 3100 // expand. 3101 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 3102 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3103 if (large_constant_pool) { 3104 // Create new nodes. 3105 loadConP_hiNode *m1 = new loadConP_hiNode(); 3106 loadConP_loNode *m2 = new loadConP_loNode(); 3107 3108 // inputs for new nodes 3109 m1->add_req(NULL, n_toc); 3110 m2->add_req(NULL, m1); 3111 3112 // operands for new nodes 3113 m1->_opnds[0] = new iRegPdstOper(); // dst 3114 m1->_opnds[1] = op_src; // src 3115 m1->_opnds[2] = new iRegPdstOper(); // toc 3116 m2->_opnds[0] = new iRegPdstOper(); // dst 3117 m2->_opnds[1] = op_src; // src 3118 m2->_opnds[2] = new iRegLdstOper(); // base 3119 3120 // Initialize ins_attrib TOC fields. 3121 m1->_const_toc_offset = -1; 3122 m2->_const_toc_offset_hi_node = m1; 3123 3124 // Register allocation for new nodes. 3125 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3126 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3127 3128 nodes->push(m1); 3129 nodes->push(m2); 3130 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3131 } else { 3132 loadConPNode *m2 = new loadConPNode(); 3133 3134 // inputs for new nodes 3135 m2->add_req(NULL, n_toc); 3136 3137 // operands for new nodes 3138 m2->_opnds[0] = new iRegPdstOper(); // dst 3139 m2->_opnds[1] = op_src; // src 3140 m2->_opnds[2] = new iRegPdstOper(); // toc 3141 3142 // Register allocation for new nodes. 3143 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3144 3145 nodes->push(m2); 3146 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3147 } 3148 %} 3149 3150 // Enc_class needed as consttanttablebase is not supported by postalloc 3151 // expand. 3152 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3153 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3154 3155 MachNode *m2; 3156 if (large_constant_pool) { 3157 m2 = new loadConFCompNode(); 3158 } else { 3159 m2 = new loadConFNode(); 3160 } 3161 // inputs for new nodes 3162 m2->add_req(NULL, n_toc); 3163 3164 // operands for new nodes 3165 m2->_opnds[0] = op_dst; 3166 m2->_opnds[1] = op_src; 3167 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3168 3169 // register allocation for new nodes 3170 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3171 nodes->push(m2); 3172 %} 3173 3174 // Enc_class needed as consttanttablebase is not supported by postalloc 3175 // expand. 3176 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3177 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3178 3179 MachNode *m2; 3180 if (large_constant_pool) { 3181 m2 = new loadConDCompNode(); 3182 } else { 3183 m2 = new loadConDNode(); 3184 } 3185 // inputs for new nodes 3186 m2->add_req(NULL, n_toc); 3187 3188 // operands for new nodes 3189 m2->_opnds[0] = op_dst; 3190 m2->_opnds[1] = op_src; 3191 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3192 3193 // register allocation for new nodes 3194 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3195 nodes->push(m2); 3196 %} 3197 3198 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3199 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3200 C2_MacroAssembler _masm(&cbuf); 3201 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3202 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3203 %} 3204 3205 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3206 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3207 C2_MacroAssembler _masm(&cbuf); 3208 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3209 // Operand 'ds' requires 4-alignment. 3210 assert((Idisp & 0x3) == 0, "unaligned offset"); 3211 __ std($src$$Register, Idisp, $mem$$base$$Register); 3212 %} 3213 3214 enc_class enc_stfs(RegF src, memory mem) %{ 3215 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3216 C2_MacroAssembler _masm(&cbuf); 3217 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3218 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3219 %} 3220 3221 enc_class enc_stfd(RegF src, memory mem) %{ 3222 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3223 C2_MacroAssembler _masm(&cbuf); 3224 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3225 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3226 %} 3227 3228 // Use release_store for card-marking to ensure that previous 3229 // oop-stores are visible before the card-mark change. 3230 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3231 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3232 // FIXME: Implement this as a cmove and use a fixed condition code 3233 // register which is written on every transition to compiled code, 3234 // e.g. in call-stub and when returning from runtime stubs. 3235 // 3236 // Proposed code sequence for the cmove implementation: 3237 // 3238 // Label skip_release; 3239 // __ beq(CCRfixed, skip_release); 3240 // __ release(); 3241 // __ bind(skip_release); 3242 // __ stb(card mark); 3243 3244 C2_MacroAssembler _masm(&cbuf); 3245 Label skip_storestore; 3246 3247 #if 0 // TODO: PPC port 3248 // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the 3249 // StoreStore barrier conditionally. 3250 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3251 __ cmpwi($crx$$CondRegister, R0, 0); 3252 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3253 #endif 3254 __ li(R0, 0); 3255 __ membar(Assembler::StoreStore); 3256 #if 0 // TODO: PPC port 3257 __ bind(skip_storestore); 3258 #endif 3259 3260 // Do the store. 3261 if ($mem$$index == 0) { 3262 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3263 } else { 3264 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3265 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3266 } 3267 %} 3268 3269 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3270 3271 if (VM_Version::has_isel()) { 3272 // use isel instruction with Power 7 3273 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3274 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3275 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3276 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3277 3278 n_compare->add_req(n_region, n_src); 3279 n_compare->_opnds[0] = op_crx; 3280 n_compare->_opnds[1] = op_src; 3281 n_compare->_opnds[2] = new immL16Oper(0); 3282 3283 n_sub_base->add_req(n_region, n_src); 3284 n_sub_base->_opnds[0] = op_dst; 3285 n_sub_base->_opnds[1] = op_src; 3286 n_sub_base->_bottom_type = _bottom_type; 3287 3288 n_shift->add_req(n_region, n_sub_base); 3289 n_shift->_opnds[0] = op_dst; 3290 n_shift->_opnds[1] = op_dst; 3291 n_shift->_bottom_type = _bottom_type; 3292 3293 n_cond_set->add_req(n_region, n_compare, n_shift); 3294 n_cond_set->_opnds[0] = op_dst; 3295 n_cond_set->_opnds[1] = op_crx; 3296 n_cond_set->_opnds[2] = op_dst; 3297 n_cond_set->_bottom_type = _bottom_type; 3298 3299 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3300 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3301 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3302 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3303 3304 nodes->push(n_compare); 3305 nodes->push(n_sub_base); 3306 nodes->push(n_shift); 3307 nodes->push(n_cond_set); 3308 3309 } else { 3310 // before Power 7 3311 moveRegNode *n_move = new moveRegNode(); 3312 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3313 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3314 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3315 3316 n_move->add_req(n_region, n_src); 3317 n_move->_opnds[0] = op_dst; 3318 n_move->_opnds[1] = op_src; 3319 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3320 3321 n_compare->add_req(n_region, n_src); 3322 n_compare->add_prec(n_move); 3323 3324 n_compare->_opnds[0] = op_crx; 3325 n_compare->_opnds[1] = op_src; 3326 n_compare->_opnds[2] = new immL16Oper(0); 3327 3328 n_sub_base->add_req(n_region, n_compare, n_src); 3329 n_sub_base->_opnds[0] = op_dst; 3330 n_sub_base->_opnds[1] = op_crx; 3331 n_sub_base->_opnds[2] = op_src; 3332 n_sub_base->_bottom_type = _bottom_type; 3333 3334 n_shift->add_req(n_region, n_sub_base); 3335 n_shift->_opnds[0] = op_dst; 3336 n_shift->_opnds[1] = op_dst; 3337 n_shift->_bottom_type = _bottom_type; 3338 3339 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3340 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3341 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3342 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3343 3344 nodes->push(n_move); 3345 nodes->push(n_compare); 3346 nodes->push(n_sub_base); 3347 nodes->push(n_shift); 3348 } 3349 3350 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3351 %} 3352 3353 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3354 3355 encodeP_subNode *n1 = new encodeP_subNode(); 3356 n1->add_req(n_region, n_src); 3357 n1->_opnds[0] = op_dst; 3358 n1->_opnds[1] = op_src; 3359 n1->_bottom_type = _bottom_type; 3360 3361 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3362 n2->add_req(n_region, n1); 3363 n2->_opnds[0] = op_dst; 3364 n2->_opnds[1] = op_dst; 3365 n2->_bottom_type = _bottom_type; 3366 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3367 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3368 3369 nodes->push(n1); 3370 nodes->push(n2); 3371 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3372 %} 3373 3374 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3375 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3376 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3377 3378 n_compare->add_req(n_region, n_src); 3379 n_compare->_opnds[0] = op_crx; 3380 n_compare->_opnds[1] = op_src; 3381 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3382 3383 n_shift->add_req(n_region, n_src); 3384 n_shift->_opnds[0] = op_dst; 3385 n_shift->_opnds[1] = op_src; 3386 n_shift->_bottom_type = _bottom_type; 3387 3388 if (VM_Version::has_isel()) { 3389 // use isel instruction with Power 7 3390 3391 decodeN_addNode *n_add_base = new decodeN_addNode(); 3392 n_add_base->add_req(n_region, n_shift); 3393 n_add_base->_opnds[0] = op_dst; 3394 n_add_base->_opnds[1] = op_dst; 3395 n_add_base->_bottom_type = _bottom_type; 3396 3397 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3398 n_cond_set->add_req(n_region, n_compare, n_add_base); 3399 n_cond_set->_opnds[0] = op_dst; 3400 n_cond_set->_opnds[1] = op_crx; 3401 n_cond_set->_opnds[2] = op_dst; 3402 n_cond_set->_bottom_type = _bottom_type; 3403 3404 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3405 ra_->set_oop(n_cond_set, true); 3406 3407 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3408 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3409 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3410 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3411 3412 nodes->push(n_compare); 3413 nodes->push(n_shift); 3414 nodes->push(n_add_base); 3415 nodes->push(n_cond_set); 3416 3417 } else { 3418 // before Power 7 3419 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3420 3421 n_add_base->add_req(n_region, n_compare, n_shift); 3422 n_add_base->_opnds[0] = op_dst; 3423 n_add_base->_opnds[1] = op_crx; 3424 n_add_base->_opnds[2] = op_dst; 3425 n_add_base->_bottom_type = _bottom_type; 3426 3427 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3428 ra_->set_oop(n_add_base, true); 3429 3430 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3431 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3432 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3433 3434 nodes->push(n_compare); 3435 nodes->push(n_shift); 3436 nodes->push(n_add_base); 3437 } 3438 %} 3439 3440 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3441 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3442 n1->add_req(n_region, n_src); 3443 n1->_opnds[0] = op_dst; 3444 n1->_opnds[1] = op_src; 3445 n1->_bottom_type = _bottom_type; 3446 3447 decodeN_addNode *n2 = new decodeN_addNode(); 3448 n2->add_req(n_region, n1); 3449 n2->_opnds[0] = op_dst; 3450 n2->_opnds[1] = op_dst; 3451 n2->_bottom_type = _bottom_type; 3452 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3453 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3454 3455 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3456 ra_->set_oop(n2, true); 3457 3458 nodes->push(n1); 3459 nodes->push(n2); 3460 %} 3461 3462 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3463 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3464 3465 C2_MacroAssembler _masm(&cbuf); 3466 int cc = $cmp$$cmpcode; 3467 int flags_reg = $crx$$reg; 3468 Label done; 3469 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3470 // Branch if not (cmp crx). 3471 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3472 __ mr($dst$$Register, $src$$Register); 3473 // TODO PPC port __ endgroup_if_needed(_size == 12); 3474 __ bind(done); 3475 %} 3476 3477 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3478 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3479 3480 C2_MacroAssembler _masm(&cbuf); 3481 Label done; 3482 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3483 // Branch if not (cmp crx). 3484 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3485 __ li($dst$$Register, $src$$constant); 3486 // TODO PPC port __ endgroup_if_needed(_size == 12); 3487 __ bind(done); 3488 %} 3489 3490 // This enc_class is needed so that scheduler gets proper 3491 // input mapping for latency computation. 3492 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3493 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3494 C2_MacroAssembler _masm(&cbuf); 3495 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3496 %} 3497 3498 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3499 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3500 3501 C2_MacroAssembler _masm(&cbuf); 3502 3503 Label done; 3504 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3505 __ li($dst$$Register, $zero$$constant); 3506 __ beq($crx$$CondRegister, done); 3507 __ li($dst$$Register, $notzero$$constant); 3508 __ bind(done); 3509 %} 3510 3511 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3512 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3513 3514 C2_MacroAssembler _masm(&cbuf); 3515 3516 Label done; 3517 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3518 __ li($dst$$Register, $zero$$constant); 3519 __ beq($crx$$CondRegister, done); 3520 __ li($dst$$Register, $notzero$$constant); 3521 __ bind(done); 3522 %} 3523 3524 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3525 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3526 3527 C2_MacroAssembler _masm(&cbuf); 3528 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3529 Label done; 3530 __ bso($crx$$CondRegister, done); 3531 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3532 // TODO PPC port __ endgroup_if_needed(_size == 12); 3533 __ bind(done); 3534 %} 3535 3536 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3537 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3538 3539 C2_MacroAssembler _masm(&cbuf); 3540 Label done; 3541 __ bso($crx$$CondRegister, done); 3542 __ mffprd($dst$$Register, $src$$FloatRegister); 3543 // TODO PPC port __ endgroup_if_needed(_size == 12); 3544 __ bind(done); 3545 %} 3546 3547 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3548 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3549 3550 C2_MacroAssembler _masm(&cbuf); 3551 Label d; // dummy 3552 __ bind(d); 3553 Label* p = ($lbl$$label); 3554 // `p' is `NULL' when this encoding class is used only to 3555 // determine the size of the encoded instruction. 3556 Label& l = (NULL == p)? d : *(p); 3557 int cc = $cmp$$cmpcode; 3558 int flags_reg = $crx$$reg; 3559 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3560 int bhint = Assembler::bhintNoHint; 3561 3562 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3563 if (_prob <= PROB_NEVER) { 3564 bhint = Assembler::bhintIsNotTaken; 3565 } else if (_prob >= PROB_ALWAYS) { 3566 bhint = Assembler::bhintIsTaken; 3567 } 3568 } 3569 3570 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3571 cc_to_biint(cc, flags_reg), 3572 l); 3573 %} 3574 3575 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3576 // The scheduler doesn't know about branch shortening, so we set the opcode 3577 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3578 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3579 3580 C2_MacroAssembler _masm(&cbuf); 3581 Label d; // dummy 3582 __ bind(d); 3583 Label* p = ($lbl$$label); 3584 // `p' is `NULL' when this encoding class is used only to 3585 // determine the size of the encoded instruction. 3586 Label& l = (NULL == p)? d : *(p); 3587 int cc = $cmp$$cmpcode; 3588 int flags_reg = $crx$$reg; 3589 int bhint = Assembler::bhintNoHint; 3590 3591 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3592 if (_prob <= PROB_NEVER) { 3593 bhint = Assembler::bhintIsNotTaken; 3594 } else if (_prob >= PROB_ALWAYS) { 3595 bhint = Assembler::bhintIsTaken; 3596 } 3597 } 3598 3599 // Tell the conditional far branch to optimize itself when being relocated. 3600 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3601 cc_to_biint(cc, flags_reg), 3602 l, 3603 MacroAssembler::bc_far_optimize_on_relocate); 3604 %} 3605 3606 // Branch used with Power6 scheduling (can be shortened without changing the node). 3607 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3608 // The scheduler doesn't know about branch shortening, so we set the opcode 3609 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3610 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3611 3612 C2_MacroAssembler _masm(&cbuf); 3613 Label d; // dummy 3614 __ bind(d); 3615 Label* p = ($lbl$$label); 3616 // `p' is `NULL' when this encoding class is used only to 3617 // determine the size of the encoded instruction. 3618 Label& l = (NULL == p)? d : *(p); 3619 int cc = $cmp$$cmpcode; 3620 int flags_reg = $crx$$reg; 3621 int bhint = Assembler::bhintNoHint; 3622 3623 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3624 if (_prob <= PROB_NEVER) { 3625 bhint = Assembler::bhintIsNotTaken; 3626 } else if (_prob >= PROB_ALWAYS) { 3627 bhint = Assembler::bhintIsTaken; 3628 } 3629 } 3630 3631 #if 0 // TODO: PPC port 3632 if (_size == 8) { 3633 // Tell the conditional far branch to optimize itself when being relocated. 3634 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3635 cc_to_biint(cc, flags_reg), 3636 l, 3637 MacroAssembler::bc_far_optimize_on_relocate); 3638 } else { 3639 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3640 cc_to_biint(cc, flags_reg), 3641 l); 3642 } 3643 #endif 3644 Unimplemented(); 3645 %} 3646 3647 // Postalloc expand emitter for loading a replicatef float constant from 3648 // the method's TOC. 3649 // Enc_class needed as consttanttablebase is not supported by postalloc 3650 // expand. 3651 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3652 // Create new nodes. 3653 3654 // Make an operand with the bit pattern to load as float. 3655 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3656 3657 loadConLNodesTuple loadConLNodes = 3658 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3659 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3660 3661 // Push new nodes. 3662 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3663 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3664 3665 assert(nodes->length() >= 1, "must have created at least 1 node"); 3666 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3667 %} 3668 3669 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3670 // Create new nodes. 3671 3672 // Make an operand with the bit pattern to load as float. 3673 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3674 immI_0Oper *op_zero = new immI_0Oper(0); 3675 3676 loadConLReplicatedNodesTuple loadConLNodes = 3677 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3678 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3679 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3680 3681 // Push new nodes. 3682 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3683 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3684 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3685 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3686 3687 assert(nodes->length() >= 1, "must have created at least 1 node"); 3688 %} 3689 3690 // This enc_class is needed so that scheduler gets proper 3691 // input mapping for latency computation. 3692 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3693 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3694 // Fake operand dst needed for PPC scheduler. 3695 assert($dst$$constant == 0x0, "dst must be 0x0"); 3696 3697 C2_MacroAssembler _masm(&cbuf); 3698 // Mark the code position where the load from the safepoint 3699 // polling page was emitted as relocInfo::poll_type. 3700 __ relocate(relocInfo::poll_type); 3701 __ load_from_polling_page($poll$$Register); 3702 %} 3703 3704 // A Java static call or a runtime call. 3705 // 3706 // Branch-and-link relative to a trampoline. 3707 // The trampoline loads the target address and does a long branch to there. 3708 // In case we call java, the trampoline branches to a interpreter_stub 3709 // which loads the inline cache and the real call target from the constant pool. 3710 // 3711 // This basically looks like this: 3712 // 3713 // >>>> consts -+ -+ 3714 // | |- offset1 3715 // [call target1] | <-+ 3716 // [IC cache] |- offset2 3717 // [call target2] <--+ 3718 // 3719 // <<<< consts 3720 // >>>> insts 3721 // 3722 // bl offset16 -+ -+ ??? // How many bits available? 3723 // | | 3724 // <<<< insts | | 3725 // >>>> stubs | | 3726 // | |- trampoline_stub_Reloc 3727 // trampoline stub: | <-+ 3728 // r2 = toc | 3729 // r2 = [r2 + offset1] | // Load call target1 from const section 3730 // mtctr r2 | 3731 // bctr |- static_stub_Reloc 3732 // comp_to_interp_stub: <---+ 3733 // r1 = toc 3734 // ICreg = [r1 + IC_offset] // Load IC from const section 3735 // r1 = [r1 + offset2] // Load call target2 from const section 3736 // mtctr r1 3737 // bctr 3738 // 3739 // <<<< stubs 3740 // 3741 // The call instruction in the code either 3742 // - Branches directly to a compiled method if the offset is encodable in instruction. 3743 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3744 // - Branches to the compiled_to_interp stub if the target is interpreted. 3745 // 3746 // Further there are three relocations from the loads to the constants in 3747 // the constant section. 3748 // 3749 // Usage of r1 and r2 in the stubs allows to distinguish them. 3750 enc_class enc_java_static_call(method meth) %{ 3751 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3752 3753 C2_MacroAssembler _masm(&cbuf); 3754 address entry_point = (address)$meth$$method; 3755 3756 if (!_method) { 3757 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3758 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3759 } else { 3760 // Remember the offset not the address. 3761 const int start_offset = __ offset(); 3762 3763 // The trampoline stub. 3764 // No entry point given, use the current pc. 3765 // Make sure branch fits into 3766 if (entry_point == 0) entry_point = __ pc(); 3767 3768 // Put the entry point as a constant into the constant pool. 3769 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3770 if (entry_point_toc_addr == NULL) { 3771 ciEnv::current()->record_out_of_memory_failure(); 3772 return; 3773 } 3774 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3775 3776 // Emit the trampoline stub which will be related to the branch-and-link below. 3777 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3778 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3779 int method_index = resolved_method_index(cbuf); 3780 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3781 : static_call_Relocation::spec(method_index)); 3782 3783 // The real call. 3784 // Note: At this point we do not have the address of the trampoline 3785 // stub, and the entry point might be too far away for bl, so __ pc() 3786 // serves as dummy and the bl will be patched later. 3787 cbuf.set_insts_mark(); 3788 __ bl(__ pc()); // Emits a relocation. 3789 3790 // The stub for call to interpreter. 3791 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3792 if (stub == NULL) { 3793 ciEnv::current()->record_failure("CodeCache is full"); 3794 return; 3795 } 3796 } 3797 %} 3798 3799 // Second node of expanded dynamic call - the call. 3800 enc_class enc_java_dynamic_call_sched(method meth) %{ 3801 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3802 3803 C2_MacroAssembler _masm(&cbuf); 3804 3805 if (!ra_->C->output()->in_scratch_emit_size()) { 3806 // Create a call trampoline stub for the given method. 3807 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3808 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3809 if (entry_point_const == NULL) { 3810 ciEnv::current()->record_out_of_memory_failure(); 3811 return; 3812 } 3813 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3814 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3815 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3816 3817 // Build relocation at call site with ic position as data. 3818 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3819 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3820 "must have one, but can't have both"); 3821 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3822 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3823 "must contain instruction offset"); 3824 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3825 ? _load_ic_hi_node->_cbuf_insts_offset 3826 : _load_ic_node->_cbuf_insts_offset; 3827 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3828 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3829 "should be load from TOC"); 3830 int method_index = resolved_method_index(cbuf); 3831 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3832 } 3833 3834 // At this point I do not have the address of the trampoline stub, 3835 // and the entry point might be too far away for bl. Pc() serves 3836 // as dummy and bl will be patched later. 3837 __ bl((address) __ pc()); 3838 %} 3839 3840 // postalloc expand emitter for virtual calls. 3841 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3842 3843 // Create the nodes for loading the IC from the TOC. 3844 loadConLNodesTuple loadConLNodes_IC = 3845 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3846 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3847 3848 // Create the call node. 3849 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3850 call->_method_handle_invoke = _method_handle_invoke; 3851 call->_vtable_index = _vtable_index; 3852 call->_method = _method; 3853 call->_bci = _bci; 3854 call->_optimized_virtual = _optimized_virtual; 3855 call->_tf = _tf; 3856 call->_entry_point = _entry_point; 3857 call->_cnt = _cnt; 3858 call->_argsize = _argsize; 3859 call->_oop_map = _oop_map; 3860 call->_jvms = _jvms; 3861 call->_jvmadj = _jvmadj; 3862 call->_in_rms = _in_rms; 3863 call->_nesting = _nesting; 3864 call->_override_symbolic_info = _override_symbolic_info; 3865 3866 // New call needs all inputs of old call. 3867 // Req... 3868 for (uint i = 0; i < req(); ++i) { 3869 // The expanded node does not need toc any more. 3870 // Add the inline cache constant here instead. This expresses the 3871 // register of the inline cache must be live at the call. 3872 // Else we would have to adapt JVMState by -1. 3873 if (i == mach_constant_base_node_input()) { 3874 call->add_req(loadConLNodes_IC._last); 3875 } else { 3876 call->add_req(in(i)); 3877 } 3878 } 3879 // ...as well as prec 3880 for (uint i = req(); i < len(); ++i) { 3881 call->add_prec(in(i)); 3882 } 3883 3884 // Remember nodes loading the inline cache into r19. 3885 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3886 call->_load_ic_node = loadConLNodes_IC._small; 3887 3888 // Operands for new nodes. 3889 call->_opnds[0] = _opnds[0]; 3890 call->_opnds[1] = _opnds[1]; 3891 3892 // Only the inline cache is associated with a register. 3893 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3894 3895 // Push new nodes. 3896 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3897 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3898 nodes->push(call); 3899 %} 3900 3901 // Compound version of call dynamic 3902 // Toc is only passed so that it can be used in ins_encode statement. 3903 // In the code we have to use $constanttablebase. 3904 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3905 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3906 C2_MacroAssembler _masm(&cbuf); 3907 int start_offset = __ offset(); 3908 3909 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3910 #if 0 3911 int vtable_index = this->_vtable_index; 3912 if (_vtable_index < 0) { 3913 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3914 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3915 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3916 3917 // Virtual call relocation will point to ic load. 3918 address virtual_call_meta_addr = __ pc(); 3919 // Load a clear inline cache. 3920 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3921 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3922 if (!success) { 3923 ciEnv::current()->record_out_of_memory_failure(); 3924 return; 3925 } 3926 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3927 // to determine who we intended to call. 3928 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3929 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3930 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3931 "Fix constant in ret_addr_offset()"); 3932 } else { 3933 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3934 // Go thru the vtable. Get receiver klass. Receiver already 3935 // checked for non-null. If we'll go thru a C2I adapter, the 3936 // interpreter expects method in R19_method. 3937 3938 __ load_klass(R11_scratch1, R3); 3939 3940 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3941 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3942 __ li(R19_method, v_off); 3943 __ ldx(R19_method/*method*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3944 // NOTE: for vtable dispatches, the vtable entry will never be 3945 // null. However it may very well end up in handle_wrong_method 3946 // if the method is abstract for the particular class. 3947 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3948 // Call target. Either compiled code or C2I adapter. 3949 __ mtctr(R11_scratch1); 3950 __ bctrl(); 3951 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3952 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3953 } 3954 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3955 "Fix constant in ret_addr_offset()"); 3956 } 3957 #endif 3958 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3959 %} 3960 3961 // a runtime call 3962 enc_class enc_java_to_runtime_call (method meth) %{ 3963 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3964 3965 C2_MacroAssembler _masm(&cbuf); 3966 const address start_pc = __ pc(); 3967 3968 #if defined(ABI_ELFv2) 3969 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3970 __ call_c(entry, relocInfo::runtime_call_type); 3971 #else 3972 // The function we're going to call. 3973 FunctionDescriptor fdtemp; 3974 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3975 3976 Register Rtoc = R12_scratch2; 3977 // Calculate the method's TOC. 3978 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3979 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3980 // pool entries; call_c_using_toc will optimize the call. 3981 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3982 if (!success) { 3983 ciEnv::current()->record_out_of_memory_failure(); 3984 return; 3985 } 3986 #endif 3987 3988 // Check the ret_addr_offset. 3989 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3990 "Fix constant in ret_addr_offset()"); 3991 %} 3992 3993 // Move to ctr for leaf call. 3994 // This enc_class is needed so that scheduler gets proper 3995 // input mapping for latency computation. 3996 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3997 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3998 C2_MacroAssembler _masm(&cbuf); 3999 __ mtctr($src$$Register); 4000 %} 4001 4002 // Postalloc expand emitter for runtime leaf calls. 4003 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 4004 loadConLNodesTuple loadConLNodes_Entry; 4005 #if defined(ABI_ELFv2) 4006 jlong entry_address = (jlong) this->entry_point(); 4007 assert(entry_address, "need address here"); 4008 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 4009 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 4010 #else 4011 // Get the struct that describes the function we are about to call. 4012 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 4013 assert(fd, "need fd here"); 4014 jlong entry_address = (jlong) fd->entry(); 4015 // new nodes 4016 loadConLNodesTuple loadConLNodes_Env; 4017 loadConLNodesTuple loadConLNodes_Toc; 4018 4019 // Create nodes and operands for loading the entry point. 4020 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 4021 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 4022 4023 4024 // Create nodes and operands for loading the env pointer. 4025 if (fd->env() != NULL) { 4026 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 4027 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 4028 } else { 4029 loadConLNodes_Env._large_hi = NULL; 4030 loadConLNodes_Env._large_lo = NULL; 4031 loadConLNodes_Env._small = NULL; 4032 loadConLNodes_Env._last = new loadConL16Node(); 4033 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 4034 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 4035 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 4036 } 4037 4038 // Create nodes and operands for loading the Toc point. 4039 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 4040 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 4041 #endif // ABI_ELFv2 4042 // mtctr node 4043 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 4044 4045 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 4046 mtctr->add_req(0, loadConLNodes_Entry._last); 4047 4048 mtctr->_opnds[0] = new iRegLdstOper(); 4049 mtctr->_opnds[1] = new iRegLdstOper(); 4050 4051 // call node 4052 MachCallLeafNode *call = new CallLeafDirectNode(); 4053 4054 call->_opnds[0] = _opnds[0]; 4055 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 4056 4057 // Make the new call node look like the old one. 4058 call->_name = _name; 4059 call->_tf = _tf; 4060 call->_entry_point = _entry_point; 4061 call->_cnt = _cnt; 4062 call->_argsize = _argsize; 4063 call->_oop_map = _oop_map; 4064 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 4065 call->_jvms = NULL; 4066 call->_jvmadj = _jvmadj; 4067 call->_in_rms = _in_rms; 4068 call->_nesting = _nesting; 4069 4070 4071 // New call needs all inputs of old call. 4072 // Req... 4073 for (uint i = 0; i < req(); ++i) { 4074 if (i != mach_constant_base_node_input()) { 4075 call->add_req(in(i)); 4076 } 4077 } 4078 4079 // These must be reqired edges, as the registers are live up to 4080 // the call. Else the constants are handled as kills. 4081 call->add_req(mtctr); 4082 #if !defined(ABI_ELFv2) 4083 call->add_req(loadConLNodes_Env._last); 4084 call->add_req(loadConLNodes_Toc._last); 4085 #endif 4086 4087 // ...as well as prec 4088 for (uint i = req(); i < len(); ++i) { 4089 call->add_prec(in(i)); 4090 } 4091 4092 // registers 4093 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 4094 4095 // Insert the new nodes. 4096 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 4097 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 4098 #if !defined(ABI_ELFv2) 4099 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 4100 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 4101 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 4102 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 4103 #endif 4104 nodes->push(mtctr); 4105 nodes->push(call); 4106 %} 4107 %} 4108 4109 //----------FRAME-------------------------------------------------------------- 4110 // Definition of frame structure and management information. 4111 4112 frame %{ 4113 // What direction does stack grow in (assumed to be same for native & Java). 4114 stack_direction(TOWARDS_LOW); 4115 4116 // These two registers define part of the calling convention between 4117 // compiled code and the interpreter. 4118 4119 // Inline Cache Register or method for I2C. 4120 inline_cache_reg(R19); // R19_method 4121 4122 // Method Oop Register when calling interpreter. 4123 interpreter_method_oop_reg(R19); // R19_method 4124 4125 // Optional: name the operand used by cisc-spilling to access 4126 // [stack_pointer + offset]. 4127 cisc_spilling_operand_name(indOffset); 4128 4129 // Number of stack slots consumed by a Monitor enter. 4130 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 4131 4132 // Compiled code's Frame Pointer. 4133 frame_pointer(R1); // R1_SP 4134 4135 // Interpreter stores its frame pointer in a register which is 4136 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 4137 // interpreted java to compiled java. 4138 // 4139 // R14_state holds pointer to caller's cInterpreter. 4140 interpreter_frame_pointer(R14); // R14_state 4141 4142 stack_alignment(frame::alignment_in_bytes); 4143 4144 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4145 4146 // Number of outgoing stack slots killed above the 4147 // out_preserve_stack_slots for calls to C. Supports the var-args 4148 // backing area for register parms. 4149 // 4150 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4151 4152 // The after-PROLOG location of the return address. Location of 4153 // return address specifies a type (REG or STACK) and a number 4154 // representing the register number (i.e. - use a register name) or 4155 // stack slot. 4156 // 4157 // A: Link register is stored in stack slot ... 4158 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4159 // J: Therefore, we make sure that the link register is also in R11_scratch1 4160 // at the end of the prolog. 4161 // B: We use R20, now. 4162 //return_addr(REG R20); 4163 4164 // G: After reading the comments made by all the luminaries on their 4165 // failure to tell the compiler where the return address really is, 4166 // I hardly dare to try myself. However, I'm convinced it's in slot 4167 // 4 what apparently works and saves us some spills. 4168 return_addr(STACK 4); 4169 4170 // This is the body of the function 4171 // 4172 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4173 // uint length, // length of array 4174 // bool is_outgoing) 4175 // 4176 // The `sig' array is to be updated. sig[j] represents the location 4177 // of the j-th argument, either a register or a stack slot. 4178 4179 // Comment taken from i486.ad: 4180 // Body of function which returns an integer array locating 4181 // arguments either in registers or in stack slots. Passed an array 4182 // of ideal registers called "sig" and a "length" count. Stack-slot 4183 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4184 // arguments for a CALLEE. Incoming stack arguments are 4185 // automatically biased by the preserve_stack_slots field above. 4186 calling_convention %{ 4187 // No difference between ingoing/outgoing. Just pass false. 4188 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4189 %} 4190 4191 // Comment taken from i486.ad: 4192 // Body of function which returns an integer array locating 4193 // arguments either in registers or in stack slots. Passed an array 4194 // of ideal registers called "sig" and a "length" count. Stack-slot 4195 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4196 // arguments for a CALLEE. Incoming stack arguments are 4197 // automatically biased by the preserve_stack_slots field above. 4198 c_calling_convention %{ 4199 // This is obviously always outgoing. 4200 // C argument in register AND stack slot. 4201 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4202 %} 4203 4204 // Location of native (C/C++) and interpreter return values. This 4205 // is specified to be the same as Java. In the 32-bit VM, long 4206 // values are actually returned from native calls in O0:O1 and 4207 // returned to the interpreter in I0:I1. The copying to and from 4208 // the register pairs is done by the appropriate call and epilog 4209 // opcodes. This simplifies the register allocator. 4210 c_return_value %{ 4211 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4212 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0), 4213 "only return normal values"); 4214 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4215 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4216 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4217 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4218 %} 4219 4220 // Location of compiled Java return values. Same as C 4221 return_value %{ 4222 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4223 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0), 4224 "only return normal values"); 4225 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4226 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4227 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4228 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4229 %} 4230 %} 4231 4232 4233 //----------ATTRIBUTES--------------------------------------------------------- 4234 4235 //----------Operand Attributes------------------------------------------------- 4236 op_attrib op_cost(1); // Required cost attribute. 4237 4238 //----------Instruction Attributes--------------------------------------------- 4239 4240 // Cost attribute. required. 4241 ins_attrib ins_cost(DEFAULT_COST); 4242 4243 // Is this instruction a non-matching short branch variant of some 4244 // long branch? Not required. 4245 ins_attrib ins_short_branch(0); 4246 4247 ins_attrib ins_is_TrapBasedCheckNode(true); 4248 4249 // Number of constants. 4250 // This instruction uses the given number of constants 4251 // (optional attribute). 4252 // This is needed to determine in time whether the constant pool will 4253 // exceed 4000 entries. Before postalloc_expand the overall number of constants 4254 // is determined. It's also used to compute the constant pool size 4255 // in Output(). 4256 ins_attrib ins_num_consts(0); 4257 4258 // Required alignment attribute (must be a power of 2) specifies the 4259 // alignment that some part of the instruction (not necessarily the 4260 // start) requires. If > 1, a compute_padding() function must be 4261 // provided for the instruction. 4262 ins_attrib ins_alignment(1); 4263 4264 // Enforce/prohibit rematerializations. 4265 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4266 // then rematerialization of that instruction is prohibited and the 4267 // instruction's value will be spilled if necessary. 4268 // Causes that MachNode::rematerialize() returns false. 4269 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 4270 // then rematerialization should be enforced and a copy of the instruction 4271 // should be inserted if possible; rematerialization is not guaranteed. 4272 // Note: this may result in rematerializations in front of every use. 4273 // Causes that MachNode::rematerialize() can return true. 4274 // (optional attribute) 4275 ins_attrib ins_cannot_rematerialize(false); 4276 ins_attrib ins_should_rematerialize(false); 4277 4278 // Instruction has variable size depending on alignment. 4279 ins_attrib ins_variable_size_depending_on_alignment(false); 4280 4281 // Instruction is a nop. 4282 ins_attrib ins_is_nop(false); 4283 4284 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4285 ins_attrib ins_use_mach_if_fast_lock_node(false); 4286 4287 // Field for the toc offset of a constant. 4288 // 4289 // This is needed if the toc offset is not encodable as an immediate in 4290 // the PPC load instruction. If so, the upper (hi) bits of the offset are 4291 // added to the toc, and from this a load with immediate is performed. 4292 // With postalloc expand, we get two nodes that require the same offset 4293 // but which don't know about each other. The offset is only known 4294 // when the constant is added to the constant pool during emitting. 4295 // It is generated in the 'hi'-node adding the upper bits, and saved 4296 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 4297 // the offset from there when it gets encoded. 4298 ins_attrib ins_field_const_toc_offset(0); 4299 ins_attrib ins_field_const_toc_offset_hi_node(0); 4300 4301 // A field that can hold the instructions offset in the code buffer. 4302 // Set in the nodes emitter. 4303 ins_attrib ins_field_cbuf_insts_offset(-1); 4304 4305 // Fields for referencing a call's load-IC-node. 4306 // If the toc offset can not be encoded as an immediate in a load, we 4307 // use two nodes. 4308 ins_attrib ins_field_load_ic_hi_node(0); 4309 ins_attrib ins_field_load_ic_node(0); 4310 4311 //----------OPERANDS----------------------------------------------------------- 4312 // Operand definitions must precede instruction definitions for correct 4313 // parsing in the ADLC because operands constitute user defined types 4314 // which are used in instruction definitions. 4315 // 4316 // Formats are generated automatically for constants and base registers. 4317 4318 operand vecX() %{ 4319 constraint(ALLOC_IN_RC(vs_reg)); 4320 match(VecX); 4321 4322 format %{ %} 4323 interface(REG_INTER); 4324 %} 4325 4326 //----------Simple Operands---------------------------------------------------- 4327 // Immediate Operands 4328 4329 // Integer Immediate: 32-bit 4330 operand immI() %{ 4331 match(ConI); 4332 op_cost(40); 4333 format %{ %} 4334 interface(CONST_INTER); 4335 %} 4336 4337 operand immI8() %{ 4338 predicate(Assembler::is_simm(n->get_int(), 8)); 4339 op_cost(0); 4340 match(ConI); 4341 format %{ %} 4342 interface(CONST_INTER); 4343 %} 4344 4345 // Integer Immediate: 16-bit 4346 operand immI16() %{ 4347 predicate(Assembler::is_simm(n->get_int(), 16)); 4348 op_cost(0); 4349 match(ConI); 4350 format %{ %} 4351 interface(CONST_INTER); 4352 %} 4353 4354 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4355 operand immIhi16() %{ 4356 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4357 match(ConI); 4358 op_cost(0); 4359 format %{ %} 4360 interface(CONST_INTER); 4361 %} 4362 4363 operand immInegpow2() %{ 4364 predicate(is_power_of_2((jlong) (julong) (juint) (-(n->get_int())))); 4365 match(ConI); 4366 op_cost(0); 4367 format %{ %} 4368 interface(CONST_INTER); 4369 %} 4370 4371 operand immIpow2minus1() %{ 4372 predicate(is_power_of_2((((jlong) (n->get_int()))+1))); 4373 match(ConI); 4374 op_cost(0); 4375 format %{ %} 4376 interface(CONST_INTER); 4377 %} 4378 4379 operand immIpowerOf2() %{ 4380 predicate(is_power_of_2((((jlong) (julong) (juint) (n->get_int()))))); 4381 match(ConI); 4382 op_cost(0); 4383 format %{ %} 4384 interface(CONST_INTER); 4385 %} 4386 4387 // Unsigned Integer Immediate: the values 0-31 4388 operand uimmI5() %{ 4389 predicate(Assembler::is_uimm(n->get_int(), 5)); 4390 match(ConI); 4391 op_cost(0); 4392 format %{ %} 4393 interface(CONST_INTER); 4394 %} 4395 4396 // Unsigned Integer Immediate: 6-bit 4397 operand uimmI6() %{ 4398 predicate(Assembler::is_uimm(n->get_int(), 6)); 4399 match(ConI); 4400 op_cost(0); 4401 format %{ %} 4402 interface(CONST_INTER); 4403 %} 4404 4405 // Unsigned Integer Immediate: 6-bit int, greater than 32 4406 operand uimmI6_ge32() %{ 4407 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4408 match(ConI); 4409 op_cost(0); 4410 format %{ %} 4411 interface(CONST_INTER); 4412 %} 4413 4414 // Unsigned Integer Immediate: 15-bit 4415 operand uimmI15() %{ 4416 predicate(Assembler::is_uimm(n->get_int(), 15)); 4417 match(ConI); 4418 op_cost(0); 4419 format %{ %} 4420 interface(CONST_INTER); 4421 %} 4422 4423 // Unsigned Integer Immediate: 16-bit 4424 operand uimmI16() %{ 4425 predicate(Assembler::is_uimm(n->get_int(), 16)); 4426 match(ConI); 4427 op_cost(0); 4428 format %{ %} 4429 interface(CONST_INTER); 4430 %} 4431 4432 // constant 'int 0'. 4433 operand immI_0() %{ 4434 predicate(n->get_int() == 0); 4435 match(ConI); 4436 op_cost(0); 4437 format %{ %} 4438 interface(CONST_INTER); 4439 %} 4440 4441 // constant 'int 1'. 4442 operand immI_1() %{ 4443 predicate(n->get_int() == 1); 4444 match(ConI); 4445 op_cost(0); 4446 format %{ %} 4447 interface(CONST_INTER); 4448 %} 4449 4450 // constant 'int -1'. 4451 operand immI_minus1() %{ 4452 predicate(n->get_int() == -1); 4453 match(ConI); 4454 op_cost(0); 4455 format %{ %} 4456 interface(CONST_INTER); 4457 %} 4458 4459 // int value 16. 4460 operand immI_16() %{ 4461 predicate(n->get_int() == 16); 4462 match(ConI); 4463 op_cost(0); 4464 format %{ %} 4465 interface(CONST_INTER); 4466 %} 4467 4468 // int value 24. 4469 operand immI_24() %{ 4470 predicate(n->get_int() == 24); 4471 match(ConI); 4472 op_cost(0); 4473 format %{ %} 4474 interface(CONST_INTER); 4475 %} 4476 4477 // Compressed oops constants 4478 // Pointer Immediate 4479 operand immN() %{ 4480 match(ConN); 4481 4482 op_cost(10); 4483 format %{ %} 4484 interface(CONST_INTER); 4485 %} 4486 4487 // NULL Pointer Immediate 4488 operand immN_0() %{ 4489 predicate(n->get_narrowcon() == 0); 4490 match(ConN); 4491 4492 op_cost(0); 4493 format %{ %} 4494 interface(CONST_INTER); 4495 %} 4496 4497 // Compressed klass constants 4498 operand immNKlass() %{ 4499 match(ConNKlass); 4500 4501 op_cost(0); 4502 format %{ %} 4503 interface(CONST_INTER); 4504 %} 4505 4506 // This operand can be used to avoid matching of an instruct 4507 // with chain rule. 4508 operand immNKlass_NM() %{ 4509 match(ConNKlass); 4510 predicate(false); 4511 op_cost(0); 4512 format %{ %} 4513 interface(CONST_INTER); 4514 %} 4515 4516 // Pointer Immediate: 64-bit 4517 operand immP() %{ 4518 match(ConP); 4519 op_cost(0); 4520 format %{ %} 4521 interface(CONST_INTER); 4522 %} 4523 4524 // Operand to avoid match of loadConP. 4525 // This operand can be used to avoid matching of an instruct 4526 // with chain rule. 4527 operand immP_NM() %{ 4528 match(ConP); 4529 predicate(false); 4530 op_cost(0); 4531 format %{ %} 4532 interface(CONST_INTER); 4533 %} 4534 4535 // costant 'pointer 0'. 4536 operand immP_0() %{ 4537 predicate(n->get_ptr() == 0); 4538 match(ConP); 4539 op_cost(0); 4540 format %{ %} 4541 interface(CONST_INTER); 4542 %} 4543 4544 // pointer 0x0 or 0x1 4545 operand immP_0or1() %{ 4546 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4547 match(ConP); 4548 op_cost(0); 4549 format %{ %} 4550 interface(CONST_INTER); 4551 %} 4552 4553 operand immL() %{ 4554 match(ConL); 4555 op_cost(40); 4556 format %{ %} 4557 interface(CONST_INTER); 4558 %} 4559 4560 operand immLmax30() %{ 4561 predicate((n->get_long() <= 30)); 4562 match(ConL); 4563 op_cost(0); 4564 format %{ %} 4565 interface(CONST_INTER); 4566 %} 4567 4568 // Long Immediate: 16-bit 4569 operand immL16() %{ 4570 predicate(Assembler::is_simm(n->get_long(), 16)); 4571 match(ConL); 4572 op_cost(0); 4573 format %{ %} 4574 interface(CONST_INTER); 4575 %} 4576 4577 // Long Immediate: 16-bit, 4-aligned 4578 operand immL16Alg4() %{ 4579 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4580 match(ConL); 4581 op_cost(0); 4582 format %{ %} 4583 interface(CONST_INTER); 4584 %} 4585 4586 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4587 operand immL32hi16() %{ 4588 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4589 match(ConL); 4590 op_cost(0); 4591 format %{ %} 4592 interface(CONST_INTER); 4593 %} 4594 4595 // Long Immediate: 32-bit 4596 operand immL32() %{ 4597 predicate(Assembler::is_simm(n->get_long(), 32)); 4598 match(ConL); 4599 op_cost(0); 4600 format %{ %} 4601 interface(CONST_INTER); 4602 %} 4603 4604 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4605 operand immLhighest16() %{ 4606 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4607 match(ConL); 4608 op_cost(0); 4609 format %{ %} 4610 interface(CONST_INTER); 4611 %} 4612 4613 operand immLnegpow2() %{ 4614 predicate(is_power_of_2((jlong)-(n->get_long()))); 4615 match(ConL); 4616 op_cost(0); 4617 format %{ %} 4618 interface(CONST_INTER); 4619 %} 4620 4621 operand immLpow2minus1() %{ 4622 predicate(is_power_of_2((((jlong) (n->get_long()))+1)) && 4623 (n->get_long() != (jlong)0xffffffffffffffffL)); 4624 match(ConL); 4625 op_cost(0); 4626 format %{ %} 4627 interface(CONST_INTER); 4628 %} 4629 4630 // constant 'long 0'. 4631 operand immL_0() %{ 4632 predicate(n->get_long() == 0L); 4633 match(ConL); 4634 op_cost(0); 4635 format %{ %} 4636 interface(CONST_INTER); 4637 %} 4638 4639 // constat ' long -1'. 4640 operand immL_minus1() %{ 4641 predicate(n->get_long() == -1L); 4642 match(ConL); 4643 op_cost(0); 4644 format %{ %} 4645 interface(CONST_INTER); 4646 %} 4647 4648 // Long Immediate: low 32-bit mask 4649 operand immL_32bits() %{ 4650 predicate(n->get_long() == 0xFFFFFFFFL); 4651 match(ConL); 4652 op_cost(0); 4653 format %{ %} 4654 interface(CONST_INTER); 4655 %} 4656 4657 // Unsigned Long Immediate: 16-bit 4658 operand uimmL16() %{ 4659 predicate(Assembler::is_uimm(n->get_long(), 16)); 4660 match(ConL); 4661 op_cost(0); 4662 format %{ %} 4663 interface(CONST_INTER); 4664 %} 4665 4666 // Float Immediate 4667 operand immF() %{ 4668 match(ConF); 4669 op_cost(40); 4670 format %{ %} 4671 interface(CONST_INTER); 4672 %} 4673 4674 // Float Immediate: +0.0f. 4675 operand immF_0() %{ 4676 predicate(jint_cast(n->getf()) == 0); 4677 match(ConF); 4678 4679 op_cost(0); 4680 format %{ %} 4681 interface(CONST_INTER); 4682 %} 4683 4684 // Double Immediate 4685 operand immD() %{ 4686 match(ConD); 4687 op_cost(40); 4688 format %{ %} 4689 interface(CONST_INTER); 4690 %} 4691 4692 // Double Immediate: +0.0d. 4693 operand immD_0() %{ 4694 predicate(jlong_cast(n->getd()) == 0); 4695 match(ConD); 4696 4697 op_cost(0); 4698 format %{ %} 4699 interface(CONST_INTER); 4700 %} 4701 4702 // Integer Register Operands 4703 // Integer Destination Register 4704 // See definition of reg_class bits32_reg_rw. 4705 operand iRegIdst() %{ 4706 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4707 match(RegI); 4708 match(rscratch1RegI); 4709 match(rscratch2RegI); 4710 match(rarg1RegI); 4711 match(rarg2RegI); 4712 match(rarg3RegI); 4713 match(rarg4RegI); 4714 format %{ %} 4715 interface(REG_INTER); 4716 %} 4717 4718 // Integer Source Register 4719 // See definition of reg_class bits32_reg_ro. 4720 operand iRegIsrc() %{ 4721 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4722 match(RegI); 4723 match(rscratch1RegI); 4724 match(rscratch2RegI); 4725 match(rarg1RegI); 4726 match(rarg2RegI); 4727 match(rarg3RegI); 4728 match(rarg4RegI); 4729 format %{ %} 4730 interface(REG_INTER); 4731 %} 4732 4733 operand rscratch1RegI() %{ 4734 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4735 match(iRegIdst); 4736 format %{ %} 4737 interface(REG_INTER); 4738 %} 4739 4740 operand rscratch2RegI() %{ 4741 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4742 match(iRegIdst); 4743 format %{ %} 4744 interface(REG_INTER); 4745 %} 4746 4747 operand rarg1RegI() %{ 4748 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4749 match(iRegIdst); 4750 format %{ %} 4751 interface(REG_INTER); 4752 %} 4753 4754 operand rarg2RegI() %{ 4755 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4756 match(iRegIdst); 4757 format %{ %} 4758 interface(REG_INTER); 4759 %} 4760 4761 operand rarg3RegI() %{ 4762 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4763 match(iRegIdst); 4764 format %{ %} 4765 interface(REG_INTER); 4766 %} 4767 4768 operand rarg4RegI() %{ 4769 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4770 match(iRegIdst); 4771 format %{ %} 4772 interface(REG_INTER); 4773 %} 4774 4775 operand rarg1RegL() %{ 4776 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4777 match(iRegLdst); 4778 format %{ %} 4779 interface(REG_INTER); 4780 %} 4781 4782 operand rarg2RegL() %{ 4783 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4784 match(iRegLdst); 4785 format %{ %} 4786 interface(REG_INTER); 4787 %} 4788 4789 operand rarg3RegL() %{ 4790 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4791 match(iRegLdst); 4792 format %{ %} 4793 interface(REG_INTER); 4794 %} 4795 4796 operand rarg4RegL() %{ 4797 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4798 match(iRegLdst); 4799 format %{ %} 4800 interface(REG_INTER); 4801 %} 4802 4803 // Pointer Destination Register 4804 // See definition of reg_class bits64_reg_rw. 4805 operand iRegPdst() %{ 4806 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4807 match(RegP); 4808 match(rscratch1RegP); 4809 match(rscratch2RegP); 4810 match(rarg1RegP); 4811 match(rarg2RegP); 4812 match(rarg3RegP); 4813 match(rarg4RegP); 4814 format %{ %} 4815 interface(REG_INTER); 4816 %} 4817 4818 // Pointer Destination Register 4819 // Operand not using r11 and r12 (killed in epilog). 4820 operand iRegPdstNoScratch() %{ 4821 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4822 match(RegP); 4823 match(rarg1RegP); 4824 match(rarg2RegP); 4825 match(rarg3RegP); 4826 match(rarg4RegP); 4827 format %{ %} 4828 interface(REG_INTER); 4829 %} 4830 4831 // Pointer Source Register 4832 // See definition of reg_class bits64_reg_ro. 4833 operand iRegPsrc() %{ 4834 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4835 match(RegP); 4836 match(iRegPdst); 4837 match(rscratch1RegP); 4838 match(rscratch2RegP); 4839 match(rarg1RegP); 4840 match(rarg2RegP); 4841 match(rarg3RegP); 4842 match(rarg4RegP); 4843 match(threadRegP); 4844 format %{ %} 4845 interface(REG_INTER); 4846 %} 4847 4848 // Thread operand. 4849 operand threadRegP() %{ 4850 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4851 match(iRegPdst); 4852 format %{ "R16" %} 4853 interface(REG_INTER); 4854 %} 4855 4856 operand rscratch1RegP() %{ 4857 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4858 match(iRegPdst); 4859 format %{ "R11" %} 4860 interface(REG_INTER); 4861 %} 4862 4863 operand rscratch2RegP() %{ 4864 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4865 match(iRegPdst); 4866 format %{ %} 4867 interface(REG_INTER); 4868 %} 4869 4870 operand rarg1RegP() %{ 4871 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4872 match(iRegPdst); 4873 format %{ %} 4874 interface(REG_INTER); 4875 %} 4876 4877 operand rarg2RegP() %{ 4878 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4879 match(iRegPdst); 4880 format %{ %} 4881 interface(REG_INTER); 4882 %} 4883 4884 operand rarg3RegP() %{ 4885 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4886 match(iRegPdst); 4887 format %{ %} 4888 interface(REG_INTER); 4889 %} 4890 4891 operand rarg4RegP() %{ 4892 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4893 match(iRegPdst); 4894 format %{ %} 4895 interface(REG_INTER); 4896 %} 4897 4898 operand iRegNsrc() %{ 4899 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4900 match(RegN); 4901 match(iRegNdst); 4902 4903 format %{ %} 4904 interface(REG_INTER); 4905 %} 4906 4907 operand iRegNdst() %{ 4908 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4909 match(RegN); 4910 4911 format %{ %} 4912 interface(REG_INTER); 4913 %} 4914 4915 // Long Destination Register 4916 // See definition of reg_class bits64_reg_rw. 4917 operand iRegLdst() %{ 4918 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4919 match(RegL); 4920 match(rscratch1RegL); 4921 match(rscratch2RegL); 4922 format %{ %} 4923 interface(REG_INTER); 4924 %} 4925 4926 // Long Source Register 4927 // See definition of reg_class bits64_reg_ro. 4928 operand iRegLsrc() %{ 4929 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4930 match(RegL); 4931 match(iRegLdst); 4932 match(rscratch1RegL); 4933 match(rscratch2RegL); 4934 format %{ %} 4935 interface(REG_INTER); 4936 %} 4937 4938 // Special operand for ConvL2I. 4939 operand iRegL2Isrc(iRegLsrc reg) %{ 4940 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4941 match(ConvL2I reg); 4942 format %{ "ConvL2I($reg)" %} 4943 interface(REG_INTER) 4944 %} 4945 4946 operand rscratch1RegL() %{ 4947 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4948 match(RegL); 4949 format %{ %} 4950 interface(REG_INTER); 4951 %} 4952 4953 operand rscratch2RegL() %{ 4954 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4955 match(RegL); 4956 format %{ %} 4957 interface(REG_INTER); 4958 %} 4959 4960 // Condition Code Flag Registers 4961 operand flagsReg() %{ 4962 constraint(ALLOC_IN_RC(int_flags)); 4963 match(RegFlags); 4964 format %{ %} 4965 interface(REG_INTER); 4966 %} 4967 4968 operand flagsRegSrc() %{ 4969 constraint(ALLOC_IN_RC(int_flags_ro)); 4970 match(RegFlags); 4971 match(flagsReg); 4972 match(flagsRegCR0); 4973 format %{ %} 4974 interface(REG_INTER); 4975 %} 4976 4977 // Condition Code Flag Register CR0 4978 operand flagsRegCR0() %{ 4979 constraint(ALLOC_IN_RC(int_flags_CR0)); 4980 match(RegFlags); 4981 format %{ "CR0" %} 4982 interface(REG_INTER); 4983 %} 4984 4985 operand flagsRegCR1() %{ 4986 constraint(ALLOC_IN_RC(int_flags_CR1)); 4987 match(RegFlags); 4988 format %{ "CR1" %} 4989 interface(REG_INTER); 4990 %} 4991 4992 operand flagsRegCR6() %{ 4993 constraint(ALLOC_IN_RC(int_flags_CR6)); 4994 match(RegFlags); 4995 format %{ "CR6" %} 4996 interface(REG_INTER); 4997 %} 4998 4999 operand regCTR() %{ 5000 constraint(ALLOC_IN_RC(ctr_reg)); 5001 // RegFlags should work. Introducing a RegSpecial type would cause a 5002 // lot of changes. 5003 match(RegFlags); 5004 format %{"SR_CTR" %} 5005 interface(REG_INTER); 5006 %} 5007 5008 operand regD() %{ 5009 constraint(ALLOC_IN_RC(dbl_reg)); 5010 match(RegD); 5011 format %{ %} 5012 interface(REG_INTER); 5013 %} 5014 5015 operand regF() %{ 5016 constraint(ALLOC_IN_RC(flt_reg)); 5017 match(RegF); 5018 format %{ %} 5019 interface(REG_INTER); 5020 %} 5021 5022 // Special Registers 5023 5024 // Method Register 5025 operand inline_cache_regP(iRegPdst reg) %{ 5026 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 5027 match(reg); 5028 format %{ %} 5029 interface(REG_INTER); 5030 %} 5031 5032 operand compiler_method_oop_regP(iRegPdst reg) %{ 5033 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 5034 match(reg); 5035 format %{ %} 5036 interface(REG_INTER); 5037 %} 5038 5039 operand interpreter_method_oop_regP(iRegPdst reg) %{ 5040 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 5041 match(reg); 5042 format %{ %} 5043 interface(REG_INTER); 5044 %} 5045 5046 // Operands to remove register moves in unscaled mode. 5047 // Match read/write registers with an EncodeP node if neither shift nor add are required. 5048 operand iRegP2N(iRegPsrc reg) %{ 5049 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0); 5050 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5051 match(EncodeP reg); 5052 format %{ "$reg" %} 5053 interface(REG_INTER) 5054 %} 5055 5056 operand iRegN2P(iRegNsrc reg) %{ 5057 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5058 constraint(ALLOC_IN_RC(bits32_reg_ro)); 5059 match(DecodeN reg); 5060 format %{ "$reg" %} 5061 interface(REG_INTER) 5062 %} 5063 5064 operand iRegN2P_klass(iRegNsrc reg) %{ 5065 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5066 constraint(ALLOC_IN_RC(bits32_reg_ro)); 5067 match(DecodeNKlass reg); 5068 format %{ "$reg" %} 5069 interface(REG_INTER) 5070 %} 5071 5072 //----------Complex Operands--------------------------------------------------- 5073 // Indirect Memory Reference 5074 operand indirect(iRegPsrc reg) %{ 5075 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5076 match(reg); 5077 op_cost(100); 5078 format %{ "[$reg]" %} 5079 interface(MEMORY_INTER) %{ 5080 base($reg); 5081 index(0x0); 5082 scale(0x0); 5083 disp(0x0); 5084 %} 5085 %} 5086 5087 // Indirect with Offset 5088 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 5089 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5090 match(AddP reg offset); 5091 op_cost(100); 5092 format %{ "[$reg + $offset]" %} 5093 interface(MEMORY_INTER) %{ 5094 base($reg); 5095 index(0x0); 5096 scale(0x0); 5097 disp($offset); 5098 %} 5099 %} 5100 5101 // Indirect with 4-aligned Offset 5102 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 5103 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5104 match(AddP reg offset); 5105 op_cost(100); 5106 format %{ "[$reg + $offset]" %} 5107 interface(MEMORY_INTER) %{ 5108 base($reg); 5109 index(0x0); 5110 scale(0x0); 5111 disp($offset); 5112 %} 5113 %} 5114 5115 //----------Complex Operands for Compressed OOPs------------------------------- 5116 // Compressed OOPs with narrow_oop_shift == 0. 5117 5118 // Indirect Memory Reference, compressed OOP 5119 operand indirectNarrow(iRegNsrc reg) %{ 5120 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5121 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5122 match(DecodeN reg); 5123 op_cost(100); 5124 format %{ "[$reg]" %} 5125 interface(MEMORY_INTER) %{ 5126 base($reg); 5127 index(0x0); 5128 scale(0x0); 5129 disp(0x0); 5130 %} 5131 %} 5132 5133 operand indirectNarrow_klass(iRegNsrc reg) %{ 5134 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5135 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5136 match(DecodeNKlass reg); 5137 op_cost(100); 5138 format %{ "[$reg]" %} 5139 interface(MEMORY_INTER) %{ 5140 base($reg); 5141 index(0x0); 5142 scale(0x0); 5143 disp(0x0); 5144 %} 5145 %} 5146 5147 // Indirect with Offset, compressed OOP 5148 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 5149 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5150 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5151 match(AddP (DecodeN reg) offset); 5152 op_cost(100); 5153 format %{ "[$reg + $offset]" %} 5154 interface(MEMORY_INTER) %{ 5155 base($reg); 5156 index(0x0); 5157 scale(0x0); 5158 disp($offset); 5159 %} 5160 %} 5161 5162 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5163 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5164 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5165 match(AddP (DecodeNKlass reg) offset); 5166 op_cost(100); 5167 format %{ "[$reg + $offset]" %} 5168 interface(MEMORY_INTER) %{ 5169 base($reg); 5170 index(0x0); 5171 scale(0x0); 5172 disp($offset); 5173 %} 5174 %} 5175 5176 // Indirect with 4-aligned Offset, compressed OOP 5177 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 5178 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5179 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5180 match(AddP (DecodeN reg) offset); 5181 op_cost(100); 5182 format %{ "[$reg + $offset]" %} 5183 interface(MEMORY_INTER) %{ 5184 base($reg); 5185 index(0x0); 5186 scale(0x0); 5187 disp($offset); 5188 %} 5189 %} 5190 5191 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5192 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5193 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5194 match(AddP (DecodeNKlass reg) offset); 5195 op_cost(100); 5196 format %{ "[$reg + $offset]" %} 5197 interface(MEMORY_INTER) %{ 5198 base($reg); 5199 index(0x0); 5200 scale(0x0); 5201 disp($offset); 5202 %} 5203 %} 5204 5205 //----------Special Memory Operands-------------------------------------------- 5206 // Stack Slot Operand 5207 // 5208 // This operand is used for loading and storing temporary values on 5209 // the stack where a match requires a value to flow through memory. 5210 operand stackSlotI(sRegI reg) %{ 5211 constraint(ALLOC_IN_RC(stack_slots)); 5212 op_cost(100); 5213 //match(RegI); 5214 format %{ "[sp+$reg]" %} 5215 interface(MEMORY_INTER) %{ 5216 base(0x1); // R1_SP 5217 index(0x0); 5218 scale(0x0); 5219 disp($reg); // Stack Offset 5220 %} 5221 %} 5222 5223 operand stackSlotL(sRegL reg) %{ 5224 constraint(ALLOC_IN_RC(stack_slots)); 5225 op_cost(100); 5226 //match(RegL); 5227 format %{ "[sp+$reg]" %} 5228 interface(MEMORY_INTER) %{ 5229 base(0x1); // R1_SP 5230 index(0x0); 5231 scale(0x0); 5232 disp($reg); // Stack Offset 5233 %} 5234 %} 5235 5236 operand stackSlotP(sRegP reg) %{ 5237 constraint(ALLOC_IN_RC(stack_slots)); 5238 op_cost(100); 5239 //match(RegP); 5240 format %{ "[sp+$reg]" %} 5241 interface(MEMORY_INTER) %{ 5242 base(0x1); // R1_SP 5243 index(0x0); 5244 scale(0x0); 5245 disp($reg); // Stack Offset 5246 %} 5247 %} 5248 5249 operand stackSlotF(sRegF reg) %{ 5250 constraint(ALLOC_IN_RC(stack_slots)); 5251 op_cost(100); 5252 //match(RegF); 5253 format %{ "[sp+$reg]" %} 5254 interface(MEMORY_INTER) %{ 5255 base(0x1); // R1_SP 5256 index(0x0); 5257 scale(0x0); 5258 disp($reg); // Stack Offset 5259 %} 5260 %} 5261 5262 operand stackSlotD(sRegD reg) %{ 5263 constraint(ALLOC_IN_RC(stack_slots)); 5264 op_cost(100); 5265 //match(RegD); 5266 format %{ "[sp+$reg]" %} 5267 interface(MEMORY_INTER) %{ 5268 base(0x1); // R1_SP 5269 index(0x0); 5270 scale(0x0); 5271 disp($reg); // Stack Offset 5272 %} 5273 %} 5274 5275 // Operands for expressing Control Flow 5276 // NOTE: Label is a predefined operand which should not be redefined in 5277 // the AD file. It is generically handled within the ADLC. 5278 5279 //----------Conditional Branch Operands---------------------------------------- 5280 // Comparison Op 5281 // 5282 // This is the operation of the comparison, and is limited to the 5283 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5284 // (!=). 5285 // 5286 // Other attributes of the comparison, such as unsignedness, are specified 5287 // by the comparison instruction that sets a condition code flags register. 5288 // That result is represented by a flags operand whose subtype is appropriate 5289 // to the unsignedness (etc.) of the comparison. 5290 // 5291 // Later, the instruction which matches both the Comparison Op (a Bool) and 5292 // the flags (produced by the Cmp) specifies the coding of the comparison op 5293 // by matching a specific subtype of Bool operand below. 5294 5295 // When used for floating point comparisons: unordered same as less. 5296 operand cmpOp() %{ 5297 match(Bool); 5298 format %{ "" %} 5299 interface(COND_INTER) %{ 5300 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5301 // BO & BI 5302 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5303 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5304 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5305 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5306 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5307 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5308 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5309 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5310 %} 5311 %} 5312 5313 //----------OPERAND CLASSES---------------------------------------------------- 5314 // Operand Classes are groups of operands that are used to simplify 5315 // instruction definitions by not requiring the AD writer to specify 5316 // seperate instructions for every form of operand when the 5317 // instruction accepts multiple operand types with the same basic 5318 // encoding and format. The classic case of this is memory operands. 5319 // Indirect is not included since its use is limited to Compare & Swap. 5320 5321 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5322 // Memory operand where offsets are 4-aligned. Required for ld, std. 5323 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5324 opclass indirectMemory(indirect, indirectNarrow); 5325 5326 // Special opclass for I and ConvL2I. 5327 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5328 5329 // Operand classes to match encode and decode. iRegN_P2N is only used 5330 // for storeN. I have never seen an encode node elsewhere. 5331 opclass iRegN_P2N(iRegNsrc, iRegP2N); 5332 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5333 5334 //----------PIPELINE----------------------------------------------------------- 5335 5336 pipeline %{ 5337 5338 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5339 // J. Res. & Dev., No. 1, Jan. 2002. 5340 5341 //----------ATTRIBUTES--------------------------------------------------------- 5342 attributes %{ 5343 5344 // Power4 instructions are of fixed length. 5345 fixed_size_instructions; 5346 5347 // TODO: if `bundle' means number of instructions fetched 5348 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5349 // max instructions issued per cycle, this is 5. 5350 max_instructions_per_bundle = 8; 5351 5352 // A Power4 instruction is 4 bytes long. 5353 instruction_unit_size = 4; 5354 5355 // The Power4 processor fetches 64 bytes... 5356 instruction_fetch_unit_size = 64; 5357 5358 // ...in one line 5359 instruction_fetch_units = 1 5360 5361 // Unused, list one so that array generated by adlc is not empty. 5362 // Aix compiler chokes if _nop_count = 0. 5363 nops(fxNop); 5364 %} 5365 5366 //----------RESOURCES---------------------------------------------------------- 5367 // Resources are the functional units available to the machine 5368 resources( 5369 PPC_BR, // branch unit 5370 PPC_CR, // condition unit 5371 PPC_FX1, // integer arithmetic unit 1 5372 PPC_FX2, // integer arithmetic unit 2 5373 PPC_LDST1, // load/store unit 1 5374 PPC_LDST2, // load/store unit 2 5375 PPC_FP1, // float arithmetic unit 1 5376 PPC_FP2, // float arithmetic unit 2 5377 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5378 PPC_FX = PPC_FX1 | PPC_FX2, 5379 PPC_FP = PPC_FP1 | PPC_FP2 5380 ); 5381 5382 //----------PIPELINE DESCRIPTION----------------------------------------------- 5383 // Pipeline Description specifies the stages in the machine's pipeline 5384 pipe_desc( 5385 // Power4 longest pipeline path 5386 PPC_IF, // instruction fetch 5387 PPC_IC, 5388 //PPC_BP, // branch prediction 5389 PPC_D0, // decode 5390 PPC_D1, // decode 5391 PPC_D2, // decode 5392 PPC_D3, // decode 5393 PPC_Xfer1, 5394 PPC_GD, // group definition 5395 PPC_MP, // map 5396 PPC_ISS, // issue 5397 PPC_RF, // resource fetch 5398 PPC_EX1, // execute (all units) 5399 PPC_EX2, // execute (FP, LDST) 5400 PPC_EX3, // execute (FP, LDST) 5401 PPC_EX4, // execute (FP) 5402 PPC_EX5, // execute (FP) 5403 PPC_EX6, // execute (FP) 5404 PPC_WB, // write back 5405 PPC_Xfer2, 5406 PPC_CP 5407 ); 5408 5409 //----------PIPELINE CLASSES--------------------------------------------------- 5410 // Pipeline Classes describe the stages in which input and output are 5411 // referenced by the hardware pipeline. 5412 5413 // Simple pipeline classes. 5414 5415 // Default pipeline class. 5416 pipe_class pipe_class_default() %{ 5417 single_instruction; 5418 fixed_latency(2); 5419 %} 5420 5421 // Pipeline class for empty instructions. 5422 pipe_class pipe_class_empty() %{ 5423 single_instruction; 5424 fixed_latency(0); 5425 %} 5426 5427 // Pipeline class for compares. 5428 pipe_class pipe_class_compare() %{ 5429 single_instruction; 5430 fixed_latency(16); 5431 %} 5432 5433 // Pipeline class for traps. 5434 pipe_class pipe_class_trap() %{ 5435 single_instruction; 5436 fixed_latency(100); 5437 %} 5438 5439 // Pipeline class for memory operations. 5440 pipe_class pipe_class_memory() %{ 5441 single_instruction; 5442 fixed_latency(16); 5443 %} 5444 5445 // Pipeline class for call. 5446 pipe_class pipe_class_call() %{ 5447 single_instruction; 5448 fixed_latency(100); 5449 %} 5450 5451 // Define the class for the Nop node. 5452 define %{ 5453 MachNop = pipe_class_default; 5454 %} 5455 5456 %} 5457 5458 //----------INSTRUCTIONS------------------------------------------------------- 5459 5460 // Naming of instructions: 5461 // opA_operB / opA_operB_operC: 5462 // Operation 'op' with one or two source operands 'oper'. Result 5463 // type is A, source operand types are B and C. 5464 // Iff A == B == C, B and C are left out. 5465 // 5466 // The instructions are ordered according to the following scheme: 5467 // - loads 5468 // - load constants 5469 // - prefetch 5470 // - store 5471 // - encode/decode 5472 // - membar 5473 // - conditional moves 5474 // - compare & swap 5475 // - arithmetic and logic operations 5476 // * int: Add, Sub, Mul, Div, Mod 5477 // * int: lShift, arShift, urShift, rot 5478 // * float: Add, Sub, Mul, Div 5479 // * and, or, xor ... 5480 // - register moves: float <-> int, reg <-> stack, repl 5481 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5482 // - conv (low level type cast requiring bit changes (sign extend etc) 5483 // - compares, range & zero checks. 5484 // - branches 5485 // - complex operations, intrinsics, min, max, replicate 5486 // - lock 5487 // - Calls 5488 // 5489 // If there are similar instructions with different types they are sorted: 5490 // int before float 5491 // small before big 5492 // signed before unsigned 5493 // e.g., loadS before loadUS before loadI before loadF. 5494 5495 5496 //----------Load/Store Instructions-------------------------------------------- 5497 5498 //----------Load Instructions-------------------------------------------------- 5499 5500 // Converts byte to int. 5501 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5502 // reuses the 'amount' operand, but adlc expects that operand specification 5503 // and operands in match rule are equivalent. 5504 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5505 effect(DEF dst, USE src); 5506 format %{ "EXTSB $dst, $src \t// byte->int" %} 5507 size(4); 5508 ins_encode %{ 5509 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5510 __ extsb($dst$$Register, $src$$Register); 5511 %} 5512 ins_pipe(pipe_class_default); 5513 %} 5514 5515 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5516 // match-rule, false predicate 5517 match(Set dst (LoadB mem)); 5518 predicate(false); 5519 5520 format %{ "LBZ $dst, $mem" %} 5521 size(4); 5522 ins_encode( enc_lbz(dst, mem) ); 5523 ins_pipe(pipe_class_memory); 5524 %} 5525 5526 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5527 // match-rule, false predicate 5528 match(Set dst (LoadB mem)); 5529 predicate(false); 5530 5531 format %{ "LBZ $dst, $mem\n\t" 5532 "TWI $dst\n\t" 5533 "ISYNC" %} 5534 size(12); 5535 ins_encode( enc_lbz_ac(dst, mem) ); 5536 ins_pipe(pipe_class_memory); 5537 %} 5538 5539 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5540 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5541 match(Set dst (LoadB mem)); 5542 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5543 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5544 expand %{ 5545 iRegIdst tmp; 5546 loadUB_indirect(tmp, mem); 5547 convB2I_reg_2(dst, tmp); 5548 %} 5549 %} 5550 5551 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5552 match(Set dst (LoadB mem)); 5553 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5554 expand %{ 5555 iRegIdst tmp; 5556 loadUB_indirect_ac(tmp, mem); 5557 convB2I_reg_2(dst, tmp); 5558 %} 5559 %} 5560 5561 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5562 // match-rule, false predicate 5563 match(Set dst (LoadB mem)); 5564 predicate(false); 5565 5566 format %{ "LBZ $dst, $mem" %} 5567 size(4); 5568 ins_encode( enc_lbz(dst, mem) ); 5569 ins_pipe(pipe_class_memory); 5570 %} 5571 5572 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5573 // match-rule, false predicate 5574 match(Set dst (LoadB mem)); 5575 predicate(false); 5576 5577 format %{ "LBZ $dst, $mem\n\t" 5578 "TWI $dst\n\t" 5579 "ISYNC" %} 5580 size(12); 5581 ins_encode( enc_lbz_ac(dst, mem) ); 5582 ins_pipe(pipe_class_memory); 5583 %} 5584 5585 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5586 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5587 match(Set dst (LoadB mem)); 5588 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5589 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5590 5591 expand %{ 5592 iRegIdst tmp; 5593 loadUB_indOffset16(tmp, mem); 5594 convB2I_reg_2(dst, tmp); 5595 %} 5596 %} 5597 5598 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5599 match(Set dst (LoadB mem)); 5600 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5601 5602 expand %{ 5603 iRegIdst tmp; 5604 loadUB_indOffset16_ac(tmp, mem); 5605 convB2I_reg_2(dst, tmp); 5606 %} 5607 %} 5608 5609 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5610 instruct loadUB(iRegIdst dst, memory mem) %{ 5611 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5612 match(Set dst (LoadUB mem)); 5613 ins_cost(MEMORY_REF_COST); 5614 5615 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5616 size(4); 5617 ins_encode( enc_lbz(dst, mem) ); 5618 ins_pipe(pipe_class_memory); 5619 %} 5620 5621 // Load Unsigned Byte (8bit UNsigned) acquire. 5622 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5623 match(Set dst (LoadUB mem)); 5624 ins_cost(3*MEMORY_REF_COST); 5625 5626 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5627 "TWI $dst\n\t" 5628 "ISYNC" %} 5629 size(12); 5630 ins_encode( enc_lbz_ac(dst, mem) ); 5631 ins_pipe(pipe_class_memory); 5632 %} 5633 5634 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5635 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5636 match(Set dst (ConvI2L (LoadUB mem))); 5637 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5638 ins_cost(MEMORY_REF_COST); 5639 5640 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5641 size(4); 5642 ins_encode( enc_lbz(dst, mem) ); 5643 ins_pipe(pipe_class_memory); 5644 %} 5645 5646 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5647 match(Set dst (ConvI2L (LoadUB mem))); 5648 ins_cost(3*MEMORY_REF_COST); 5649 5650 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5651 "TWI $dst\n\t" 5652 "ISYNC" %} 5653 size(12); 5654 ins_encode( enc_lbz_ac(dst, mem) ); 5655 ins_pipe(pipe_class_memory); 5656 %} 5657 5658 // Load Short (16bit signed) 5659 instruct loadS(iRegIdst dst, memory mem) %{ 5660 match(Set dst (LoadS mem)); 5661 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5662 ins_cost(MEMORY_REF_COST); 5663 5664 format %{ "LHA $dst, $mem" %} 5665 size(4); 5666 ins_encode %{ 5667 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5668 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5669 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5670 %} 5671 ins_pipe(pipe_class_memory); 5672 %} 5673 5674 // Load Short (16bit signed) acquire. 5675 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5676 match(Set dst (LoadS mem)); 5677 ins_cost(3*MEMORY_REF_COST); 5678 5679 format %{ "LHA $dst, $mem\t acquire\n\t" 5680 "TWI $dst\n\t" 5681 "ISYNC" %} 5682 size(12); 5683 ins_encode %{ 5684 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5685 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5686 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5687 __ twi_0($dst$$Register); 5688 __ isync(); 5689 %} 5690 ins_pipe(pipe_class_memory); 5691 %} 5692 5693 // Load Char (16bit unsigned) 5694 instruct loadUS(iRegIdst dst, memory mem) %{ 5695 match(Set dst (LoadUS mem)); 5696 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5697 ins_cost(MEMORY_REF_COST); 5698 5699 format %{ "LHZ $dst, $mem" %} 5700 size(4); 5701 ins_encode( enc_lhz(dst, mem) ); 5702 ins_pipe(pipe_class_memory); 5703 %} 5704 5705 // Load Char (16bit unsigned) acquire. 5706 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5707 match(Set dst (LoadUS mem)); 5708 ins_cost(3*MEMORY_REF_COST); 5709 5710 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5711 "TWI $dst\n\t" 5712 "ISYNC" %} 5713 size(12); 5714 ins_encode( enc_lhz_ac(dst, mem) ); 5715 ins_pipe(pipe_class_memory); 5716 %} 5717 5718 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5719 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5720 match(Set dst (ConvI2L (LoadUS mem))); 5721 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5722 ins_cost(MEMORY_REF_COST); 5723 5724 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5725 size(4); 5726 ins_encode( enc_lhz(dst, mem) ); 5727 ins_pipe(pipe_class_memory); 5728 %} 5729 5730 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5731 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5732 match(Set dst (ConvI2L (LoadUS mem))); 5733 ins_cost(3*MEMORY_REF_COST); 5734 5735 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5736 "TWI $dst\n\t" 5737 "ISYNC" %} 5738 size(12); 5739 ins_encode( enc_lhz_ac(dst, mem) ); 5740 ins_pipe(pipe_class_memory); 5741 %} 5742 5743 // Load Integer. 5744 instruct loadI(iRegIdst dst, memory mem) %{ 5745 match(Set dst (LoadI mem)); 5746 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5747 ins_cost(MEMORY_REF_COST); 5748 5749 format %{ "LWZ $dst, $mem" %} 5750 size(4); 5751 ins_encode( enc_lwz(dst, mem) ); 5752 ins_pipe(pipe_class_memory); 5753 %} 5754 5755 // Load Integer acquire. 5756 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5757 match(Set dst (LoadI mem)); 5758 ins_cost(3*MEMORY_REF_COST); 5759 5760 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5761 "TWI $dst\n\t" 5762 "ISYNC" %} 5763 size(12); 5764 ins_encode( enc_lwz_ac(dst, mem) ); 5765 ins_pipe(pipe_class_memory); 5766 %} 5767 5768 // Match loading integer and casting it to unsigned int in 5769 // long register. 5770 // LoadI + ConvI2L + AndL 0xffffffff. 5771 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5772 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5773 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5774 ins_cost(MEMORY_REF_COST); 5775 5776 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5777 size(4); 5778 ins_encode( enc_lwz(dst, mem) ); 5779 ins_pipe(pipe_class_memory); 5780 %} 5781 5782 // Match loading integer and casting it to long. 5783 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5784 match(Set dst (ConvI2L (LoadI mem))); 5785 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5786 ins_cost(MEMORY_REF_COST); 5787 5788 format %{ "LWA $dst, $mem \t// loadI2L" %} 5789 size(4); 5790 ins_encode %{ 5791 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5792 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5793 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5794 %} 5795 ins_pipe(pipe_class_memory); 5796 %} 5797 5798 // Match loading integer and casting it to long - acquire. 5799 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5800 match(Set dst (ConvI2L (LoadI mem))); 5801 ins_cost(3*MEMORY_REF_COST); 5802 5803 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5804 "TWI $dst\n\t" 5805 "ISYNC" %} 5806 size(12); 5807 ins_encode %{ 5808 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5809 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5810 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5811 __ twi_0($dst$$Register); 5812 __ isync(); 5813 %} 5814 ins_pipe(pipe_class_memory); 5815 %} 5816 5817 // Load Long - aligned 5818 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5819 match(Set dst (LoadL mem)); 5820 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5821 ins_cost(MEMORY_REF_COST); 5822 5823 format %{ "LD $dst, $mem \t// long" %} 5824 size(4); 5825 ins_encode( enc_ld(dst, mem) ); 5826 ins_pipe(pipe_class_memory); 5827 %} 5828 5829 // Load Long - aligned acquire. 5830 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5831 match(Set dst (LoadL mem)); 5832 ins_cost(3*MEMORY_REF_COST); 5833 5834 format %{ "LD $dst, $mem \t// long acquire\n\t" 5835 "TWI $dst\n\t" 5836 "ISYNC" %} 5837 size(12); 5838 ins_encode( enc_ld_ac(dst, mem) ); 5839 ins_pipe(pipe_class_memory); 5840 %} 5841 5842 // Load Long - UNaligned 5843 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5844 match(Set dst (LoadL_unaligned mem)); 5845 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5846 ins_cost(MEMORY_REF_COST); 5847 5848 format %{ "LD $dst, $mem \t// unaligned long" %} 5849 size(4); 5850 ins_encode( enc_ld(dst, mem) ); 5851 ins_pipe(pipe_class_memory); 5852 %} 5853 5854 // Load nodes for superwords 5855 5856 // Load Aligned Packed Byte 5857 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5858 predicate(n->as_LoadVector()->memory_size() == 8); 5859 match(Set dst (LoadVector mem)); 5860 ins_cost(MEMORY_REF_COST); 5861 5862 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5863 size(4); 5864 ins_encode( enc_ld(dst, mem) ); 5865 ins_pipe(pipe_class_memory); 5866 %} 5867 5868 // Load Aligned Packed Byte 5869 instruct loadV16(vecX dst, indirect mem) %{ 5870 predicate(n->as_LoadVector()->memory_size() == 16); 5871 match(Set dst (LoadVector mem)); 5872 ins_cost(MEMORY_REF_COST); 5873 5874 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5875 size(4); 5876 ins_encode %{ 5877 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5878 %} 5879 ins_pipe(pipe_class_default); 5880 %} 5881 5882 // Load Range, range = array length (=jint) 5883 instruct loadRange(iRegIdst dst, memory mem) %{ 5884 match(Set dst (LoadRange mem)); 5885 ins_cost(MEMORY_REF_COST); 5886 5887 format %{ "LWZ $dst, $mem \t// range" %} 5888 size(4); 5889 ins_encode( enc_lwz(dst, mem) ); 5890 ins_pipe(pipe_class_memory); 5891 %} 5892 5893 // Load Compressed Pointer 5894 instruct loadN(iRegNdst dst, memory mem) %{ 5895 match(Set dst (LoadN mem)); 5896 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5897 ins_cost(MEMORY_REF_COST); 5898 5899 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5900 size(4); 5901 ins_encode( enc_lwz(dst, mem) ); 5902 ins_pipe(pipe_class_memory); 5903 %} 5904 5905 // Load Compressed Pointer acquire. 5906 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5907 match(Set dst (LoadN mem)); 5908 ins_cost(3*MEMORY_REF_COST); 5909 5910 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5911 "TWI $dst\n\t" 5912 "ISYNC" %} 5913 size(12); 5914 ins_encode( enc_lwz_ac(dst, mem) ); 5915 ins_pipe(pipe_class_memory); 5916 %} 5917 5918 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5919 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5920 match(Set dst (DecodeN (LoadN mem))); 5921 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0); 5922 ins_cost(MEMORY_REF_COST); 5923 5924 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5925 size(4); 5926 ins_encode( enc_lwz(dst, mem) ); 5927 ins_pipe(pipe_class_memory); 5928 %} 5929 5930 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5931 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5932 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0 && 5933 _kids[0]->_leaf->as_Load()->is_unordered()); 5934 ins_cost(MEMORY_REF_COST); 5935 5936 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5937 size(4); 5938 ins_encode( enc_lwz(dst, mem) ); 5939 ins_pipe(pipe_class_memory); 5940 %} 5941 5942 // Load Pointer 5943 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5944 match(Set dst (LoadP mem)); 5945 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5946 ins_cost(MEMORY_REF_COST); 5947 5948 format %{ "LD $dst, $mem \t// ptr" %} 5949 size(4); 5950 ins_encode( enc_ld(dst, mem) ); 5951 ins_pipe(pipe_class_memory); 5952 %} 5953 5954 // Load Pointer acquire. 5955 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5956 match(Set dst (LoadP mem)); 5957 ins_cost(3*MEMORY_REF_COST); 5958 5959 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5960 "TWI $dst\n\t" 5961 "ISYNC" %} 5962 size(12); 5963 ins_encode( enc_ld_ac(dst, mem) ); 5964 ins_pipe(pipe_class_memory); 5965 %} 5966 5967 // LoadP + CastP2L 5968 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5969 match(Set dst (CastP2X (LoadP mem))); 5970 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5971 ins_cost(MEMORY_REF_COST); 5972 5973 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5974 size(4); 5975 ins_encode( enc_ld(dst, mem) ); 5976 ins_pipe(pipe_class_memory); 5977 %} 5978 5979 // Load compressed klass pointer. 5980 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5981 match(Set dst (LoadNKlass mem)); 5982 ins_cost(MEMORY_REF_COST); 5983 5984 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5985 size(4); 5986 ins_encode( enc_lwz(dst, mem) ); 5987 ins_pipe(pipe_class_memory); 5988 %} 5989 5990 // Load Klass Pointer 5991 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5992 match(Set dst (LoadKlass mem)); 5993 ins_cost(MEMORY_REF_COST); 5994 5995 format %{ "LD $dst, $mem \t// klass ptr" %} 5996 size(4); 5997 ins_encode( enc_ld(dst, mem) ); 5998 ins_pipe(pipe_class_memory); 5999 %} 6000 6001 // Load Float 6002 instruct loadF(regF dst, memory mem) %{ 6003 match(Set dst (LoadF mem)); 6004 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 6005 ins_cost(MEMORY_REF_COST); 6006 6007 format %{ "LFS $dst, $mem" %} 6008 size(4); 6009 ins_encode %{ 6010 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6011 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6012 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 6013 %} 6014 ins_pipe(pipe_class_memory); 6015 %} 6016 6017 // Load Float acquire. 6018 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 6019 match(Set dst (LoadF mem)); 6020 effect(TEMP cr0); 6021 ins_cost(3*MEMORY_REF_COST); 6022 6023 format %{ "LFS $dst, $mem \t// acquire\n\t" 6024 "FCMPU cr0, $dst, $dst\n\t" 6025 "BNE cr0, next\n" 6026 "next:\n\t" 6027 "ISYNC" %} 6028 size(16); 6029 ins_encode %{ 6030 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6031 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6032 Label next; 6033 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 6034 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 6035 __ bne(CCR0, next); 6036 __ bind(next); 6037 __ isync(); 6038 %} 6039 ins_pipe(pipe_class_memory); 6040 %} 6041 6042 // Load Double - aligned 6043 instruct loadD(regD dst, memory mem) %{ 6044 match(Set dst (LoadD mem)); 6045 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 6046 ins_cost(MEMORY_REF_COST); 6047 6048 format %{ "LFD $dst, $mem" %} 6049 size(4); 6050 ins_encode( enc_lfd(dst, mem) ); 6051 ins_pipe(pipe_class_memory); 6052 %} 6053 6054 // Load Double - aligned acquire. 6055 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 6056 match(Set dst (LoadD mem)); 6057 effect(TEMP cr0); 6058 ins_cost(3*MEMORY_REF_COST); 6059 6060 format %{ "LFD $dst, $mem \t// acquire\n\t" 6061 "FCMPU cr0, $dst, $dst\n\t" 6062 "BNE cr0, next\n" 6063 "next:\n\t" 6064 "ISYNC" %} 6065 size(16); 6066 ins_encode %{ 6067 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6068 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6069 Label next; 6070 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 6071 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 6072 __ bne(CCR0, next); 6073 __ bind(next); 6074 __ isync(); 6075 %} 6076 ins_pipe(pipe_class_memory); 6077 %} 6078 6079 // Load Double - UNaligned 6080 instruct loadD_unaligned(regD dst, memory mem) %{ 6081 match(Set dst (LoadD_unaligned mem)); 6082 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 6083 ins_cost(MEMORY_REF_COST); 6084 6085 format %{ "LFD $dst, $mem" %} 6086 size(4); 6087 ins_encode( enc_lfd(dst, mem) ); 6088 ins_pipe(pipe_class_memory); 6089 %} 6090 6091 //----------Constants-------------------------------------------------------- 6092 6093 // Load MachConstantTableBase: add hi offset to global toc. 6094 // TODO: Handle hidden register r29 in bundler! 6095 instruct loadToc_hi(iRegLdst dst) %{ 6096 effect(DEF dst); 6097 ins_cost(DEFAULT_COST); 6098 6099 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 6100 size(4); 6101 ins_encode %{ 6102 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6103 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 6104 %} 6105 ins_pipe(pipe_class_default); 6106 %} 6107 6108 // Load MachConstantTableBase: add lo offset to global toc. 6109 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 6110 effect(DEF dst, USE src); 6111 ins_cost(DEFAULT_COST); 6112 6113 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 6114 size(4); 6115 ins_encode %{ 6116 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6117 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 6118 %} 6119 ins_pipe(pipe_class_default); 6120 %} 6121 6122 // Load 16-bit integer constant 0xssss???? 6123 instruct loadConI16(iRegIdst dst, immI16 src) %{ 6124 match(Set dst src); 6125 6126 format %{ "LI $dst, $src" %} 6127 size(4); 6128 ins_encode %{ 6129 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6130 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6131 %} 6132 ins_pipe(pipe_class_default); 6133 %} 6134 6135 // Load integer constant 0x????0000 6136 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 6137 match(Set dst src); 6138 ins_cost(DEFAULT_COST); 6139 6140 format %{ "LIS $dst, $src.hi" %} 6141 size(4); 6142 ins_encode %{ 6143 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6144 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 6145 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6146 %} 6147 ins_pipe(pipe_class_default); 6148 %} 6149 6150 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 6151 // and sign extended), this adds the low 16 bits. 6152 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6153 // no match-rule, false predicate 6154 effect(DEF dst, USE src1, USE src2); 6155 predicate(false); 6156 6157 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6158 size(4); 6159 ins_encode %{ 6160 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6161 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6162 %} 6163 ins_pipe(pipe_class_default); 6164 %} 6165 6166 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6167 match(Set dst src); 6168 ins_cost(DEFAULT_COST*2); 6169 6170 expand %{ 6171 // Would like to use $src$$constant. 6172 immI16 srcLo %{ _opnds[1]->constant() %} 6173 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6174 immIhi16 srcHi %{ _opnds[1]->constant() %} 6175 iRegIdst tmpI; 6176 loadConIhi16(tmpI, srcHi); 6177 loadConI32_lo16(dst, tmpI, srcLo); 6178 %} 6179 %} 6180 6181 // No constant pool entries required. 6182 instruct loadConL16(iRegLdst dst, immL16 src) %{ 6183 match(Set dst src); 6184 6185 format %{ "LI $dst, $src \t// long" %} 6186 size(4); 6187 ins_encode %{ 6188 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6189 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6190 %} 6191 ins_pipe(pipe_class_default); 6192 %} 6193 6194 // Load long constant 0xssssssss????0000 6195 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6196 match(Set dst src); 6197 ins_cost(DEFAULT_COST); 6198 6199 format %{ "LIS $dst, $src.hi \t// long" %} 6200 size(4); 6201 ins_encode %{ 6202 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6203 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6204 %} 6205 ins_pipe(pipe_class_default); 6206 %} 6207 6208 // To load a 32 bit constant: merge lower 16 bits into already loaded 6209 // high 16 bits. 6210 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6211 // no match-rule, false predicate 6212 effect(DEF dst, USE src1, USE src2); 6213 predicate(false); 6214 6215 format %{ "ORI $dst, $src1, $src2.lo" %} 6216 size(4); 6217 ins_encode %{ 6218 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6219 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6220 %} 6221 ins_pipe(pipe_class_default); 6222 %} 6223 6224 // Load 32-bit long constant 6225 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6226 match(Set dst src); 6227 ins_cost(DEFAULT_COST*2); 6228 6229 expand %{ 6230 // Would like to use $src$$constant. 6231 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6232 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6233 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6234 iRegLdst tmpL; 6235 loadConL32hi16(tmpL, srcHi); 6236 loadConL32_lo16(dst, tmpL, srcLo); 6237 %} 6238 %} 6239 6240 // Load long constant 0x????000000000000. 6241 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6242 match(Set dst src); 6243 ins_cost(DEFAULT_COST); 6244 6245 expand %{ 6246 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6247 immI shift32 %{ 32 %} 6248 iRegLdst tmpL; 6249 loadConL32hi16(tmpL, srcHi); 6250 lshiftL_regL_immI(dst, tmpL, shift32); 6251 %} 6252 %} 6253 6254 // Expand node for constant pool load: small offset. 6255 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6256 effect(DEF dst, USE src, USE toc); 6257 ins_cost(MEMORY_REF_COST); 6258 6259 ins_num_consts(1); 6260 // Needed so that CallDynamicJavaDirect can compute the address of this 6261 // instruction for relocation. 6262 ins_field_cbuf_insts_offset(int); 6263 6264 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6265 size(4); 6266 ins_encode( enc_load_long_constL(dst, src, toc) ); 6267 ins_pipe(pipe_class_memory); 6268 %} 6269 6270 // Expand node for constant pool load: large offset. 6271 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6272 effect(DEF dst, USE src, USE toc); 6273 predicate(false); 6274 6275 ins_num_consts(1); 6276 ins_field_const_toc_offset(int); 6277 // Needed so that CallDynamicJavaDirect can compute the address of this 6278 // instruction for relocation. 6279 ins_field_cbuf_insts_offset(int); 6280 6281 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6282 size(4); 6283 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6284 ins_pipe(pipe_class_default); 6285 %} 6286 6287 // Expand node for constant pool load: large offset. 6288 // No constant pool entries required. 6289 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6290 effect(DEF dst, USE src, USE base); 6291 predicate(false); 6292 6293 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6294 6295 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6296 size(4); 6297 ins_encode %{ 6298 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6299 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6300 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6301 %} 6302 ins_pipe(pipe_class_memory); 6303 %} 6304 6305 // Load long constant from constant table. Expand in case of 6306 // offset > 16 bit is needed. 6307 // Adlc adds toc node MachConstantTableBase. 6308 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6309 match(Set dst src); 6310 ins_cost(MEMORY_REF_COST); 6311 6312 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6313 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6314 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6315 %} 6316 6317 // Load NULL as compressed oop. 6318 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6319 match(Set dst src); 6320 ins_cost(DEFAULT_COST); 6321 6322 format %{ "LI $dst, $src \t// compressed ptr" %} 6323 size(4); 6324 ins_encode %{ 6325 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6326 __ li($dst$$Register, 0); 6327 %} 6328 ins_pipe(pipe_class_default); 6329 %} 6330 6331 // Load hi part of compressed oop constant. 6332 instruct loadConN_hi(iRegNdst dst, immN src) %{ 6333 effect(DEF dst, USE src); 6334 ins_cost(DEFAULT_COST); 6335 6336 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6337 size(4); 6338 ins_encode %{ 6339 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6340 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6341 %} 6342 ins_pipe(pipe_class_default); 6343 %} 6344 6345 // Add lo part of compressed oop constant to already loaded hi part. 6346 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6347 effect(DEF dst, USE src1, USE src2); 6348 ins_cost(DEFAULT_COST); 6349 6350 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6351 size(4); 6352 ins_encode %{ 6353 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6354 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6355 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6356 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6357 __ relocate(rspec, 1); 6358 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6359 %} 6360 ins_pipe(pipe_class_default); 6361 %} 6362 6363 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6364 effect(DEF dst, USE src, USE shift, USE mask_begin); 6365 6366 size(4); 6367 ins_encode %{ 6368 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6369 %} 6370 ins_pipe(pipe_class_default); 6371 %} 6372 6373 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6374 // leaving the upper 32 bits with sign-extension bits. 6375 // This clears these bits: dst = src & 0xFFFFFFFF. 6376 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6377 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6378 effect(DEF dst, USE src); 6379 predicate(false); 6380 6381 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6382 size(4); 6383 ins_encode %{ 6384 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6385 __ clrldi($dst$$Register, $src$$Register, 0x20); 6386 %} 6387 ins_pipe(pipe_class_default); 6388 %} 6389 6390 // Optimize DecodeN for disjoint base. 6391 // Load base of compressed oops into a register 6392 instruct loadBase(iRegLdst dst) %{ 6393 effect(DEF dst); 6394 6395 format %{ "LoadConst $dst, heapbase" %} 6396 ins_encode %{ 6397 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6398 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0); 6399 %} 6400 ins_pipe(pipe_class_default); 6401 %} 6402 6403 // Loading ConN must be postalloc expanded so that edges between 6404 // the nodes are safe. They may not interfere with a safepoint. 6405 // GL TODO: This needs three instructions: better put this into the constant pool. 6406 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6407 match(Set dst src); 6408 ins_cost(DEFAULT_COST*2); 6409 6410 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6411 postalloc_expand %{ 6412 MachNode *m1 = new loadConN_hiNode(); 6413 MachNode *m2 = new loadConN_loNode(); 6414 MachNode *m3 = new clearMs32bNode(); 6415 m1->add_req(NULL); 6416 m2->add_req(NULL, m1); 6417 m3->add_req(NULL, m2); 6418 m1->_opnds[0] = op_dst; 6419 m1->_opnds[1] = op_src; 6420 m2->_opnds[0] = op_dst; 6421 m2->_opnds[1] = op_dst; 6422 m2->_opnds[2] = op_src; 6423 m3->_opnds[0] = op_dst; 6424 m3->_opnds[1] = op_dst; 6425 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6426 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6427 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6428 nodes->push(m1); 6429 nodes->push(m2); 6430 nodes->push(m3); 6431 %} 6432 %} 6433 6434 // We have seen a safepoint between the hi and lo parts, and this node was handled 6435 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6436 // not a narrow oop. 6437 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6438 match(Set dst src); 6439 effect(DEF dst, USE src); 6440 ins_cost(DEFAULT_COST); 6441 6442 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6443 size(4); 6444 ins_encode %{ 6445 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6446 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant); 6447 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6448 %} 6449 ins_pipe(pipe_class_default); 6450 %} 6451 6452 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6453 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6454 match(Set dst src1); 6455 effect(TEMP src2); 6456 ins_cost(DEFAULT_COST); 6457 6458 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6459 size(4); 6460 ins_encode %{ 6461 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6462 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6463 %} 6464 ins_pipe(pipe_class_default); 6465 %} 6466 6467 // This needs a match rule so that build_oop_map knows this is 6468 // not a narrow oop. 6469 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6470 match(Set dst src1); 6471 effect(TEMP src2); 6472 ins_cost(DEFAULT_COST); 6473 6474 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6475 size(4); 6476 ins_encode %{ 6477 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6478 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src1$$constant); 6479 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6480 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6481 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6482 6483 __ relocate(rspec, 1); 6484 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6485 %} 6486 ins_pipe(pipe_class_default); 6487 %} 6488 6489 // Loading ConNKlass must be postalloc expanded so that edges between 6490 // the nodes are safe. They may not interfere with a safepoint. 6491 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6492 match(Set dst src); 6493 ins_cost(DEFAULT_COST*2); 6494 6495 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6496 postalloc_expand %{ 6497 // Load high bits into register. Sign extended. 6498 MachNode *m1 = new loadConNKlass_hiNode(); 6499 m1->add_req(NULL); 6500 m1->_opnds[0] = op_dst; 6501 m1->_opnds[1] = op_src; 6502 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6503 nodes->push(m1); 6504 6505 MachNode *m2 = m1; 6506 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) { 6507 // Value might be 1-extended. Mask out these bits. 6508 m2 = new loadConNKlass_maskNode(); 6509 m2->add_req(NULL, m1); 6510 m2->_opnds[0] = op_dst; 6511 m2->_opnds[1] = op_src; 6512 m2->_opnds[2] = op_dst; 6513 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6514 nodes->push(m2); 6515 } 6516 6517 MachNode *m3 = new loadConNKlass_loNode(); 6518 m3->add_req(NULL, m2); 6519 m3->_opnds[0] = op_dst; 6520 m3->_opnds[1] = op_src; 6521 m3->_opnds[2] = op_dst; 6522 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6523 nodes->push(m3); 6524 %} 6525 %} 6526 6527 // 0x1 is used in object initialization (initial object header). 6528 // No constant pool entries required. 6529 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6530 match(Set dst src); 6531 6532 format %{ "LI $dst, $src \t// ptr" %} 6533 size(4); 6534 ins_encode %{ 6535 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6536 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6537 %} 6538 ins_pipe(pipe_class_default); 6539 %} 6540 6541 // Expand node for constant pool load: small offset. 6542 // The match rule is needed to generate the correct bottom_type(), 6543 // however this node should never match. The use of predicate is not 6544 // possible since ADLC forbids predicates for chain rules. The higher 6545 // costs do not prevent matching in this case. For that reason the 6546 // operand immP_NM with predicate(false) is used. 6547 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6548 match(Set dst src); 6549 effect(TEMP toc); 6550 6551 ins_num_consts(1); 6552 6553 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6554 size(4); 6555 ins_encode( enc_load_long_constP(dst, src, toc) ); 6556 ins_pipe(pipe_class_memory); 6557 %} 6558 6559 // Expand node for constant pool load: large offset. 6560 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6561 effect(DEF dst, USE src, USE toc); 6562 predicate(false); 6563 6564 ins_num_consts(1); 6565 ins_field_const_toc_offset(int); 6566 6567 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6568 size(4); 6569 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6570 ins_pipe(pipe_class_default); 6571 %} 6572 6573 // Expand node for constant pool load: large offset. 6574 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6575 match(Set dst src); 6576 effect(TEMP base); 6577 6578 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6579 6580 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6581 size(4); 6582 ins_encode %{ 6583 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6584 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6585 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6586 %} 6587 ins_pipe(pipe_class_memory); 6588 %} 6589 6590 // Load pointer constant from constant table. Expand in case an 6591 // offset > 16 bit is needed. 6592 // Adlc adds toc node MachConstantTableBase. 6593 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6594 match(Set dst src); 6595 ins_cost(MEMORY_REF_COST); 6596 6597 // This rule does not use "expand" because then 6598 // the result type is not known to be an Oop. An ADLC 6599 // enhancement will be needed to make that work - not worth it! 6600 6601 // If this instruction rematerializes, it prolongs the live range 6602 // of the toc node, causing illegal graphs. 6603 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6604 ins_cannot_rematerialize(true); 6605 6606 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6607 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6608 %} 6609 6610 // Expand node for constant pool load: small offset. 6611 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6612 effect(DEF dst, USE src, USE toc); 6613 ins_cost(MEMORY_REF_COST); 6614 6615 ins_num_consts(1); 6616 6617 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6618 size(4); 6619 ins_encode %{ 6620 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6621 address float_address = __ float_constant($src$$constant); 6622 if (float_address == NULL) { 6623 ciEnv::current()->record_out_of_memory_failure(); 6624 return; 6625 } 6626 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6627 %} 6628 ins_pipe(pipe_class_memory); 6629 %} 6630 6631 // Expand node for constant pool load: large offset. 6632 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6633 effect(DEF dst, USE src, USE toc); 6634 ins_cost(MEMORY_REF_COST); 6635 6636 ins_num_consts(1); 6637 6638 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6639 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6640 "ADDIS $toc, $toc, -offset_hi"%} 6641 size(12); 6642 ins_encode %{ 6643 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6644 FloatRegister Rdst = $dst$$FloatRegister; 6645 Register Rtoc = $toc$$Register; 6646 address float_address = __ float_constant($src$$constant); 6647 if (float_address == NULL) { 6648 ciEnv::current()->record_out_of_memory_failure(); 6649 return; 6650 } 6651 int offset = __ offset_to_method_toc(float_address); 6652 int hi = (offset + (1<<15))>>16; 6653 int lo = offset - hi * (1<<16); 6654 6655 __ addis(Rtoc, Rtoc, hi); 6656 __ lfs(Rdst, lo, Rtoc); 6657 __ addis(Rtoc, Rtoc, -hi); 6658 %} 6659 ins_pipe(pipe_class_memory); 6660 %} 6661 6662 // Adlc adds toc node MachConstantTableBase. 6663 instruct loadConF_Ex(regF dst, immF src) %{ 6664 match(Set dst src); 6665 ins_cost(MEMORY_REF_COST); 6666 6667 // See loadConP. 6668 ins_cannot_rematerialize(true); 6669 6670 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6671 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6672 %} 6673 6674 // Expand node for constant pool load: small offset. 6675 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6676 effect(DEF dst, USE src, USE toc); 6677 ins_cost(MEMORY_REF_COST); 6678 6679 ins_num_consts(1); 6680 6681 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6682 size(4); 6683 ins_encode %{ 6684 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6685 address float_address = __ double_constant($src$$constant); 6686 if (float_address == NULL) { 6687 ciEnv::current()->record_out_of_memory_failure(); 6688 return; 6689 } 6690 int offset = __ offset_to_method_toc(float_address); 6691 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6692 %} 6693 ins_pipe(pipe_class_memory); 6694 %} 6695 6696 // Expand node for constant pool load: large offset. 6697 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6698 effect(DEF dst, USE src, USE toc); 6699 ins_cost(MEMORY_REF_COST); 6700 6701 ins_num_consts(1); 6702 6703 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6704 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6705 "ADDIS $toc, $toc, -offset_hi" %} 6706 size(12); 6707 ins_encode %{ 6708 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6709 FloatRegister Rdst = $dst$$FloatRegister; 6710 Register Rtoc = $toc$$Register; 6711 address float_address = __ double_constant($src$$constant); 6712 if (float_address == NULL) { 6713 ciEnv::current()->record_out_of_memory_failure(); 6714 return; 6715 } 6716 int offset = __ offset_to_method_toc(float_address); 6717 int hi = (offset + (1<<15))>>16; 6718 int lo = offset - hi * (1<<16); 6719 6720 __ addis(Rtoc, Rtoc, hi); 6721 __ lfd(Rdst, lo, Rtoc); 6722 __ addis(Rtoc, Rtoc, -hi); 6723 %} 6724 ins_pipe(pipe_class_memory); 6725 %} 6726 6727 // Adlc adds toc node MachConstantTableBase. 6728 instruct loadConD_Ex(regD dst, immD src) %{ 6729 match(Set dst src); 6730 ins_cost(MEMORY_REF_COST); 6731 6732 // See loadConP. 6733 ins_cannot_rematerialize(true); 6734 6735 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6736 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6737 %} 6738 6739 // Prefetch instructions. 6740 // Must be safe to execute with invalid address (cannot fault). 6741 6742 // Special prefetch versions which use the dcbz instruction. 6743 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6744 match(PrefetchAllocation (AddP mem src)); 6745 predicate(AllocatePrefetchStyle == 3); 6746 ins_cost(MEMORY_REF_COST); 6747 6748 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6749 size(4); 6750 ins_encode %{ 6751 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6752 __ dcbz($src$$Register, $mem$$base$$Register); 6753 %} 6754 ins_pipe(pipe_class_memory); 6755 %} 6756 6757 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6758 match(PrefetchAllocation mem); 6759 predicate(AllocatePrefetchStyle == 3); 6760 ins_cost(MEMORY_REF_COST); 6761 6762 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6763 size(4); 6764 ins_encode %{ 6765 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6766 __ dcbz($mem$$base$$Register); 6767 %} 6768 ins_pipe(pipe_class_memory); 6769 %} 6770 6771 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6772 match(PrefetchAllocation (AddP mem src)); 6773 predicate(AllocatePrefetchStyle != 3); 6774 ins_cost(MEMORY_REF_COST); 6775 6776 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6777 size(4); 6778 ins_encode %{ 6779 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6780 __ dcbtst($src$$Register, $mem$$base$$Register); 6781 %} 6782 ins_pipe(pipe_class_memory); 6783 %} 6784 6785 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6786 match(PrefetchAllocation mem); 6787 predicate(AllocatePrefetchStyle != 3); 6788 ins_cost(MEMORY_REF_COST); 6789 6790 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6791 size(4); 6792 ins_encode %{ 6793 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6794 __ dcbtst($mem$$base$$Register); 6795 %} 6796 ins_pipe(pipe_class_memory); 6797 %} 6798 6799 //----------Store Instructions------------------------------------------------- 6800 6801 // Store Byte 6802 instruct storeB(memory mem, iRegIsrc src) %{ 6803 match(Set mem (StoreB mem src)); 6804 ins_cost(MEMORY_REF_COST); 6805 6806 format %{ "STB $src, $mem \t// byte" %} 6807 size(4); 6808 ins_encode %{ 6809 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6810 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6811 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6812 %} 6813 ins_pipe(pipe_class_memory); 6814 %} 6815 6816 // Store Char/Short 6817 instruct storeC(memory mem, iRegIsrc src) %{ 6818 match(Set mem (StoreC mem src)); 6819 ins_cost(MEMORY_REF_COST); 6820 6821 format %{ "STH $src, $mem \t// short" %} 6822 size(4); 6823 ins_encode %{ 6824 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6825 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6826 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6827 %} 6828 ins_pipe(pipe_class_memory); 6829 %} 6830 6831 // Store Integer 6832 instruct storeI(memory mem, iRegIsrc src) %{ 6833 match(Set mem (StoreI mem src)); 6834 ins_cost(MEMORY_REF_COST); 6835 6836 format %{ "STW $src, $mem" %} 6837 size(4); 6838 ins_encode( enc_stw(src, mem) ); 6839 ins_pipe(pipe_class_memory); 6840 %} 6841 6842 // ConvL2I + StoreI. 6843 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6844 match(Set mem (StoreI mem (ConvL2I src))); 6845 ins_cost(MEMORY_REF_COST); 6846 6847 format %{ "STW l2i($src), $mem" %} 6848 size(4); 6849 ins_encode( enc_stw(src, mem) ); 6850 ins_pipe(pipe_class_memory); 6851 %} 6852 6853 // Store Long 6854 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6855 match(Set mem (StoreL mem src)); 6856 ins_cost(MEMORY_REF_COST); 6857 6858 format %{ "STD $src, $mem \t// long" %} 6859 size(4); 6860 ins_encode( enc_std(src, mem) ); 6861 ins_pipe(pipe_class_memory); 6862 %} 6863 6864 // Store super word nodes. 6865 6866 // Store Aligned Packed Byte long register to memory 6867 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6868 predicate(n->as_StoreVector()->memory_size() == 8); 6869 match(Set mem (StoreVector mem src)); 6870 ins_cost(MEMORY_REF_COST); 6871 6872 format %{ "STD $mem, $src \t// packed8B" %} 6873 size(4); 6874 ins_encode( enc_std(src, mem) ); 6875 ins_pipe(pipe_class_memory); 6876 %} 6877 6878 // Store Packed Byte long register to memory 6879 instruct storeV16(indirect mem, vecX src) %{ 6880 predicate(n->as_StoreVector()->memory_size() == 16); 6881 match(Set mem (StoreVector mem src)); 6882 ins_cost(MEMORY_REF_COST); 6883 6884 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6885 size(4); 6886 ins_encode %{ 6887 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6888 %} 6889 ins_pipe(pipe_class_default); 6890 %} 6891 6892 // Store Compressed Oop 6893 instruct storeN(memory dst, iRegN_P2N src) %{ 6894 match(Set dst (StoreN dst src)); 6895 ins_cost(MEMORY_REF_COST); 6896 6897 format %{ "STW $src, $dst \t// compressed oop" %} 6898 size(4); 6899 ins_encode( enc_stw(src, dst) ); 6900 ins_pipe(pipe_class_memory); 6901 %} 6902 6903 // Store Compressed KLass 6904 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6905 match(Set dst (StoreNKlass dst src)); 6906 ins_cost(MEMORY_REF_COST); 6907 6908 format %{ "STW $src, $dst \t// compressed klass" %} 6909 size(4); 6910 ins_encode( enc_stw(src, dst) ); 6911 ins_pipe(pipe_class_memory); 6912 %} 6913 6914 // Store Pointer 6915 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6916 match(Set dst (StoreP dst src)); 6917 ins_cost(MEMORY_REF_COST); 6918 6919 format %{ "STD $src, $dst \t// ptr" %} 6920 size(4); 6921 ins_encode( enc_std(src, dst) ); 6922 ins_pipe(pipe_class_memory); 6923 %} 6924 6925 // Store Float 6926 instruct storeF(memory mem, regF src) %{ 6927 match(Set mem (StoreF mem src)); 6928 ins_cost(MEMORY_REF_COST); 6929 6930 format %{ "STFS $src, $mem" %} 6931 size(4); 6932 ins_encode( enc_stfs(src, mem) ); 6933 ins_pipe(pipe_class_memory); 6934 %} 6935 6936 // Store Double 6937 instruct storeD(memory mem, regD src) %{ 6938 match(Set mem (StoreD mem src)); 6939 ins_cost(MEMORY_REF_COST); 6940 6941 format %{ "STFD $src, $mem" %} 6942 size(4); 6943 ins_encode( enc_stfd(src, mem) ); 6944 ins_pipe(pipe_class_memory); 6945 %} 6946 6947 //----------Store Instructions With Zeros-------------------------------------- 6948 6949 // Card-mark for CMS garbage collection. 6950 // This cardmark does an optimization so that it must not always 6951 // do a releasing store. For this, it gets the address of 6952 // CMSCollectorCardTableBarrierSetBSExt::_requires_release as input. 6953 // (Using releaseFieldAddr in the match rule is a hack.) 6954 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6955 match(Set mem (StoreCM mem releaseFieldAddr)); 6956 effect(TEMP crx); 6957 predicate(false); 6958 ins_cost(MEMORY_REF_COST); 6959 6960 // See loadConP. 6961 ins_cannot_rematerialize(true); 6962 6963 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6964 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6965 ins_pipe(pipe_class_memory); 6966 %} 6967 6968 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6969 match(Set mem (StoreCM mem zero)); 6970 predicate(UseG1GC); 6971 ins_cost(MEMORY_REF_COST); 6972 6973 ins_cannot_rematerialize(true); 6974 6975 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6976 size(8); 6977 ins_encode %{ 6978 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6979 __ li(R0, 0); 6980 //__ release(); // G1: oops are allowed to get visible after dirty marking 6981 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6982 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6983 %} 6984 ins_pipe(pipe_class_memory); 6985 %} 6986 6987 // Convert oop pointer into compressed form. 6988 6989 // Nodes for postalloc expand. 6990 6991 // Shift node for expand. 6992 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6993 // The match rule is needed to make it a 'MachTypeNode'! 6994 match(Set dst (EncodeP src)); 6995 predicate(false); 6996 6997 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6998 size(4); 6999 ins_encode %{ 7000 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7001 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 7002 %} 7003 ins_pipe(pipe_class_default); 7004 %} 7005 7006 // Add node for expand. 7007 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 7008 // The match rule is needed to make it a 'MachTypeNode'! 7009 match(Set dst (EncodeP src)); 7010 predicate(false); 7011 7012 format %{ "SUB $dst, $src, oop_base \t// encode" %} 7013 ins_encode %{ 7014 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7015 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 7016 %} 7017 ins_pipe(pipe_class_default); 7018 %} 7019 7020 // Conditional sub base. 7021 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7022 // The match rule is needed to make it a 'MachTypeNode'! 7023 match(Set dst (EncodeP (Binary crx src1))); 7024 predicate(false); 7025 7026 format %{ "BEQ $crx, done\n\t" 7027 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 7028 "done:" %} 7029 ins_encode %{ 7030 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7031 Label done; 7032 __ beq($crx$$CondRegister, done); 7033 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0); 7034 __ bind(done); 7035 %} 7036 ins_pipe(pipe_class_default); 7037 %} 7038 7039 // Power 7 can use isel instruction 7040 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7041 // The match rule is needed to make it a 'MachTypeNode'! 7042 match(Set dst (EncodeP (Binary crx src1))); 7043 predicate(false); 7044 7045 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 7046 size(4); 7047 ins_encode %{ 7048 // This is a Power7 instruction for which no machine description exists. 7049 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7050 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7051 %} 7052 ins_pipe(pipe_class_default); 7053 %} 7054 7055 // Disjoint narrow oop base. 7056 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7057 match(Set dst (EncodeP src)); 7058 predicate(CompressedOops::base_disjoint()); 7059 7060 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7061 size(4); 7062 ins_encode %{ 7063 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7064 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32); 7065 %} 7066 ins_pipe(pipe_class_default); 7067 %} 7068 7069 // shift != 0, base != 0 7070 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 7071 match(Set dst (EncodeP src)); 7072 effect(TEMP crx); 7073 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 7074 CompressedOops::shift() != 0 && 7075 CompressedOops::base_overlaps()); 7076 7077 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 7078 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 7079 %} 7080 7081 // shift != 0, base != 0 7082 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 7083 match(Set dst (EncodeP src)); 7084 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 7085 CompressedOops::shift() != 0 && 7086 CompressedOops::base_overlaps()); 7087 7088 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 7089 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 7090 %} 7091 7092 // shift != 0, base == 0 7093 // TODO: This is the same as encodeP_shift. Merge! 7094 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 7095 match(Set dst (EncodeP src)); 7096 predicate(CompressedOops::shift() != 0 && 7097 CompressedOops::base() ==0); 7098 7099 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 7100 size(4); 7101 ins_encode %{ 7102 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7103 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 7104 %} 7105 ins_pipe(pipe_class_default); 7106 %} 7107 7108 // Compressed OOPs with narrow_oop_shift == 0. 7109 // shift == 0, base == 0 7110 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 7111 match(Set dst (EncodeP src)); 7112 predicate(CompressedOops::shift() == 0); 7113 7114 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 7115 // variable size, 0 or 4. 7116 ins_encode %{ 7117 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7118 __ mr_if_needed($dst$$Register, $src$$Register); 7119 %} 7120 ins_pipe(pipe_class_default); 7121 %} 7122 7123 // Decode nodes. 7124 7125 // Shift node for expand. 7126 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 7127 // The match rule is needed to make it a 'MachTypeNode'! 7128 match(Set dst (DecodeN src)); 7129 predicate(false); 7130 7131 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 7132 size(4); 7133 ins_encode %{ 7134 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7135 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 7136 %} 7137 ins_pipe(pipe_class_default); 7138 %} 7139 7140 // Add node for expand. 7141 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7142 // The match rule is needed to make it a 'MachTypeNode'! 7143 match(Set dst (DecodeN src)); 7144 predicate(false); 7145 7146 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7147 ins_encode %{ 7148 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7149 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 7150 %} 7151 ins_pipe(pipe_class_default); 7152 %} 7153 7154 // conditianal add base for expand 7155 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7156 // The match rule is needed to make it a 'MachTypeNode'! 7157 // NOTICE that the rule is nonsense - we just have to make sure that: 7158 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7159 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7160 match(Set dst (DecodeN (Binary crx src))); 7161 predicate(false); 7162 7163 format %{ "BEQ $crx, done\n\t" 7164 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7165 "done:" %} 7166 ins_encode %{ 7167 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7168 Label done; 7169 __ beq($crx$$CondRegister, done); 7170 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 7171 __ bind(done); 7172 %} 7173 ins_pipe(pipe_class_default); 7174 %} 7175 7176 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7177 // The match rule is needed to make it a 'MachTypeNode'! 7178 // NOTICE that the rule is nonsense - we just have to make sure that: 7179 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7180 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7181 match(Set dst (DecodeN (Binary crx src1))); 7182 predicate(false); 7183 7184 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7185 size(4); 7186 ins_encode %{ 7187 // This is a Power7 instruction for which no machine description exists. 7188 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7189 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7190 %} 7191 ins_pipe(pipe_class_default); 7192 %} 7193 7194 // shift != 0, base != 0 7195 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7196 match(Set dst (DecodeN src)); 7197 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7198 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7199 CompressedOops::shift() != 0 && 7200 CompressedOops::base() != 0); 7201 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7202 effect(TEMP crx); 7203 7204 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7205 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7206 %} 7207 7208 // shift != 0, base == 0 7209 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7210 match(Set dst (DecodeN src)); 7211 predicate(CompressedOops::shift() != 0 && 7212 CompressedOops::base() == 0); 7213 7214 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7215 size(4); 7216 ins_encode %{ 7217 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7218 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 7219 %} 7220 ins_pipe(pipe_class_default); 7221 %} 7222 7223 // Optimize DecodeN for disjoint base. 7224 // Shift narrow oop and or it into register that already contains the heap base. 7225 // Base == dst must hold, and is assured by construction in postaloc_expand. 7226 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7227 match(Set dst (DecodeN src)); 7228 effect(TEMP base); 7229 predicate(false); 7230 7231 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7232 size(4); 7233 ins_encode %{ 7234 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7235 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift()); 7236 %} 7237 ins_pipe(pipe_class_default); 7238 %} 7239 7240 // Optimize DecodeN for disjoint base. 7241 // This node requires only one cycle on the critical path. 7242 // We must postalloc_expand as we can not express use_def effects where 7243 // the used register is L and the def'ed register P. 7244 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7245 match(Set dst (DecodeN src)); 7246 effect(TEMP_DEF dst); 7247 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7248 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7249 CompressedOops::base_disjoint()); 7250 ins_cost(DEFAULT_COST); 7251 7252 format %{ "MOV $dst, heapbase \t\n" 7253 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7254 postalloc_expand %{ 7255 loadBaseNode *n1 = new loadBaseNode(); 7256 n1->add_req(NULL); 7257 n1->_opnds[0] = op_dst; 7258 7259 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7260 n2->add_req(n_region, n_src, n1); 7261 n2->_opnds[0] = op_dst; 7262 n2->_opnds[1] = op_src; 7263 n2->_opnds[2] = op_dst; 7264 n2->_bottom_type = _bottom_type; 7265 7266 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7267 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7268 7269 nodes->push(n1); 7270 nodes->push(n2); 7271 %} 7272 %} 7273 7274 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7275 match(Set dst (DecodeN src)); 7276 effect(TEMP_DEF dst, TEMP crx); 7277 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7278 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7279 CompressedOops::base_disjoint() && VM_Version::has_isel()); 7280 ins_cost(3 * DEFAULT_COST); 7281 7282 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7283 postalloc_expand %{ 7284 loadBaseNode *n1 = new loadBaseNode(); 7285 n1->add_req(NULL); 7286 n1->_opnds[0] = op_dst; 7287 7288 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7289 n_compare->add_req(n_region, n_src); 7290 n_compare->_opnds[0] = op_crx; 7291 n_compare->_opnds[1] = op_src; 7292 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7293 7294 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7295 n2->add_req(n_region, n_src, n1); 7296 n2->_opnds[0] = op_dst; 7297 n2->_opnds[1] = op_src; 7298 n2->_opnds[2] = op_dst; 7299 n2->_bottom_type = _bottom_type; 7300 7301 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7302 n_cond_set->add_req(n_region, n_compare, n2); 7303 n_cond_set->_opnds[0] = op_dst; 7304 n_cond_set->_opnds[1] = op_crx; 7305 n_cond_set->_opnds[2] = op_dst; 7306 n_cond_set->_bottom_type = _bottom_type; 7307 7308 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7309 ra_->set_oop(n_cond_set, true); 7310 7311 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7312 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7313 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7314 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7315 7316 nodes->push(n1); 7317 nodes->push(n_compare); 7318 nodes->push(n2); 7319 nodes->push(n_cond_set); 7320 %} 7321 %} 7322 7323 // src != 0, shift != 0, base != 0 7324 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7325 match(Set dst (DecodeN src)); 7326 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7327 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7328 CompressedOops::shift() != 0 && 7329 CompressedOops::base() != 0); 7330 ins_cost(2 * DEFAULT_COST); 7331 7332 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7333 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7334 %} 7335 7336 // Compressed OOPs with narrow_oop_shift == 0. 7337 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7338 match(Set dst (DecodeN src)); 7339 predicate(CompressedOops::shift() == 0); 7340 ins_cost(DEFAULT_COST); 7341 7342 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7343 // variable size, 0 or 4. 7344 ins_encode %{ 7345 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7346 __ mr_if_needed($dst$$Register, $src$$Register); 7347 %} 7348 ins_pipe(pipe_class_default); 7349 %} 7350 7351 // Convert compressed oop into int for vectors alignment masking. 7352 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7353 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7354 predicate(CompressedOops::shift() == 0); 7355 ins_cost(DEFAULT_COST); 7356 7357 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7358 // variable size, 0 or 4. 7359 ins_encode %{ 7360 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7361 __ mr_if_needed($dst$$Register, $src$$Register); 7362 %} 7363 ins_pipe(pipe_class_default); 7364 %} 7365 7366 // Convert klass pointer into compressed form. 7367 7368 // Nodes for postalloc expand. 7369 7370 // Shift node for expand. 7371 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7372 // The match rule is needed to make it a 'MachTypeNode'! 7373 match(Set dst (EncodePKlass src)); 7374 predicate(false); 7375 7376 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7377 size(4); 7378 ins_encode %{ 7379 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7380 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 7381 %} 7382 ins_pipe(pipe_class_default); 7383 %} 7384 7385 // Add node for expand. 7386 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7387 // The match rule is needed to make it a 'MachTypeNode'! 7388 match(Set dst (EncodePKlass (Binary base src))); 7389 predicate(false); 7390 7391 format %{ "SUB $dst, $base, $src \t// encode" %} 7392 size(4); 7393 ins_encode %{ 7394 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7395 __ subf($dst$$Register, $base$$Register, $src$$Register); 7396 %} 7397 ins_pipe(pipe_class_default); 7398 %} 7399 7400 // Disjoint narrow oop base. 7401 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7402 match(Set dst (EncodePKlass src)); 7403 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/); 7404 7405 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7406 size(4); 7407 ins_encode %{ 7408 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7409 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32); 7410 %} 7411 ins_pipe(pipe_class_default); 7412 %} 7413 7414 // shift != 0, base != 0 7415 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7416 match(Set dst (EncodePKlass (Binary base src))); 7417 predicate(false); 7418 7419 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7420 postalloc_expand %{ 7421 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7422 n1->add_req(n_region, n_base, n_src); 7423 n1->_opnds[0] = op_dst; 7424 n1->_opnds[1] = op_base; 7425 n1->_opnds[2] = op_src; 7426 n1->_bottom_type = _bottom_type; 7427 7428 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7429 n2->add_req(n_region, n1); 7430 n2->_opnds[0] = op_dst; 7431 n2->_opnds[1] = op_dst; 7432 n2->_bottom_type = _bottom_type; 7433 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7434 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7435 7436 nodes->push(n1); 7437 nodes->push(n2); 7438 %} 7439 %} 7440 7441 // shift != 0, base != 0 7442 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7443 match(Set dst (EncodePKlass src)); 7444 //predicate(CompressedKlassPointers::shift() != 0 && 7445 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/); 7446 7447 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7448 ins_cost(DEFAULT_COST*2); // Don't count constant. 7449 expand %{ 7450 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %} 7451 iRegLdst base; 7452 loadConL_Ex(base, baseImm); 7453 encodePKlass_not_null_Ex(dst, base, src); 7454 %} 7455 %} 7456 7457 // Decode nodes. 7458 7459 // Shift node for expand. 7460 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7461 // The match rule is needed to make it a 'MachTypeNode'! 7462 match(Set dst (DecodeNKlass src)); 7463 predicate(false); 7464 7465 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7466 size(4); 7467 ins_encode %{ 7468 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7469 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 7470 %} 7471 ins_pipe(pipe_class_default); 7472 %} 7473 7474 // Add node for expand. 7475 7476 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7477 // The match rule is needed to make it a 'MachTypeNode'! 7478 match(Set dst (DecodeNKlass (Binary base src))); 7479 predicate(false); 7480 7481 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7482 size(4); 7483 ins_encode %{ 7484 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7485 __ add($dst$$Register, $base$$Register, $src$$Register); 7486 %} 7487 ins_pipe(pipe_class_default); 7488 %} 7489 7490 // src != 0, shift != 0, base != 0 7491 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7492 match(Set dst (DecodeNKlass (Binary base src))); 7493 //effect(kill src); // We need a register for the immediate result after shifting. 7494 predicate(false); 7495 7496 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7497 postalloc_expand %{ 7498 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7499 n1->add_req(n_region, n_base, n_src); 7500 n1->_opnds[0] = op_dst; 7501 n1->_opnds[1] = op_base; 7502 n1->_opnds[2] = op_src; 7503 n1->_bottom_type = _bottom_type; 7504 7505 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7506 n2->add_req(n_region, n1); 7507 n2->_opnds[0] = op_dst; 7508 n2->_opnds[1] = op_dst; 7509 n2->_bottom_type = _bottom_type; 7510 7511 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7512 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7513 7514 nodes->push(n1); 7515 nodes->push(n2); 7516 %} 7517 %} 7518 7519 // src != 0, shift != 0, base != 0 7520 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7521 match(Set dst (DecodeNKlass src)); 7522 // predicate(CompressedKlassPointers::shift() != 0 && 7523 // CompressedKlassPointers::base() != 0); 7524 7525 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7526 7527 ins_cost(DEFAULT_COST*2); // Don't count constant. 7528 expand %{ 7529 // We add first, then we shift. Like this, we can get along with one register less. 7530 // But we have to load the base pre-shifted. 7531 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %} 7532 iRegLdst base; 7533 loadConL_Ex(base, baseImm); 7534 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7535 %} 7536 %} 7537 7538 //----------MemBar Instructions----------------------------------------------- 7539 // Memory barrier flavors 7540 7541 instruct membar_acquire() %{ 7542 match(LoadFence); 7543 ins_cost(4*MEMORY_REF_COST); 7544 7545 format %{ "MEMBAR-acquire" %} 7546 size(4); 7547 ins_encode %{ 7548 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7549 __ acquire(); 7550 %} 7551 ins_pipe(pipe_class_default); 7552 %} 7553 7554 instruct unnecessary_membar_acquire() %{ 7555 match(MemBarAcquire); 7556 ins_cost(0); 7557 7558 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7559 size(0); 7560 ins_encode( /*empty*/ ); 7561 ins_pipe(pipe_class_default); 7562 %} 7563 7564 instruct membar_acquire_lock() %{ 7565 match(MemBarAcquireLock); 7566 ins_cost(0); 7567 7568 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7569 size(0); 7570 ins_encode( /*empty*/ ); 7571 ins_pipe(pipe_class_default); 7572 %} 7573 7574 instruct membar_release() %{ 7575 match(MemBarRelease); 7576 match(StoreFence); 7577 ins_cost(4*MEMORY_REF_COST); 7578 7579 format %{ "MEMBAR-release" %} 7580 size(4); 7581 ins_encode %{ 7582 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7583 __ release(); 7584 %} 7585 ins_pipe(pipe_class_default); 7586 %} 7587 7588 instruct membar_storestore() %{ 7589 match(MemBarStoreStore); 7590 ins_cost(4*MEMORY_REF_COST); 7591 7592 format %{ "MEMBAR-store-store" %} 7593 size(4); 7594 ins_encode %{ 7595 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7596 __ membar(Assembler::StoreStore); 7597 %} 7598 ins_pipe(pipe_class_default); 7599 %} 7600 7601 instruct membar_release_lock() %{ 7602 match(MemBarReleaseLock); 7603 ins_cost(0); 7604 7605 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7606 size(0); 7607 ins_encode( /*empty*/ ); 7608 ins_pipe(pipe_class_default); 7609 %} 7610 7611 instruct membar_volatile() %{ 7612 match(MemBarVolatile); 7613 ins_cost(4*MEMORY_REF_COST); 7614 7615 format %{ "MEMBAR-volatile" %} 7616 size(4); 7617 ins_encode %{ 7618 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7619 __ fence(); 7620 %} 7621 ins_pipe(pipe_class_default); 7622 %} 7623 7624 // This optimization is wrong on PPC. The following pattern is not supported: 7625 // MemBarVolatile 7626 // ^ ^ 7627 // | | 7628 // CtrlProj MemProj 7629 // ^ ^ 7630 // | | 7631 // | Load 7632 // | 7633 // MemBarVolatile 7634 // 7635 // The first MemBarVolatile could get optimized out! According to 7636 // Vladimir, this pattern can not occur on Oracle platforms. 7637 // However, it does occur on PPC64 (because of membars in 7638 // inline_unsafe_load_store). 7639 // 7640 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7641 // Don't forget to look at the implementation of post_store_load_barrier again, 7642 // we did other fixes in that method. 7643 //instruct unnecessary_membar_volatile() %{ 7644 // match(MemBarVolatile); 7645 // predicate(Matcher::post_store_load_barrier(n)); 7646 // ins_cost(0); 7647 // 7648 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7649 // size(0); 7650 // ins_encode( /*empty*/ ); 7651 // ins_pipe(pipe_class_default); 7652 //%} 7653 7654 instruct membar_CPUOrder() %{ 7655 match(MemBarCPUOrder); 7656 ins_cost(0); 7657 7658 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7659 size(0); 7660 ins_encode( /*empty*/ ); 7661 ins_pipe(pipe_class_default); 7662 %} 7663 7664 //----------Conditional Move--------------------------------------------------- 7665 7666 // Cmove using isel. 7667 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7668 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7669 predicate(VM_Version::has_isel()); 7670 ins_cost(DEFAULT_COST); 7671 7672 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7673 size(4); 7674 ins_encode %{ 7675 // This is a Power7 instruction for which no machine description 7676 // exists. Anyways, the scheduler should be off on Power7. 7677 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7678 int cc = $cmp$$cmpcode; 7679 __ isel($dst$$Register, $crx$$CondRegister, 7680 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7681 %} 7682 ins_pipe(pipe_class_default); 7683 %} 7684 7685 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7686 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7687 predicate(!VM_Version::has_isel()); 7688 ins_cost(DEFAULT_COST+BRANCH_COST); 7689 7690 ins_variable_size_depending_on_alignment(true); 7691 7692 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7693 // Worst case is branch + move + stop, no stop without scheduler 7694 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7695 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7696 ins_pipe(pipe_class_default); 7697 %} 7698 7699 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7700 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7701 ins_cost(DEFAULT_COST+BRANCH_COST); 7702 7703 ins_variable_size_depending_on_alignment(true); 7704 7705 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7706 // Worst case is branch + move + stop, no stop without scheduler 7707 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7708 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7709 ins_pipe(pipe_class_default); 7710 %} 7711 7712 // Cmove using isel. 7713 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7714 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7715 predicate(VM_Version::has_isel()); 7716 ins_cost(DEFAULT_COST); 7717 7718 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7719 size(4); 7720 ins_encode %{ 7721 // This is a Power7 instruction for which no machine description 7722 // exists. Anyways, the scheduler should be off on Power7. 7723 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7724 int cc = $cmp$$cmpcode; 7725 __ isel($dst$$Register, $crx$$CondRegister, 7726 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7727 %} 7728 ins_pipe(pipe_class_default); 7729 %} 7730 7731 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7732 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7733 predicate(!VM_Version::has_isel()); 7734 ins_cost(DEFAULT_COST+BRANCH_COST); 7735 7736 ins_variable_size_depending_on_alignment(true); 7737 7738 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7739 // Worst case is branch + move + stop, no stop without scheduler. 7740 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7741 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7742 ins_pipe(pipe_class_default); 7743 %} 7744 7745 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7746 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7747 ins_cost(DEFAULT_COST+BRANCH_COST); 7748 7749 ins_variable_size_depending_on_alignment(true); 7750 7751 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7752 // Worst case is branch + move + stop, no stop without scheduler. 7753 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7754 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7755 ins_pipe(pipe_class_default); 7756 %} 7757 7758 // Cmove using isel. 7759 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7760 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7761 predicate(VM_Version::has_isel()); 7762 ins_cost(DEFAULT_COST); 7763 7764 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7765 size(4); 7766 ins_encode %{ 7767 // This is a Power7 instruction for which no machine description 7768 // exists. Anyways, the scheduler should be off on Power7. 7769 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7770 int cc = $cmp$$cmpcode; 7771 __ isel($dst$$Register, $crx$$CondRegister, 7772 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7773 %} 7774 ins_pipe(pipe_class_default); 7775 %} 7776 7777 // Conditional move for RegN. Only cmov(reg, reg). 7778 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7779 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7780 predicate(!VM_Version::has_isel()); 7781 ins_cost(DEFAULT_COST+BRANCH_COST); 7782 7783 ins_variable_size_depending_on_alignment(true); 7784 7785 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7786 // Worst case is branch + move + stop, no stop without scheduler. 7787 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7788 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7789 ins_pipe(pipe_class_default); 7790 %} 7791 7792 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7793 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7794 ins_cost(DEFAULT_COST+BRANCH_COST); 7795 7796 ins_variable_size_depending_on_alignment(true); 7797 7798 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7799 // Worst case is branch + move + stop, no stop without scheduler. 7800 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7801 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7802 ins_pipe(pipe_class_default); 7803 %} 7804 7805 // Cmove using isel. 7806 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7807 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7808 predicate(VM_Version::has_isel()); 7809 ins_cost(DEFAULT_COST); 7810 7811 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7812 size(4); 7813 ins_encode %{ 7814 // This is a Power7 instruction for which no machine description 7815 // exists. Anyways, the scheduler should be off on Power7. 7816 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7817 int cc = $cmp$$cmpcode; 7818 __ isel($dst$$Register, $crx$$CondRegister, 7819 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7820 %} 7821 ins_pipe(pipe_class_default); 7822 %} 7823 7824 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7825 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7826 predicate(!VM_Version::has_isel()); 7827 ins_cost(DEFAULT_COST+BRANCH_COST); 7828 7829 ins_variable_size_depending_on_alignment(true); 7830 7831 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7832 // Worst case is branch + move + stop, no stop without scheduler. 7833 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7834 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7835 ins_pipe(pipe_class_default); 7836 %} 7837 7838 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7839 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7840 ins_cost(DEFAULT_COST+BRANCH_COST); 7841 7842 ins_variable_size_depending_on_alignment(true); 7843 7844 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7845 // Worst case is branch + move + stop, no stop without scheduler. 7846 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7847 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7848 ins_pipe(pipe_class_default); 7849 %} 7850 7851 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7852 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7853 ins_cost(DEFAULT_COST+BRANCH_COST); 7854 7855 ins_variable_size_depending_on_alignment(true); 7856 7857 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7858 // Worst case is branch + move + stop, no stop without scheduler. 7859 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7860 ins_encode %{ 7861 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7862 Label done; 7863 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7864 // Branch if not (cmp crx). 7865 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7866 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7867 // TODO PPC port __ endgroup_if_needed(_size == 12); 7868 __ bind(done); 7869 %} 7870 ins_pipe(pipe_class_default); 7871 %} 7872 7873 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7874 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7875 ins_cost(DEFAULT_COST+BRANCH_COST); 7876 7877 ins_variable_size_depending_on_alignment(true); 7878 7879 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7880 // Worst case is branch + move + stop, no stop without scheduler. 7881 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7882 ins_encode %{ 7883 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7884 Label done; 7885 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7886 // Branch if not (cmp crx). 7887 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7888 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7889 // TODO PPC port __ endgroup_if_needed(_size == 12); 7890 __ bind(done); 7891 %} 7892 ins_pipe(pipe_class_default); 7893 %} 7894 7895 //----------Conditional_store-------------------------------------------------- 7896 // Conditional-store of the updated heap-top. 7897 // Used during allocation of the shared heap. 7898 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7899 7900 // As compareAndSwapL, but return flag register instead of boolean value in 7901 // int register. 7902 // Used by sun/misc/AtomicLongCSImpl.java. 7903 // Mem_ptr must be a memory operand, else this node does not get 7904 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7905 // can be rematerialized which leads to errors. 7906 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7907 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7908 effect(TEMP cr0); 7909 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7910 ins_encode %{ 7911 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7912 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7913 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7914 noreg, NULL, true); 7915 %} 7916 ins_pipe(pipe_class_default); 7917 %} 7918 7919 // As compareAndSwapP, but return flag register instead of boolean value in 7920 // int register. 7921 // This instruction is matched if UseTLAB is off. 7922 // Mem_ptr must be a memory operand, else this node does not get 7923 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7924 // can be rematerialized which leads to errors. 7925 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7926 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7927 ins_cost(2*MEMORY_REF_COST); 7928 7929 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7930 ins_encode %{ 7931 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7932 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7933 %} 7934 ins_pipe(pipe_class_memory); 7935 %} 7936 7937 // Implement LoadPLocked. Must be ordered against changes of the memory location 7938 // by storePConditional. 7939 // Don't know whether this is ever used. 7940 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7941 match(Set dst (LoadPLocked mem)); 7942 ins_cost(2*MEMORY_REF_COST); 7943 7944 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7945 size(4); 7946 ins_encode %{ 7947 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7948 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7949 %} 7950 ins_pipe(pipe_class_memory); 7951 %} 7952 7953 //----------Compare-And-Swap--------------------------------------------------- 7954 7955 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7956 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7957 // matched. 7958 7959 // Strong versions: 7960 7961 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7962 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7963 predicate(VM_Version::has_lqarx()); 7964 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7965 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7966 ins_encode %{ 7967 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7968 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7969 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7970 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7971 $res$$Register, true); 7972 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7973 __ isync(); 7974 } else { 7975 __ sync(); 7976 } 7977 %} 7978 ins_pipe(pipe_class_default); 7979 %} 7980 7981 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7982 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7983 predicate(!VM_Version::has_lqarx()); 7984 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7985 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7986 ins_encode %{ 7987 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7988 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7989 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7990 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7991 $res$$Register, true); 7992 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7993 __ isync(); 7994 } else { 7995 __ sync(); 7996 } 7997 %} 7998 ins_pipe(pipe_class_default); 7999 %} 8000 8001 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8002 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 8003 predicate(VM_Version::has_lqarx()); 8004 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8005 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8006 ins_encode %{ 8007 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8008 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8009 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8010 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8011 $res$$Register, true); 8012 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8013 __ isync(); 8014 } else { 8015 __ sync(); 8016 } 8017 %} 8018 ins_pipe(pipe_class_default); 8019 %} 8020 8021 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8022 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 8023 predicate(!VM_Version::has_lqarx()); 8024 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8025 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8026 ins_encode %{ 8027 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8028 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8029 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8030 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8031 $res$$Register, true); 8032 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8033 __ isync(); 8034 } else { 8035 __ sync(); 8036 } 8037 %} 8038 ins_pipe(pipe_class_default); 8039 %} 8040 8041 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8042 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 8043 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8044 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8045 ins_encode %{ 8046 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8047 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8048 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8049 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8050 $res$$Register, true); 8051 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8052 __ isync(); 8053 } else { 8054 __ sync(); 8055 } 8056 %} 8057 ins_pipe(pipe_class_default); 8058 %} 8059 8060 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8061 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 8062 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8063 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8064 ins_encode %{ 8065 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8066 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8067 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8068 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8069 $res$$Register, true); 8070 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8071 __ isync(); 8072 } else { 8073 __ sync(); 8074 } 8075 %} 8076 ins_pipe(pipe_class_default); 8077 %} 8078 8079 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8080 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 8081 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8082 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8083 ins_encode %{ 8084 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8085 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8086 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8087 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8088 $res$$Register, NULL, true); 8089 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8090 __ isync(); 8091 } else { 8092 __ sync(); 8093 } 8094 %} 8095 ins_pipe(pipe_class_default); 8096 %} 8097 8098 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8099 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 8100 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8101 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8102 ins_encode %{ 8103 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8104 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8105 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8106 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8107 $res$$Register, NULL, true); 8108 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8109 __ isync(); 8110 } else { 8111 __ sync(); 8112 } 8113 %} 8114 ins_pipe(pipe_class_default); 8115 %} 8116 8117 // Weak versions: 8118 8119 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8120 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8121 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8122 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8123 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8124 ins_encode %{ 8125 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8126 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8127 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8128 MacroAssembler::MemBarNone, 8129 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8130 %} 8131 ins_pipe(pipe_class_default); 8132 %} 8133 8134 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8135 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8136 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8137 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8138 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8139 ins_encode %{ 8140 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8141 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8142 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8143 MacroAssembler::MemBarNone, 8144 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8145 %} 8146 ins_pipe(pipe_class_default); 8147 %} 8148 8149 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8150 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8151 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8152 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8153 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8154 ins_encode %{ 8155 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8156 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8157 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8158 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8159 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8160 %} 8161 ins_pipe(pipe_class_default); 8162 %} 8163 8164 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8165 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8166 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8167 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8168 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8169 ins_encode %{ 8170 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8171 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8172 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8173 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8174 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8175 %} 8176 ins_pipe(pipe_class_default); 8177 %} 8178 8179 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8180 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8181 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8182 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8183 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8184 ins_encode %{ 8185 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8186 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8187 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8188 MacroAssembler::MemBarNone, 8189 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8190 %} 8191 ins_pipe(pipe_class_default); 8192 %} 8193 8194 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8195 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8196 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8197 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8198 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8199 ins_encode %{ 8200 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8201 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8202 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8203 MacroAssembler::MemBarNone, 8204 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8205 %} 8206 ins_pipe(pipe_class_default); 8207 %} 8208 8209 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8210 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8211 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8212 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8213 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8214 ins_encode %{ 8215 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8216 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8217 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8218 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8219 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8220 %} 8221 ins_pipe(pipe_class_default); 8222 %} 8223 8224 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8225 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8226 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8227 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8228 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8229 ins_encode %{ 8230 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8231 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8232 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8233 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8234 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8235 %} 8236 ins_pipe(pipe_class_default); 8237 %} 8238 8239 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8240 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8241 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8242 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8243 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8244 ins_encode %{ 8245 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8246 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8247 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8248 MacroAssembler::MemBarNone, 8249 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8250 %} 8251 ins_pipe(pipe_class_default); 8252 %} 8253 8254 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8255 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8256 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8257 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8258 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8259 ins_encode %{ 8260 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8261 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8262 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8263 // value is never passed to caller. 8264 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8265 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8266 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8267 %} 8268 ins_pipe(pipe_class_default); 8269 %} 8270 8271 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8272 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8273 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8274 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8275 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8276 ins_encode %{ 8277 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8278 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8279 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8280 MacroAssembler::MemBarNone, 8281 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8282 %} 8283 ins_pipe(pipe_class_default); 8284 %} 8285 8286 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8287 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8288 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8289 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8290 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8291 ins_encode %{ 8292 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8293 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8294 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8295 // value is never passed to caller. 8296 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8297 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8298 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8299 %} 8300 ins_pipe(pipe_class_default); 8301 %} 8302 8303 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8304 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8305 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8306 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8307 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8308 ins_encode %{ 8309 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8310 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8311 // value is never passed to caller. 8312 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8313 MacroAssembler::MemBarNone, 8314 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8315 %} 8316 ins_pipe(pipe_class_default); 8317 %} 8318 8319 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8320 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8321 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8322 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8323 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 8324 ins_encode %{ 8325 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8326 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8327 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8328 // value is never passed to caller. 8329 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8330 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8331 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8332 %} 8333 ins_pipe(pipe_class_default); 8334 %} 8335 8336 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8337 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8338 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8339 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8340 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8341 ins_encode %{ 8342 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8343 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8344 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8345 MacroAssembler::MemBarNone, 8346 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8347 %} 8348 ins_pipe(pipe_class_default); 8349 %} 8350 8351 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8352 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8353 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8354 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8355 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8356 ins_encode %{ 8357 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8358 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8359 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8360 // value is never passed to caller. 8361 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8362 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8363 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8364 %} 8365 ins_pipe(pipe_class_default); 8366 %} 8367 8368 // CompareAndExchange 8369 8370 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8371 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8372 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8373 effect(TEMP_DEF res, TEMP cr0); 8374 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8375 ins_encode %{ 8376 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8377 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8378 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8379 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8380 noreg, true); 8381 %} 8382 ins_pipe(pipe_class_default); 8383 %} 8384 8385 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8386 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8387 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8388 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8389 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8390 ins_encode %{ 8391 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8392 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8393 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8394 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8395 noreg, true); 8396 %} 8397 ins_pipe(pipe_class_default); 8398 %} 8399 8400 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8401 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8402 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8403 effect(TEMP_DEF res, TEMP cr0); 8404 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8405 ins_encode %{ 8406 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8407 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8408 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8409 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8410 noreg, true); 8411 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8412 __ isync(); 8413 } else { 8414 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8415 __ sync(); 8416 } 8417 %} 8418 ins_pipe(pipe_class_default); 8419 %} 8420 8421 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8422 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8423 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8424 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8425 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8426 ins_encode %{ 8427 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8428 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8429 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8430 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8431 noreg, true); 8432 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8433 __ isync(); 8434 } else { 8435 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8436 __ sync(); 8437 } 8438 %} 8439 ins_pipe(pipe_class_default); 8440 %} 8441 8442 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8443 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8444 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8445 effect(TEMP_DEF res, TEMP cr0); 8446 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8447 ins_encode %{ 8448 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8449 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8450 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8451 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8452 noreg, true); 8453 %} 8454 ins_pipe(pipe_class_default); 8455 %} 8456 8457 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8458 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8459 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8460 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8461 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8462 ins_encode %{ 8463 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8464 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8465 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8466 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8467 noreg, true); 8468 %} 8469 ins_pipe(pipe_class_default); 8470 %} 8471 8472 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8473 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8474 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8475 effect(TEMP_DEF res, TEMP cr0); 8476 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8477 ins_encode %{ 8478 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8479 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8480 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8481 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8482 noreg, true); 8483 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8484 __ isync(); 8485 } else { 8486 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8487 __ sync(); 8488 } 8489 %} 8490 ins_pipe(pipe_class_default); 8491 %} 8492 8493 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8494 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8495 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8496 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8497 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8498 ins_encode %{ 8499 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8500 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8501 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8502 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8503 noreg, true); 8504 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8505 __ isync(); 8506 } else { 8507 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8508 __ sync(); 8509 } 8510 %} 8511 ins_pipe(pipe_class_default); 8512 %} 8513 8514 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8515 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8516 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8517 effect(TEMP_DEF res, TEMP cr0); 8518 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8519 ins_encode %{ 8520 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8521 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8522 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8523 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8524 noreg, true); 8525 %} 8526 ins_pipe(pipe_class_default); 8527 %} 8528 8529 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8530 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8531 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8532 effect(TEMP_DEF res, TEMP cr0); 8533 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8534 ins_encode %{ 8535 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8536 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8537 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8538 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8539 noreg, true); 8540 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8541 __ isync(); 8542 } else { 8543 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8544 __ sync(); 8545 } 8546 %} 8547 ins_pipe(pipe_class_default); 8548 %} 8549 8550 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8551 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8552 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8553 effect(TEMP_DEF res, TEMP cr0); 8554 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8555 ins_encode %{ 8556 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8557 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8558 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8559 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8560 noreg, true); 8561 %} 8562 ins_pipe(pipe_class_default); 8563 %} 8564 8565 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8566 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8567 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8568 effect(TEMP_DEF res, TEMP cr0); 8569 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8570 ins_encode %{ 8571 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8572 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8573 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8574 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8575 noreg, true); 8576 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8577 __ isync(); 8578 } else { 8579 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8580 __ sync(); 8581 } 8582 %} 8583 ins_pipe(pipe_class_default); 8584 %} 8585 8586 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8587 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8588 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8589 effect(TEMP_DEF res, TEMP cr0); 8590 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8591 ins_encode %{ 8592 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8593 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8594 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8595 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8596 noreg, NULL, true); 8597 %} 8598 ins_pipe(pipe_class_default); 8599 %} 8600 8601 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8602 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8603 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8604 effect(TEMP_DEF res, TEMP cr0); 8605 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8606 ins_encode %{ 8607 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8608 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8609 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8610 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8611 noreg, NULL, true); 8612 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8613 __ isync(); 8614 } else { 8615 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8616 __ sync(); 8617 } 8618 %} 8619 ins_pipe(pipe_class_default); 8620 %} 8621 8622 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8623 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8624 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8625 effect(TEMP_DEF res, TEMP cr0); 8626 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8627 ins_encode %{ 8628 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8629 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8630 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8631 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8632 noreg, NULL, true); 8633 %} 8634 ins_pipe(pipe_class_default); 8635 %} 8636 8637 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8638 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8639 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8640 effect(TEMP_DEF res, TEMP cr0); 8641 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8642 ins_encode %{ 8643 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8644 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8645 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8646 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8647 noreg, NULL, true); 8648 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8649 __ isync(); 8650 } else { 8651 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8652 __ sync(); 8653 } 8654 %} 8655 ins_pipe(pipe_class_default); 8656 %} 8657 8658 // Special RMW 8659 8660 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8661 match(Set res (GetAndAddB mem_ptr src)); 8662 predicate(VM_Version::has_lqarx()); 8663 effect(TEMP_DEF res, TEMP cr0); 8664 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8665 ins_encode %{ 8666 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8667 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8668 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8669 __ isync(); 8670 } else { 8671 __ sync(); 8672 } 8673 %} 8674 ins_pipe(pipe_class_default); 8675 %} 8676 8677 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8678 match(Set res (GetAndAddB mem_ptr src)); 8679 predicate(!VM_Version::has_lqarx()); 8680 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8681 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8682 ins_encode %{ 8683 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8684 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8685 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8686 __ isync(); 8687 } else { 8688 __ sync(); 8689 } 8690 %} 8691 ins_pipe(pipe_class_default); 8692 %} 8693 8694 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8695 match(Set res (GetAndAddS mem_ptr src)); 8696 predicate(VM_Version::has_lqarx()); 8697 effect(TEMP_DEF res, TEMP cr0); 8698 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8699 ins_encode %{ 8700 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8701 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8702 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8703 __ isync(); 8704 } else { 8705 __ sync(); 8706 } 8707 %} 8708 ins_pipe(pipe_class_default); 8709 %} 8710 8711 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8712 match(Set res (GetAndAddS mem_ptr src)); 8713 predicate(!VM_Version::has_lqarx()); 8714 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8715 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8716 ins_encode %{ 8717 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8718 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8719 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8720 __ isync(); 8721 } else { 8722 __ sync(); 8723 } 8724 %} 8725 ins_pipe(pipe_class_default); 8726 %} 8727 8728 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8729 match(Set res (GetAndAddI mem_ptr src)); 8730 effect(TEMP_DEF res, TEMP cr0); 8731 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8732 ins_encode %{ 8733 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8734 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8735 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8736 __ isync(); 8737 } else { 8738 __ sync(); 8739 } 8740 %} 8741 ins_pipe(pipe_class_default); 8742 %} 8743 8744 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8745 match(Set res (GetAndAddL mem_ptr src)); 8746 effect(TEMP_DEF res, TEMP cr0); 8747 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8748 ins_encode %{ 8749 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8750 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8751 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8752 __ isync(); 8753 } else { 8754 __ sync(); 8755 } 8756 %} 8757 ins_pipe(pipe_class_default); 8758 %} 8759 8760 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8761 match(Set res (GetAndSetB mem_ptr src)); 8762 predicate(VM_Version::has_lqarx()); 8763 effect(TEMP_DEF res, TEMP cr0); 8764 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8765 ins_encode %{ 8766 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8767 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8768 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8769 __ isync(); 8770 } else { 8771 __ sync(); 8772 } 8773 %} 8774 ins_pipe(pipe_class_default); 8775 %} 8776 8777 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8778 match(Set res (GetAndSetB mem_ptr src)); 8779 predicate(!VM_Version::has_lqarx()); 8780 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8781 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8782 ins_encode %{ 8783 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8784 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8785 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8786 __ isync(); 8787 } else { 8788 __ sync(); 8789 } 8790 %} 8791 ins_pipe(pipe_class_default); 8792 %} 8793 8794 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8795 match(Set res (GetAndSetS mem_ptr src)); 8796 predicate(VM_Version::has_lqarx()); 8797 effect(TEMP_DEF res, TEMP cr0); 8798 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8799 ins_encode %{ 8800 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8801 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8802 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8803 __ isync(); 8804 } else { 8805 __ sync(); 8806 } 8807 %} 8808 ins_pipe(pipe_class_default); 8809 %} 8810 8811 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8812 match(Set res (GetAndSetS mem_ptr src)); 8813 predicate(!VM_Version::has_lqarx()); 8814 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8815 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8816 ins_encode %{ 8817 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8818 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8819 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8820 __ isync(); 8821 } else { 8822 __ sync(); 8823 } 8824 %} 8825 ins_pipe(pipe_class_default); 8826 %} 8827 8828 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8829 match(Set res (GetAndSetI mem_ptr src)); 8830 effect(TEMP_DEF res, TEMP cr0); 8831 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8832 ins_encode %{ 8833 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8834 MacroAssembler::cmpxchgx_hint_atomic_update()); 8835 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8836 __ isync(); 8837 } else { 8838 __ sync(); 8839 } 8840 %} 8841 ins_pipe(pipe_class_default); 8842 %} 8843 8844 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8845 match(Set res (GetAndSetL mem_ptr src)); 8846 effect(TEMP_DEF res, TEMP cr0); 8847 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8848 ins_encode %{ 8849 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8850 MacroAssembler::cmpxchgx_hint_atomic_update()); 8851 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8852 __ isync(); 8853 } else { 8854 __ sync(); 8855 } 8856 %} 8857 ins_pipe(pipe_class_default); 8858 %} 8859 8860 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8861 match(Set res (GetAndSetP mem_ptr src)); 8862 effect(TEMP_DEF res, TEMP cr0); 8863 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8864 ins_encode %{ 8865 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8866 MacroAssembler::cmpxchgx_hint_atomic_update()); 8867 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8868 __ isync(); 8869 } else { 8870 __ sync(); 8871 } 8872 %} 8873 ins_pipe(pipe_class_default); 8874 %} 8875 8876 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8877 match(Set res (GetAndSetN mem_ptr src)); 8878 effect(TEMP_DEF res, TEMP cr0); 8879 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8880 ins_encode %{ 8881 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8882 MacroAssembler::cmpxchgx_hint_atomic_update()); 8883 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8884 __ isync(); 8885 } else { 8886 __ sync(); 8887 } 8888 %} 8889 ins_pipe(pipe_class_default); 8890 %} 8891 8892 //----------Arithmetic Instructions-------------------------------------------- 8893 // Addition Instructions 8894 8895 // Register Addition 8896 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8897 match(Set dst (AddI src1 src2)); 8898 format %{ "ADD $dst, $src1, $src2" %} 8899 size(4); 8900 ins_encode %{ 8901 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8902 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8903 %} 8904 ins_pipe(pipe_class_default); 8905 %} 8906 8907 // Expand does not work with above instruct. (??) 8908 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8909 // no match-rule 8910 effect(DEF dst, USE src1, USE src2); 8911 format %{ "ADD $dst, $src1, $src2" %} 8912 size(4); 8913 ins_encode %{ 8914 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8915 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8916 %} 8917 ins_pipe(pipe_class_default); 8918 %} 8919 8920 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8921 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8922 ins_cost(DEFAULT_COST*3); 8923 8924 expand %{ 8925 // FIXME: we should do this in the ideal world. 8926 iRegIdst tmp1; 8927 iRegIdst tmp2; 8928 addI_reg_reg(tmp1, src1, src2); 8929 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8930 addI_reg_reg(dst, tmp1, tmp2); 8931 %} 8932 %} 8933 8934 // Immediate Addition 8935 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8936 match(Set dst (AddI src1 src2)); 8937 format %{ "ADDI $dst, $src1, $src2" %} 8938 size(4); 8939 ins_encode %{ 8940 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8941 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8942 %} 8943 ins_pipe(pipe_class_default); 8944 %} 8945 8946 // Immediate Addition with 16-bit shifted operand 8947 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8948 match(Set dst (AddI src1 src2)); 8949 format %{ "ADDIS $dst, $src1, $src2" %} 8950 size(4); 8951 ins_encode %{ 8952 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8953 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8954 %} 8955 ins_pipe(pipe_class_default); 8956 %} 8957 8958 // Long Addition 8959 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8960 match(Set dst (AddL src1 src2)); 8961 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8962 size(4); 8963 ins_encode %{ 8964 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8965 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8966 %} 8967 ins_pipe(pipe_class_default); 8968 %} 8969 8970 // Expand does not work with above instruct. (??) 8971 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8972 // no match-rule 8973 effect(DEF dst, USE src1, USE src2); 8974 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8975 size(4); 8976 ins_encode %{ 8977 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8978 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8979 %} 8980 ins_pipe(pipe_class_default); 8981 %} 8982 8983 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8984 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8985 ins_cost(DEFAULT_COST*3); 8986 8987 expand %{ 8988 // FIXME: we should do this in the ideal world. 8989 iRegLdst tmp1; 8990 iRegLdst tmp2; 8991 addL_reg_reg(tmp1, src1, src2); 8992 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8993 addL_reg_reg(dst, tmp1, tmp2); 8994 %} 8995 %} 8996 8997 // AddL + ConvL2I. 8998 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8999 match(Set dst (ConvL2I (AddL src1 src2))); 9000 9001 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 9002 size(4); 9003 ins_encode %{ 9004 // TODO: PPC port $archOpcode(ppc64Opcode_add); 9005 __ add($dst$$Register, $src1$$Register, $src2$$Register); 9006 %} 9007 ins_pipe(pipe_class_default); 9008 %} 9009 9010 // No constant pool entries required. 9011 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9012 match(Set dst (AddL src1 src2)); 9013 9014 format %{ "ADDI $dst, $src1, $src2" %} 9015 size(4); 9016 ins_encode %{ 9017 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 9018 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 9019 %} 9020 ins_pipe(pipe_class_default); 9021 %} 9022 9023 // Long Immediate Addition with 16-bit shifted operand. 9024 // No constant pool entries required. 9025 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 9026 match(Set dst (AddL src1 src2)); 9027 9028 format %{ "ADDIS $dst, $src1, $src2" %} 9029 size(4); 9030 ins_encode %{ 9031 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 9032 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 9033 %} 9034 ins_pipe(pipe_class_default); 9035 %} 9036 9037 // Pointer Register Addition 9038 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 9039 match(Set dst (AddP src1 src2)); 9040 format %{ "ADD $dst, $src1, $src2" %} 9041 size(4); 9042 ins_encode %{ 9043 // TODO: PPC port $archOpcode(ppc64Opcode_add); 9044 __ add($dst$$Register, $src1$$Register, $src2$$Register); 9045 %} 9046 ins_pipe(pipe_class_default); 9047 %} 9048 9049 // Pointer Immediate Addition 9050 // No constant pool entries required. 9051 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 9052 match(Set dst (AddP src1 src2)); 9053 9054 format %{ "ADDI $dst, $src1, $src2" %} 9055 size(4); 9056 ins_encode %{ 9057 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 9058 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 9059 %} 9060 ins_pipe(pipe_class_default); 9061 %} 9062 9063 // Pointer Immediate Addition with 16-bit shifted operand. 9064 // No constant pool entries required. 9065 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 9066 match(Set dst (AddP src1 src2)); 9067 9068 format %{ "ADDIS $dst, $src1, $src2" %} 9069 size(4); 9070 ins_encode %{ 9071 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 9072 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 9073 %} 9074 ins_pipe(pipe_class_default); 9075 %} 9076 9077 //--------------------- 9078 // Subtraction Instructions 9079 9080 // Register Subtraction 9081 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9082 match(Set dst (SubI src1 src2)); 9083 format %{ "SUBF $dst, $src2, $src1" %} 9084 size(4); 9085 ins_encode %{ 9086 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9087 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9088 %} 9089 ins_pipe(pipe_class_default); 9090 %} 9091 9092 // Immediate Subtraction 9093 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 9094 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 9095 9096 // SubI from constant (using subfic). 9097 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 9098 match(Set dst (SubI src1 src2)); 9099 format %{ "SUBI $dst, $src1, $src2" %} 9100 9101 size(4); 9102 ins_encode %{ 9103 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 9104 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 9105 %} 9106 ins_pipe(pipe_class_default); 9107 %} 9108 9109 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 9110 // positive integers and 0xF...F for negative ones. 9111 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 9112 // no match-rule, false predicate 9113 effect(DEF dst, USE src); 9114 predicate(false); 9115 9116 format %{ "SRAWI $dst, $src, #31" %} 9117 size(4); 9118 ins_encode %{ 9119 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9120 __ srawi($dst$$Register, $src$$Register, 0x1f); 9121 %} 9122 ins_pipe(pipe_class_default); 9123 %} 9124 9125 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 9126 match(Set dst (AbsI src)); 9127 ins_cost(DEFAULT_COST*3); 9128 9129 expand %{ 9130 iRegIdst tmp1; 9131 iRegIdst tmp2; 9132 signmask32I_regI(tmp1, src); 9133 xorI_reg_reg(tmp2, tmp1, src); 9134 subI_reg_reg(dst, tmp2, tmp1); 9135 %} 9136 %} 9137 9138 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9139 match(Set dst (SubI zero src2)); 9140 format %{ "NEG $dst, $src2" %} 9141 size(4); 9142 ins_encode %{ 9143 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9144 __ neg($dst$$Register, $src2$$Register); 9145 %} 9146 ins_pipe(pipe_class_default); 9147 %} 9148 9149 // Long subtraction 9150 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9151 match(Set dst (SubL src1 src2)); 9152 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9153 size(4); 9154 ins_encode %{ 9155 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9156 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9157 %} 9158 ins_pipe(pipe_class_default); 9159 %} 9160 9161 // SubL + convL2I. 9162 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9163 match(Set dst (ConvL2I (SubL src1 src2))); 9164 9165 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9166 size(4); 9167 ins_encode %{ 9168 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9169 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9170 %} 9171 ins_pipe(pipe_class_default); 9172 %} 9173 9174 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9175 // positive longs and 0xF...F for negative ones. 9176 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9177 // no match-rule, false predicate 9178 effect(DEF dst, USE src); 9179 predicate(false); 9180 9181 format %{ "SRADI $dst, $src, #63" %} 9182 size(4); 9183 ins_encode %{ 9184 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9185 __ sradi($dst$$Register, $src$$Register, 0x3f); 9186 %} 9187 ins_pipe(pipe_class_default); 9188 %} 9189 9190 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9191 // positive longs and 0xF...F for negative ones. 9192 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9193 // no match-rule, false predicate 9194 effect(DEF dst, USE src); 9195 predicate(false); 9196 9197 format %{ "SRADI $dst, $src, #63" %} 9198 size(4); 9199 ins_encode %{ 9200 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9201 __ sradi($dst$$Register, $src$$Register, 0x3f); 9202 %} 9203 ins_pipe(pipe_class_default); 9204 %} 9205 9206 instruct absL_reg_Ex(iRegLdst dst, iRegLsrc src) %{ 9207 match(Set dst (AbsL src)); 9208 ins_cost(DEFAULT_COST*3); 9209 9210 expand %{ 9211 iRegLdst tmp1; 9212 iRegLdst tmp2; 9213 signmask64L_regL(tmp1, src); 9214 xorL_reg_reg(tmp2, tmp1, src); 9215 subL_reg_reg(dst, tmp2, tmp1); 9216 %} 9217 %} 9218 9219 // Long negation 9220 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9221 match(Set dst (SubL zero src2)); 9222 format %{ "NEG $dst, $src2 \t// long" %} 9223 size(4); 9224 ins_encode %{ 9225 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9226 __ neg($dst$$Register, $src2$$Register); 9227 %} 9228 ins_pipe(pipe_class_default); 9229 %} 9230 9231 // NegL + ConvL2I. 9232 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9233 match(Set dst (ConvL2I (SubL zero src2))); 9234 9235 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9236 size(4); 9237 ins_encode %{ 9238 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9239 __ neg($dst$$Register, $src2$$Register); 9240 %} 9241 ins_pipe(pipe_class_default); 9242 %} 9243 9244 // Multiplication Instructions 9245 // Integer Multiplication 9246 9247 // Register Multiplication 9248 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9249 match(Set dst (MulI src1 src2)); 9250 ins_cost(DEFAULT_COST); 9251 9252 format %{ "MULLW $dst, $src1, $src2" %} 9253 size(4); 9254 ins_encode %{ 9255 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9256 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9257 %} 9258 ins_pipe(pipe_class_default); 9259 %} 9260 9261 // Immediate Multiplication 9262 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9263 match(Set dst (MulI src1 src2)); 9264 ins_cost(DEFAULT_COST); 9265 9266 format %{ "MULLI $dst, $src1, $src2" %} 9267 size(4); 9268 ins_encode %{ 9269 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9270 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9271 %} 9272 ins_pipe(pipe_class_default); 9273 %} 9274 9275 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9276 match(Set dst (MulL src1 src2)); 9277 ins_cost(DEFAULT_COST); 9278 9279 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9280 size(4); 9281 ins_encode %{ 9282 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9283 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9284 %} 9285 ins_pipe(pipe_class_default); 9286 %} 9287 9288 // Multiply high for optimized long division by constant. 9289 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9290 match(Set dst (MulHiL src1 src2)); 9291 ins_cost(DEFAULT_COST); 9292 9293 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9294 size(4); 9295 ins_encode %{ 9296 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9297 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9298 %} 9299 ins_pipe(pipe_class_default); 9300 %} 9301 9302 // Immediate Multiplication 9303 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9304 match(Set dst (MulL src1 src2)); 9305 ins_cost(DEFAULT_COST); 9306 9307 format %{ "MULLI $dst, $src1, $src2" %} 9308 size(4); 9309 ins_encode %{ 9310 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9311 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9312 %} 9313 ins_pipe(pipe_class_default); 9314 %} 9315 9316 // Integer Division with Immediate -1: Negate. 9317 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9318 match(Set dst (DivI src1 src2)); 9319 ins_cost(DEFAULT_COST); 9320 9321 format %{ "NEG $dst, $src1 \t// /-1" %} 9322 size(4); 9323 ins_encode %{ 9324 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9325 __ neg($dst$$Register, $src1$$Register); 9326 %} 9327 ins_pipe(pipe_class_default); 9328 %} 9329 9330 // Integer Division with constant, but not -1. 9331 // We should be able to improve this by checking the type of src2. 9332 // It might well be that src2 is known to be positive. 9333 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9334 match(Set dst (DivI src1 src2)); 9335 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9336 ins_cost(2*DEFAULT_COST); 9337 9338 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9339 size(4); 9340 ins_encode %{ 9341 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9342 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9343 %} 9344 ins_pipe(pipe_class_default); 9345 %} 9346 9347 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9348 effect(USE_DEF dst, USE src1, USE crx); 9349 predicate(false); 9350 9351 ins_variable_size_depending_on_alignment(true); 9352 9353 format %{ "CMOVE $dst, neg($src1), $crx" %} 9354 // Worst case is branch + move + stop, no stop without scheduler. 9355 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9356 ins_encode %{ 9357 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9358 Label done; 9359 __ bne($crx$$CondRegister, done); 9360 __ neg($dst$$Register, $src1$$Register); 9361 // TODO PPC port __ endgroup_if_needed(_size == 12); 9362 __ bind(done); 9363 %} 9364 ins_pipe(pipe_class_default); 9365 %} 9366 9367 // Integer Division with Registers not containing constants. 9368 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9369 match(Set dst (DivI src1 src2)); 9370 ins_cost(10*DEFAULT_COST); 9371 9372 expand %{ 9373 immI16 imm %{ (int)-1 %} 9374 flagsReg tmp1; 9375 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9376 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9377 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9378 %} 9379 %} 9380 9381 // Long Division with Immediate -1: Negate. 9382 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9383 match(Set dst (DivL src1 src2)); 9384 ins_cost(DEFAULT_COST); 9385 9386 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9387 size(4); 9388 ins_encode %{ 9389 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9390 __ neg($dst$$Register, $src1$$Register); 9391 %} 9392 ins_pipe(pipe_class_default); 9393 %} 9394 9395 // Long Division with constant, but not -1. 9396 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9397 match(Set dst (DivL src1 src2)); 9398 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9399 ins_cost(2*DEFAULT_COST); 9400 9401 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9402 size(4); 9403 ins_encode %{ 9404 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9405 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9406 %} 9407 ins_pipe(pipe_class_default); 9408 %} 9409 9410 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9411 effect(USE_DEF dst, USE src1, USE crx); 9412 predicate(false); 9413 9414 ins_variable_size_depending_on_alignment(true); 9415 9416 format %{ "CMOVE $dst, neg($src1), $crx" %} 9417 // Worst case is branch + move + stop, no stop without scheduler. 9418 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9419 ins_encode %{ 9420 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9421 Label done; 9422 __ bne($crx$$CondRegister, done); 9423 __ neg($dst$$Register, $src1$$Register); 9424 // TODO PPC port __ endgroup_if_needed(_size == 12); 9425 __ bind(done); 9426 %} 9427 ins_pipe(pipe_class_default); 9428 %} 9429 9430 // Long Division with Registers not containing constants. 9431 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9432 match(Set dst (DivL src1 src2)); 9433 ins_cost(10*DEFAULT_COST); 9434 9435 expand %{ 9436 immL16 imm %{ (int)-1 %} 9437 flagsReg tmp1; 9438 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9439 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9440 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9441 %} 9442 %} 9443 9444 // Integer Remainder with registers. 9445 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9446 match(Set dst (ModI src1 src2)); 9447 ins_cost(10*DEFAULT_COST); 9448 9449 expand %{ 9450 immI16 imm %{ (int)-1 %} 9451 flagsReg tmp1; 9452 iRegIdst tmp2; 9453 iRegIdst tmp3; 9454 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9455 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9456 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9457 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9458 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9459 %} 9460 %} 9461 9462 // Long Remainder with registers 9463 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9464 match(Set dst (ModL src1 src2)); 9465 ins_cost(10*DEFAULT_COST); 9466 9467 expand %{ 9468 immL16 imm %{ (int)-1 %} 9469 flagsReg tmp1; 9470 iRegLdst tmp2; 9471 iRegLdst tmp3; 9472 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9473 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9474 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9475 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9476 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9477 %} 9478 %} 9479 9480 // Integer Shift Instructions 9481 9482 // Register Shift Left 9483 9484 // Clear all but the lowest #mask bits. 9485 // Used to normalize shift amounts in registers. 9486 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9487 // no match-rule, false predicate 9488 effect(DEF dst, USE src, USE mask); 9489 predicate(false); 9490 9491 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9492 size(4); 9493 ins_encode %{ 9494 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9495 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9496 %} 9497 ins_pipe(pipe_class_default); 9498 %} 9499 9500 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9501 // no match-rule, false predicate 9502 effect(DEF dst, USE src1, USE src2); 9503 predicate(false); 9504 9505 format %{ "SLW $dst, $src1, $src2" %} 9506 size(4); 9507 ins_encode %{ 9508 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9509 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9510 %} 9511 ins_pipe(pipe_class_default); 9512 %} 9513 9514 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9515 match(Set dst (LShiftI src1 src2)); 9516 ins_cost(DEFAULT_COST*2); 9517 expand %{ 9518 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9519 iRegIdst tmpI; 9520 maskI_reg_imm(tmpI, src2, mask); 9521 lShiftI_reg_reg(dst, src1, tmpI); 9522 %} 9523 %} 9524 9525 // Register Shift Left Immediate 9526 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9527 match(Set dst (LShiftI src1 src2)); 9528 9529 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9530 size(4); 9531 ins_encode %{ 9532 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9533 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9534 %} 9535 ins_pipe(pipe_class_default); 9536 %} 9537 9538 // AndI with negpow2-constant + LShiftI 9539 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9540 match(Set dst (LShiftI (AndI src1 src2) src3)); 9541 predicate(UseRotateAndMaskInstructionsPPC64); 9542 9543 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9544 size(4); 9545 ins_encode %{ 9546 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9547 long src2 = $src2$$constant; 9548 long src3 = $src3$$constant; 9549 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9550 if (maskbits >= 32) { 9551 __ li($dst$$Register, 0); // addi 9552 } else { 9553 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9554 } 9555 %} 9556 ins_pipe(pipe_class_default); 9557 %} 9558 9559 // RShiftI + AndI with negpow2-constant + LShiftI 9560 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9561 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9562 predicate(UseRotateAndMaskInstructionsPPC64); 9563 9564 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9565 size(4); 9566 ins_encode %{ 9567 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9568 long src2 = $src2$$constant; 9569 long src3 = $src3$$constant; 9570 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9571 if (maskbits >= 32) { 9572 __ li($dst$$Register, 0); // addi 9573 } else { 9574 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9575 } 9576 %} 9577 ins_pipe(pipe_class_default); 9578 %} 9579 9580 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9581 // no match-rule, false predicate 9582 effect(DEF dst, USE src1, USE src2); 9583 predicate(false); 9584 9585 format %{ "SLD $dst, $src1, $src2" %} 9586 size(4); 9587 ins_encode %{ 9588 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9589 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9590 %} 9591 ins_pipe(pipe_class_default); 9592 %} 9593 9594 // Register Shift Left 9595 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9596 match(Set dst (LShiftL src1 src2)); 9597 ins_cost(DEFAULT_COST*2); 9598 expand %{ 9599 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9600 iRegIdst tmpI; 9601 maskI_reg_imm(tmpI, src2, mask); 9602 lShiftL_regL_regI(dst, src1, tmpI); 9603 %} 9604 %} 9605 9606 // Register Shift Left Immediate 9607 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9608 match(Set dst (LShiftL src1 src2)); 9609 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9610 size(4); 9611 ins_encode %{ 9612 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9613 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9614 %} 9615 ins_pipe(pipe_class_default); 9616 %} 9617 9618 // If we shift more than 32 bits, we need not convert I2L. 9619 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9620 match(Set dst (LShiftL (ConvI2L src1) src2)); 9621 ins_cost(DEFAULT_COST); 9622 9623 size(4); 9624 format %{ "SLDI $dst, i2l($src1), $src2" %} 9625 ins_encode %{ 9626 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9627 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9628 %} 9629 ins_pipe(pipe_class_default); 9630 %} 9631 9632 // Shift a postivie int to the left. 9633 // Clrlsldi clears the upper 32 bits and shifts. 9634 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9635 match(Set dst (LShiftL (ConvI2L src1) src2)); 9636 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9637 9638 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9639 size(4); 9640 ins_encode %{ 9641 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9642 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9643 %} 9644 ins_pipe(pipe_class_default); 9645 %} 9646 9647 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9648 // no match-rule, false predicate 9649 effect(DEF dst, USE src1, USE src2); 9650 predicate(false); 9651 9652 format %{ "SRAW $dst, $src1, $src2" %} 9653 size(4); 9654 ins_encode %{ 9655 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9656 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9657 %} 9658 ins_pipe(pipe_class_default); 9659 %} 9660 9661 // Register Arithmetic Shift Right 9662 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9663 match(Set dst (RShiftI src1 src2)); 9664 ins_cost(DEFAULT_COST*2); 9665 expand %{ 9666 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9667 iRegIdst tmpI; 9668 maskI_reg_imm(tmpI, src2, mask); 9669 arShiftI_reg_reg(dst, src1, tmpI); 9670 %} 9671 %} 9672 9673 // Register Arithmetic Shift Right Immediate 9674 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9675 match(Set dst (RShiftI src1 src2)); 9676 9677 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9678 size(4); 9679 ins_encode %{ 9680 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9681 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9682 %} 9683 ins_pipe(pipe_class_default); 9684 %} 9685 9686 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9687 // no match-rule, false predicate 9688 effect(DEF dst, USE src1, USE src2); 9689 predicate(false); 9690 9691 format %{ "SRAD $dst, $src1, $src2" %} 9692 size(4); 9693 ins_encode %{ 9694 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9695 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9696 %} 9697 ins_pipe(pipe_class_default); 9698 %} 9699 9700 // Register Shift Right Arithmetic Long 9701 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9702 match(Set dst (RShiftL src1 src2)); 9703 ins_cost(DEFAULT_COST*2); 9704 9705 expand %{ 9706 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9707 iRegIdst tmpI; 9708 maskI_reg_imm(tmpI, src2, mask); 9709 arShiftL_regL_regI(dst, src1, tmpI); 9710 %} 9711 %} 9712 9713 // Register Shift Right Immediate 9714 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9715 match(Set dst (RShiftL src1 src2)); 9716 9717 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9718 size(4); 9719 ins_encode %{ 9720 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9721 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9722 %} 9723 ins_pipe(pipe_class_default); 9724 %} 9725 9726 // RShiftL + ConvL2I 9727 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9728 match(Set dst (ConvL2I (RShiftL src1 src2))); 9729 9730 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9731 size(4); 9732 ins_encode %{ 9733 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9734 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9735 %} 9736 ins_pipe(pipe_class_default); 9737 %} 9738 9739 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9740 // no match-rule, false predicate 9741 effect(DEF dst, USE src1, USE src2); 9742 predicate(false); 9743 9744 format %{ "SRW $dst, $src1, $src2" %} 9745 size(4); 9746 ins_encode %{ 9747 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9748 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9749 %} 9750 ins_pipe(pipe_class_default); 9751 %} 9752 9753 // Register Shift Right 9754 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9755 match(Set dst (URShiftI src1 src2)); 9756 ins_cost(DEFAULT_COST*2); 9757 9758 expand %{ 9759 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9760 iRegIdst tmpI; 9761 maskI_reg_imm(tmpI, src2, mask); 9762 urShiftI_reg_reg(dst, src1, tmpI); 9763 %} 9764 %} 9765 9766 // Register Shift Right Immediate 9767 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9768 match(Set dst (URShiftI src1 src2)); 9769 9770 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9771 size(4); 9772 ins_encode %{ 9773 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9774 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9775 %} 9776 ins_pipe(pipe_class_default); 9777 %} 9778 9779 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9780 // no match-rule, false predicate 9781 effect(DEF dst, USE src1, USE src2); 9782 predicate(false); 9783 9784 format %{ "SRD $dst, $src1, $src2" %} 9785 size(4); 9786 ins_encode %{ 9787 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9788 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9789 %} 9790 ins_pipe(pipe_class_default); 9791 %} 9792 9793 // Register Shift Right 9794 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9795 match(Set dst (URShiftL src1 src2)); 9796 ins_cost(DEFAULT_COST*2); 9797 9798 expand %{ 9799 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9800 iRegIdst tmpI; 9801 maskI_reg_imm(tmpI, src2, mask); 9802 urShiftL_regL_regI(dst, src1, tmpI); 9803 %} 9804 %} 9805 9806 // Register Shift Right Immediate 9807 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9808 match(Set dst (URShiftL src1 src2)); 9809 9810 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9811 size(4); 9812 ins_encode %{ 9813 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9814 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9815 %} 9816 ins_pipe(pipe_class_default); 9817 %} 9818 9819 // URShiftL + ConvL2I. 9820 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9821 match(Set dst (ConvL2I (URShiftL src1 src2))); 9822 9823 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9824 size(4); 9825 ins_encode %{ 9826 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9827 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9828 %} 9829 ins_pipe(pipe_class_default); 9830 %} 9831 9832 // Register Shift Right Immediate with a CastP2X 9833 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9834 match(Set dst (URShiftL (CastP2X src1) src2)); 9835 9836 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9837 size(4); 9838 ins_encode %{ 9839 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9840 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9841 %} 9842 ins_pipe(pipe_class_default); 9843 %} 9844 9845 // Bitfield Extract: URShiftI + AndI 9846 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9847 match(Set dst (AndI (URShiftI src1 src2) src3)); 9848 9849 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9850 size(4); 9851 ins_encode %{ 9852 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9853 int rshift = ($src2$$constant) & 0x1f; 9854 int length = log2_long(((jlong) $src3$$constant) + 1); 9855 if (rshift + length > 32) { 9856 // if necessary, adjust mask to omit rotated bits. 9857 length = 32 - rshift; 9858 } 9859 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9860 %} 9861 ins_pipe(pipe_class_default); 9862 %} 9863 9864 // Bitfield Extract: URShiftL + AndL 9865 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9866 match(Set dst (AndL (URShiftL src1 src2) src3)); 9867 9868 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9869 size(4); 9870 ins_encode %{ 9871 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9872 int rshift = ($src2$$constant) & 0x3f; 9873 int length = log2_long(((jlong) $src3$$constant) + 1); 9874 if (rshift + length > 64) { 9875 // if necessary, adjust mask to omit rotated bits. 9876 length = 64 - rshift; 9877 } 9878 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9879 %} 9880 ins_pipe(pipe_class_default); 9881 %} 9882 9883 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9884 match(Set dst (ConvL2I (ConvI2L src))); 9885 9886 format %{ "EXTSW $dst, $src \t// int->int" %} 9887 size(4); 9888 ins_encode %{ 9889 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9890 __ extsw($dst$$Register, $src$$Register); 9891 %} 9892 ins_pipe(pipe_class_default); 9893 %} 9894 9895 //----------Rotate Instructions------------------------------------------------ 9896 9897 // Rotate Left by 8-bit immediate 9898 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9899 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9900 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9901 9902 format %{ "ROTLWI $dst, $src, $lshift" %} 9903 size(4); 9904 ins_encode %{ 9905 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9906 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9907 %} 9908 ins_pipe(pipe_class_default); 9909 %} 9910 9911 // Rotate Right by 8-bit immediate 9912 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9913 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9914 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9915 9916 format %{ "ROTRWI $dst, $rshift" %} 9917 size(4); 9918 ins_encode %{ 9919 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9920 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9921 %} 9922 ins_pipe(pipe_class_default); 9923 %} 9924 9925 //----------Floating Point Arithmetic Instructions----------------------------- 9926 9927 // Add float single precision 9928 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9929 match(Set dst (AddF src1 src2)); 9930 9931 format %{ "FADDS $dst, $src1, $src2" %} 9932 size(4); 9933 ins_encode %{ 9934 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9935 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9936 %} 9937 ins_pipe(pipe_class_default); 9938 %} 9939 9940 // Add float double precision 9941 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9942 match(Set dst (AddD src1 src2)); 9943 9944 format %{ "FADD $dst, $src1, $src2" %} 9945 size(4); 9946 ins_encode %{ 9947 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9948 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9949 %} 9950 ins_pipe(pipe_class_default); 9951 %} 9952 9953 // Sub float single precision 9954 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9955 match(Set dst (SubF src1 src2)); 9956 9957 format %{ "FSUBS $dst, $src1, $src2" %} 9958 size(4); 9959 ins_encode %{ 9960 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9961 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9962 %} 9963 ins_pipe(pipe_class_default); 9964 %} 9965 9966 // Sub float double precision 9967 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9968 match(Set dst (SubD src1 src2)); 9969 format %{ "FSUB $dst, $src1, $src2" %} 9970 size(4); 9971 ins_encode %{ 9972 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9973 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9974 %} 9975 ins_pipe(pipe_class_default); 9976 %} 9977 9978 // Mul float single precision 9979 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9980 match(Set dst (MulF src1 src2)); 9981 format %{ "FMULS $dst, $src1, $src2" %} 9982 size(4); 9983 ins_encode %{ 9984 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9985 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9986 %} 9987 ins_pipe(pipe_class_default); 9988 %} 9989 9990 // Mul float double precision 9991 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9992 match(Set dst (MulD src1 src2)); 9993 format %{ "FMUL $dst, $src1, $src2" %} 9994 size(4); 9995 ins_encode %{ 9996 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9997 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9998 %} 9999 ins_pipe(pipe_class_default); 10000 %} 10001 10002 // Div float single precision 10003 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 10004 match(Set dst (DivF src1 src2)); 10005 format %{ "FDIVS $dst, $src1, $src2" %} 10006 size(4); 10007 ins_encode %{ 10008 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 10009 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 10010 %} 10011 ins_pipe(pipe_class_default); 10012 %} 10013 10014 // Div float double precision 10015 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 10016 match(Set dst (DivD src1 src2)); 10017 format %{ "FDIV $dst, $src1, $src2" %} 10018 size(4); 10019 ins_encode %{ 10020 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 10021 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 10022 %} 10023 ins_pipe(pipe_class_default); 10024 %} 10025 10026 // Absolute float single precision 10027 instruct absF_reg(regF dst, regF src) %{ 10028 match(Set dst (AbsF src)); 10029 format %{ "FABS $dst, $src \t// float" %} 10030 size(4); 10031 ins_encode %{ 10032 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 10033 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 10034 %} 10035 ins_pipe(pipe_class_default); 10036 %} 10037 10038 // Absolute float double precision 10039 instruct absD_reg(regD dst, regD src) %{ 10040 match(Set dst (AbsD src)); 10041 format %{ "FABS $dst, $src \t// double" %} 10042 size(4); 10043 ins_encode %{ 10044 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 10045 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 10046 %} 10047 ins_pipe(pipe_class_default); 10048 %} 10049 10050 instruct negF_reg(regF dst, regF src) %{ 10051 match(Set dst (NegF src)); 10052 format %{ "FNEG $dst, $src \t// float" %} 10053 size(4); 10054 ins_encode %{ 10055 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 10056 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 10057 %} 10058 ins_pipe(pipe_class_default); 10059 %} 10060 10061 instruct negD_reg(regD dst, regD src) %{ 10062 match(Set dst (NegD src)); 10063 format %{ "FNEG $dst, $src \t// double" %} 10064 size(4); 10065 ins_encode %{ 10066 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 10067 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 10068 %} 10069 ins_pipe(pipe_class_default); 10070 %} 10071 10072 // AbsF + NegF. 10073 instruct negF_absF_reg(regF dst, regF src) %{ 10074 match(Set dst (NegF (AbsF src))); 10075 format %{ "FNABS $dst, $src \t// float" %} 10076 size(4); 10077 ins_encode %{ 10078 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10079 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10080 %} 10081 ins_pipe(pipe_class_default); 10082 %} 10083 10084 // AbsD + NegD. 10085 instruct negD_absD_reg(regD dst, regD src) %{ 10086 match(Set dst (NegD (AbsD src))); 10087 format %{ "FNABS $dst, $src \t// double" %} 10088 size(4); 10089 ins_encode %{ 10090 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10091 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10092 %} 10093 ins_pipe(pipe_class_default); 10094 %} 10095 10096 // VM_Version::has_fsqrt() decides if this node will be used. 10097 // Sqrt float double precision 10098 instruct sqrtD_reg(regD dst, regD src) %{ 10099 match(Set dst (SqrtD src)); 10100 format %{ "FSQRT $dst, $src" %} 10101 size(4); 10102 ins_encode %{ 10103 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 10104 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 10105 %} 10106 ins_pipe(pipe_class_default); 10107 %} 10108 10109 // Single-precision sqrt. 10110 instruct sqrtF_reg(regF dst, regF src) %{ 10111 match(Set dst (SqrtF src)); 10112 predicate(VM_Version::has_fsqrts()); 10113 ins_cost(DEFAULT_COST); 10114 10115 format %{ "FSQRTS $dst, $src" %} 10116 size(4); 10117 ins_encode %{ 10118 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 10119 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 10120 %} 10121 ins_pipe(pipe_class_default); 10122 %} 10123 10124 instruct roundDouble_nop(regD dst) %{ 10125 match(Set dst (RoundDouble dst)); 10126 ins_cost(0); 10127 10128 format %{ " -- \t// RoundDouble not needed - empty" %} 10129 size(0); 10130 // PPC results are already "rounded" (i.e., normal-format IEEE). 10131 ins_encode( /*empty*/ ); 10132 ins_pipe(pipe_class_default); 10133 %} 10134 10135 instruct roundFloat_nop(regF dst) %{ 10136 match(Set dst (RoundFloat dst)); 10137 ins_cost(0); 10138 10139 format %{ " -- \t// RoundFloat not needed - empty" %} 10140 size(0); 10141 // PPC results are already "rounded" (i.e., normal-format IEEE). 10142 ins_encode( /*empty*/ ); 10143 ins_pipe(pipe_class_default); 10144 %} 10145 10146 10147 // Multiply-Accumulate 10148 // src1 * src2 + src3 10149 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10150 match(Set dst (FmaF src3 (Binary src1 src2))); 10151 10152 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10153 size(4); 10154 ins_encode %{ 10155 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10156 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10157 %} 10158 ins_pipe(pipe_class_default); 10159 %} 10160 10161 // src1 * src2 + src3 10162 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10163 match(Set dst (FmaD src3 (Binary src1 src2))); 10164 10165 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10166 size(4); 10167 ins_encode %{ 10168 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10169 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10170 %} 10171 ins_pipe(pipe_class_default); 10172 %} 10173 10174 // -src1 * src2 + src3 = -(src1*src2-src3) 10175 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10176 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10177 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10178 10179 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10180 size(4); 10181 ins_encode %{ 10182 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10183 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10184 %} 10185 ins_pipe(pipe_class_default); 10186 %} 10187 10188 // -src1 * src2 + src3 = -(src1*src2-src3) 10189 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10190 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10191 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10192 10193 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10194 size(4); 10195 ins_encode %{ 10196 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10197 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10198 %} 10199 ins_pipe(pipe_class_default); 10200 %} 10201 10202 // -src1 * src2 - src3 = -(src1*src2+src3) 10203 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10204 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10205 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10206 10207 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10208 size(4); 10209 ins_encode %{ 10210 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10211 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10212 %} 10213 ins_pipe(pipe_class_default); 10214 %} 10215 10216 // -src1 * src2 - src3 = -(src1*src2+src3) 10217 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10218 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10219 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10220 10221 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10222 size(4); 10223 ins_encode %{ 10224 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10225 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10226 %} 10227 ins_pipe(pipe_class_default); 10228 %} 10229 10230 // src1 * src2 - src3 10231 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10232 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10233 10234 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10235 size(4); 10236 ins_encode %{ 10237 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10238 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10239 %} 10240 ins_pipe(pipe_class_default); 10241 %} 10242 10243 // src1 * src2 - src3 10244 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10245 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10246 10247 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10248 size(4); 10249 ins_encode %{ 10250 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10251 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10252 %} 10253 ins_pipe(pipe_class_default); 10254 %} 10255 10256 10257 //----------Logical Instructions----------------------------------------------- 10258 10259 // And Instructions 10260 10261 // Register And 10262 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10263 match(Set dst (AndI src1 src2)); 10264 format %{ "AND $dst, $src1, $src2" %} 10265 size(4); 10266 ins_encode %{ 10267 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10268 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10269 %} 10270 ins_pipe(pipe_class_default); 10271 %} 10272 10273 // Left shifted Immediate And 10274 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10275 match(Set dst (AndI src1 src2)); 10276 effect(KILL cr0); 10277 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10278 size(4); 10279 ins_encode %{ 10280 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10281 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10282 %} 10283 ins_pipe(pipe_class_default); 10284 %} 10285 10286 // Immediate And 10287 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10288 match(Set dst (AndI src1 src2)); 10289 effect(KILL cr0); 10290 10291 format %{ "ANDI $dst, $src1, $src2" %} 10292 size(4); 10293 ins_encode %{ 10294 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10295 // FIXME: avoid andi_ ? 10296 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10297 %} 10298 ins_pipe(pipe_class_default); 10299 %} 10300 10301 // Immediate And where the immediate is a negative power of 2. 10302 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10303 match(Set dst (AndI src1 src2)); 10304 format %{ "ANDWI $dst, $src1, $src2" %} 10305 size(4); 10306 ins_encode %{ 10307 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10308 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10309 %} 10310 ins_pipe(pipe_class_default); 10311 %} 10312 10313 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10314 match(Set dst (AndI src1 src2)); 10315 format %{ "ANDWI $dst, $src1, $src2" %} 10316 size(4); 10317 ins_encode %{ 10318 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10319 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10320 %} 10321 ins_pipe(pipe_class_default); 10322 %} 10323 10324 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10325 match(Set dst (AndI src1 src2)); 10326 predicate(UseRotateAndMaskInstructionsPPC64); 10327 format %{ "ANDWI $dst, $src1, $src2" %} 10328 size(4); 10329 ins_encode %{ 10330 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10331 __ rlwinm($dst$$Register, $src1$$Register, 0, 10332 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10333 %} 10334 ins_pipe(pipe_class_default); 10335 %} 10336 10337 // Register And Long 10338 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10339 match(Set dst (AndL src1 src2)); 10340 ins_cost(DEFAULT_COST); 10341 10342 format %{ "AND $dst, $src1, $src2 \t// long" %} 10343 size(4); 10344 ins_encode %{ 10345 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10346 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10347 %} 10348 ins_pipe(pipe_class_default); 10349 %} 10350 10351 // Immediate And long 10352 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10353 match(Set dst (AndL src1 src2)); 10354 effect(KILL cr0); 10355 10356 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10357 size(4); 10358 ins_encode %{ 10359 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10360 // FIXME: avoid andi_ ? 10361 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10362 %} 10363 ins_pipe(pipe_class_default); 10364 %} 10365 10366 // Immediate And Long where the immediate is a negative power of 2. 10367 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10368 match(Set dst (AndL src1 src2)); 10369 format %{ "ANDDI $dst, $src1, $src2" %} 10370 size(4); 10371 ins_encode %{ 10372 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10373 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10374 %} 10375 ins_pipe(pipe_class_default); 10376 %} 10377 10378 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10379 match(Set dst (AndL src1 src2)); 10380 format %{ "ANDDI $dst, $src1, $src2" %} 10381 size(4); 10382 ins_encode %{ 10383 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10384 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10385 %} 10386 ins_pipe(pipe_class_default); 10387 %} 10388 10389 // AndL + ConvL2I. 10390 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10391 match(Set dst (ConvL2I (AndL src1 src2))); 10392 ins_cost(DEFAULT_COST); 10393 10394 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10395 size(4); 10396 ins_encode %{ 10397 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10398 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10399 %} 10400 ins_pipe(pipe_class_default); 10401 %} 10402 10403 // Or Instructions 10404 10405 // Register Or 10406 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10407 match(Set dst (OrI src1 src2)); 10408 format %{ "OR $dst, $src1, $src2" %} 10409 size(4); 10410 ins_encode %{ 10411 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10412 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10413 %} 10414 ins_pipe(pipe_class_default); 10415 %} 10416 10417 // Expand does not work with above instruct. (??) 10418 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10419 // no match-rule 10420 effect(DEF dst, USE src1, USE src2); 10421 format %{ "OR $dst, $src1, $src2" %} 10422 size(4); 10423 ins_encode %{ 10424 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10425 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10426 %} 10427 ins_pipe(pipe_class_default); 10428 %} 10429 10430 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10431 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10432 ins_cost(DEFAULT_COST*3); 10433 10434 expand %{ 10435 // FIXME: we should do this in the ideal world. 10436 iRegIdst tmp1; 10437 iRegIdst tmp2; 10438 orI_reg_reg(tmp1, src1, src2); 10439 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10440 orI_reg_reg(dst, tmp1, tmp2); 10441 %} 10442 %} 10443 10444 // Immediate Or 10445 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10446 match(Set dst (OrI src1 src2)); 10447 format %{ "ORI $dst, $src1, $src2" %} 10448 size(4); 10449 ins_encode %{ 10450 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10451 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10452 %} 10453 ins_pipe(pipe_class_default); 10454 %} 10455 10456 // Register Or Long 10457 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10458 match(Set dst (OrL src1 src2)); 10459 ins_cost(DEFAULT_COST); 10460 10461 size(4); 10462 format %{ "OR $dst, $src1, $src2 \t// long" %} 10463 ins_encode %{ 10464 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10465 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10466 %} 10467 ins_pipe(pipe_class_default); 10468 %} 10469 10470 // OrL + ConvL2I. 10471 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10472 match(Set dst (ConvL2I (OrL src1 src2))); 10473 ins_cost(DEFAULT_COST); 10474 10475 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10476 size(4); 10477 ins_encode %{ 10478 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10479 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10480 %} 10481 ins_pipe(pipe_class_default); 10482 %} 10483 10484 // Immediate Or long 10485 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10486 match(Set dst (OrL src1 con)); 10487 ins_cost(DEFAULT_COST); 10488 10489 format %{ "ORI $dst, $src1, $con \t// long" %} 10490 size(4); 10491 ins_encode %{ 10492 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10493 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10494 %} 10495 ins_pipe(pipe_class_default); 10496 %} 10497 10498 // Xor Instructions 10499 10500 // Register Xor 10501 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10502 match(Set dst (XorI src1 src2)); 10503 format %{ "XOR $dst, $src1, $src2" %} 10504 size(4); 10505 ins_encode %{ 10506 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10507 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10508 %} 10509 ins_pipe(pipe_class_default); 10510 %} 10511 10512 // Expand does not work with above instruct. (??) 10513 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10514 // no match-rule 10515 effect(DEF dst, USE src1, USE src2); 10516 format %{ "XOR $dst, $src1, $src2" %} 10517 size(4); 10518 ins_encode %{ 10519 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10520 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10521 %} 10522 ins_pipe(pipe_class_default); 10523 %} 10524 10525 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10526 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10527 ins_cost(DEFAULT_COST*3); 10528 10529 expand %{ 10530 // FIXME: we should do this in the ideal world. 10531 iRegIdst tmp1; 10532 iRegIdst tmp2; 10533 xorI_reg_reg(tmp1, src1, src2); 10534 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10535 xorI_reg_reg(dst, tmp1, tmp2); 10536 %} 10537 %} 10538 10539 // Immediate Xor 10540 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10541 match(Set dst (XorI src1 src2)); 10542 format %{ "XORI $dst, $src1, $src2" %} 10543 size(4); 10544 ins_encode %{ 10545 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10546 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10547 %} 10548 ins_pipe(pipe_class_default); 10549 %} 10550 10551 // Register Xor Long 10552 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10553 match(Set dst (XorL src1 src2)); 10554 ins_cost(DEFAULT_COST); 10555 10556 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10557 size(4); 10558 ins_encode %{ 10559 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10560 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10561 %} 10562 ins_pipe(pipe_class_default); 10563 %} 10564 10565 // XorL + ConvL2I. 10566 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10567 match(Set dst (ConvL2I (XorL src1 src2))); 10568 ins_cost(DEFAULT_COST); 10569 10570 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10571 size(4); 10572 ins_encode %{ 10573 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10574 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10575 %} 10576 ins_pipe(pipe_class_default); 10577 %} 10578 10579 // Immediate Xor Long 10580 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10581 match(Set dst (XorL src1 src2)); 10582 ins_cost(DEFAULT_COST); 10583 10584 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10585 size(4); 10586 ins_encode %{ 10587 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10588 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10589 %} 10590 ins_pipe(pipe_class_default); 10591 %} 10592 10593 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10594 match(Set dst (XorI src1 src2)); 10595 ins_cost(DEFAULT_COST); 10596 10597 format %{ "NOT $dst, $src1 ($src2)" %} 10598 size(4); 10599 ins_encode %{ 10600 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10601 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10602 %} 10603 ins_pipe(pipe_class_default); 10604 %} 10605 10606 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10607 match(Set dst (XorL src1 src2)); 10608 ins_cost(DEFAULT_COST); 10609 10610 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10611 size(4); 10612 ins_encode %{ 10613 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10614 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10615 %} 10616 ins_pipe(pipe_class_default); 10617 %} 10618 10619 // And-complement 10620 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10621 match(Set dst (AndI (XorI src1 src2) src3)); 10622 ins_cost(DEFAULT_COST); 10623 10624 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10625 size(4); 10626 ins_encode( enc_andc(dst, src3, src1) ); 10627 ins_pipe(pipe_class_default); 10628 %} 10629 10630 // And-complement 10631 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10632 // no match-rule, false predicate 10633 effect(DEF dst, USE src1, USE src2); 10634 predicate(false); 10635 10636 format %{ "ANDC $dst, $src1, $src2" %} 10637 size(4); 10638 ins_encode %{ 10639 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10640 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10641 %} 10642 ins_pipe(pipe_class_default); 10643 %} 10644 10645 //----------Moves between int/long and float/double---------------------------- 10646 // 10647 // The following rules move values from int/long registers/stack-locations 10648 // to float/double registers/stack-locations and vice versa, without doing any 10649 // conversions. These rules are used to implement the bit-conversion methods 10650 // of java.lang.Float etc., e.g. 10651 // int floatToIntBits(float value) 10652 // float intBitsToFloat(int bits) 10653 // 10654 // Notes on the implementation on ppc64: 10655 // For Power7 and earlier, the rules are limited to those which move between a 10656 // register and a stack-location, because we always have to go through memory 10657 // when moving between a float register and an integer register. 10658 // This restriction is removed in Power8 with the introduction of the mtfprd 10659 // and mffprd instructions. 10660 10661 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10662 match(Set dst (MoveL2D src)); 10663 predicate(VM_Version::has_mtfprd()); 10664 10665 format %{ "MTFPRD $dst, $src" %} 10666 size(4); 10667 ins_encode %{ 10668 __ mtfprd($dst$$FloatRegister, $src$$Register); 10669 %} 10670 ins_pipe(pipe_class_default); 10671 %} 10672 10673 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10674 // no match-rule, false predicate 10675 effect(DEF dst, USE src); 10676 predicate(false); 10677 10678 format %{ "MTFPRWA $dst, $src" %} 10679 size(4); 10680 ins_encode %{ 10681 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10682 %} 10683 ins_pipe(pipe_class_default); 10684 %} 10685 10686 //---------- Chain stack slots between similar types -------- 10687 10688 // These are needed so that the rules below can match. 10689 10690 // Load integer from stack slot 10691 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10692 match(Set dst src); 10693 ins_cost(MEMORY_REF_COST); 10694 10695 format %{ "LWZ $dst, $src" %} 10696 size(4); 10697 ins_encode( enc_lwz(dst, src) ); 10698 ins_pipe(pipe_class_memory); 10699 %} 10700 10701 // Store integer to stack slot 10702 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10703 match(Set dst src); 10704 ins_cost(MEMORY_REF_COST); 10705 10706 format %{ "STW $src, $dst \t// stk" %} 10707 size(4); 10708 ins_encode( enc_stw(src, dst) ); // rs=rt 10709 ins_pipe(pipe_class_memory); 10710 %} 10711 10712 // Load long from stack slot 10713 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10714 match(Set dst src); 10715 ins_cost(MEMORY_REF_COST); 10716 10717 format %{ "LD $dst, $src \t// long" %} 10718 size(4); 10719 ins_encode( enc_ld(dst, src) ); 10720 ins_pipe(pipe_class_memory); 10721 %} 10722 10723 // Store long to stack slot 10724 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10725 match(Set dst src); 10726 ins_cost(MEMORY_REF_COST); 10727 10728 format %{ "STD $src, $dst \t// long" %} 10729 size(4); 10730 ins_encode( enc_std(src, dst) ); // rs=rt 10731 ins_pipe(pipe_class_memory); 10732 %} 10733 10734 //----------Moves between int and float 10735 10736 // Move float value from float stack-location to integer register. 10737 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10738 match(Set dst (MoveF2I src)); 10739 ins_cost(MEMORY_REF_COST); 10740 10741 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10742 size(4); 10743 ins_encode( enc_lwz(dst, src) ); 10744 ins_pipe(pipe_class_memory); 10745 %} 10746 10747 // Move float value from float register to integer stack-location. 10748 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10749 match(Set dst (MoveF2I src)); 10750 ins_cost(MEMORY_REF_COST); 10751 10752 format %{ "STFS $src, $dst \t// MoveF2I" %} 10753 size(4); 10754 ins_encode( enc_stfs(src, dst) ); 10755 ins_pipe(pipe_class_memory); 10756 %} 10757 10758 // Move integer value from integer stack-location to float register. 10759 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10760 match(Set dst (MoveI2F src)); 10761 ins_cost(MEMORY_REF_COST); 10762 10763 format %{ "LFS $dst, $src \t// MoveI2F" %} 10764 size(4); 10765 ins_encode %{ 10766 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10767 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10768 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10769 %} 10770 ins_pipe(pipe_class_memory); 10771 %} 10772 10773 // Move integer value from integer register to float stack-location. 10774 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10775 match(Set dst (MoveI2F src)); 10776 ins_cost(MEMORY_REF_COST); 10777 10778 format %{ "STW $src, $dst \t// MoveI2F" %} 10779 size(4); 10780 ins_encode( enc_stw(src, dst) ); 10781 ins_pipe(pipe_class_memory); 10782 %} 10783 10784 //----------Moves between long and float 10785 10786 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10787 // no match-rule, false predicate 10788 effect(DEF dst, USE src); 10789 predicate(false); 10790 10791 format %{ "storeD $src, $dst \t// STACK" %} 10792 size(4); 10793 ins_encode( enc_stfd(src, dst) ); 10794 ins_pipe(pipe_class_default); 10795 %} 10796 10797 //----------Moves between long and double 10798 10799 // Move double value from double stack-location to long register. 10800 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10801 match(Set dst (MoveD2L src)); 10802 ins_cost(MEMORY_REF_COST); 10803 size(4); 10804 format %{ "LD $dst, $src \t// MoveD2L" %} 10805 ins_encode( enc_ld(dst, src) ); 10806 ins_pipe(pipe_class_memory); 10807 %} 10808 10809 // Move double value from double register to long stack-location. 10810 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10811 match(Set dst (MoveD2L src)); 10812 effect(DEF dst, USE src); 10813 ins_cost(MEMORY_REF_COST); 10814 10815 format %{ "STFD $src, $dst \t// MoveD2L" %} 10816 size(4); 10817 ins_encode( enc_stfd(src, dst) ); 10818 ins_pipe(pipe_class_memory); 10819 %} 10820 10821 // Move long value from long stack-location to double register. 10822 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10823 match(Set dst (MoveL2D src)); 10824 ins_cost(MEMORY_REF_COST); 10825 10826 format %{ "LFD $dst, $src \t// MoveL2D" %} 10827 size(4); 10828 ins_encode( enc_lfd(dst, src) ); 10829 ins_pipe(pipe_class_memory); 10830 %} 10831 10832 // Move long value from long register to double stack-location. 10833 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10834 match(Set dst (MoveL2D src)); 10835 ins_cost(MEMORY_REF_COST); 10836 10837 format %{ "STD $src, $dst \t// MoveL2D" %} 10838 size(4); 10839 ins_encode( enc_std(src, dst) ); 10840 ins_pipe(pipe_class_memory); 10841 %} 10842 10843 //----------Register Move Instructions----------------------------------------- 10844 10845 // Replicate for Superword 10846 10847 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10848 predicate(false); 10849 effect(DEF dst, USE src); 10850 10851 format %{ "MR $dst, $src \t// replicate " %} 10852 // variable size, 0 or 4. 10853 ins_encode %{ 10854 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10855 __ mr_if_needed($dst$$Register, $src$$Register); 10856 %} 10857 ins_pipe(pipe_class_default); 10858 %} 10859 10860 //----------Cast instructions (Java-level type cast)--------------------------- 10861 10862 // Cast Long to Pointer for unsafe natives. 10863 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10864 match(Set dst (CastX2P src)); 10865 10866 format %{ "MR $dst, $src \t// Long->Ptr" %} 10867 // variable size, 0 or 4. 10868 ins_encode %{ 10869 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10870 __ mr_if_needed($dst$$Register, $src$$Register); 10871 %} 10872 ins_pipe(pipe_class_default); 10873 %} 10874 10875 // Cast Pointer to Long for unsafe natives. 10876 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10877 match(Set dst (CastP2X src)); 10878 10879 format %{ "MR $dst, $src \t// Ptr->Long" %} 10880 // variable size, 0 or 4. 10881 ins_encode %{ 10882 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10883 __ mr_if_needed($dst$$Register, $src$$Register); 10884 %} 10885 ins_pipe(pipe_class_default); 10886 %} 10887 10888 instruct castPP(iRegPdst dst) %{ 10889 match(Set dst (CastPP dst)); 10890 format %{ " -- \t// castPP of $dst" %} 10891 size(0); 10892 ins_encode( /*empty*/ ); 10893 ins_pipe(pipe_class_default); 10894 %} 10895 10896 instruct castII(iRegIdst dst) %{ 10897 match(Set dst (CastII dst)); 10898 format %{ " -- \t// castII of $dst" %} 10899 size(0); 10900 ins_encode( /*empty*/ ); 10901 ins_pipe(pipe_class_default); 10902 %} 10903 10904 instruct checkCastPP(iRegPdst dst) %{ 10905 match(Set dst (CheckCastPP dst)); 10906 format %{ " -- \t// checkcastPP of $dst" %} 10907 size(0); 10908 ins_encode( /*empty*/ ); 10909 ins_pipe(pipe_class_default); 10910 %} 10911 10912 //----------Convert instructions----------------------------------------------- 10913 10914 // Convert to boolean. 10915 10916 // int_to_bool(src) : { 1 if src != 0 10917 // { 0 else 10918 // 10919 // strategy: 10920 // 1) Count leading zeros of 32 bit-value src, 10921 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10922 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10923 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10924 10925 // convI2Bool 10926 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10927 match(Set dst (Conv2B src)); 10928 predicate(UseCountLeadingZerosInstructionsPPC64); 10929 ins_cost(DEFAULT_COST); 10930 10931 expand %{ 10932 immI shiftAmount %{ 0x5 %} 10933 uimmI16 mask %{ 0x1 %} 10934 iRegIdst tmp1; 10935 iRegIdst tmp2; 10936 countLeadingZerosI(tmp1, src); 10937 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10938 xorI_reg_uimm16(dst, tmp2, mask); 10939 %} 10940 %} 10941 10942 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10943 match(Set dst (Conv2B src)); 10944 effect(TEMP crx); 10945 predicate(!UseCountLeadingZerosInstructionsPPC64); 10946 ins_cost(DEFAULT_COST); 10947 10948 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10949 "LI $dst, #0\n\t" 10950 "BEQ $crx, done\n\t" 10951 "LI $dst, #1\n" 10952 "done:" %} 10953 size(16); 10954 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10955 ins_pipe(pipe_class_compare); 10956 %} 10957 10958 // ConvI2B + XorI 10959 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10960 match(Set dst (XorI (Conv2B src) mask)); 10961 predicate(UseCountLeadingZerosInstructionsPPC64); 10962 ins_cost(DEFAULT_COST); 10963 10964 expand %{ 10965 immI shiftAmount %{ 0x5 %} 10966 iRegIdst tmp1; 10967 countLeadingZerosI(tmp1, src); 10968 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10969 %} 10970 %} 10971 10972 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10973 match(Set dst (XorI (Conv2B src) mask)); 10974 effect(TEMP crx); 10975 predicate(!UseCountLeadingZerosInstructionsPPC64); 10976 ins_cost(DEFAULT_COST); 10977 10978 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10979 "LI $dst, #1\n\t" 10980 "BEQ $crx, done\n\t" 10981 "LI $dst, #0\n" 10982 "done:" %} 10983 size(16); 10984 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10985 ins_pipe(pipe_class_compare); 10986 %} 10987 10988 // AndI 0b0..010..0 + ConvI2B 10989 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10990 match(Set dst (Conv2B (AndI src mask))); 10991 predicate(UseRotateAndMaskInstructionsPPC64); 10992 ins_cost(DEFAULT_COST); 10993 10994 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10995 size(4); 10996 ins_encode %{ 10997 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10998 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10999 %} 11000 ins_pipe(pipe_class_default); 11001 %} 11002 11003 // Convert pointer to boolean. 11004 // 11005 // ptr_to_bool(src) : { 1 if src != 0 11006 // { 0 else 11007 // 11008 // strategy: 11009 // 1) Count leading zeros of 64 bit-value src, 11010 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 11011 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 11012 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 11013 11014 // ConvP2B 11015 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 11016 match(Set dst (Conv2B src)); 11017 predicate(UseCountLeadingZerosInstructionsPPC64); 11018 ins_cost(DEFAULT_COST); 11019 11020 expand %{ 11021 immI shiftAmount %{ 0x6 %} 11022 uimmI16 mask %{ 0x1 %} 11023 iRegIdst tmp1; 11024 iRegIdst tmp2; 11025 countLeadingZerosP(tmp1, src); 11026 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 11027 xorI_reg_uimm16(dst, tmp2, mask); 11028 %} 11029 %} 11030 11031 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 11032 match(Set dst (Conv2B src)); 11033 effect(TEMP crx); 11034 predicate(!UseCountLeadingZerosInstructionsPPC64); 11035 ins_cost(DEFAULT_COST); 11036 11037 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 11038 "LI $dst, #0\n\t" 11039 "BEQ $crx, done\n\t" 11040 "LI $dst, #1\n" 11041 "done:" %} 11042 size(16); 11043 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 11044 ins_pipe(pipe_class_compare); 11045 %} 11046 11047 // ConvP2B + XorI 11048 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 11049 match(Set dst (XorI (Conv2B src) mask)); 11050 predicate(UseCountLeadingZerosInstructionsPPC64); 11051 ins_cost(DEFAULT_COST); 11052 11053 expand %{ 11054 immI shiftAmount %{ 0x6 %} 11055 iRegIdst tmp1; 11056 countLeadingZerosP(tmp1, src); 11057 urShiftI_reg_imm(dst, tmp1, shiftAmount); 11058 %} 11059 %} 11060 11061 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 11062 match(Set dst (XorI (Conv2B src) mask)); 11063 effect(TEMP crx); 11064 predicate(!UseCountLeadingZerosInstructionsPPC64); 11065 ins_cost(DEFAULT_COST); 11066 11067 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 11068 "LI $dst, #1\n\t" 11069 "BEQ $crx, done\n\t" 11070 "LI $dst, #0\n" 11071 "done:" %} 11072 size(16); 11073 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 11074 ins_pipe(pipe_class_compare); 11075 %} 11076 11077 // if src1 < src2, return -1 else return 0 11078 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 11079 match(Set dst (CmpLTMask src1 src2)); 11080 ins_cost(DEFAULT_COST*4); 11081 11082 expand %{ 11083 iRegLdst src1s; 11084 iRegLdst src2s; 11085 iRegLdst diff; 11086 convI2L_reg(src1s, src1); // Ensure proper sign extension. 11087 convI2L_reg(src2s, src2); // Ensure proper sign extension. 11088 subL_reg_reg(diff, src1s, src2s); 11089 // Need to consider >=33 bit result, therefore we need signmaskL. 11090 signmask64I_regL(dst, diff); 11091 %} 11092 %} 11093 11094 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 11095 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 11096 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 11097 size(4); 11098 ins_encode %{ 11099 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 11100 __ srawi($dst$$Register, $src1$$Register, 0x1f); 11101 %} 11102 ins_pipe(pipe_class_default); 11103 %} 11104 11105 //----------Arithmetic Conversion Instructions--------------------------------- 11106 11107 // Convert to Byte -- nop 11108 // Convert to Short -- nop 11109 11110 // Convert to Int 11111 11112 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 11113 match(Set dst (RShiftI (LShiftI src amount) amount)); 11114 format %{ "EXTSB $dst, $src \t// byte->int" %} 11115 size(4); 11116 ins_encode %{ 11117 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 11118 __ extsb($dst$$Register, $src$$Register); 11119 %} 11120 ins_pipe(pipe_class_default); 11121 %} 11122 11123 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 11124 effect(DEF dst, USE src); 11125 11126 size(4); 11127 ins_encode %{ 11128 __ extsh($dst$$Register, $src$$Register); 11129 %} 11130 ins_pipe(pipe_class_default); 11131 %} 11132 11133 // LShiftI 16 + RShiftI 16 converts short to int. 11134 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 11135 match(Set dst (RShiftI (LShiftI src amount) amount)); 11136 format %{ "EXTSH $dst, $src \t// short->int" %} 11137 size(4); 11138 ins_encode %{ 11139 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 11140 __ extsh($dst$$Register, $src$$Register); 11141 %} 11142 ins_pipe(pipe_class_default); 11143 %} 11144 11145 // ConvL2I + ConvI2L: Sign extend int in long register. 11146 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11147 match(Set dst (ConvI2L (ConvL2I src))); 11148 11149 format %{ "EXTSW $dst, $src \t// long->long" %} 11150 size(4); 11151 ins_encode %{ 11152 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11153 __ extsw($dst$$Register, $src$$Register); 11154 %} 11155 ins_pipe(pipe_class_default); 11156 %} 11157 11158 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11159 match(Set dst (ConvL2I src)); 11160 format %{ "MR $dst, $src \t// long->int" %} 11161 // variable size, 0 or 4 11162 ins_encode %{ 11163 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11164 __ mr_if_needed($dst$$Register, $src$$Register); 11165 %} 11166 ins_pipe(pipe_class_default); 11167 %} 11168 11169 instruct convD2IRaw_regD(regD dst, regD src) %{ 11170 // no match-rule, false predicate 11171 effect(DEF dst, USE src); 11172 predicate(false); 11173 11174 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11175 size(4); 11176 ins_encode %{ 11177 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11178 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11179 %} 11180 ins_pipe(pipe_class_default); 11181 %} 11182 11183 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 11184 // no match-rule, false predicate 11185 effect(DEF dst, USE crx, USE src); 11186 predicate(false); 11187 11188 ins_variable_size_depending_on_alignment(true); 11189 11190 format %{ "cmovI $crx, $dst, $src" %} 11191 // Worst case is branch + move + stop, no stop without scheduler. 11192 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11193 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11194 ins_pipe(pipe_class_default); 11195 %} 11196 11197 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11198 // no match-rule, false predicate 11199 effect(DEF dst, USE crx, USE src); 11200 predicate(false); 11201 11202 ins_variable_size_depending_on_alignment(true); 11203 11204 format %{ "cmovI $crx, $dst, $src" %} 11205 // Worst case is branch + move + stop, no stop without scheduler. 11206 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11207 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11208 ins_pipe(pipe_class_default); 11209 %} 11210 11211 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11212 // no match-rule, false predicate 11213 effect(DEF dst, USE crx, USE mem); 11214 predicate(false); 11215 11216 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11217 postalloc_expand %{ 11218 // 11219 // replaces 11220 // 11221 // region dst crx mem 11222 // \ | | / 11223 // dst=cmovI_bso_stackSlotL_conLvalue0 11224 // 11225 // with 11226 // 11227 // region dst 11228 // \ / 11229 // dst=loadConI16(0) 11230 // | 11231 // ^ region dst crx mem 11232 // | \ | | / 11233 // dst=cmovI_bso_stackSlotL 11234 // 11235 11236 // Create new nodes. 11237 MachNode *m1 = new loadConI16Node(); 11238 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11239 11240 // inputs for new nodes 11241 m1->add_req(n_region); 11242 m2->add_req(n_region, n_crx, n_mem); 11243 11244 // precedences for new nodes 11245 m2->add_prec(m1); 11246 11247 // operands for new nodes 11248 m1->_opnds[0] = op_dst; 11249 m1->_opnds[1] = new immI16Oper(0); 11250 11251 m2->_opnds[0] = op_dst; 11252 m2->_opnds[1] = op_crx; 11253 m2->_opnds[2] = op_mem; 11254 11255 // registers for new nodes 11256 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11257 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11258 11259 // Insert new nodes. 11260 nodes->push(m1); 11261 nodes->push(m2); 11262 %} 11263 %} 11264 11265 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11266 // no match-rule, false predicate 11267 effect(DEF dst, USE crx, USE src); 11268 predicate(false); 11269 11270 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11271 postalloc_expand %{ 11272 // 11273 // replaces 11274 // 11275 // region dst crx src 11276 // \ | | / 11277 // dst=cmovI_bso_reg_conLvalue0 11278 // 11279 // with 11280 // 11281 // region dst 11282 // \ / 11283 // dst=loadConI16(0) 11284 // | 11285 // ^ region dst crx src 11286 // | \ | | / 11287 // dst=cmovI_bso_reg 11288 // 11289 11290 // Create new nodes. 11291 MachNode *m1 = new loadConI16Node(); 11292 MachNode *m2 = new cmovI_bso_regNode(); 11293 11294 // inputs for new nodes 11295 m1->add_req(n_region); 11296 m2->add_req(n_region, n_crx, n_src); 11297 11298 // precedences for new nodes 11299 m2->add_prec(m1); 11300 11301 // operands for new nodes 11302 m1->_opnds[0] = op_dst; 11303 m1->_opnds[1] = new immI16Oper(0); 11304 11305 m2->_opnds[0] = op_dst; 11306 m2->_opnds[1] = op_crx; 11307 m2->_opnds[2] = op_src; 11308 11309 // registers for new nodes 11310 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11311 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11312 11313 // Insert new nodes. 11314 nodes->push(m1); 11315 nodes->push(m2); 11316 %} 11317 %} 11318 11319 // Double to Int conversion, NaN is mapped to 0. 11320 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11321 match(Set dst (ConvD2I src)); 11322 predicate(!VM_Version::has_mtfprd()); 11323 ins_cost(DEFAULT_COST); 11324 11325 expand %{ 11326 regD tmpD; 11327 stackSlotL tmpS; 11328 flagsReg crx; 11329 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11330 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11331 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11332 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11333 %} 11334 %} 11335 11336 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11337 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11338 match(Set dst (ConvD2I src)); 11339 predicate(VM_Version::has_mtfprd()); 11340 ins_cost(DEFAULT_COST); 11341 11342 expand %{ 11343 regD tmpD; 11344 flagsReg crx; 11345 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11346 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11347 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11348 %} 11349 %} 11350 11351 instruct convF2IRaw_regF(regF dst, regF src) %{ 11352 // no match-rule, false predicate 11353 effect(DEF dst, USE src); 11354 predicate(false); 11355 11356 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11357 size(4); 11358 ins_encode %{ 11359 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11360 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11361 %} 11362 ins_pipe(pipe_class_default); 11363 %} 11364 11365 // Float to Int conversion, NaN is mapped to 0. 11366 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11367 match(Set dst (ConvF2I src)); 11368 predicate(!VM_Version::has_mtfprd()); 11369 ins_cost(DEFAULT_COST); 11370 11371 expand %{ 11372 regF tmpF; 11373 stackSlotL tmpS; 11374 flagsReg crx; 11375 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11376 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11377 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11378 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11379 %} 11380 %} 11381 11382 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11383 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11384 match(Set dst (ConvF2I src)); 11385 predicate(VM_Version::has_mtfprd()); 11386 ins_cost(DEFAULT_COST); 11387 11388 expand %{ 11389 regF tmpF; 11390 flagsReg crx; 11391 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11392 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11393 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11394 %} 11395 %} 11396 11397 // Convert to Long 11398 11399 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11400 match(Set dst (ConvI2L src)); 11401 format %{ "EXTSW $dst, $src \t// int->long" %} 11402 size(4); 11403 ins_encode %{ 11404 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11405 __ extsw($dst$$Register, $src$$Register); 11406 %} 11407 ins_pipe(pipe_class_default); 11408 %} 11409 11410 // Zero-extend: convert unsigned int to long (convUI2L). 11411 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11412 match(Set dst (AndL (ConvI2L src) mask)); 11413 ins_cost(DEFAULT_COST); 11414 11415 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11416 size(4); 11417 ins_encode %{ 11418 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11419 __ clrldi($dst$$Register, $src$$Register, 32); 11420 %} 11421 ins_pipe(pipe_class_default); 11422 %} 11423 11424 // Zero-extend: convert unsigned int to long in long register. 11425 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11426 match(Set dst (AndL src mask)); 11427 ins_cost(DEFAULT_COST); 11428 11429 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11430 size(4); 11431 ins_encode %{ 11432 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11433 __ clrldi($dst$$Register, $src$$Register, 32); 11434 %} 11435 ins_pipe(pipe_class_default); 11436 %} 11437 11438 instruct convF2LRaw_regF(regF dst, regF src) %{ 11439 // no match-rule, false predicate 11440 effect(DEF dst, USE src); 11441 predicate(false); 11442 11443 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11444 size(4); 11445 ins_encode %{ 11446 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11447 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11448 %} 11449 ins_pipe(pipe_class_default); 11450 %} 11451 11452 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 11453 // no match-rule, false predicate 11454 effect(DEF dst, USE crx, USE src); 11455 predicate(false); 11456 11457 ins_variable_size_depending_on_alignment(true); 11458 11459 format %{ "cmovL $crx, $dst, $src" %} 11460 // Worst case is branch + move + stop, no stop without scheduler. 11461 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11462 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11463 ins_pipe(pipe_class_default); 11464 %} 11465 11466 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11467 // no match-rule, false predicate 11468 effect(DEF dst, USE crx, USE src); 11469 predicate(false); 11470 11471 ins_variable_size_depending_on_alignment(true); 11472 11473 format %{ "cmovL $crx, $dst, $src" %} 11474 // Worst case is branch + move + stop, no stop without scheduler. 11475 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11476 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11477 ins_pipe(pipe_class_default); 11478 %} 11479 11480 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11481 // no match-rule, false predicate 11482 effect(DEF dst, USE crx, USE mem); 11483 predicate(false); 11484 11485 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11486 postalloc_expand %{ 11487 // 11488 // replaces 11489 // 11490 // region dst crx mem 11491 // \ | | / 11492 // dst=cmovL_bso_stackSlotL_conLvalue0 11493 // 11494 // with 11495 // 11496 // region dst 11497 // \ / 11498 // dst=loadConL16(0) 11499 // | 11500 // ^ region dst crx mem 11501 // | \ | | / 11502 // dst=cmovL_bso_stackSlotL 11503 // 11504 11505 // Create new nodes. 11506 MachNode *m1 = new loadConL16Node(); 11507 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11508 11509 // inputs for new nodes 11510 m1->add_req(n_region); 11511 m2->add_req(n_region, n_crx, n_mem); 11512 m2->add_prec(m1); 11513 11514 // operands for new nodes 11515 m1->_opnds[0] = op_dst; 11516 m1->_opnds[1] = new immL16Oper(0); 11517 m2->_opnds[0] = op_dst; 11518 m2->_opnds[1] = op_crx; 11519 m2->_opnds[2] = op_mem; 11520 11521 // registers for new nodes 11522 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11523 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11524 11525 // Insert new nodes. 11526 nodes->push(m1); 11527 nodes->push(m2); 11528 %} 11529 %} 11530 11531 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11532 // no match-rule, false predicate 11533 effect(DEF dst, USE crx, USE src); 11534 predicate(false); 11535 11536 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11537 postalloc_expand %{ 11538 // 11539 // replaces 11540 // 11541 // region dst crx src 11542 // \ | | / 11543 // dst=cmovL_bso_reg_conLvalue0 11544 // 11545 // with 11546 // 11547 // region dst 11548 // \ / 11549 // dst=loadConL16(0) 11550 // | 11551 // ^ region dst crx src 11552 // | \ | | / 11553 // dst=cmovL_bso_reg 11554 // 11555 11556 // Create new nodes. 11557 MachNode *m1 = new loadConL16Node(); 11558 MachNode *m2 = new cmovL_bso_regNode(); 11559 11560 // inputs for new nodes 11561 m1->add_req(n_region); 11562 m2->add_req(n_region, n_crx, n_src); 11563 m2->add_prec(m1); 11564 11565 // operands for new nodes 11566 m1->_opnds[0] = op_dst; 11567 m1->_opnds[1] = new immL16Oper(0); 11568 m2->_opnds[0] = op_dst; 11569 m2->_opnds[1] = op_crx; 11570 m2->_opnds[2] = op_src; 11571 11572 // registers for new nodes 11573 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11574 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11575 11576 // Insert new nodes. 11577 nodes->push(m1); 11578 nodes->push(m2); 11579 %} 11580 %} 11581 11582 // Float to Long conversion, NaN is mapped to 0. 11583 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11584 match(Set dst (ConvF2L src)); 11585 predicate(!VM_Version::has_mtfprd()); 11586 ins_cost(DEFAULT_COST); 11587 11588 expand %{ 11589 regF tmpF; 11590 stackSlotL tmpS; 11591 flagsReg crx; 11592 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11593 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11594 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11595 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11596 %} 11597 %} 11598 11599 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11600 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11601 match(Set dst (ConvF2L src)); 11602 predicate(VM_Version::has_mtfprd()); 11603 ins_cost(DEFAULT_COST); 11604 11605 expand %{ 11606 regF tmpF; 11607 flagsReg crx; 11608 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11609 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11610 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11611 %} 11612 %} 11613 11614 instruct convD2LRaw_regD(regD dst, regD src) %{ 11615 // no match-rule, false predicate 11616 effect(DEF dst, USE src); 11617 predicate(false); 11618 11619 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11620 size(4); 11621 ins_encode %{ 11622 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11623 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11624 %} 11625 ins_pipe(pipe_class_default); 11626 %} 11627 11628 // Double to Long conversion, NaN is mapped to 0. 11629 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11630 match(Set dst (ConvD2L src)); 11631 predicate(!VM_Version::has_mtfprd()); 11632 ins_cost(DEFAULT_COST); 11633 11634 expand %{ 11635 regD tmpD; 11636 stackSlotL tmpS; 11637 flagsReg crx; 11638 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11639 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11640 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11641 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11642 %} 11643 %} 11644 11645 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11646 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11647 match(Set dst (ConvD2L src)); 11648 predicate(VM_Version::has_mtfprd()); 11649 ins_cost(DEFAULT_COST); 11650 11651 expand %{ 11652 regD tmpD; 11653 flagsReg crx; 11654 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11655 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11656 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11657 %} 11658 %} 11659 11660 // Convert to Float 11661 11662 // Placed here as needed in expand. 11663 instruct convL2DRaw_regD(regD dst, regD src) %{ 11664 // no match-rule, false predicate 11665 effect(DEF dst, USE src); 11666 predicate(false); 11667 11668 format %{ "FCFID $dst, $src \t// convL2D" %} 11669 size(4); 11670 ins_encode %{ 11671 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11672 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11673 %} 11674 ins_pipe(pipe_class_default); 11675 %} 11676 11677 // Placed here as needed in expand. 11678 instruct convD2F_reg(regF dst, regD src) %{ 11679 match(Set dst (ConvD2F src)); 11680 format %{ "FRSP $dst, $src \t// convD2F" %} 11681 size(4); 11682 ins_encode %{ 11683 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11684 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11685 %} 11686 ins_pipe(pipe_class_default); 11687 %} 11688 11689 // Integer to Float conversion. 11690 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11691 match(Set dst (ConvI2F src)); 11692 predicate(!VM_Version::has_fcfids()); 11693 ins_cost(DEFAULT_COST); 11694 11695 expand %{ 11696 iRegLdst tmpL; 11697 stackSlotL tmpS; 11698 regD tmpD; 11699 regD tmpD2; 11700 convI2L_reg(tmpL, src); // Sign-extension int to long. 11701 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11702 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11703 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11704 convD2F_reg(dst, tmpD2); // Convert double to float. 11705 %} 11706 %} 11707 11708 instruct convL2FRaw_regF(regF dst, regD src) %{ 11709 // no match-rule, false predicate 11710 effect(DEF dst, USE src); 11711 predicate(false); 11712 11713 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11714 size(4); 11715 ins_encode %{ 11716 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11717 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11718 %} 11719 ins_pipe(pipe_class_default); 11720 %} 11721 11722 // Integer to Float conversion. Special version for Power7. 11723 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11724 match(Set dst (ConvI2F src)); 11725 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11726 ins_cost(DEFAULT_COST); 11727 11728 expand %{ 11729 iRegLdst tmpL; 11730 stackSlotL tmpS; 11731 regD tmpD; 11732 convI2L_reg(tmpL, src); // Sign-extension int to long. 11733 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11734 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11735 convL2FRaw_regF(dst, tmpD); // Convert to float. 11736 %} 11737 %} 11738 11739 // Integer to Float conversion. Special version for Power8. 11740 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11741 match(Set dst (ConvI2F src)); 11742 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11743 ins_cost(DEFAULT_COST); 11744 11745 expand %{ 11746 regD tmpD; 11747 moveI2D_reg(tmpD, src); 11748 convL2FRaw_regF(dst, tmpD); // Convert to float. 11749 %} 11750 %} 11751 11752 // L2F to avoid runtime call. 11753 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11754 match(Set dst (ConvL2F src)); 11755 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11756 ins_cost(DEFAULT_COST); 11757 11758 expand %{ 11759 stackSlotL tmpS; 11760 regD tmpD; 11761 regL_to_stkL(tmpS, src); // Store long to stack. 11762 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11763 convL2FRaw_regF(dst, tmpD); // Convert to float. 11764 %} 11765 %} 11766 11767 // L2F to avoid runtime call. Special version for Power8. 11768 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11769 match(Set dst (ConvL2F src)); 11770 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11771 ins_cost(DEFAULT_COST); 11772 11773 expand %{ 11774 regD tmpD; 11775 moveL2D_reg(tmpD, src); 11776 convL2FRaw_regF(dst, tmpD); // Convert to float. 11777 %} 11778 %} 11779 11780 // Moved up as used in expand. 11781 //instruct convD2F_reg(regF dst, regD src) %{%} 11782 11783 // Convert to Double 11784 11785 // Integer to Double conversion. 11786 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11787 match(Set dst (ConvI2D src)); 11788 predicate(!VM_Version::has_mtfprd()); 11789 ins_cost(DEFAULT_COST); 11790 11791 expand %{ 11792 iRegLdst tmpL; 11793 stackSlotL tmpS; 11794 regD tmpD; 11795 convI2L_reg(tmpL, src); // Sign-extension int to long. 11796 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11797 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11798 convL2DRaw_regD(dst, tmpD); // Convert to double. 11799 %} 11800 %} 11801 11802 // Integer to Double conversion. Special version for Power8. 11803 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11804 match(Set dst (ConvI2D src)); 11805 predicate(VM_Version::has_mtfprd()); 11806 ins_cost(DEFAULT_COST); 11807 11808 expand %{ 11809 regD tmpD; 11810 moveI2D_reg(tmpD, src); 11811 convL2DRaw_regD(dst, tmpD); // Convert to double. 11812 %} 11813 %} 11814 11815 // Long to Double conversion 11816 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11817 match(Set dst (ConvL2D src)); 11818 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11819 11820 expand %{ 11821 regD tmpD; 11822 moveL2D_stack_reg(tmpD, src); 11823 convL2DRaw_regD(dst, tmpD); 11824 %} 11825 %} 11826 11827 // Long to Double conversion. Special version for Power8. 11828 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11829 match(Set dst (ConvL2D src)); 11830 predicate(VM_Version::has_mtfprd()); 11831 ins_cost(DEFAULT_COST); 11832 11833 expand %{ 11834 regD tmpD; 11835 moveL2D_reg(tmpD, src); 11836 convL2DRaw_regD(dst, tmpD); // Convert to double. 11837 %} 11838 %} 11839 11840 instruct convF2D_reg(regD dst, regF src) %{ 11841 match(Set dst (ConvF2D src)); 11842 format %{ "FMR $dst, $src \t// float->double" %} 11843 // variable size, 0 or 4 11844 ins_encode %{ 11845 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11846 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11847 %} 11848 ins_pipe(pipe_class_default); 11849 %} 11850 11851 //----------Control Flow Instructions------------------------------------------ 11852 // Compare Instructions 11853 11854 // Compare Integers 11855 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11856 match(Set crx (CmpI src1 src2)); 11857 size(4); 11858 format %{ "CMPW $crx, $src1, $src2" %} 11859 ins_encode %{ 11860 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11861 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11862 %} 11863 ins_pipe(pipe_class_compare); 11864 %} 11865 11866 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11867 match(Set crx (CmpI src1 src2)); 11868 format %{ "CMPWI $crx, $src1, $src2" %} 11869 size(4); 11870 ins_encode %{ 11871 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11872 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11873 %} 11874 ins_pipe(pipe_class_compare); 11875 %} 11876 11877 // (src1 & src2) == 0? 11878 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11879 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11880 // r0 is killed 11881 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11882 size(4); 11883 ins_encode %{ 11884 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11885 __ andi_(R0, $src1$$Register, $src2$$constant); 11886 %} 11887 ins_pipe(pipe_class_compare); 11888 %} 11889 11890 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11891 match(Set crx (CmpL src1 src2)); 11892 format %{ "CMPD $crx, $src1, $src2" %} 11893 size(4); 11894 ins_encode %{ 11895 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11896 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11897 %} 11898 ins_pipe(pipe_class_compare); 11899 %} 11900 11901 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11902 match(Set crx (CmpL src1 src2)); 11903 format %{ "CMPDI $crx, $src1, $src2" %} 11904 size(4); 11905 ins_encode %{ 11906 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11907 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11908 %} 11909 ins_pipe(pipe_class_compare); 11910 %} 11911 11912 // Added CmpUL for LoopPredicate. 11913 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11914 match(Set crx (CmpUL src1 src2)); 11915 format %{ "CMPLD $crx, $src1, $src2" %} 11916 size(4); 11917 ins_encode %{ 11918 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11919 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11920 %} 11921 ins_pipe(pipe_class_compare); 11922 %} 11923 11924 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11925 match(Set crx (CmpUL src1 src2)); 11926 format %{ "CMPLDI $crx, $src1, $src2" %} 11927 size(4); 11928 ins_encode %{ 11929 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11930 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11931 %} 11932 ins_pipe(pipe_class_compare); 11933 %} 11934 11935 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11936 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11937 // r0 is killed 11938 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11939 size(4); 11940 ins_encode %{ 11941 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11942 __ and_(R0, $src1$$Register, $src2$$Register); 11943 %} 11944 ins_pipe(pipe_class_compare); 11945 %} 11946 11947 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11948 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11949 // r0 is killed 11950 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11951 size(4); 11952 ins_encode %{ 11953 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11954 __ andi_(R0, $src1$$Register, $src2$$constant); 11955 %} 11956 ins_pipe(pipe_class_compare); 11957 %} 11958 11959 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11960 // no match-rule, false predicate 11961 effect(DEF dst, USE crx); 11962 predicate(false); 11963 11964 ins_variable_size_depending_on_alignment(true); 11965 11966 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11967 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11968 size((false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16)); 11969 ins_encode %{ 11970 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11971 Label done; 11972 // li(Rdst, 0); // equal -> 0 11973 __ beq($crx$$CondRegister, done); 11974 __ li($dst$$Register, 1); // greater -> +1 11975 __ bgt($crx$$CondRegister, done); 11976 __ li($dst$$Register, -1); // unordered or less -> -1 11977 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11978 __ bind(done); 11979 %} 11980 ins_pipe(pipe_class_compare); 11981 %} 11982 11983 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11984 // no match-rule, false predicate 11985 effect(DEF dst, USE crx); 11986 predicate(false); 11987 11988 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11989 postalloc_expand %{ 11990 // 11991 // replaces 11992 // 11993 // region crx 11994 // \ | 11995 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11996 // 11997 // with 11998 // 11999 // region 12000 // \ 12001 // dst=loadConI16(0) 12002 // | 12003 // ^ region crx 12004 // | \ | 12005 // dst=cmovI_conIvalueMinus1_conIvalue1 12006 // 12007 12008 // Create new nodes. 12009 MachNode *m1 = new loadConI16Node(); 12010 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 12011 12012 // inputs for new nodes 12013 m1->add_req(n_region); 12014 m2->add_req(n_region, n_crx); 12015 m2->add_prec(m1); 12016 12017 // operands for new nodes 12018 m1->_opnds[0] = op_dst; 12019 m1->_opnds[1] = new immI16Oper(0); 12020 m2->_opnds[0] = op_dst; 12021 m2->_opnds[1] = op_crx; 12022 12023 // registers for new nodes 12024 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 12025 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 12026 12027 // Insert new nodes. 12028 nodes->push(m1); 12029 nodes->push(m2); 12030 %} 12031 %} 12032 12033 // Manifest a CmpL3 result in an integer register. Very painful. 12034 // This is the test to avoid. 12035 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 12036 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 12037 match(Set dst (CmpL3 src1 src2)); 12038 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12039 12040 expand %{ 12041 flagsReg tmp1; 12042 cmpL_reg_reg(tmp1, src1, src2); 12043 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12044 %} 12045 %} 12046 12047 // Implicit range checks. 12048 // A range check in the ideal world has one of the following shapes: 12049 // - (If le (CmpU length index)), (IfTrue throw exception) 12050 // - (If lt (CmpU index length)), (IfFalse throw exception) 12051 // 12052 // Match range check 'If le (CmpU length index)'. 12053 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 12054 match(If cmp (CmpU src_length index)); 12055 effect(USE labl); 12056 predicate(TrapBasedRangeChecks && 12057 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 12058 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 12059 (Matcher::branches_to_uncommon_trap(_leaf))); 12060 12061 ins_is_TrapBasedCheckNode(true); 12062 12063 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 12064 size(4); 12065 ins_encode %{ 12066 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12067 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 12068 __ trap_range_check_le($src_length$$Register, $index$$constant); 12069 } else { 12070 // Both successors are uncommon traps, probability is 0. 12071 // Node got flipped during fixup flow. 12072 assert($cmp$$cmpcode == 0x9, "must be greater"); 12073 __ trap_range_check_g($src_length$$Register, $index$$constant); 12074 } 12075 %} 12076 ins_pipe(pipe_class_trap); 12077 %} 12078 12079 // Match range check 'If lt (CmpU index length)'. 12080 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 12081 match(If cmp (CmpU src_index src_length)); 12082 effect(USE labl); 12083 predicate(TrapBasedRangeChecks && 12084 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12085 _leaf->as_If()->_prob >= PROB_ALWAYS && 12086 (Matcher::branches_to_uncommon_trap(_leaf))); 12087 12088 ins_is_TrapBasedCheckNode(true); 12089 12090 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 12091 size(4); 12092 ins_encode %{ 12093 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 12094 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12095 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 12096 } else { 12097 // Both successors are uncommon traps, probability is 0. 12098 // Node got flipped during fixup flow. 12099 assert($cmp$$cmpcode == 0x8, "must be less"); 12100 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 12101 } 12102 %} 12103 ins_pipe(pipe_class_trap); 12104 %} 12105 12106 // Match range check 'If lt (CmpU index length)'. 12107 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 12108 match(If cmp (CmpU src_index length)); 12109 effect(USE labl); 12110 predicate(TrapBasedRangeChecks && 12111 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12112 _leaf->as_If()->_prob >= PROB_ALWAYS && 12113 (Matcher::branches_to_uncommon_trap(_leaf))); 12114 12115 ins_is_TrapBasedCheckNode(true); 12116 12117 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 12118 size(4); 12119 ins_encode %{ 12120 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12121 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12122 __ trap_range_check_ge($src_index$$Register, $length$$constant); 12123 } else { 12124 // Both successors are uncommon traps, probability is 0. 12125 // Node got flipped during fixup flow. 12126 assert($cmp$$cmpcode == 0x8, "must be less"); 12127 __ trap_range_check_l($src_index$$Register, $length$$constant); 12128 } 12129 %} 12130 ins_pipe(pipe_class_trap); 12131 %} 12132 12133 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 12134 match(Set crx (CmpU src1 src2)); 12135 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 12136 size(4); 12137 ins_encode %{ 12138 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12139 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12140 %} 12141 ins_pipe(pipe_class_compare); 12142 %} 12143 12144 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 12145 match(Set crx (CmpU src1 src2)); 12146 size(4); 12147 format %{ "CMPLWI $crx, $src1, $src2" %} 12148 ins_encode %{ 12149 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12150 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12151 %} 12152 ins_pipe(pipe_class_compare); 12153 %} 12154 12155 // Implicit zero checks (more implicit null checks). 12156 // No constant pool entries required. 12157 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12158 match(If cmp (CmpN value zero)); 12159 effect(USE labl); 12160 predicate(TrapBasedNullChecks && 12161 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12162 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12163 Matcher::branches_to_uncommon_trap(_leaf)); 12164 ins_cost(1); 12165 12166 ins_is_TrapBasedCheckNode(true); 12167 12168 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12169 size(4); 12170 ins_encode %{ 12171 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12172 if ($cmp$$cmpcode == 0xA) { 12173 __ trap_null_check($value$$Register); 12174 } else { 12175 // Both successors are uncommon traps, probability is 0. 12176 // Node got flipped during fixup flow. 12177 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12178 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12179 } 12180 %} 12181 ins_pipe(pipe_class_trap); 12182 %} 12183 12184 // Compare narrow oops. 12185 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12186 match(Set crx (CmpN src1 src2)); 12187 12188 size(4); 12189 ins_cost(2); 12190 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12191 ins_encode %{ 12192 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12193 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12194 %} 12195 ins_pipe(pipe_class_compare); 12196 %} 12197 12198 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12199 match(Set crx (CmpN src1 src2)); 12200 // Make this more expensive than zeroCheckN_iReg_imm0. 12201 ins_cost(2); 12202 12203 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12204 size(4); 12205 ins_encode %{ 12206 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12207 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12208 %} 12209 ins_pipe(pipe_class_compare); 12210 %} 12211 12212 // Implicit zero checks (more implicit null checks). 12213 // No constant pool entries required. 12214 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12215 match(If cmp (CmpP value zero)); 12216 effect(USE labl); 12217 predicate(TrapBasedNullChecks && 12218 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12219 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12220 Matcher::branches_to_uncommon_trap(_leaf)); 12221 ins_cost(1); // Should not be cheaper than zeroCheckN. 12222 12223 ins_is_TrapBasedCheckNode(true); 12224 12225 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12226 size(4); 12227 ins_encode %{ 12228 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12229 if ($cmp$$cmpcode == 0xA) { 12230 __ trap_null_check($value$$Register); 12231 } else { 12232 // Both successors are uncommon traps, probability is 0. 12233 // Node got flipped during fixup flow. 12234 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12235 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12236 } 12237 %} 12238 ins_pipe(pipe_class_trap); 12239 %} 12240 12241 // Compare Pointers 12242 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12243 match(Set crx (CmpP src1 src2)); 12244 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12245 size(4); 12246 ins_encode %{ 12247 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12248 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12249 %} 12250 ins_pipe(pipe_class_compare); 12251 %} 12252 12253 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12254 match(Set crx (CmpP src1 src2)); 12255 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12256 size(4); 12257 ins_encode %{ 12258 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12259 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12260 %} 12261 ins_pipe(pipe_class_compare); 12262 %} 12263 12264 // Used in postalloc expand. 12265 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12266 // This match rule prevents reordering of node before a safepoint. 12267 // This only makes sense if this instructions is used exclusively 12268 // for the expansion of EncodeP! 12269 match(Set crx (CmpP src1 src2)); 12270 predicate(false); 12271 12272 format %{ "CMPDI $crx, $src1, $src2" %} 12273 size(4); 12274 ins_encode %{ 12275 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12276 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12277 %} 12278 ins_pipe(pipe_class_compare); 12279 %} 12280 12281 //----------Float Compares---------------------------------------------------- 12282 12283 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12284 // Needs matchrule, see cmpDUnordered. 12285 match(Set crx (CmpF src1 src2)); 12286 // no match-rule, false predicate 12287 predicate(false); 12288 12289 format %{ "cmpFUrd $crx, $src1, $src2" %} 12290 size(4); 12291 ins_encode %{ 12292 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12293 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12294 %} 12295 ins_pipe(pipe_class_default); 12296 %} 12297 12298 instruct cmov_bns_less(flagsReg crx) %{ 12299 // no match-rule, false predicate 12300 effect(DEF crx); 12301 predicate(false); 12302 12303 ins_variable_size_depending_on_alignment(true); 12304 12305 format %{ "cmov $crx" %} 12306 // Worst case is branch + move + stop, no stop without scheduler. 12307 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12)); 12308 ins_encode %{ 12309 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12310 Label done; 12311 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12312 __ li(R0, 0); 12313 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12314 // TODO PPC port __ endgroup_if_needed(_size == 16); 12315 __ bind(done); 12316 %} 12317 ins_pipe(pipe_class_default); 12318 %} 12319 12320 // Compare floating, generate condition code. 12321 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12322 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12323 // 12324 // The following code sequence occurs a lot in mpegaudio: 12325 // 12326 // block BXX: 12327 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12328 // cmpFUrd CCR6, F11, F9 12329 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12330 // cmov CCR6 12331 // 8: instruct branchConSched: 12332 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12333 match(Set crx (CmpF src1 src2)); 12334 ins_cost(DEFAULT_COST+BRANCH_COST); 12335 12336 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12337 postalloc_expand %{ 12338 // 12339 // replaces 12340 // 12341 // region src1 src2 12342 // \ | | 12343 // crx=cmpF_reg_reg 12344 // 12345 // with 12346 // 12347 // region src1 src2 12348 // \ | | 12349 // crx=cmpFUnordered_reg_reg 12350 // | 12351 // ^ region 12352 // | \ 12353 // crx=cmov_bns_less 12354 // 12355 12356 // Create new nodes. 12357 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12358 MachNode *m2 = new cmov_bns_lessNode(); 12359 12360 // inputs for new nodes 12361 m1->add_req(n_region, n_src1, n_src2); 12362 m2->add_req(n_region); 12363 m2->add_prec(m1); 12364 12365 // operands for new nodes 12366 m1->_opnds[0] = op_crx; 12367 m1->_opnds[1] = op_src1; 12368 m1->_opnds[2] = op_src2; 12369 m2->_opnds[0] = op_crx; 12370 12371 // registers for new nodes 12372 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12373 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12374 12375 // Insert new nodes. 12376 nodes->push(m1); 12377 nodes->push(m2); 12378 %} 12379 %} 12380 12381 // Compare float, generate -1,0,1 12382 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12383 match(Set dst (CmpF3 src1 src2)); 12384 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12385 12386 expand %{ 12387 flagsReg tmp1; 12388 cmpFUnordered_reg_reg(tmp1, src1, src2); 12389 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12390 %} 12391 %} 12392 12393 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12394 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12395 // node right before the conditional move using it. 12396 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12397 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12398 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12399 // conditional move was supposed to be spilled. 12400 match(Set crx (CmpD src1 src2)); 12401 // False predicate, shall not be matched. 12402 predicate(false); 12403 12404 format %{ "cmpFUrd $crx, $src1, $src2" %} 12405 size(4); 12406 ins_encode %{ 12407 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12408 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12409 %} 12410 ins_pipe(pipe_class_default); 12411 %} 12412 12413 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12414 match(Set crx (CmpD src1 src2)); 12415 ins_cost(DEFAULT_COST+BRANCH_COST); 12416 12417 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12418 postalloc_expand %{ 12419 // 12420 // replaces 12421 // 12422 // region src1 src2 12423 // \ | | 12424 // crx=cmpD_reg_reg 12425 // 12426 // with 12427 // 12428 // region src1 src2 12429 // \ | | 12430 // crx=cmpDUnordered_reg_reg 12431 // | 12432 // ^ region 12433 // | \ 12434 // crx=cmov_bns_less 12435 // 12436 12437 // create new nodes 12438 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12439 MachNode *m2 = new cmov_bns_lessNode(); 12440 12441 // inputs for new nodes 12442 m1->add_req(n_region, n_src1, n_src2); 12443 m2->add_req(n_region); 12444 m2->add_prec(m1); 12445 12446 // operands for new nodes 12447 m1->_opnds[0] = op_crx; 12448 m1->_opnds[1] = op_src1; 12449 m1->_opnds[2] = op_src2; 12450 m2->_opnds[0] = op_crx; 12451 12452 // registers for new nodes 12453 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12454 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12455 12456 // Insert new nodes. 12457 nodes->push(m1); 12458 nodes->push(m2); 12459 %} 12460 %} 12461 12462 // Compare double, generate -1,0,1 12463 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12464 match(Set dst (CmpD3 src1 src2)); 12465 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12466 12467 expand %{ 12468 flagsReg tmp1; 12469 cmpDUnordered_reg_reg(tmp1, src1, src2); 12470 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12471 %} 12472 %} 12473 12474 // Compare char 12475 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12476 match(Set dst (Digit src1)); 12477 effect(TEMP src2, TEMP crx); 12478 ins_cost(3 * DEFAULT_COST); 12479 12480 format %{ "LI $src2, 0x3930\n\t" 12481 "CMPRB $crx, 0, $src1, $src2\n\t" 12482 "SETB $dst, $crx" %} 12483 size(12); 12484 ins_encode %{ 12485 // 0x30: 0, 0x39: 9 12486 __ li($src2$$Register, 0x3930); 12487 // compare src1 with ranges 0x30 to 0x39 12488 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12489 __ setb($dst$$Register, $crx$$CondRegister); 12490 %} 12491 ins_pipe(pipe_class_default); 12492 %} 12493 12494 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12495 match(Set dst (LowerCase src1)); 12496 effect(TEMP src2, TEMP crx); 12497 ins_cost(12 * DEFAULT_COST); 12498 12499 format %{ "LI $src2, 0x7A61\n\t" 12500 "CMPRB $crx, 0, $src1, $src2\n\t" 12501 "BGT $crx, done\n\t" 12502 "LIS $src2, (signed short)0xF6DF\n\t" 12503 "ORI $src2, $src2, 0xFFF8\n\t" 12504 "CMPRB $crx, 1, $src1, $src2\n\t" 12505 "BGT $crx, done\n\t" 12506 "LIS $src2, (signed short)0xAAB5\n\t" 12507 "ORI $src2, $src2, 0xBABA\n\t" 12508 "INSRDI $src2, $src2, 32, 0\n\t" 12509 "CMPEQB $crx, 1, $src1, $src2\n" 12510 "done:\n\t" 12511 "SETB $dst, $crx" %} 12512 12513 size(48); 12514 ins_encode %{ 12515 Label done; 12516 // 0x61: a, 0x7A: z 12517 __ li($src2$$Register, 0x7A61); 12518 // compare src1 with ranges 0x61 to 0x7A 12519 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12520 __ bgt($crx$$CondRegister, done); 12521 12522 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case 12523 __ lis($src2$$Register, (signed short)0xF6DF); 12524 __ ori($src2$$Register, $src2$$Register, 0xFFF8); 12525 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF 12526 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12527 __ bgt($crx$$CondRegister, done); 12528 12529 // 0xAA: feminine ordinal indicator 12530 // 0xB5: micro sign 12531 // 0xBA: masculine ordinal indicator 12532 __ lis($src2$$Register, (signed short)0xAAB5); 12533 __ ori($src2$$Register, $src2$$Register, 0xBABA); 12534 __ insrdi($src2$$Register, $src2$$Register, 32, 0); 12535 // compare src1 with 0xAA, 0xB5, and 0xBA 12536 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register); 12537 12538 __ bind(done); 12539 __ setb($dst$$Register, $crx$$CondRegister); 12540 %} 12541 ins_pipe(pipe_class_default); 12542 %} 12543 12544 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12545 match(Set dst (UpperCase src1)); 12546 effect(TEMP src2, TEMP crx); 12547 ins_cost(7 * DEFAULT_COST); 12548 12549 format %{ "LI $src2, 0x5A41\n\t" 12550 "CMPRB $crx, 0, $src1, $src2\n\t" 12551 "BGT $crx, done\n\t" 12552 "LIS $src2, (signed short)0xD6C0\n\t" 12553 "ORI $src2, $src2, 0xDED8\n\t" 12554 "CMPRB $crx, 1, $src1, $src2\n" 12555 "done:\n\t" 12556 "SETB $dst, $crx" %} 12557 12558 size(28); 12559 ins_encode %{ 12560 Label done; 12561 // 0x41: A, 0x5A: Z 12562 __ li($src2$$Register, 0x5A41); 12563 // compare src1 with a range 0x41 to 0x5A 12564 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12565 __ bgt($crx$$CondRegister, done); 12566 12567 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case 12568 __ lis($src2$$Register, (signed short)0xD6C0); 12569 __ ori($src2$$Register, $src2$$Register, 0xDED8); 12570 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE 12571 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12572 12573 __ bind(done); 12574 __ setb($dst$$Register, $crx$$CondRegister); 12575 %} 12576 ins_pipe(pipe_class_default); 12577 %} 12578 12579 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12580 match(Set dst (Whitespace src1)); 12581 effect(TEMP src2, TEMP crx); 12582 ins_cost(4 * DEFAULT_COST); 12583 12584 format %{ "LI $src2, 0x0D09\n\t" 12585 "ADDIS $src2, 0x201C\n\t" 12586 "CMPRB $crx, 1, $src1, $src2\n\t" 12587 "SETB $dst, $crx" %} 12588 size(16); 12589 ins_encode %{ 12590 // 0x09 to 0x0D, 0x1C to 0x20 12591 __ li($src2$$Register, 0x0D09); 12592 __ addis($src2$$Register, $src2$$Register, 0x0201C); 12593 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20 12594 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12595 __ setb($dst$$Register, $crx$$CondRegister); 12596 %} 12597 ins_pipe(pipe_class_default); 12598 %} 12599 12600 //----------Branches--------------------------------------------------------- 12601 // Jump 12602 12603 // Direct Branch. 12604 instruct branch(label labl) %{ 12605 match(Goto); 12606 effect(USE labl); 12607 ins_cost(BRANCH_COST); 12608 12609 format %{ "B $labl" %} 12610 size(4); 12611 ins_encode %{ 12612 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12613 Label d; // dummy 12614 __ bind(d); 12615 Label* p = $labl$$label; 12616 // `p' is `NULL' when this encoding class is used only to 12617 // determine the size of the encoded instruction. 12618 Label& l = (NULL == p)? d : *(p); 12619 __ b(l); 12620 %} 12621 ins_pipe(pipe_class_default); 12622 %} 12623 12624 // Conditional Near Branch 12625 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12626 // Same match rule as `branchConFar'. 12627 match(If cmp crx); 12628 effect(USE lbl); 12629 ins_cost(BRANCH_COST); 12630 12631 // If set to 1 this indicates that the current instruction is a 12632 // short variant of a long branch. This avoids using this 12633 // instruction in first-pass matching. It will then only be used in 12634 // the `Shorten_branches' pass. 12635 ins_short_branch(1); 12636 12637 format %{ "B$cmp $crx, $lbl" %} 12638 size(4); 12639 ins_encode( enc_bc(crx, cmp, lbl) ); 12640 ins_pipe(pipe_class_default); 12641 %} 12642 12643 // This is for cases when the ppc64 `bc' instruction does not 12644 // reach far enough. So we emit a far branch here, which is more 12645 // expensive. 12646 // 12647 // Conditional Far Branch 12648 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12649 // Same match rule as `branchCon'. 12650 match(If cmp crx); 12651 effect(USE crx, USE lbl); 12652 predicate(!false /* TODO: PPC port HB_Schedule*/); 12653 // Higher cost than `branchCon'. 12654 ins_cost(5*BRANCH_COST); 12655 12656 // This is not a short variant of a branch, but the long variant. 12657 ins_short_branch(0); 12658 12659 format %{ "B_FAR$cmp $crx, $lbl" %} 12660 size(8); 12661 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12662 ins_pipe(pipe_class_default); 12663 %} 12664 12665 // Conditional Branch used with Power6 scheduler (can be far or short). 12666 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12667 // Same match rule as `branchCon'. 12668 match(If cmp crx); 12669 effect(USE crx, USE lbl); 12670 predicate(false /* TODO: PPC port HB_Schedule*/); 12671 // Higher cost than `branchCon'. 12672 ins_cost(5*BRANCH_COST); 12673 12674 // Actually size doesn't depend on alignment but on shortening. 12675 ins_variable_size_depending_on_alignment(true); 12676 // long variant. 12677 ins_short_branch(0); 12678 12679 format %{ "B_FAR$cmp $crx, $lbl" %} 12680 size(8); // worst case 12681 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12682 ins_pipe(pipe_class_default); 12683 %} 12684 12685 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12686 match(CountedLoopEnd cmp crx); 12687 effect(USE labl); 12688 ins_cost(BRANCH_COST); 12689 12690 // short variant. 12691 ins_short_branch(1); 12692 12693 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12694 size(4); 12695 ins_encode( enc_bc(crx, cmp, labl) ); 12696 ins_pipe(pipe_class_default); 12697 %} 12698 12699 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12700 match(CountedLoopEnd cmp crx); 12701 effect(USE labl); 12702 predicate(!false /* TODO: PPC port HB_Schedule */); 12703 ins_cost(BRANCH_COST); 12704 12705 // Long variant. 12706 ins_short_branch(0); 12707 12708 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12709 size(8); 12710 ins_encode( enc_bc_far(crx, cmp, labl) ); 12711 ins_pipe(pipe_class_default); 12712 %} 12713 12714 // Conditional Branch used with Power6 scheduler (can be far or short). 12715 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12716 match(CountedLoopEnd cmp crx); 12717 effect(USE labl); 12718 predicate(false /* TODO: PPC port HB_Schedule */); 12719 // Higher cost than `branchCon'. 12720 ins_cost(5*BRANCH_COST); 12721 12722 // Actually size doesn't depend on alignment but on shortening. 12723 ins_variable_size_depending_on_alignment(true); 12724 // Long variant. 12725 ins_short_branch(0); 12726 12727 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12728 size(8); // worst case 12729 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12730 ins_pipe(pipe_class_default); 12731 %} 12732 12733 // ============================================================================ 12734 // Java runtime operations, intrinsics and other complex operations. 12735 12736 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12737 // array for an instance of the superklass. Set a hidden internal cache on a 12738 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12739 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12740 // 12741 // GL TODO: Improve this. 12742 // - result should not be a TEMP 12743 // - Add match rule as on sparc avoiding additional Cmp. 12744 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12745 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12746 match(Set result (PartialSubtypeCheck subklass superklass)); 12747 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12748 ins_cost(DEFAULT_COST*10); 12749 12750 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12751 ins_encode %{ 12752 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12753 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12754 $tmp_klass$$Register, NULL, $result$$Register); 12755 %} 12756 ins_pipe(pipe_class_default); 12757 %} 12758 12759 // inlined locking and unlocking 12760 12761 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12762 match(Set crx (FastLock oop box)); 12763 effect(TEMP tmp1, TEMP tmp2); 12764 predicate(!Compile::current()->use_rtm()); 12765 12766 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12767 ins_encode %{ 12768 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12769 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12770 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12771 UseBiasedLocking && !UseOptoBiasInlining); 12772 // If locking was successfull, crx should indicate 'EQ'. 12773 // The compiler generates a branch to the runtime call to 12774 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12775 %} 12776 ins_pipe(pipe_class_compare); 12777 %} 12778 12779 // Separate version for TM. Use bound register for box to enable USE_KILL. 12780 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12781 match(Set crx (FastLock oop box)); 12782 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12783 predicate(Compile::current()->use_rtm()); 12784 12785 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12786 ins_encode %{ 12787 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12788 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12789 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12790 /*Biased Locking*/ false, 12791 _rtm_counters, _stack_rtm_counters, 12792 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12793 /*TM*/ true, ra_->C->profile_rtm()); 12794 // If locking was successfull, crx should indicate 'EQ'. 12795 // The compiler generates a branch to the runtime call to 12796 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12797 %} 12798 ins_pipe(pipe_class_compare); 12799 %} 12800 12801 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12802 match(Set crx (FastUnlock oop box)); 12803 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12804 predicate(!Compile::current()->use_rtm()); 12805 12806 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12807 ins_encode %{ 12808 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12809 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12810 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12811 UseBiasedLocking && !UseOptoBiasInlining, 12812 false); 12813 // If unlocking was successfull, crx should indicate 'EQ'. 12814 // The compiler generates a branch to the runtime call to 12815 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12816 %} 12817 ins_pipe(pipe_class_compare); 12818 %} 12819 12820 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12821 match(Set crx (FastUnlock oop box)); 12822 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12823 predicate(Compile::current()->use_rtm()); 12824 12825 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12826 ins_encode %{ 12827 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12828 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12829 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12830 /*Biased Locking*/ false, /*TM*/ true); 12831 // If unlocking was successfull, crx should indicate 'EQ'. 12832 // The compiler generates a branch to the runtime call to 12833 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12834 %} 12835 ins_pipe(pipe_class_compare); 12836 %} 12837 12838 // Align address. 12839 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12840 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12841 12842 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12843 size(4); 12844 ins_encode %{ 12845 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12846 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12847 %} 12848 ins_pipe(pipe_class_default); 12849 %} 12850 12851 // Array size computation. 12852 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12853 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12854 12855 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12856 size(4); 12857 ins_encode %{ 12858 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12859 __ subf($dst$$Register, $start$$Register, $end$$Register); 12860 %} 12861 ins_pipe(pipe_class_default); 12862 %} 12863 12864 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12865 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12866 match(Set dummy (ClearArray cnt base)); 12867 effect(USE_KILL base, KILL ctr); 12868 ins_cost(2 * MEMORY_REF_COST); 12869 12870 format %{ "ClearArray $cnt, $base" %} 12871 ins_encode %{ 12872 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12873 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12874 %} 12875 ins_pipe(pipe_class_default); 12876 %} 12877 12878 // Clear-array with constant large array length. 12879 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12880 match(Set dummy (ClearArray cnt base)); 12881 effect(USE_KILL base, TEMP tmp, KILL ctr); 12882 ins_cost(3 * MEMORY_REF_COST); 12883 12884 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12885 ins_encode %{ 12886 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12887 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12888 %} 12889 ins_pipe(pipe_class_default); 12890 %} 12891 12892 // Clear-array with dynamic array length. 12893 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12894 match(Set dummy (ClearArray cnt base)); 12895 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12896 ins_cost(4 * MEMORY_REF_COST); 12897 12898 format %{ "ClearArray $cnt, $base" %} 12899 ins_encode %{ 12900 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12901 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12902 %} 12903 ins_pipe(pipe_class_default); 12904 %} 12905 12906 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12907 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12908 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12909 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12910 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12911 ins_cost(300); 12912 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12913 ins_encode %{ 12914 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12915 __ string_compare($str1$$Register, $str2$$Register, 12916 $cnt1$$Register, $cnt2$$Register, 12917 $tmp$$Register, 12918 $result$$Register, StrIntrinsicNode::LL); 12919 %} 12920 ins_pipe(pipe_class_default); 12921 %} 12922 12923 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12924 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12925 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12926 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12927 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12928 ins_cost(300); 12929 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12930 ins_encode %{ 12931 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12932 __ string_compare($str1$$Register, $str2$$Register, 12933 $cnt1$$Register, $cnt2$$Register, 12934 $tmp$$Register, 12935 $result$$Register, StrIntrinsicNode::UU); 12936 %} 12937 ins_pipe(pipe_class_default); 12938 %} 12939 12940 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12941 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12942 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12943 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12944 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12945 ins_cost(300); 12946 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12947 ins_encode %{ 12948 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12949 __ string_compare($str1$$Register, $str2$$Register, 12950 $cnt1$$Register, $cnt2$$Register, 12951 $tmp$$Register, 12952 $result$$Register, StrIntrinsicNode::LU); 12953 %} 12954 ins_pipe(pipe_class_default); 12955 %} 12956 12957 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12958 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12959 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12960 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12961 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12962 ins_cost(300); 12963 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12964 ins_encode %{ 12965 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12966 __ string_compare($str2$$Register, $str1$$Register, 12967 $cnt2$$Register, $cnt1$$Register, 12968 $tmp$$Register, 12969 $result$$Register, StrIntrinsicNode::UL); 12970 %} 12971 ins_pipe(pipe_class_default); 12972 %} 12973 12974 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12975 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12976 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12977 match(Set result (StrEquals (Binary str1 str2) cnt)); 12978 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12979 ins_cost(300); 12980 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12981 ins_encode %{ 12982 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12983 __ array_equals(false, $str1$$Register, $str2$$Register, 12984 $cnt$$Register, $tmp$$Register, 12985 $result$$Register, true /* byte */); 12986 %} 12987 ins_pipe(pipe_class_default); 12988 %} 12989 12990 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12991 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12992 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12993 match(Set result (StrEquals (Binary str1 str2) cnt)); 12994 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12995 ins_cost(300); 12996 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12997 ins_encode %{ 12998 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12999 __ array_equals(false, $str1$$Register, $str2$$Register, 13000 $cnt$$Register, $tmp$$Register, 13001 $result$$Register, false /* byte */); 13002 %} 13003 ins_pipe(pipe_class_default); 13004 %} 13005 13006 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 13007 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 13008 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 13009 match(Set result (AryEq ary1 ary2)); 13010 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 13011 ins_cost(300); 13012 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 13013 ins_encode %{ 13014 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13015 __ array_equals(true, $ary1$$Register, $ary2$$Register, 13016 $tmp1$$Register, $tmp2$$Register, 13017 $result$$Register, true /* byte */); 13018 %} 13019 ins_pipe(pipe_class_default); 13020 %} 13021 13022 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 13023 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 13024 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 13025 match(Set result (AryEq ary1 ary2)); 13026 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 13027 ins_cost(300); 13028 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 13029 ins_encode %{ 13030 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13031 __ array_equals(true, $ary1$$Register, $ary2$$Register, 13032 $tmp1$$Register, $tmp2$$Register, 13033 $result$$Register, false /* byte */); 13034 %} 13035 ins_pipe(pipe_class_default); 13036 %} 13037 13038 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13039 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13040 iRegIdst tmp1, iRegIdst tmp2, 13041 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13042 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13043 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13044 // Required for EA: check if it is still a type_array. 13045 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13046 ins_cost(150); 13047 13048 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13049 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13050 13051 ins_encode %{ 13052 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13053 immPOper *needleOper = (immPOper *)$needleImm; 13054 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13055 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13056 jchar chr; 13057 #ifdef VM_LITTLE_ENDIAN 13058 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 13059 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 13060 #else 13061 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 13062 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 13063 #endif 13064 __ string_indexof_char($result$$Register, 13065 $haystack$$Register, $haycnt$$Register, 13066 R0, chr, 13067 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13068 %} 13069 ins_pipe(pipe_class_compare); 13070 %} 13071 13072 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13073 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13074 iRegIdst tmp1, iRegIdst tmp2, 13075 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13076 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13077 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13078 // Required for EA: check if it is still a type_array. 13079 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13080 ins_cost(150); 13081 13082 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13083 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13084 13085 ins_encode %{ 13086 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13087 immPOper *needleOper = (immPOper *)$needleImm; 13088 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13089 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13090 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13091 __ string_indexof_char($result$$Register, 13092 $haystack$$Register, $haycnt$$Register, 13093 R0, chr, 13094 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13095 %} 13096 ins_pipe(pipe_class_compare); 13097 %} 13098 13099 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13100 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13101 iRegIdst tmp1, iRegIdst tmp2, 13102 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13103 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13104 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13105 // Required for EA: check if it is still a type_array. 13106 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13107 ins_cost(150); 13108 13109 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13110 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13111 13112 ins_encode %{ 13113 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13114 immPOper *needleOper = (immPOper *)$needleImm; 13115 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13116 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13117 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13118 __ string_indexof_char($result$$Register, 13119 $haystack$$Register, $haycnt$$Register, 13120 R0, chr, 13121 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13122 %} 13123 ins_pipe(pipe_class_compare); 13124 %} 13125 13126 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13127 rscratch2RegP needle, immI_1 needlecntImm, 13128 iRegIdst tmp1, iRegIdst tmp2, 13129 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13130 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13131 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13132 // Required for EA: check if it is still a type_array. 13133 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13134 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13135 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13136 ins_cost(180); 13137 13138 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13139 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13140 ins_encode %{ 13141 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13142 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13143 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13144 guarantee(needle_values, "sanity"); 13145 jchar chr; 13146 #ifdef VM_LITTLE_ENDIAN 13147 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 13148 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 13149 #else 13150 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 13151 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 13152 #endif 13153 __ string_indexof_char($result$$Register, 13154 $haystack$$Register, $haycnt$$Register, 13155 R0, chr, 13156 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13157 %} 13158 ins_pipe(pipe_class_compare); 13159 %} 13160 13161 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13162 rscratch2RegP needle, immI_1 needlecntImm, 13163 iRegIdst tmp1, iRegIdst tmp2, 13164 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13165 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13166 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13167 // Required for EA: check if it is still a type_array. 13168 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13169 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13170 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13171 ins_cost(180); 13172 13173 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13174 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13175 ins_encode %{ 13176 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13177 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13178 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13179 guarantee(needle_values, "sanity"); 13180 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13181 __ string_indexof_char($result$$Register, 13182 $haystack$$Register, $haycnt$$Register, 13183 R0, chr, 13184 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13185 %} 13186 ins_pipe(pipe_class_compare); 13187 %} 13188 13189 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13190 rscratch2RegP needle, immI_1 needlecntImm, 13191 iRegIdst tmp1, iRegIdst tmp2, 13192 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13193 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13194 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13195 // Required for EA: check if it is still a type_array. 13196 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13197 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13198 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13199 ins_cost(180); 13200 13201 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13202 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13203 ins_encode %{ 13204 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13205 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13206 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13207 guarantee(needle_values, "sanity"); 13208 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13209 __ string_indexof_char($result$$Register, 13210 $haystack$$Register, $haycnt$$Register, 13211 R0, chr, 13212 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13213 %} 13214 ins_pipe(pipe_class_compare); 13215 %} 13216 13217 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13218 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 13219 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13220 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 13221 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13222 ins_cost(180); 13223 13224 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 13225 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13226 ins_encode %{ 13227 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13228 __ string_indexof_char($result$$Register, 13229 $haystack$$Register, $haycnt$$Register, 13230 $ch$$Register, 0 /* this is not used if the character is already in a register */, 13231 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13232 %} 13233 ins_pipe(pipe_class_compare); 13234 %} 13235 13236 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13237 iRegPsrc needle, uimmI15 needlecntImm, 13238 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13239 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13240 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13241 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13242 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13243 // Required for EA: check if it is still a type_array. 13244 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13245 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13246 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13247 ins_cost(250); 13248 13249 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13250 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13251 ins_encode %{ 13252 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13253 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13254 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13255 13256 __ string_indexof($result$$Register, 13257 $haystack$$Register, $haycnt$$Register, 13258 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13259 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13260 %} 13261 ins_pipe(pipe_class_compare); 13262 %} 13263 13264 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13265 iRegPsrc needle, uimmI15 needlecntImm, 13266 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13267 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13268 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13269 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13270 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13271 // Required for EA: check if it is still a type_array. 13272 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13273 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13274 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13275 ins_cost(250); 13276 13277 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13278 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13279 ins_encode %{ 13280 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13281 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13282 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13283 13284 __ string_indexof($result$$Register, 13285 $haystack$$Register, $haycnt$$Register, 13286 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13287 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13288 %} 13289 ins_pipe(pipe_class_compare); 13290 %} 13291 13292 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13293 iRegPsrc needle, uimmI15 needlecntImm, 13294 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13295 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13296 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13297 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13298 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13299 // Required for EA: check if it is still a type_array. 13300 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13301 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13302 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13303 ins_cost(250); 13304 13305 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13306 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13307 ins_encode %{ 13308 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13309 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13310 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13311 13312 __ string_indexof($result$$Register, 13313 $haystack$$Register, $haycnt$$Register, 13314 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13315 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13316 %} 13317 ins_pipe(pipe_class_compare); 13318 %} 13319 13320 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13321 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13322 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13323 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13324 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13325 TEMP_DEF result, 13326 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13327 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13328 ins_cost(300); 13329 13330 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13331 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13332 ins_encode %{ 13333 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13334 __ string_indexof($result$$Register, 13335 $haystack$$Register, $haycnt$$Register, 13336 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13337 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13338 %} 13339 ins_pipe(pipe_class_compare); 13340 %} 13341 13342 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13343 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13344 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13345 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13346 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13347 TEMP_DEF result, 13348 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13349 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13350 ins_cost(300); 13351 13352 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13353 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13354 ins_encode %{ 13355 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13356 __ string_indexof($result$$Register, 13357 $haystack$$Register, $haycnt$$Register, 13358 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13359 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13360 %} 13361 ins_pipe(pipe_class_compare); 13362 %} 13363 13364 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13365 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13366 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13367 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13368 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13369 TEMP_DEF result, 13370 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13371 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13372 ins_cost(300); 13373 13374 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13375 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13376 ins_encode %{ 13377 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13378 __ string_indexof($result$$Register, 13379 $haystack$$Register, $haycnt$$Register, 13380 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13381 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13382 %} 13383 ins_pipe(pipe_class_compare); 13384 %} 13385 13386 // char[] to byte[] compression 13387 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13388 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13389 match(Set result (StrCompressedCopy src (Binary dst len))); 13390 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13391 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13392 ins_cost(300); 13393 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13394 ins_encode %{ 13395 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13396 Label Lskip, Ldone; 13397 __ li($result$$Register, 0); 13398 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13399 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13400 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13401 __ beq(CCR0, Lskip); 13402 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13403 __ bind(Lskip); 13404 __ mr($result$$Register, $len$$Register); 13405 __ bind(Ldone); 13406 %} 13407 ins_pipe(pipe_class_default); 13408 %} 13409 13410 // byte[] to char[] inflation 13411 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13412 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13413 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13414 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13415 ins_cost(300); 13416 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13417 ins_encode %{ 13418 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13419 Label Ldone; 13420 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13421 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13422 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13423 __ beq(CCR0, Ldone); 13424 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13425 __ bind(Ldone); 13426 %} 13427 ins_pipe(pipe_class_default); 13428 %} 13429 13430 // StringCoding.java intrinsics 13431 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13432 regCTR ctr, flagsRegCR0 cr0) 13433 %{ 13434 match(Set result (HasNegatives ary1 len)); 13435 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13436 ins_cost(300); 13437 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13438 ins_encode %{ 13439 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13440 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13441 $tmp1$$Register, $tmp2$$Register); 13442 %} 13443 ins_pipe(pipe_class_default); 13444 %} 13445 13446 // encode char[] to byte[] in ISO_8859_1 13447 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13448 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13449 match(Set result (EncodeISOArray src (Binary dst len))); 13450 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13451 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13452 ins_cost(300); 13453 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13454 ins_encode %{ 13455 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13456 Label Lslow, Lfailure1, Lfailure2, Ldone; 13457 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13458 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13459 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13460 __ beq(CCR0, Ldone); 13461 __ bind(Lslow); 13462 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13463 __ li($result$$Register, 0); 13464 __ b(Ldone); 13465 13466 __ bind(Lfailure1); 13467 __ mr($result$$Register, $len$$Register); 13468 __ mfctr($tmp1$$Register); 13469 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13470 __ beq(CCR0, Ldone); 13471 __ b(Lslow); 13472 13473 __ bind(Lfailure2); 13474 __ mfctr($result$$Register); // Remaining characters. 13475 13476 __ bind(Ldone); 13477 __ subf($result$$Register, $result$$Register, $len$$Register); 13478 %} 13479 ins_pipe(pipe_class_default); 13480 %} 13481 13482 13483 //---------- Min/Max Instructions --------------------------------------------- 13484 13485 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13486 match(Set dst (MinI src1 src2)); 13487 ins_cost(DEFAULT_COST*6); 13488 13489 expand %{ 13490 iRegLdst src1s; 13491 iRegLdst src2s; 13492 iRegLdst diff; 13493 iRegLdst sm; 13494 iRegLdst doz; // difference or zero 13495 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13496 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13497 subL_reg_reg(diff, src2s, src1s); 13498 // Need to consider >=33 bit result, therefore we need signmaskL. 13499 signmask64L_regL(sm, diff); 13500 andL_reg_reg(doz, diff, sm); // <=0 13501 addI_regL_regL(dst, doz, src1s); 13502 %} 13503 %} 13504 13505 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13506 match(Set dst (MinI src1 src2)); 13507 effect(KILL cr0); 13508 predicate(VM_Version::has_isel()); 13509 ins_cost(DEFAULT_COST*2); 13510 13511 ins_encode %{ 13512 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13513 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13514 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13515 %} 13516 ins_pipe(pipe_class_default); 13517 %} 13518 13519 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13520 match(Set dst (MaxI src1 src2)); 13521 ins_cost(DEFAULT_COST*6); 13522 13523 expand %{ 13524 iRegLdst src1s; 13525 iRegLdst src2s; 13526 iRegLdst diff; 13527 iRegLdst sm; 13528 iRegLdst doz; // difference or zero 13529 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13530 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13531 subL_reg_reg(diff, src2s, src1s); 13532 // Need to consider >=33 bit result, therefore we need signmaskL. 13533 signmask64L_regL(sm, diff); 13534 andcL_reg_reg(doz, diff, sm); // >=0 13535 addI_regL_regL(dst, doz, src1s); 13536 %} 13537 %} 13538 13539 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13540 match(Set dst (MaxI src1 src2)); 13541 effect(KILL cr0); 13542 predicate(VM_Version::has_isel()); 13543 ins_cost(DEFAULT_COST*2); 13544 13545 ins_encode %{ 13546 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13547 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13548 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13549 %} 13550 ins_pipe(pipe_class_default); 13551 %} 13552 13553 //---------- Population Count Instructions ------------------------------------ 13554 13555 // Popcnt for Power7. 13556 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13557 match(Set dst (PopCountI src)); 13558 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13559 ins_cost(DEFAULT_COST); 13560 13561 format %{ "POPCNTW $dst, $src" %} 13562 size(4); 13563 ins_encode %{ 13564 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13565 __ popcntw($dst$$Register, $src$$Register); 13566 %} 13567 ins_pipe(pipe_class_default); 13568 %} 13569 13570 // Popcnt for Power7. 13571 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13572 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13573 match(Set dst (PopCountL src)); 13574 ins_cost(DEFAULT_COST); 13575 13576 format %{ "POPCNTD $dst, $src" %} 13577 size(4); 13578 ins_encode %{ 13579 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13580 __ popcntd($dst$$Register, $src$$Register); 13581 %} 13582 ins_pipe(pipe_class_default); 13583 %} 13584 13585 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13586 match(Set dst (CountLeadingZerosI src)); 13587 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13588 ins_cost(DEFAULT_COST); 13589 13590 format %{ "CNTLZW $dst, $src" %} 13591 size(4); 13592 ins_encode %{ 13593 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13594 __ cntlzw($dst$$Register, $src$$Register); 13595 %} 13596 ins_pipe(pipe_class_default); 13597 %} 13598 13599 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13600 match(Set dst (CountLeadingZerosL src)); 13601 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13602 ins_cost(DEFAULT_COST); 13603 13604 format %{ "CNTLZD $dst, $src" %} 13605 size(4); 13606 ins_encode %{ 13607 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13608 __ cntlzd($dst$$Register, $src$$Register); 13609 %} 13610 ins_pipe(pipe_class_default); 13611 %} 13612 13613 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13614 // no match-rule, false predicate 13615 effect(DEF dst, USE src); 13616 predicate(false); 13617 13618 format %{ "CNTLZD $dst, $src" %} 13619 size(4); 13620 ins_encode %{ 13621 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13622 __ cntlzd($dst$$Register, $src$$Register); 13623 %} 13624 ins_pipe(pipe_class_default); 13625 %} 13626 13627 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13628 match(Set dst (CountTrailingZerosI src)); 13629 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13630 ins_cost(DEFAULT_COST); 13631 13632 expand %{ 13633 immI16 imm1 %{ (int)-1 %} 13634 immI16 imm2 %{ (int)32 %} 13635 immI_minus1 m1 %{ -1 %} 13636 iRegIdst tmpI1; 13637 iRegIdst tmpI2; 13638 iRegIdst tmpI3; 13639 addI_reg_imm16(tmpI1, src, imm1); 13640 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13641 countLeadingZerosI(tmpI3, tmpI2); 13642 subI_imm16_reg(dst, imm2, tmpI3); 13643 %} 13644 %} 13645 13646 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{ 13647 match(Set dst (CountTrailingZerosI src)); 13648 predicate(UseCountTrailingZerosInstructionsPPC64); 13649 ins_cost(DEFAULT_COST); 13650 13651 format %{ "CNTTZW $dst, $src" %} 13652 size(4); 13653 ins_encode %{ 13654 __ cnttzw($dst$$Register, $src$$Register); 13655 %} 13656 ins_pipe(pipe_class_default); 13657 %} 13658 13659 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13660 match(Set dst (CountTrailingZerosL src)); 13661 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13662 ins_cost(DEFAULT_COST); 13663 13664 expand %{ 13665 immL16 imm1 %{ (long)-1 %} 13666 immI16 imm2 %{ (int)64 %} 13667 iRegLdst tmpL1; 13668 iRegLdst tmpL2; 13669 iRegIdst tmpL3; 13670 addL_reg_imm16(tmpL1, src, imm1); 13671 andcL_reg_reg(tmpL2, tmpL1, src); 13672 countLeadingZerosL(tmpL3, tmpL2); 13673 subI_imm16_reg(dst, imm2, tmpL3); 13674 %} 13675 %} 13676 13677 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{ 13678 match(Set dst (CountTrailingZerosL src)); 13679 predicate(UseCountTrailingZerosInstructionsPPC64); 13680 ins_cost(DEFAULT_COST); 13681 13682 format %{ "CNTTZD $dst, $src" %} 13683 size(4); 13684 ins_encode %{ 13685 __ cnttzd($dst$$Register, $src$$Register); 13686 %} 13687 ins_pipe(pipe_class_default); 13688 %} 13689 13690 // Expand nodes for byte_reverse_int. 13691 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13692 effect(DEF dst, USE src, USE pos, USE shift); 13693 predicate(false); 13694 13695 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13696 size(4); 13697 ins_encode %{ 13698 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13699 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13700 %} 13701 ins_pipe(pipe_class_default); 13702 %} 13703 13704 // As insrwi_a, but with USE_DEF. 13705 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13706 effect(USE_DEF dst, USE src, USE pos, USE shift); 13707 predicate(false); 13708 13709 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13710 size(4); 13711 ins_encode %{ 13712 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13713 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13714 %} 13715 ins_pipe(pipe_class_default); 13716 %} 13717 13718 // Just slightly faster than java implementation. 13719 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13720 match(Set dst (ReverseBytesI src)); 13721 ins_cost(7*DEFAULT_COST); 13722 13723 expand %{ 13724 immI16 imm24 %{ (int) 24 %} 13725 immI16 imm16 %{ (int) 16 %} 13726 immI16 imm8 %{ (int) 8 %} 13727 immI16 imm4 %{ (int) 4 %} 13728 immI16 imm0 %{ (int) 0 %} 13729 iRegLdst tmpI1; 13730 iRegLdst tmpI2; 13731 iRegLdst tmpI3; 13732 13733 urShiftI_reg_imm(tmpI1, src, imm24); 13734 insrwi_a(dst, tmpI1, imm24, imm8); 13735 urShiftI_reg_imm(tmpI2, src, imm16); 13736 insrwi(dst, tmpI2, imm8, imm16); 13737 urShiftI_reg_imm(tmpI3, src, imm8); 13738 insrwi(dst, tmpI3, imm8, imm8); 13739 insrwi(dst, src, imm0, imm8); 13740 %} 13741 %} 13742 13743 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{ 13744 match(Set dst (ReverseBytesI src)); 13745 predicate(UseVectorByteReverseInstructionsPPC64); 13746 effect(TEMP tmpV); 13747 ins_cost(DEFAULT_COST*3); 13748 size(12); 13749 format %{ "MTVSRWZ $tmpV, $src\n" 13750 "\tXXBRW $tmpV, $tmpV\n" 13751 "\tMFVSRWZ $dst, $tmpV" %} 13752 13753 ins_encode %{ 13754 __ mtvsrwz($tmpV$$VectorSRegister, $src$$Register); 13755 __ xxbrw($tmpV$$VectorSRegister, $tmpV$$VectorSRegister); 13756 __ mfvsrwz($dst$$Register, $tmpV$$VectorSRegister); 13757 %} 13758 ins_pipe(pipe_class_default); 13759 %} 13760 13761 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13762 match(Set dst (ReverseBytesL src)); 13763 ins_cost(15*DEFAULT_COST); 13764 13765 expand %{ 13766 immI16 imm56 %{ (int) 56 %} 13767 immI16 imm48 %{ (int) 48 %} 13768 immI16 imm40 %{ (int) 40 %} 13769 immI16 imm32 %{ (int) 32 %} 13770 immI16 imm24 %{ (int) 24 %} 13771 immI16 imm16 %{ (int) 16 %} 13772 immI16 imm8 %{ (int) 8 %} 13773 immI16 imm0 %{ (int) 0 %} 13774 iRegLdst tmpL1; 13775 iRegLdst tmpL2; 13776 iRegLdst tmpL3; 13777 iRegLdst tmpL4; 13778 iRegLdst tmpL5; 13779 iRegLdst tmpL6; 13780 13781 // src : |a|b|c|d|e|f|g|h| 13782 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13783 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13784 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13785 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13786 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13787 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13788 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13789 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13790 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13791 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13792 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13793 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13794 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13795 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13796 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13797 %} 13798 %} 13799 13800 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{ 13801 match(Set dst (ReverseBytesL src)); 13802 predicate(UseVectorByteReverseInstructionsPPC64); 13803 effect(TEMP tmpV); 13804 ins_cost(DEFAULT_COST*3); 13805 size(12); 13806 format %{ "MTVSRD $tmpV, $src\n" 13807 "\tXXBRD $tmpV, $tmpV\n" 13808 "\tMFVSRD $dst, $tmpV" %} 13809 13810 ins_encode %{ 13811 __ mtvsrd($tmpV$$VectorSRegister, $src$$Register); 13812 __ xxbrd($tmpV$$VectorSRegister, $tmpV$$VectorSRegister); 13813 __ mfvsrd($dst$$Register, $tmpV$$VectorSRegister); 13814 %} 13815 ins_pipe(pipe_class_default); 13816 %} 13817 13818 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13819 match(Set dst (ReverseBytesUS src)); 13820 ins_cost(2*DEFAULT_COST); 13821 13822 expand %{ 13823 immI16 imm16 %{ (int) 16 %} 13824 immI16 imm8 %{ (int) 8 %} 13825 13826 urShiftI_reg_imm(dst, src, imm8); 13827 insrwi(dst, src, imm16, imm8); 13828 %} 13829 %} 13830 13831 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13832 match(Set dst (ReverseBytesS src)); 13833 ins_cost(3*DEFAULT_COST); 13834 13835 expand %{ 13836 immI16 imm16 %{ (int) 16 %} 13837 immI16 imm8 %{ (int) 8 %} 13838 iRegLdst tmpI1; 13839 13840 urShiftI_reg_imm(tmpI1, src, imm8); 13841 insrwi(tmpI1, src, imm16, imm8); 13842 extsh(dst, tmpI1); 13843 %} 13844 %} 13845 13846 // Load Integer reversed byte order 13847 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13848 match(Set dst (ReverseBytesI (LoadI mem))); 13849 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13850 ins_cost(MEMORY_REF_COST); 13851 13852 size(4); 13853 ins_encode %{ 13854 __ lwbrx($dst$$Register, $mem$$Register); 13855 %} 13856 ins_pipe(pipe_class_default); 13857 %} 13858 13859 instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{ 13860 match(Set dst (ReverseBytesI (LoadI mem))); 13861 ins_cost(2 * MEMORY_REF_COST); 13862 13863 size(12); 13864 ins_encode %{ 13865 __ lwbrx($dst$$Register, $mem$$Register); 13866 __ twi_0($dst$$Register); 13867 __ isync(); 13868 %} 13869 ins_pipe(pipe_class_default); 13870 %} 13871 13872 // Load Long - aligned and reversed 13873 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13874 match(Set dst (ReverseBytesL (LoadL mem))); 13875 predicate(VM_Version::has_ldbrx() && (n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)))); 13876 ins_cost(MEMORY_REF_COST); 13877 13878 size(4); 13879 ins_encode %{ 13880 __ ldbrx($dst$$Register, $mem$$Register); 13881 %} 13882 ins_pipe(pipe_class_default); 13883 %} 13884 13885 instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{ 13886 match(Set dst (ReverseBytesL (LoadL mem))); 13887 predicate(VM_Version::has_ldbrx()); 13888 ins_cost(2 * MEMORY_REF_COST); 13889 13890 size(12); 13891 ins_encode %{ 13892 __ ldbrx($dst$$Register, $mem$$Register); 13893 __ twi_0($dst$$Register); 13894 __ isync(); 13895 %} 13896 ins_pipe(pipe_class_default); 13897 %} 13898 13899 // Load unsigned short / char reversed byte order 13900 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13901 match(Set dst (ReverseBytesUS (LoadUS mem))); 13902 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13903 ins_cost(MEMORY_REF_COST); 13904 13905 size(4); 13906 ins_encode %{ 13907 __ lhbrx($dst$$Register, $mem$$Register); 13908 %} 13909 ins_pipe(pipe_class_default); 13910 %} 13911 13912 instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{ 13913 match(Set dst (ReverseBytesUS (LoadUS mem))); 13914 ins_cost(2 * MEMORY_REF_COST); 13915 13916 size(12); 13917 ins_encode %{ 13918 __ lhbrx($dst$$Register, $mem$$Register); 13919 __ twi_0($dst$$Register); 13920 __ isync(); 13921 %} 13922 ins_pipe(pipe_class_default); 13923 %} 13924 13925 // Load short reversed byte order 13926 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13927 match(Set dst (ReverseBytesS (LoadS mem))); 13928 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13929 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13930 13931 size(8); 13932 ins_encode %{ 13933 __ lhbrx($dst$$Register, $mem$$Register); 13934 __ extsh($dst$$Register, $dst$$Register); 13935 %} 13936 ins_pipe(pipe_class_default); 13937 %} 13938 13939 instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{ 13940 match(Set dst (ReverseBytesS (LoadS mem))); 13941 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13942 13943 size(16); 13944 ins_encode %{ 13945 __ lhbrx($dst$$Register, $mem$$Register); 13946 __ twi_0($dst$$Register); 13947 __ extsh($dst$$Register, $dst$$Register); 13948 __ isync(); 13949 %} 13950 ins_pipe(pipe_class_default); 13951 %} 13952 13953 // Store Integer reversed byte order 13954 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13955 match(Set mem (StoreI mem (ReverseBytesI src))); 13956 ins_cost(MEMORY_REF_COST); 13957 13958 size(4); 13959 ins_encode %{ 13960 __ stwbrx($src$$Register, $mem$$Register); 13961 %} 13962 ins_pipe(pipe_class_default); 13963 %} 13964 13965 // Store Long reversed byte order 13966 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13967 match(Set mem (StoreL mem (ReverseBytesL src))); 13968 predicate(VM_Version::has_stdbrx()); 13969 ins_cost(MEMORY_REF_COST); 13970 13971 size(4); 13972 ins_encode %{ 13973 __ stdbrx($src$$Register, $mem$$Register); 13974 %} 13975 ins_pipe(pipe_class_default); 13976 %} 13977 13978 // Store unsigned short / char reversed byte order 13979 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13980 match(Set mem (StoreC mem (ReverseBytesUS src))); 13981 ins_cost(MEMORY_REF_COST); 13982 13983 size(4); 13984 ins_encode %{ 13985 __ sthbrx($src$$Register, $mem$$Register); 13986 %} 13987 ins_pipe(pipe_class_default); 13988 %} 13989 13990 // Store short reversed byte order 13991 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13992 match(Set mem (StoreC mem (ReverseBytesS src))); 13993 ins_cost(MEMORY_REF_COST); 13994 13995 size(4); 13996 ins_encode %{ 13997 __ sthbrx($src$$Register, $mem$$Register); 13998 %} 13999 ins_pipe(pipe_class_default); 14000 %} 14001 14002 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 14003 effect(DEF temp1, USE src); 14004 14005 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %} 14006 size(4); 14007 ins_encode %{ 14008 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 14009 %} 14010 ins_pipe(pipe_class_default); 14011 %} 14012 14013 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 14014 effect(DEF dst, USE src, USE imm1); 14015 14016 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %} 14017 size(4); 14018 ins_encode %{ 14019 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 14020 %} 14021 ins_pipe(pipe_class_default); 14022 %} 14023 14024 instruct xscvdpspn_regF(vecX dst, regF src) %{ 14025 effect(DEF dst, USE src); 14026 14027 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %} 14028 size(4); 14029 ins_encode %{ 14030 __ xscvdpspn($dst$$VectorSRegister, $src$$FloatRegister->to_vsr()); 14031 %} 14032 ins_pipe(pipe_class_default); 14033 %} 14034 14035 //---------- Replicate Vector Instructions ------------------------------------ 14036 14037 // Insrdi does replicate if src == dst. 14038 instruct repl32(iRegLdst dst) %{ 14039 predicate(false); 14040 effect(USE_DEF dst); 14041 14042 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 14043 size(4); 14044 ins_encode %{ 14045 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 14046 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 14047 %} 14048 ins_pipe(pipe_class_default); 14049 %} 14050 14051 // Insrdi does replicate if src == dst. 14052 instruct repl48(iRegLdst dst) %{ 14053 predicate(false); 14054 effect(USE_DEF dst); 14055 14056 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 14057 size(4); 14058 ins_encode %{ 14059 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 14060 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 14061 %} 14062 ins_pipe(pipe_class_default); 14063 %} 14064 14065 // Insrdi does replicate if src == dst. 14066 instruct repl56(iRegLdst dst) %{ 14067 predicate(false); 14068 effect(USE_DEF dst); 14069 14070 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 14071 size(4); 14072 ins_encode %{ 14073 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 14074 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 14075 %} 14076 ins_pipe(pipe_class_default); 14077 %} 14078 14079 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14080 match(Set dst (ReplicateB src)); 14081 predicate(n->as_Vector()->length() == 8); 14082 expand %{ 14083 moveReg(dst, src); 14084 repl56(dst); 14085 repl48(dst); 14086 repl32(dst); 14087 %} 14088 %} 14089 14090 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 14091 match(Set dst (ReplicateB zero)); 14092 predicate(n->as_Vector()->length() == 8); 14093 format %{ "LI $dst, #0 \t// replicate8B" %} 14094 size(4); 14095 ins_encode %{ 14096 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14097 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14098 %} 14099 ins_pipe(pipe_class_default); 14100 %} 14101 14102 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14103 match(Set dst (ReplicateB src)); 14104 predicate(n->as_Vector()->length() == 8); 14105 format %{ "LI $dst, #-1 \t// replicate8B" %} 14106 size(4); 14107 ins_encode %{ 14108 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14109 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14110 %} 14111 ins_pipe(pipe_class_default); 14112 %} 14113 14114 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 14115 match(Set dst (ReplicateB src)); 14116 predicate(n->as_Vector()->length() == 16); 14117 14118 expand %{ 14119 iRegLdst tmpL; 14120 vecX tmpV; 14121 immI8 imm1 %{ (int) 1 %} 14122 moveReg(tmpL, src); 14123 repl56(tmpL); 14124 repl48(tmpL); 14125 mtvsrwz(tmpV, tmpL); 14126 xxspltw(dst, tmpV, imm1); 14127 %} 14128 %} 14129 14130 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 14131 match(Set dst (ReplicateB zero)); 14132 predicate(n->as_Vector()->length() == 16); 14133 14134 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 14135 size(4); 14136 ins_encode %{ 14137 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14138 %} 14139 ins_pipe(pipe_class_default); 14140 %} 14141 14142 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 14143 match(Set dst (ReplicateB src)); 14144 predicate(n->as_Vector()->length() == 16); 14145 14146 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14147 size(4); 14148 ins_encode %{ 14149 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14150 %} 14151 ins_pipe(pipe_class_default); 14152 %} 14153 14154 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14155 match(Set dst (ReplicateS src)); 14156 predicate(n->as_Vector()->length() == 4); 14157 expand %{ 14158 moveReg(dst, src); 14159 repl48(dst); 14160 repl32(dst); 14161 %} 14162 %} 14163 14164 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 14165 match(Set dst (ReplicateS zero)); 14166 predicate(n->as_Vector()->length() == 4); 14167 format %{ "LI $dst, #0 \t// replicate4S" %} 14168 size(4); 14169 ins_encode %{ 14170 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14171 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14172 %} 14173 ins_pipe(pipe_class_default); 14174 %} 14175 14176 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14177 match(Set dst (ReplicateS src)); 14178 predicate(n->as_Vector()->length() == 4); 14179 format %{ "LI $dst, -1 \t// replicate4S" %} 14180 size(4); 14181 ins_encode %{ 14182 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14183 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14184 %} 14185 ins_pipe(pipe_class_default); 14186 %} 14187 14188 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 14189 match(Set dst (ReplicateS src)); 14190 predicate(n->as_Vector()->length() == 8); 14191 14192 expand %{ 14193 iRegLdst tmpL; 14194 vecX tmpV; 14195 immI8 zero %{ (int) 0 %} 14196 moveReg(tmpL, src); 14197 repl48(tmpL); 14198 repl32(tmpL); 14199 mtvsrd(tmpV, tmpL); 14200 xxpermdi(dst, tmpV, tmpV, zero); 14201 %} 14202 %} 14203 14204 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 14205 match(Set dst (ReplicateS zero)); 14206 predicate(n->as_Vector()->length() == 8); 14207 14208 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 14209 size(4); 14210 ins_encode %{ 14211 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14212 %} 14213 ins_pipe(pipe_class_default); 14214 %} 14215 14216 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 14217 match(Set dst (ReplicateS src)); 14218 predicate(n->as_Vector()->length() == 8); 14219 14220 format %{ "XXLEQV $dst, $src \t// replicate8S" %} 14221 size(4); 14222 ins_encode %{ 14223 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14224 %} 14225 ins_pipe(pipe_class_default); 14226 %} 14227 14228 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14229 match(Set dst (ReplicateI src)); 14230 predicate(n->as_Vector()->length() == 2); 14231 ins_cost(2 * DEFAULT_COST); 14232 expand %{ 14233 moveReg(dst, src); 14234 repl32(dst); 14235 %} 14236 %} 14237 14238 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 14239 match(Set dst (ReplicateI zero)); 14240 predicate(n->as_Vector()->length() == 2); 14241 format %{ "LI $dst, #0 \t// replicate2I" %} 14242 size(4); 14243 ins_encode %{ 14244 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14245 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14246 %} 14247 ins_pipe(pipe_class_default); 14248 %} 14249 14250 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14251 match(Set dst (ReplicateI src)); 14252 predicate(n->as_Vector()->length() == 2); 14253 format %{ "LI $dst, -1 \t// replicate2I" %} 14254 size(4); 14255 ins_encode %{ 14256 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14257 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14258 %} 14259 ins_pipe(pipe_class_default); 14260 %} 14261 14262 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 14263 match(Set dst (ReplicateI src)); 14264 predicate(n->as_Vector()->length() == 4); 14265 ins_cost(2 * DEFAULT_COST); 14266 14267 expand %{ 14268 iRegLdst tmpL; 14269 vecX tmpV; 14270 immI8 zero %{ (int) 0 %} 14271 moveReg(tmpL, src); 14272 repl32(tmpL); 14273 mtvsrd(tmpV, tmpL); 14274 xxpermdi(dst, tmpV, tmpV, zero); 14275 %} 14276 %} 14277 14278 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 14279 match(Set dst (ReplicateI zero)); 14280 predicate(n->as_Vector()->length() == 4); 14281 14282 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 14283 size(4); 14284 ins_encode %{ 14285 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14286 %} 14287 ins_pipe(pipe_class_default); 14288 %} 14289 14290 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 14291 match(Set dst (ReplicateI src)); 14292 predicate(n->as_Vector()->length() == 4); 14293 14294 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 14295 size(4); 14296 ins_encode %{ 14297 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14298 %} 14299 ins_pipe(pipe_class_default); 14300 %} 14301 14302 // Move float to int register via stack, replicate. 14303 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 14304 match(Set dst (ReplicateF src)); 14305 predicate(n->as_Vector()->length() == 2); 14306 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14307 expand %{ 14308 stackSlotL tmpS; 14309 iRegIdst tmpI; 14310 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14311 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14312 moveReg(dst, tmpI); // Move int to long reg. 14313 repl32(dst); // Replicate bitpattern. 14314 %} 14315 %} 14316 14317 // Replicate scalar constant to packed float values in Double register 14318 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 14319 match(Set dst (ReplicateF src)); 14320 predicate(n->as_Vector()->length() == 2); 14321 ins_cost(5 * DEFAULT_COST); 14322 14323 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 14324 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 14325 %} 14326 14327 // Replicate scalar zero constant to packed float values in Double register 14328 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 14329 match(Set dst (ReplicateF zero)); 14330 predicate(n->as_Vector()->length() == 2); 14331 14332 format %{ "LI $dst, #0 \t// replicate2F" %} 14333 ins_encode %{ 14334 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14335 __ li($dst$$Register, 0x0); 14336 %} 14337 ins_pipe(pipe_class_default); 14338 %} 14339 14340 14341 //----------Vector Arithmetic Instructions-------------------------------------- 14342 14343 // Vector Addition Instructions 14344 14345 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{ 14346 match(Set dst (AddVB src1 src2)); 14347 predicate(n->as_Vector()->length() == 16); 14348 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %} 14349 size(4); 14350 ins_encode %{ 14351 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14352 %} 14353 ins_pipe(pipe_class_default); 14354 %} 14355 14356 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{ 14357 match(Set dst (AddVS src1 src2)); 14358 predicate(n->as_Vector()->length() == 8); 14359 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %} 14360 size(4); 14361 ins_encode %{ 14362 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14363 %} 14364 ins_pipe(pipe_class_default); 14365 %} 14366 14367 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{ 14368 match(Set dst (AddVI src1 src2)); 14369 predicate(n->as_Vector()->length() == 4); 14370 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %} 14371 size(4); 14372 ins_encode %{ 14373 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14374 %} 14375 ins_pipe(pipe_class_default); 14376 %} 14377 14378 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{ 14379 match(Set dst (AddVF src1 src2)); 14380 predicate(n->as_Vector()->length() == 4); 14381 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %} 14382 size(4); 14383 ins_encode %{ 14384 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14385 %} 14386 ins_pipe(pipe_class_default); 14387 %} 14388 14389 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{ 14390 match(Set dst (AddVL src1 src2)); 14391 predicate(n->as_Vector()->length() == 2); 14392 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %} 14393 size(4); 14394 ins_encode %{ 14395 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14396 %} 14397 ins_pipe(pipe_class_default); 14398 %} 14399 14400 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{ 14401 match(Set dst (AddVD src1 src2)); 14402 predicate(n->as_Vector()->length() == 2); 14403 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %} 14404 size(4); 14405 ins_encode %{ 14406 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14407 %} 14408 ins_pipe(pipe_class_default); 14409 %} 14410 14411 // Vector Subtraction Instructions 14412 14413 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{ 14414 match(Set dst (SubVB src1 src2)); 14415 predicate(n->as_Vector()->length() == 16); 14416 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %} 14417 size(4); 14418 ins_encode %{ 14419 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14420 %} 14421 ins_pipe(pipe_class_default); 14422 %} 14423 14424 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{ 14425 match(Set dst (SubVS src1 src2)); 14426 predicate(n->as_Vector()->length() == 8); 14427 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %} 14428 size(4); 14429 ins_encode %{ 14430 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14431 %} 14432 ins_pipe(pipe_class_default); 14433 %} 14434 14435 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{ 14436 match(Set dst (SubVI src1 src2)); 14437 predicate(n->as_Vector()->length() == 4); 14438 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %} 14439 size(4); 14440 ins_encode %{ 14441 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14442 %} 14443 ins_pipe(pipe_class_default); 14444 %} 14445 14446 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{ 14447 match(Set dst (SubVF src1 src2)); 14448 predicate(n->as_Vector()->length() == 4); 14449 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %} 14450 size(4); 14451 ins_encode %{ 14452 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14453 %} 14454 ins_pipe(pipe_class_default); 14455 %} 14456 14457 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{ 14458 match(Set dst (SubVL src1 src2)); 14459 predicate(n->as_Vector()->length() == 2); 14460 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %} 14461 size(4); 14462 ins_encode %{ 14463 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14464 %} 14465 ins_pipe(pipe_class_default); 14466 %} 14467 14468 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{ 14469 match(Set dst (SubVD src1 src2)); 14470 predicate(n->as_Vector()->length() == 2); 14471 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %} 14472 size(4); 14473 ins_encode %{ 14474 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14475 %} 14476 ins_pipe(pipe_class_default); 14477 %} 14478 14479 // Vector Multiplication Instructions 14480 14481 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 14482 match(Set dst (MulVS src1 src2)); 14483 predicate(n->as_Vector()->length() == 8); 14484 effect(TEMP tmp); 14485 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %} 14486 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %} 14487 size(8); 14488 ins_encode %{ 14489 __ vspltish($tmp$$VectorSRegister->to_vr(), 0); 14490 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr()); 14491 %} 14492 ins_pipe(pipe_class_default); 14493 %} 14494 14495 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{ 14496 match(Set dst (MulVI src1 src2)); 14497 predicate(n->as_Vector()->length() == 4); 14498 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %} 14499 size(4); 14500 ins_encode %{ 14501 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14502 %} 14503 ins_pipe(pipe_class_default); 14504 %} 14505 14506 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{ 14507 match(Set dst (MulVF src1 src2)); 14508 predicate(n->as_Vector()->length() == 4); 14509 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %} 14510 size(4); 14511 ins_encode %{ 14512 __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14513 %} 14514 ins_pipe(pipe_class_default); 14515 %} 14516 14517 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{ 14518 match(Set dst (MulVD src1 src2)); 14519 predicate(n->as_Vector()->length() == 2); 14520 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %} 14521 size(4); 14522 ins_encode %{ 14523 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14524 %} 14525 ins_pipe(pipe_class_default); 14526 %} 14527 14528 // Vector Division Instructions 14529 14530 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{ 14531 match(Set dst (DivVF src1 src2)); 14532 predicate(n->as_Vector()->length() == 4); 14533 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %} 14534 size(4); 14535 ins_encode %{ 14536 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14537 %} 14538 ins_pipe(pipe_class_default); 14539 %} 14540 14541 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ 14542 match(Set dst (DivVD src1 src2)); 14543 predicate(n->as_Vector()->length() == 2); 14544 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %} 14545 size(4); 14546 ins_encode %{ 14547 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14548 %} 14549 ins_pipe(pipe_class_default); 14550 %} 14551 14552 // Vector Absolute Instructions 14553 14554 instruct vabs4F_reg(vecX dst, vecX src) %{ 14555 match(Set dst (AbsVF src)); 14556 predicate(n->as_Vector()->length() == 4); 14557 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %} 14558 size(4); 14559 ins_encode %{ 14560 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister); 14561 %} 14562 ins_pipe(pipe_class_default); 14563 %} 14564 14565 instruct vabs2D_reg(vecX dst, vecX src) %{ 14566 match(Set dst (AbsVD src)); 14567 predicate(n->as_Vector()->length() == 2); 14568 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %} 14569 size(4); 14570 ins_encode %{ 14571 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister); 14572 %} 14573 ins_pipe(pipe_class_default); 14574 %} 14575 14576 // Round Instructions 14577 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{ 14578 match(Set dst (RoundDoubleMode src rmode)); 14579 format %{ "RoundDoubleMode $src,$rmode" %} 14580 size(4); 14581 ins_encode %{ 14582 switch ($rmode$$constant) { 14583 case RoundDoubleModeNode::rmode_rint: 14584 __ frin($dst$$FloatRegister, $src$$FloatRegister); 14585 break; 14586 case RoundDoubleModeNode::rmode_floor: 14587 __ frim($dst$$FloatRegister, $src$$FloatRegister); 14588 break; 14589 case RoundDoubleModeNode::rmode_ceil: 14590 __ frip($dst$$FloatRegister, $src$$FloatRegister); 14591 break; 14592 default: 14593 ShouldNotReachHere(); 14594 } 14595 %} 14596 ins_pipe(pipe_class_default); 14597 %} 14598 14599 // Vector Round Instructions 14600 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{ 14601 match(Set dst (RoundDoubleModeV src rmode)); 14602 predicate(n->as_Vector()->length() == 2); 14603 format %{ "RoundDoubleModeV $src,$rmode" %} 14604 size(4); 14605 ins_encode %{ 14606 switch ($rmode$$constant) { 14607 case RoundDoubleModeNode::rmode_rint: 14608 __ xvrdpi($dst$$VectorSRegister, $src$$VectorSRegister); 14609 break; 14610 case RoundDoubleModeNode::rmode_floor: 14611 __ xvrdpim($dst$$VectorSRegister, $src$$VectorSRegister); 14612 break; 14613 case RoundDoubleModeNode::rmode_ceil: 14614 __ xvrdpip($dst$$VectorSRegister, $src$$VectorSRegister); 14615 break; 14616 default: 14617 ShouldNotReachHere(); 14618 } 14619 %} 14620 ins_pipe(pipe_class_default); 14621 %} 14622 14623 // Vector Negate Instructions 14624 14625 instruct vneg4F_reg(vecX dst, vecX src) %{ 14626 match(Set dst (NegVF src)); 14627 predicate(n->as_Vector()->length() == 4); 14628 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %} 14629 size(4); 14630 ins_encode %{ 14631 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister); 14632 %} 14633 ins_pipe(pipe_class_default); 14634 %} 14635 14636 instruct vneg2D_reg(vecX dst, vecX src) %{ 14637 match(Set dst (NegVD src)); 14638 predicate(n->as_Vector()->length() == 2); 14639 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %} 14640 size(4); 14641 ins_encode %{ 14642 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister); 14643 %} 14644 ins_pipe(pipe_class_default); 14645 %} 14646 14647 // Vector Square Root Instructions 14648 14649 instruct vsqrt4F_reg(vecX dst, vecX src) %{ 14650 match(Set dst (SqrtVF src)); 14651 predicate(n->as_Vector()->length() == 4); 14652 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %} 14653 size(4); 14654 ins_encode %{ 14655 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister); 14656 %} 14657 ins_pipe(pipe_class_default); 14658 %} 14659 14660 instruct vsqrt2D_reg(vecX dst, vecX src) %{ 14661 match(Set dst (SqrtVD src)); 14662 predicate(n->as_Vector()->length() == 2); 14663 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %} 14664 size(4); 14665 ins_encode %{ 14666 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister); 14667 %} 14668 ins_pipe(pipe_class_default); 14669 %} 14670 14671 // Vector Population Count Instructions 14672 14673 instruct vpopcnt4I_reg(vecX dst, vecX src) %{ 14674 match(Set dst (PopCountVI src)); 14675 predicate(n->as_Vector()->length() == 4); 14676 format %{ "VPOPCNTW $dst,$src\t// pop count packed4I" %} 14677 size(4); 14678 ins_encode %{ 14679 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14680 %} 14681 ins_pipe(pipe_class_default); 14682 %} 14683 14684 // --------------------------------- FMA -------------------------------------- 14685 // dst + src1 * src2 14686 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{ 14687 match(Set dst (FmaVF dst (Binary src1 src2))); 14688 predicate(n->as_Vector()->length() == 4); 14689 14690 format %{ "XVMADDASP $dst, $src1, $src2" %} 14691 14692 size(4); 14693 ins_encode %{ 14694 __ xvmaddasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14695 %} 14696 ins_pipe(pipe_class_default); 14697 %} 14698 14699 // dst - src1 * src2 14700 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{ 14701 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 14702 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 14703 predicate(n->as_Vector()->length() == 4); 14704 14705 format %{ "XVNMSUBASP $dst, $src1, $src2" %} 14706 14707 size(4); 14708 ins_encode %{ 14709 __ xvnmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14710 %} 14711 ins_pipe(pipe_class_default); 14712 %} 14713 14714 // - dst + src1 * src2 14715 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{ 14716 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2))); 14717 predicate(n->as_Vector()->length() == 4); 14718 14719 format %{ "XVMSUBASP $dst, $src1, $src2" %} 14720 14721 size(4); 14722 ins_encode %{ 14723 __ xvmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14724 %} 14725 ins_pipe(pipe_class_default); 14726 %} 14727 14728 // dst + src1 * src2 14729 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{ 14730 match(Set dst (FmaVD dst (Binary src1 src2))); 14731 predicate(n->as_Vector()->length() == 2); 14732 14733 format %{ "XVMADDADP $dst, $src1, $src2" %} 14734 14735 size(4); 14736 ins_encode %{ 14737 __ xvmaddadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14738 %} 14739 ins_pipe(pipe_class_default); 14740 %} 14741 14742 // dst - src1 * src2 14743 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{ 14744 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 14745 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 14746 predicate(n->as_Vector()->length() == 2); 14747 14748 format %{ "XVNMSUBADP $dst, $src1, $src2" %} 14749 14750 size(4); 14751 ins_encode %{ 14752 __ xvnmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14753 %} 14754 ins_pipe(pipe_class_default); 14755 %} 14756 14757 // - dst + src1 * src2 14758 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{ 14759 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2))); 14760 predicate(n->as_Vector()->length() == 2); 14761 14762 format %{ "XVMSUBADP $dst, $src1, $src2" %} 14763 14764 size(4); 14765 ins_encode %{ 14766 __ xvmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14767 %} 14768 ins_pipe(pipe_class_default); 14769 %} 14770 14771 //----------Overflow Math Instructions----------------------------------------- 14772 14773 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 14774 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14775 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14776 14777 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14778 match(Set cr0 (OverflowAddL op1 op2)); 14779 14780 format %{ "add_ $op1, $op2\t# overflow check long" %} 14781 ins_encode %{ 14782 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14783 __ li(R0, 0); 14784 __ mtxer(R0); // clear XER.SO 14785 __ addo_(R0, $op1$$Register, $op2$$Register); 14786 %} 14787 ins_pipe(pipe_class_default); 14788 %} 14789 14790 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14791 match(Set cr0 (OverflowSubL op1 op2)); 14792 14793 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14794 ins_encode %{ 14795 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14796 __ li(R0, 0); 14797 __ mtxer(R0); // clear XER.SO 14798 __ subfo_(R0, $op2$$Register, $op1$$Register); 14799 %} 14800 ins_pipe(pipe_class_default); 14801 %} 14802 14803 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14804 match(Set cr0 (OverflowSubL zero op2)); 14805 14806 format %{ "nego_ R0, $op2\t# overflow check long" %} 14807 ins_encode %{ 14808 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14809 __ li(R0, 0); 14810 __ mtxer(R0); // clear XER.SO 14811 __ nego_(R0, $op2$$Register); 14812 %} 14813 ins_pipe(pipe_class_default); 14814 %} 14815 14816 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14817 match(Set cr0 (OverflowMulL op1 op2)); 14818 14819 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14820 ins_encode %{ 14821 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14822 __ li(R0, 0); 14823 __ mtxer(R0); // clear XER.SO 14824 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14825 %} 14826 ins_pipe(pipe_class_default); 14827 %} 14828 14829 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14830 match(Set dst (ReplicateF src)); 14831 predicate(n->as_Vector()->length() == 4); 14832 ins_cost(DEFAULT_COST); 14833 expand %{ 14834 vecX tmpV; 14835 immI8 zero %{ (int) 0 %} 14836 14837 xscvdpspn_regF(tmpV, src); 14838 xxspltw(dst, tmpV, zero); 14839 %} 14840 %} 14841 14842 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14843 match(Set dst (ReplicateF src)); 14844 predicate(n->as_Vector()->length() == 4); 14845 effect(TEMP tmp); 14846 ins_cost(10 * DEFAULT_COST); 14847 14848 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14849 %} 14850 14851 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14852 match(Set dst (ReplicateF zero)); 14853 predicate(n->as_Vector()->length() == 4); 14854 14855 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14856 ins_encode %{ 14857 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14858 %} 14859 ins_pipe(pipe_class_default); 14860 %} 14861 14862 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14863 match(Set dst (ReplicateD src)); 14864 predicate(n->as_Vector()->length() == 2); 14865 14866 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %} 14867 size(4); 14868 ins_encode %{ 14869 __ xxpermdi($dst$$VectorSRegister, $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0); 14870 %} 14871 ins_pipe(pipe_class_default); 14872 %} 14873 14874 instruct repl2D_immD0(vecX dst, immD_0 zero) %{ 14875 match(Set dst (ReplicateD zero)); 14876 predicate(n->as_Vector()->length() == 2); 14877 14878 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14879 size(4); 14880 ins_encode %{ 14881 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14882 %} 14883 ins_pipe(pipe_class_default); 14884 %} 14885 14886 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14887 predicate(false); 14888 effect(DEF dst, USE src); 14889 14890 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %} 14891 size(4); 14892 ins_encode %{ 14893 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14894 %} 14895 ins_pipe(pipe_class_default); 14896 %} 14897 14898 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14899 effect(DEF dst, USE src, USE zero); 14900 14901 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %} 14902 size(4); 14903 ins_encode %{ 14904 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14905 %} 14906 ins_pipe(pipe_class_default); 14907 %} 14908 14909 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14910 effect(DEF dst, USE src1, USE src2, USE zero); 14911 14912 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %} 14913 size(4); 14914 ins_encode %{ 14915 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14916 %} 14917 ins_pipe(pipe_class_default); 14918 %} 14919 14920 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14921 match(Set dst (ReplicateL src)); 14922 predicate(n->as_Vector()->length() == 2); 14923 expand %{ 14924 vecX tmpV; 14925 immI8 zero %{ (int) 0 %} 14926 mtvsrd(tmpV, src); 14927 xxpermdi(dst, tmpV, tmpV, zero); 14928 %} 14929 %} 14930 14931 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14932 match(Set dst (ReplicateL zero)); 14933 predicate(n->as_Vector()->length() == 2); 14934 14935 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14936 size(4); 14937 ins_encode %{ 14938 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14939 %} 14940 ins_pipe(pipe_class_default); 14941 %} 14942 14943 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14944 match(Set dst (ReplicateL src)); 14945 predicate(n->as_Vector()->length() == 2); 14946 14947 format %{ "XXLEQV $dst, $src \t// replicate2L" %} 14948 size(4); 14949 ins_encode %{ 14950 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14951 %} 14952 ins_pipe(pipe_class_default); 14953 %} 14954 14955 // ============================================================================ 14956 // Safepoint Instruction 14957 14958 instruct safePoint_poll(iRegPdst poll) %{ 14959 match(SafePoint poll); 14960 14961 // It caused problems to add the effect that r0 is killed, but this 14962 // effect no longer needs to be mentioned, since r0 is not contained 14963 // in a reg_class. 14964 14965 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14966 size(4); 14967 ins_encode( enc_poll(0x0, poll) ); 14968 ins_pipe(pipe_class_default); 14969 %} 14970 14971 // ============================================================================ 14972 // Call Instructions 14973 14974 // Call Java Static Instruction 14975 14976 // Schedulable version of call static node. 14977 instruct CallStaticJavaDirect(method meth) %{ 14978 match(CallStaticJava); 14979 effect(USE meth); 14980 ins_cost(CALL_COST); 14981 14982 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14983 14984 format %{ "CALL,static $meth \t// ==> " %} 14985 size(4); 14986 ins_encode( enc_java_static_call(meth) ); 14987 ins_pipe(pipe_class_call); 14988 %} 14989 14990 // Call Java Dynamic Instruction 14991 14992 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14993 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14994 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14995 // The call destination must still be placed in the constant pool. 14996 instruct CallDynamicJavaDirectSched(method meth) %{ 14997 match(CallDynamicJava); // To get all the data fields we need ... 14998 effect(USE meth); 14999 predicate(false); // ... but never match. 15000 15001 ins_field_load_ic_hi_node(loadConL_hiNode*); 15002 ins_field_load_ic_node(loadConLNode*); 15003 ins_num_consts(1 /* 1 patchable constant: call destination */); 15004 15005 format %{ "BL \t// dynamic $meth ==> " %} 15006 size(4); 15007 ins_encode( enc_java_dynamic_call_sched(meth) ); 15008 ins_pipe(pipe_class_call); 15009 %} 15010 15011 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 15012 // We use postalloc expanded calls if we use inline caches 15013 // and do not update method data. 15014 // 15015 // This instruction has two constants: inline cache (IC) and call destination. 15016 // Loading the inline cache will be postalloc expanded, thus leaving a call with 15017 // one constant. 15018 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 15019 match(CallDynamicJava); 15020 effect(USE meth); 15021 predicate(UseInlineCaches); 15022 ins_cost(CALL_COST); 15023 15024 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 15025 15026 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 15027 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 15028 %} 15029 15030 // Compound version of call dynamic java 15031 // We use postalloc expanded calls if we use inline caches 15032 // and do not update method data. 15033 instruct CallDynamicJavaDirect(method meth) %{ 15034 match(CallDynamicJava); 15035 effect(USE meth); 15036 predicate(!UseInlineCaches); 15037 ins_cost(CALL_COST); 15038 15039 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 15040 ins_num_consts(4); 15041 15042 format %{ "CALL,dynamic $meth \t// ==> " %} 15043 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 15044 ins_pipe(pipe_class_call); 15045 %} 15046 15047 // Call Runtime Instruction 15048 15049 instruct CallRuntimeDirect(method meth) %{ 15050 match(CallRuntime); 15051 effect(USE meth); 15052 ins_cost(CALL_COST); 15053 15054 // Enc_java_to_runtime_call needs up to 3 constants: call target, 15055 // env for callee, C-toc. 15056 ins_num_consts(3); 15057 15058 format %{ "CALL,runtime" %} 15059 ins_encode( enc_java_to_runtime_call(meth) ); 15060 ins_pipe(pipe_class_call); 15061 %} 15062 15063 // Call Leaf 15064 15065 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 15066 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 15067 effect(DEF dst, USE src); 15068 15069 ins_num_consts(1); 15070 15071 format %{ "MTCTR $src" %} 15072 size(4); 15073 ins_encode( enc_leaf_call_mtctr(src) ); 15074 ins_pipe(pipe_class_default); 15075 %} 15076 15077 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 15078 instruct CallLeafDirect(method meth) %{ 15079 match(CallLeaf); // To get the data all the data fields we need ... 15080 effect(USE meth); 15081 predicate(false); // but never match. 15082 15083 format %{ "BCTRL \t// leaf call $meth ==> " %} 15084 size(4); 15085 ins_encode %{ 15086 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 15087 __ bctrl(); 15088 %} 15089 ins_pipe(pipe_class_call); 15090 %} 15091 15092 // postalloc expand of CallLeafDirect. 15093 // Load adress to call from TOC, then bl to it. 15094 instruct CallLeafDirect_Ex(method meth) %{ 15095 match(CallLeaf); 15096 effect(USE meth); 15097 ins_cost(CALL_COST); 15098 15099 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 15100 // env for callee, C-toc. 15101 ins_num_consts(3); 15102 15103 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 15104 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 15105 %} 15106 15107 // Call runtime without safepoint - same as CallLeaf. 15108 // postalloc expand of CallLeafNoFPDirect. 15109 // Load adress to call from TOC, then bl to it. 15110 instruct CallLeafNoFPDirect_Ex(method meth) %{ 15111 match(CallLeafNoFP); 15112 effect(USE meth); 15113 ins_cost(CALL_COST); 15114 15115 // Enc_java_to_runtime_call needs up to 3 constants: call target, 15116 // env for callee, C-toc. 15117 ins_num_consts(3); 15118 15119 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 15120 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 15121 %} 15122 15123 // Tail Call; Jump from runtime stub to Java code. 15124 // Also known as an 'interprocedural jump'. 15125 // Target of jump will eventually return to caller. 15126 // TailJump below removes the return address. 15127 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ptr) %{ 15128 match(TailCall jump_target method_ptr); 15129 ins_cost(CALL_COST); 15130 15131 format %{ "MTCTR $jump_target \t// $method_ptr holds method\n\t" 15132 "BCTR \t// tail call" %} 15133 size(8); 15134 ins_encode %{ 15135 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 15136 __ mtctr($jump_target$$Register); 15137 __ bctr(); 15138 %} 15139 ins_pipe(pipe_class_call); 15140 %} 15141 15142 // Return Instruction 15143 instruct Ret() %{ 15144 match(Return); 15145 format %{ "BLR \t// branch to link register" %} 15146 size(4); 15147 ins_encode %{ 15148 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 15149 // LR is restored in MachEpilogNode. Just do the RET here. 15150 __ blr(); 15151 %} 15152 ins_pipe(pipe_class_default); 15153 %} 15154 15155 // Tail Jump; remove the return address; jump to target. 15156 // TailCall above leaves the return address around. 15157 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 15158 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 15159 // "restore" before this instruction (in Epilogue), we need to materialize it 15160 // in %i0. 15161 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 15162 match(TailJump jump_target ex_oop); 15163 ins_cost(CALL_COST); 15164 15165 format %{ "LD R4_ARG2 = LR\n\t" 15166 "MTCTR $jump_target\n\t" 15167 "BCTR \t// TailJump, exception oop: $ex_oop" %} 15168 size(12); 15169 ins_encode %{ 15170 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 15171 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 15172 __ mtctr($jump_target$$Register); 15173 __ bctr(); 15174 %} 15175 ins_pipe(pipe_class_call); 15176 %} 15177 15178 // Create exception oop: created by stack-crawling runtime code. 15179 // Created exception is now available to this handler, and is setup 15180 // just prior to jumping to this handler. No code emitted. 15181 instruct CreateException(rarg1RegP ex_oop) %{ 15182 match(Set ex_oop (CreateEx)); 15183 ins_cost(0); 15184 15185 format %{ " -- \t// exception oop; no code emitted" %} 15186 size(0); 15187 ins_encode( /*empty*/ ); 15188 ins_pipe(pipe_class_default); 15189 %} 15190 15191 // Rethrow exception: The exception oop will come in the first 15192 // argument position. Then JUMP (not call) to the rethrow stub code. 15193 instruct RethrowException() %{ 15194 match(Rethrow); 15195 ins_cost(CALL_COST); 15196 15197 format %{ "Jmp rethrow_stub" %} 15198 ins_encode %{ 15199 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 15200 cbuf.set_insts_mark(); 15201 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 15202 %} 15203 ins_pipe(pipe_class_call); 15204 %} 15205 15206 // Die now. 15207 instruct ShouldNotReachHere() %{ 15208 match(Halt); 15209 ins_cost(CALL_COST); 15210 15211 format %{ "ShouldNotReachHere" %} 15212 ins_encode %{ 15213 if (is_reachable()) { 15214 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 15215 __ stop(_halt_reason); 15216 } 15217 %} 15218 ins_pipe(pipe_class_default); 15219 %} 15220 15221 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 15222 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 15223 // Get a DEF on threadRegP, no costs, no encoding, use 15224 // 'ins_should_rematerialize(true)' to avoid spilling. 15225 instruct tlsLoadP(threadRegP dst) %{ 15226 match(Set dst (ThreadLocal)); 15227 ins_cost(0); 15228 15229 ins_should_rematerialize(true); 15230 15231 format %{ " -- \t// $dst=Thread::current(), empty" %} 15232 size(0); 15233 ins_encode( /*empty*/ ); 15234 ins_pipe(pipe_class_empty); 15235 %} 15236 15237 //---Some PPC specific nodes--------------------------------------------------- 15238 15239 // Stop a group. 15240 instruct endGroup() %{ 15241 ins_cost(0); 15242 15243 ins_is_nop(true); 15244 15245 format %{ "End Bundle (ori r1, r1, 0)" %} 15246 size(4); 15247 ins_encode %{ 15248 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 15249 __ endgroup(); 15250 %} 15251 ins_pipe(pipe_class_default); 15252 %} 15253 15254 // Nop instructions 15255 15256 instruct fxNop() %{ 15257 ins_cost(0); 15258 15259 ins_is_nop(true); 15260 15261 format %{ "fxNop" %} 15262 size(4); 15263 ins_encode %{ 15264 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15265 __ nop(); 15266 %} 15267 ins_pipe(pipe_class_default); 15268 %} 15269 15270 instruct fpNop0() %{ 15271 ins_cost(0); 15272 15273 ins_is_nop(true); 15274 15275 format %{ "fpNop0" %} 15276 size(4); 15277 ins_encode %{ 15278 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15279 __ fpnop0(); 15280 %} 15281 ins_pipe(pipe_class_default); 15282 %} 15283 15284 instruct fpNop1() %{ 15285 ins_cost(0); 15286 15287 ins_is_nop(true); 15288 15289 format %{ "fpNop1" %} 15290 size(4); 15291 ins_encode %{ 15292 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15293 __ fpnop1(); 15294 %} 15295 ins_pipe(pipe_class_default); 15296 %} 15297 15298 instruct brNop0() %{ 15299 ins_cost(0); 15300 size(4); 15301 format %{ "brNop0" %} 15302 ins_encode %{ 15303 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15304 __ brnop0(); 15305 %} 15306 ins_is_nop(true); 15307 ins_pipe(pipe_class_default); 15308 %} 15309 15310 instruct brNop1() %{ 15311 ins_cost(0); 15312 15313 ins_is_nop(true); 15314 15315 format %{ "brNop1" %} 15316 size(4); 15317 ins_encode %{ 15318 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15319 __ brnop1(); 15320 %} 15321 ins_pipe(pipe_class_default); 15322 %} 15323 15324 instruct brNop2() %{ 15325 ins_cost(0); 15326 15327 ins_is_nop(true); 15328 15329 format %{ "brNop2" %} 15330 size(4); 15331 ins_encode %{ 15332 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15333 __ brnop2(); 15334 %} 15335 ins_pipe(pipe_class_default); 15336 %} 15337 15338 instruct cacheWB(indirect addr) 15339 %{ 15340 match(CacheWB addr); 15341 15342 ins_cost(100); 15343 format %{ "cache writeback, address = $addr" %} 15344 ins_encode %{ 15345 assert($addr->index_position() < 0, "should be"); 15346 assert($addr$$disp == 0, "should be"); 15347 __ cache_wb(Address($addr$$base$$Register)); 15348 %} 15349 ins_pipe(pipe_class_default); 15350 %} 15351 15352 instruct cacheWBPreSync() 15353 %{ 15354 match(CacheWBPreSync); 15355 15356 ins_cost(0); 15357 format %{ "cache writeback presync" %} 15358 ins_encode %{ 15359 __ cache_wbsync(true); 15360 %} 15361 ins_pipe(pipe_class_default); 15362 %} 15363 15364 instruct cacheWBPostSync() 15365 %{ 15366 match(CacheWBPostSync); 15367 15368 ins_cost(100); 15369 format %{ "cache writeback postsync" %} 15370 ins_encode %{ 15371 __ cache_wbsync(false); 15372 %} 15373 ins_pipe(pipe_class_default); 15374 %} 15375 15376 //----------PEEPHOLE RULES----------------------------------------------------- 15377 // These must follow all instruction definitions as they use the names 15378 // defined in the instructions definitions. 15379 // 15380 // peepmatch ( root_instr_name [preceeding_instruction]* ); 15381 // 15382 // peepconstraint %{ 15383 // (instruction_number.operand_name relational_op instruction_number.operand_name 15384 // [, ...] ); 15385 // // instruction numbers are zero-based using left to right order in peepmatch 15386 // 15387 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 15388 // // provide an instruction_number.operand_name for each operand that appears 15389 // // in the replacement instruction's match rule 15390 // 15391 // ---------VM FLAGS--------------------------------------------------------- 15392 // 15393 // All peephole optimizations can be turned off using -XX:-OptoPeephole 15394 // 15395 // Each peephole rule is given an identifying number starting with zero and 15396 // increasing by one in the order seen by the parser. An individual peephole 15397 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 15398 // on the command-line. 15399 // 15400 // ---------CURRENT LIMITATIONS---------------------------------------------- 15401 // 15402 // Only match adjacent instructions in same basic block 15403 // Only equality constraints 15404 // Only constraints between operands, not (0.dest_reg == EAX_enc) 15405 // Only one replacement instruction 15406 // 15407 // ---------EXAMPLE---------------------------------------------------------- 15408 // 15409 // // pertinent parts of existing instructions in architecture description 15410 // instruct movI(eRegI dst, eRegI src) %{ 15411 // match(Set dst (CopyI src)); 15412 // %} 15413 // 15414 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 15415 // match(Set dst (AddI dst src)); 15416 // effect(KILL cr); 15417 // %} 15418 // 15419 // // Change (inc mov) to lea 15420 // peephole %{ 15421 // // increment preceeded by register-register move 15422 // peepmatch ( incI_eReg movI ); 15423 // // require that the destination register of the increment 15424 // // match the destination register of the move 15425 // peepconstraint ( 0.dst == 1.dst ); 15426 // // construct a replacement instruction that sets 15427 // // the destination to ( move's source register + one ) 15428 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15429 // %} 15430 // 15431 // Implementation no longer uses movX instructions since 15432 // machine-independent system no longer uses CopyX nodes. 15433 // 15434 // peephole %{ 15435 // peepmatch ( incI_eReg movI ); 15436 // peepconstraint ( 0.dst == 1.dst ); 15437 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15438 // %} 15439 // 15440 // peephole %{ 15441 // peepmatch ( decI_eReg movI ); 15442 // peepconstraint ( 0.dst == 1.dst ); 15443 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15444 // %} 15445 // 15446 // peephole %{ 15447 // peepmatch ( addI_eReg_imm movI ); 15448 // peepconstraint ( 0.dst == 1.dst ); 15449 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15450 // %} 15451 // 15452 // peephole %{ 15453 // peepmatch ( addP_eReg_imm movP ); 15454 // peepconstraint ( 0.dst == 1.dst ); 15455 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 15456 // %} 15457 15458 // // Change load of spilled value to only a spill 15459 // instruct storeI(memory mem, eRegI src) %{ 15460 // match(Set mem (StoreI mem src)); 15461 // %} 15462 // 15463 // instruct loadI(eRegI dst, memory mem) %{ 15464 // match(Set dst (LoadI mem)); 15465 // %} 15466 // 15467 peephole %{ 15468 peepmatch ( loadI storeI ); 15469 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15470 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 15471 %} 15472 15473 peephole %{ 15474 peepmatch ( loadL storeL ); 15475 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15476 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 15477 %} 15478 15479 peephole %{ 15480 peepmatch ( loadP storeP ); 15481 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 15482 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 15483 %} 15484 15485 //----------SMARTSPILL RULES--------------------------------------------------- 15486 // These must follow all instruction definitions as they use the names 15487 // defined in the instructions definitions.