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 const bool Matcher::supports_scalable_vector() { 2383 return false; 2384 } 2385 2386 const int Matcher::scalable_vector_reg_size(const BasicType bt) { 2387 return -1; 2388 } 2389 2390 // PPC implementation uses VSX load/store instructions (if 2391 // SuperwordUseVSX) which support 4 byte but not arbitrary alignment 2392 const bool Matcher::misaligned_vectors_ok() { 2393 return false; 2394 } 2395 2396 // PPC AES support not yet implemented 2397 const bool Matcher::pass_original_key_for_aes() { 2398 return false; 2399 } 2400 2401 // RETURNS: whether this branch offset is short enough that a short 2402 // branch can be used. 2403 // 2404 // If the platform does not provide any short branch variants, then 2405 // this method should return `false' for offset 0. 2406 // 2407 // `Compile::Fill_buffer' will decide on basis of this information 2408 // whether to do the pass `Compile::Shorten_branches' at all. 2409 // 2410 // And `Compile::Shorten_branches' will decide on basis of this 2411 // information whether to replace particular branch sites by short 2412 // ones. 2413 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2414 // Is the offset within the range of a ppc64 pc relative branch? 2415 bool b; 2416 2417 const int safety_zone = 3 * BytesPerInstWord; 2418 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2419 29 - 16 + 1 + 2); 2420 return b; 2421 } 2422 2423 const bool Matcher::isSimpleConstant64(jlong value) { 2424 // Probably always true, even if a temp register is required. 2425 return true; 2426 } 2427 /* TODO: PPC port 2428 // Make a new machine dependent decode node (with its operands). 2429 MachTypeNode *Matcher::make_decode_node() { 2430 assert(CompressedOops::base() == NULL && CompressedOops::shift() == 0, 2431 "This method is only implemented for unscaled cOops mode so far"); 2432 MachTypeNode *decode = new decodeN_unscaledNode(); 2433 decode->set_opnd_array(0, new iRegPdstOper()); 2434 decode->set_opnd_array(1, new iRegNsrcOper()); 2435 return decode; 2436 } 2437 */ 2438 2439 // false => size gets scaled to BytesPerLong, ok. 2440 const bool Matcher::init_array_count_is_in_bytes = false; 2441 2442 // Use conditional move (CMOVL) on Power7. 2443 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2444 2445 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2446 // fsel doesn't accept a condition register as input, so this would be slightly different. 2447 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2448 2449 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2450 const bool Matcher::require_postalloc_expand = true; 2451 2452 // Do we need to mask the count passed to shift instructions or does 2453 // the cpu only look at the lower 5/6 bits anyway? 2454 // PowerPC requires masked shift counts. 2455 const bool Matcher::need_masked_shift_count = true; 2456 2457 // No support for generic vector operands. 2458 const bool Matcher::supports_generic_vector_operands = false; 2459 2460 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { 2461 ShouldNotReachHere(); // generic vector operands not supported 2462 return NULL; 2463 } 2464 2465 bool Matcher::is_generic_reg2reg_move(MachNode* m) { 2466 ShouldNotReachHere(); // generic vector operands not supported 2467 return false; 2468 } 2469 2470 bool Matcher::is_generic_vector(MachOper* opnd) { 2471 ShouldNotReachHere(); // generic vector operands not supported 2472 return false; 2473 } 2474 2475 // This affects two different things: 2476 // - how Decode nodes are matched 2477 // - how ImplicitNullCheck opportunities are recognized 2478 // If true, the matcher will try to remove all Decodes and match them 2479 // (as operands) into nodes. NullChecks are not prepared to deal with 2480 // Decodes by final_graph_reshaping(). 2481 // If false, final_graph_reshaping() forces the decode behind the Cmp 2482 // for a NullCheck. The matcher matches the Decode node into a register. 2483 // Implicit_null_check optimization moves the Decode along with the 2484 // memory operation back up before the NullCheck. 2485 bool Matcher::narrow_oop_use_complex_address() { 2486 // TODO: PPC port if (MatchDecodeNodes) return true; 2487 return false; 2488 } 2489 2490 bool Matcher::narrow_klass_use_complex_address() { 2491 NOT_LP64(ShouldNotCallThis()); 2492 assert(UseCompressedClassPointers, "only for compressed klass code"); 2493 // TODO: PPC port if (MatchDecodeNodes) return true; 2494 return false; 2495 } 2496 2497 bool Matcher::const_oop_prefer_decode() { 2498 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2499 return CompressedOops::base() == NULL; 2500 } 2501 2502 bool Matcher::const_klass_prefer_decode() { 2503 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2504 return CompressedKlassPointers::base() == NULL; 2505 } 2506 2507 // Is it better to copy float constants, or load them directly from memory? 2508 // Intel can load a float constant from a direct address, requiring no 2509 // extra registers. Most RISCs will have to materialize an address into a 2510 // register first, so they would do better to copy the constant from stack. 2511 const bool Matcher::rematerialize_float_constants = false; 2512 2513 // If CPU can load and store mis-aligned doubles directly then no fixup is 2514 // needed. Else we split the double into 2 integer pieces and move it 2515 // piece-by-piece. Only happens when passing doubles into C code as the 2516 // Java calling convention forces doubles to be aligned. 2517 const bool Matcher::misaligned_doubles_ok = true; 2518 2519 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2520 Unimplemented(); 2521 } 2522 2523 // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. 2524 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2525 2526 // Do floats take an entire double register or just half? 2527 // 2528 // A float occupies a ppc64 double register. For the allocator, a 2529 // ppc64 double register appears as a pair of float registers. 2530 bool Matcher::float_in_double() { return true; } 2531 2532 // Do ints take an entire long register or just half? 2533 // The relevant question is how the int is callee-saved: 2534 // the whole long is written but de-opt'ing will have to extract 2535 // the relevant 32 bits. 2536 const bool Matcher::int_in_long = true; 2537 2538 // Constants for c2c and c calling conventions. 2539 2540 const MachRegisterNumbers iarg_reg[8] = { 2541 R3_num, R4_num, R5_num, R6_num, 2542 R7_num, R8_num, R9_num, R10_num 2543 }; 2544 2545 const MachRegisterNumbers farg_reg[13] = { 2546 F1_num, F2_num, F3_num, F4_num, 2547 F5_num, F6_num, F7_num, F8_num, 2548 F9_num, F10_num, F11_num, F12_num, 2549 F13_num 2550 }; 2551 2552 const MachRegisterNumbers vsarg_reg[64] = { 2553 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2554 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2555 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2556 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2557 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2558 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2559 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2560 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2561 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2562 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2563 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2564 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2565 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2566 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2567 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2568 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2569 }; 2570 2571 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2572 2573 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2574 2575 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2576 2577 // Return whether or not this register is ever used as an argument. This 2578 // function is used on startup to build the trampoline stubs in generateOptoStub. 2579 // Registers not mentioned will be killed by the VM call in the trampoline, and 2580 // arguments in those registers not be available to the callee. 2581 bool Matcher::can_be_java_arg(int reg) { 2582 // We return true for all registers contained in iarg_reg[] and 2583 // farg_reg[] and their virtual halves. 2584 // We must include the virtual halves in order to get STDs and LDs 2585 // instead of STWs and LWs in the trampoline stubs. 2586 2587 if ( reg == R3_num || reg == R3_H_num 2588 || reg == R4_num || reg == R4_H_num 2589 || reg == R5_num || reg == R5_H_num 2590 || reg == R6_num || reg == R6_H_num 2591 || reg == R7_num || reg == R7_H_num 2592 || reg == R8_num || reg == R8_H_num 2593 || reg == R9_num || reg == R9_H_num 2594 || reg == R10_num || reg == R10_H_num) 2595 return true; 2596 2597 if ( reg == F1_num || reg == F1_H_num 2598 || reg == F2_num || reg == F2_H_num 2599 || reg == F3_num || reg == F3_H_num 2600 || reg == F4_num || reg == F4_H_num 2601 || reg == F5_num || reg == F5_H_num 2602 || reg == F6_num || reg == F6_H_num 2603 || reg == F7_num || reg == F7_H_num 2604 || reg == F8_num || reg == F8_H_num 2605 || reg == F9_num || reg == F9_H_num 2606 || reg == F10_num || reg == F10_H_num 2607 || reg == F11_num || reg == F11_H_num 2608 || reg == F12_num || reg == F12_H_num 2609 || reg == F13_num || reg == F13_H_num) 2610 return true; 2611 2612 return false; 2613 } 2614 2615 bool Matcher::is_spillable_arg(int reg) { 2616 return can_be_java_arg(reg); 2617 } 2618 2619 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2620 return false; 2621 } 2622 2623 // Register for DIVI projection of divmodI. 2624 RegMask Matcher::divI_proj_mask() { 2625 ShouldNotReachHere(); 2626 return RegMask(); 2627 } 2628 2629 // Register for MODI projection of divmodI. 2630 RegMask Matcher::modI_proj_mask() { 2631 ShouldNotReachHere(); 2632 return RegMask(); 2633 } 2634 2635 // Register for DIVL projection of divmodL. 2636 RegMask Matcher::divL_proj_mask() { 2637 ShouldNotReachHere(); 2638 return RegMask(); 2639 } 2640 2641 // Register for MODL projection of divmodL. 2642 RegMask Matcher::modL_proj_mask() { 2643 ShouldNotReachHere(); 2644 return RegMask(); 2645 } 2646 2647 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2648 return RegMask(); 2649 } 2650 2651 const bool Matcher::convi2l_type_required = true; 2652 2653 %} 2654 2655 //----------ENCODING BLOCK----------------------------------------------------- 2656 // This block specifies the encoding classes used by the compiler to output 2657 // byte streams. Encoding classes are parameterized macros used by 2658 // Machine Instruction Nodes in order to generate the bit encoding of the 2659 // instruction. Operands specify their base encoding interface with the 2660 // interface keyword. There are currently supported four interfaces, 2661 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2662 // operand to generate a function which returns its register number when 2663 // queried. CONST_INTER causes an operand to generate a function which 2664 // returns the value of the constant when queried. MEMORY_INTER causes an 2665 // operand to generate four functions which return the Base Register, the 2666 // Index Register, the Scale Value, and the Offset Value of the operand when 2667 // queried. COND_INTER causes an operand to generate six functions which 2668 // return the encoding code (ie - encoding bits for the instruction) 2669 // associated with each basic boolean condition for a conditional instruction. 2670 // 2671 // Instructions specify two basic values for encoding. Again, a function 2672 // is available to check if the constant displacement is an oop. They use the 2673 // ins_encode keyword to specify their encoding classes (which must be 2674 // a sequence of enc_class names, and their parameters, specified in 2675 // the encoding block), and they use the 2676 // opcode keyword to specify, in order, their primary, secondary, and 2677 // tertiary opcode. Only the opcode sections which a particular instruction 2678 // needs for encoding need to be specified. 2679 encode %{ 2680 enc_class enc_unimplemented %{ 2681 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2682 C2_MacroAssembler _masm(&cbuf); 2683 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2684 %} 2685 2686 enc_class enc_untested %{ 2687 #ifdef ASSERT 2688 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2689 C2_MacroAssembler _masm(&cbuf); 2690 __ untested("Untested mach node encoding in AD file."); 2691 #else 2692 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2693 #endif 2694 %} 2695 2696 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2697 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 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 %} 2702 2703 // Load acquire. 2704 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2705 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2706 C2_MacroAssembler _masm(&cbuf); 2707 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2708 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2709 __ twi_0($dst$$Register); 2710 __ isync(); 2711 %} 2712 2713 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2714 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2715 2716 C2_MacroAssembler _masm(&cbuf); 2717 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2718 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2719 %} 2720 2721 // Load acquire. 2722 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2723 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2724 2725 C2_MacroAssembler _masm(&cbuf); 2726 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2727 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2728 __ twi_0($dst$$Register); 2729 __ isync(); 2730 %} 2731 2732 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2733 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2734 2735 C2_MacroAssembler _masm(&cbuf); 2736 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2737 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2738 %} 2739 2740 // Load acquire. 2741 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2742 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2743 2744 C2_MacroAssembler _masm(&cbuf); 2745 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2746 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2747 __ twi_0($dst$$Register); 2748 __ isync(); 2749 %} 2750 2751 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2752 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2753 C2_MacroAssembler _masm(&cbuf); 2754 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2755 // Operand 'ds' requires 4-alignment. 2756 assert((Idisp & 0x3) == 0, "unaligned offset"); 2757 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2758 %} 2759 2760 // Load acquire. 2761 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2762 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2763 C2_MacroAssembler _masm(&cbuf); 2764 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2765 // Operand 'ds' requires 4-alignment. 2766 assert((Idisp & 0x3) == 0, "unaligned offset"); 2767 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2768 __ twi_0($dst$$Register); 2769 __ isync(); 2770 %} 2771 2772 enc_class enc_lfd(RegF dst, memory mem) %{ 2773 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2774 C2_MacroAssembler _masm(&cbuf); 2775 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2776 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2777 %} 2778 2779 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2780 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2781 2782 C2_MacroAssembler _masm(&cbuf); 2783 int toc_offset = 0; 2784 2785 address const_toc_addr; 2786 // Create a non-oop constant, no relocation needed. 2787 // If it is an IC, it has a virtual_call_Relocation. 2788 const_toc_addr = __ long_constant((jlong)$src$$constant); 2789 if (const_toc_addr == NULL) { 2790 ciEnv::current()->record_out_of_memory_failure(); 2791 return; 2792 } 2793 2794 // Get the constant's TOC offset. 2795 toc_offset = __ offset_to_method_toc(const_toc_addr); 2796 2797 // Keep the current instruction offset in mind. 2798 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2799 2800 __ ld($dst$$Register, toc_offset, $toc$$Register); 2801 %} 2802 2803 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2804 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2805 2806 C2_MacroAssembler _masm(&cbuf); 2807 2808 if (!ra_->C->output()->in_scratch_emit_size()) { 2809 address const_toc_addr; 2810 // Create a non-oop constant, no relocation needed. 2811 // If it is an IC, it has a virtual_call_Relocation. 2812 const_toc_addr = __ long_constant((jlong)$src$$constant); 2813 if (const_toc_addr == NULL) { 2814 ciEnv::current()->record_out_of_memory_failure(); 2815 return; 2816 } 2817 2818 // Get the constant's TOC offset. 2819 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2820 // Store the toc offset of the constant. 2821 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2822 2823 // Also keep the current instruction offset in mind. 2824 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2825 } 2826 2827 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2828 %} 2829 2830 %} // encode 2831 2832 source %{ 2833 2834 typedef struct { 2835 loadConL_hiNode *_large_hi; 2836 loadConL_loNode *_large_lo; 2837 loadConLNode *_small; 2838 MachNode *_last; 2839 } loadConLNodesTuple; 2840 2841 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2842 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2843 loadConLNodesTuple nodes; 2844 2845 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2846 if (large_constant_pool) { 2847 // Create new nodes. 2848 loadConL_hiNode *m1 = new loadConL_hiNode(); 2849 loadConL_loNode *m2 = new loadConL_loNode(); 2850 2851 // inputs for new nodes 2852 m1->add_req(NULL, toc); 2853 m2->add_req(NULL, m1); 2854 2855 // operands for new nodes 2856 m1->_opnds[0] = new iRegLdstOper(); // dst 2857 m1->_opnds[1] = immSrc; // src 2858 m1->_opnds[2] = new iRegPdstOper(); // toc 2859 m2->_opnds[0] = new iRegLdstOper(); // dst 2860 m2->_opnds[1] = immSrc; // src 2861 m2->_opnds[2] = new iRegLdstOper(); // base 2862 2863 // Initialize ins_attrib TOC fields. 2864 m1->_const_toc_offset = -1; 2865 m2->_const_toc_offset_hi_node = m1; 2866 2867 // Initialize ins_attrib instruction offset. 2868 m1->_cbuf_insts_offset = -1; 2869 2870 // register allocation for new nodes 2871 ra_->set_pair(m1->_idx, reg_second, reg_first); 2872 ra_->set_pair(m2->_idx, reg_second, reg_first); 2873 2874 // Create result. 2875 nodes._large_hi = m1; 2876 nodes._large_lo = m2; 2877 nodes._small = NULL; 2878 nodes._last = nodes._large_lo; 2879 assert(m2->bottom_type()->isa_long(), "must be long"); 2880 } else { 2881 loadConLNode *m2 = new loadConLNode(); 2882 2883 // inputs for new nodes 2884 m2->add_req(NULL, toc); 2885 2886 // operands for new nodes 2887 m2->_opnds[0] = new iRegLdstOper(); // dst 2888 m2->_opnds[1] = immSrc; // src 2889 m2->_opnds[2] = new iRegPdstOper(); // toc 2890 2891 // Initialize ins_attrib instruction offset. 2892 m2->_cbuf_insts_offset = -1; 2893 2894 // register allocation for new nodes 2895 ra_->set_pair(m2->_idx, reg_second, reg_first); 2896 2897 // Create result. 2898 nodes._large_hi = NULL; 2899 nodes._large_lo = NULL; 2900 nodes._small = m2; 2901 nodes._last = nodes._small; 2902 assert(m2->bottom_type()->isa_long(), "must be long"); 2903 } 2904 2905 return nodes; 2906 } 2907 2908 typedef struct { 2909 loadConL_hiNode *_large_hi; 2910 loadConL_loNode *_large_lo; 2911 mtvsrdNode *_moved; 2912 xxspltdNode *_replicated; 2913 loadConLNode *_small; 2914 MachNode *_last; 2915 } loadConLReplicatedNodesTuple; 2916 2917 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2918 vecXOper *dst, immI_0Oper *zero, 2919 OptoReg::Name reg_second, OptoReg::Name reg_first, 2920 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2921 loadConLReplicatedNodesTuple nodes; 2922 2923 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2924 if (large_constant_pool) { 2925 // Create new nodes. 2926 loadConL_hiNode *m1 = new loadConL_hiNode(); 2927 loadConL_loNode *m2 = new loadConL_loNode(); 2928 mtvsrdNode *m3 = new mtvsrdNode(); 2929 xxspltdNode *m4 = new xxspltdNode(); 2930 2931 // inputs for new nodes 2932 m1->add_req(NULL, toc); 2933 m2->add_req(NULL, m1); 2934 m3->add_req(NULL, m2); 2935 m4->add_req(NULL, m3); 2936 2937 // operands for new nodes 2938 m1->_opnds[0] = new iRegLdstOper(); // dst 2939 m1->_opnds[1] = immSrc; // src 2940 m1->_opnds[2] = new iRegPdstOper(); // toc 2941 2942 m2->_opnds[0] = new iRegLdstOper(); // dst 2943 m2->_opnds[1] = immSrc; // src 2944 m2->_opnds[2] = new iRegLdstOper(); // base 2945 2946 m3->_opnds[0] = new vecXOper(); // dst 2947 m3->_opnds[1] = new iRegLdstOper(); // src 2948 2949 m4->_opnds[0] = new vecXOper(); // dst 2950 m4->_opnds[1] = new vecXOper(); // src 2951 m4->_opnds[2] = zero; 2952 2953 // Initialize ins_attrib TOC fields. 2954 m1->_const_toc_offset = -1; 2955 m2->_const_toc_offset_hi_node = m1; 2956 2957 // Initialize ins_attrib instruction offset. 2958 m1->_cbuf_insts_offset = -1; 2959 2960 // register allocation for new nodes 2961 ra_->set_pair(m1->_idx, reg_second, reg_first); 2962 ra_->set_pair(m2->_idx, reg_second, reg_first); 2963 ra_->set1(m3->_idx, reg_second); 2964 ra_->set2(m3->_idx, reg_vec_first); 2965 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2966 2967 // Create result. 2968 nodes._large_hi = m1; 2969 nodes._large_lo = m2; 2970 nodes._moved = m3; 2971 nodes._replicated = m4; 2972 nodes._small = NULL; 2973 nodes._last = nodes._replicated; 2974 assert(m2->bottom_type()->isa_long(), "must be long"); 2975 } else { 2976 loadConLNode *m2 = new loadConLNode(); 2977 mtvsrdNode *m3 = new mtvsrdNode(); 2978 xxspltdNode *m4 = new xxspltdNode(); 2979 2980 // inputs for new nodes 2981 m2->add_req(NULL, toc); 2982 2983 // operands for new nodes 2984 m2->_opnds[0] = new iRegLdstOper(); // dst 2985 m2->_opnds[1] = immSrc; // src 2986 m2->_opnds[2] = new iRegPdstOper(); // toc 2987 2988 m3->_opnds[0] = new vecXOper(); // dst 2989 m3->_opnds[1] = new iRegLdstOper(); // src 2990 2991 m4->_opnds[0] = new vecXOper(); // dst 2992 m4->_opnds[1] = new vecXOper(); // src 2993 m4->_opnds[2] = zero; 2994 2995 // Initialize ins_attrib instruction offset. 2996 m2->_cbuf_insts_offset = -1; 2997 ra_->set1(m3->_idx, reg_second); 2998 ra_->set2(m3->_idx, reg_vec_first); 2999 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 3000 3001 // register allocation for new nodes 3002 ra_->set_pair(m2->_idx, reg_second, reg_first); 3003 3004 // Create result. 3005 nodes._large_hi = NULL; 3006 nodes._large_lo = NULL; 3007 nodes._small = m2; 3008 nodes._moved = m3; 3009 nodes._replicated = m4; 3010 nodes._last = nodes._replicated; 3011 assert(m2->bottom_type()->isa_long(), "must be long"); 3012 } 3013 3014 return nodes; 3015 } 3016 3017 %} // source 3018 3019 encode %{ 3020 // Postalloc expand emitter for loading a long constant from the method's TOC. 3021 // Enc_class needed as consttanttablebase is not supported by postalloc 3022 // expand. 3023 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 3024 // Create new nodes. 3025 loadConLNodesTuple loadConLNodes = 3026 loadConLNodesTuple_create(ra_, n_toc, op_src, 3027 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3028 3029 // Push new nodes. 3030 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3031 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3032 3033 // some asserts 3034 assert(nodes->length() >= 1, "must have created at least 1 node"); 3035 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3036 %} 3037 3038 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 3039 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3040 3041 C2_MacroAssembler _masm(&cbuf); 3042 int toc_offset = 0; 3043 3044 intptr_t val = $src$$constant; 3045 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 3046 address const_toc_addr; 3047 if (constant_reloc == relocInfo::oop_type) { 3048 // Create an oop constant and a corresponding relocation. 3049 AddressLiteral a = __ allocate_oop_address((jobject)val); 3050 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3051 __ relocate(a.rspec()); 3052 } else if (constant_reloc == relocInfo::metadata_type) { 3053 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 3054 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3055 __ relocate(a.rspec()); 3056 } else { 3057 // Create a non-oop constant, no relocation needed. 3058 const_toc_addr = __ long_constant((jlong)$src$$constant); 3059 } 3060 3061 if (const_toc_addr == NULL) { 3062 ciEnv::current()->record_out_of_memory_failure(); 3063 return; 3064 } 3065 // Get the constant's TOC offset. 3066 toc_offset = __ offset_to_method_toc(const_toc_addr); 3067 3068 __ ld($dst$$Register, toc_offset, $toc$$Register); 3069 %} 3070 3071 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 3072 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 3073 3074 C2_MacroAssembler _masm(&cbuf); 3075 if (!ra_->C->output()->in_scratch_emit_size()) { 3076 intptr_t val = $src$$constant; 3077 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 3078 address const_toc_addr; 3079 if (constant_reloc == relocInfo::oop_type) { 3080 // Create an oop constant and a corresponding relocation. 3081 AddressLiteral a = __ allocate_oop_address((jobject)val); 3082 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3083 __ relocate(a.rspec()); 3084 } else if (constant_reloc == relocInfo::metadata_type) { 3085 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 3086 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3087 __ relocate(a.rspec()); 3088 } else { // non-oop pointers, e.g. card mark base, heap top 3089 // Create a non-oop constant, no relocation needed. 3090 const_toc_addr = __ long_constant((jlong)$src$$constant); 3091 } 3092 3093 if (const_toc_addr == NULL) { 3094 ciEnv::current()->record_out_of_memory_failure(); 3095 return; 3096 } 3097 // Get the constant's TOC offset. 3098 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 3099 // Store the toc offset of the constant. 3100 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 3101 } 3102 3103 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 3104 %} 3105 3106 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 3107 // Enc_class needed as consttanttablebase is not supported by postalloc 3108 // expand. 3109 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 3110 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3111 if (large_constant_pool) { 3112 // Create new nodes. 3113 loadConP_hiNode *m1 = new loadConP_hiNode(); 3114 loadConP_loNode *m2 = new loadConP_loNode(); 3115 3116 // inputs for new nodes 3117 m1->add_req(NULL, n_toc); 3118 m2->add_req(NULL, m1); 3119 3120 // operands for new nodes 3121 m1->_opnds[0] = new iRegPdstOper(); // dst 3122 m1->_opnds[1] = op_src; // src 3123 m1->_opnds[2] = new iRegPdstOper(); // toc 3124 m2->_opnds[0] = new iRegPdstOper(); // dst 3125 m2->_opnds[1] = op_src; // src 3126 m2->_opnds[2] = new iRegLdstOper(); // base 3127 3128 // Initialize ins_attrib TOC fields. 3129 m1->_const_toc_offset = -1; 3130 m2->_const_toc_offset_hi_node = m1; 3131 3132 // Register allocation for new nodes. 3133 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3134 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3135 3136 nodes->push(m1); 3137 nodes->push(m2); 3138 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3139 } else { 3140 loadConPNode *m2 = new loadConPNode(); 3141 3142 // inputs for new nodes 3143 m2->add_req(NULL, n_toc); 3144 3145 // operands for new nodes 3146 m2->_opnds[0] = new iRegPdstOper(); // dst 3147 m2->_opnds[1] = op_src; // src 3148 m2->_opnds[2] = new iRegPdstOper(); // toc 3149 3150 // Register allocation for new nodes. 3151 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3152 3153 nodes->push(m2); 3154 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3155 } 3156 %} 3157 3158 // Enc_class needed as consttanttablebase is not supported by postalloc 3159 // expand. 3160 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3161 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3162 3163 MachNode *m2; 3164 if (large_constant_pool) { 3165 m2 = new loadConFCompNode(); 3166 } else { 3167 m2 = new loadConFNode(); 3168 } 3169 // inputs for new nodes 3170 m2->add_req(NULL, n_toc); 3171 3172 // operands for new nodes 3173 m2->_opnds[0] = op_dst; 3174 m2->_opnds[1] = op_src; 3175 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3176 3177 // register allocation for new nodes 3178 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3179 nodes->push(m2); 3180 %} 3181 3182 // Enc_class needed as consttanttablebase is not supported by postalloc 3183 // expand. 3184 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3185 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3186 3187 MachNode *m2; 3188 if (large_constant_pool) { 3189 m2 = new loadConDCompNode(); 3190 } else { 3191 m2 = new loadConDNode(); 3192 } 3193 // inputs for new nodes 3194 m2->add_req(NULL, n_toc); 3195 3196 // operands for new nodes 3197 m2->_opnds[0] = op_dst; 3198 m2->_opnds[1] = op_src; 3199 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3200 3201 // register allocation for new nodes 3202 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3203 nodes->push(m2); 3204 %} 3205 3206 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3207 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3208 C2_MacroAssembler _masm(&cbuf); 3209 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3210 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3211 %} 3212 3213 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3214 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3215 C2_MacroAssembler _masm(&cbuf); 3216 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3217 // Operand 'ds' requires 4-alignment. 3218 assert((Idisp & 0x3) == 0, "unaligned offset"); 3219 __ std($src$$Register, Idisp, $mem$$base$$Register); 3220 %} 3221 3222 enc_class enc_stfs(RegF src, memory mem) %{ 3223 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3224 C2_MacroAssembler _masm(&cbuf); 3225 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3226 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3227 %} 3228 3229 enc_class enc_stfd(RegF src, memory mem) %{ 3230 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3231 C2_MacroAssembler _masm(&cbuf); 3232 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3233 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3234 %} 3235 3236 // Use release_store for card-marking to ensure that previous 3237 // oop-stores are visible before the card-mark change. 3238 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3239 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3240 // FIXME: Implement this as a cmove and use a fixed condition code 3241 // register which is written on every transition to compiled code, 3242 // e.g. in call-stub and when returning from runtime stubs. 3243 // 3244 // Proposed code sequence for the cmove implementation: 3245 // 3246 // Label skip_release; 3247 // __ beq(CCRfixed, skip_release); 3248 // __ release(); 3249 // __ bind(skip_release); 3250 // __ stb(card mark); 3251 3252 C2_MacroAssembler _masm(&cbuf); 3253 Label skip_storestore; 3254 3255 #if 0 // TODO: PPC port 3256 // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the 3257 // StoreStore barrier conditionally. 3258 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3259 __ cmpwi($crx$$CondRegister, R0, 0); 3260 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3261 #endif 3262 __ li(R0, 0); 3263 __ membar(Assembler::StoreStore); 3264 #if 0 // TODO: PPC port 3265 __ bind(skip_storestore); 3266 #endif 3267 3268 // Do the store. 3269 if ($mem$$index == 0) { 3270 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3271 } else { 3272 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3273 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3274 } 3275 %} 3276 3277 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3278 3279 if (VM_Version::has_isel()) { 3280 // use isel instruction with Power 7 3281 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3282 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3283 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3284 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3285 3286 n_compare->add_req(n_region, n_src); 3287 n_compare->_opnds[0] = op_crx; 3288 n_compare->_opnds[1] = op_src; 3289 n_compare->_opnds[2] = new immL16Oper(0); 3290 3291 n_sub_base->add_req(n_region, n_src); 3292 n_sub_base->_opnds[0] = op_dst; 3293 n_sub_base->_opnds[1] = op_src; 3294 n_sub_base->_bottom_type = _bottom_type; 3295 3296 n_shift->add_req(n_region, n_sub_base); 3297 n_shift->_opnds[0] = op_dst; 3298 n_shift->_opnds[1] = op_dst; 3299 n_shift->_bottom_type = _bottom_type; 3300 3301 n_cond_set->add_req(n_region, n_compare, n_shift); 3302 n_cond_set->_opnds[0] = op_dst; 3303 n_cond_set->_opnds[1] = op_crx; 3304 n_cond_set->_opnds[2] = op_dst; 3305 n_cond_set->_bottom_type = _bottom_type; 3306 3307 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3308 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3309 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3310 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3311 3312 nodes->push(n_compare); 3313 nodes->push(n_sub_base); 3314 nodes->push(n_shift); 3315 nodes->push(n_cond_set); 3316 3317 } else { 3318 // before Power 7 3319 moveRegNode *n_move = new moveRegNode(); 3320 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3321 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3322 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3323 3324 n_move->add_req(n_region, n_src); 3325 n_move->_opnds[0] = op_dst; 3326 n_move->_opnds[1] = op_src; 3327 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3328 3329 n_compare->add_req(n_region, n_src); 3330 n_compare->add_prec(n_move); 3331 3332 n_compare->_opnds[0] = op_crx; 3333 n_compare->_opnds[1] = op_src; 3334 n_compare->_opnds[2] = new immL16Oper(0); 3335 3336 n_sub_base->add_req(n_region, n_compare, n_src); 3337 n_sub_base->_opnds[0] = op_dst; 3338 n_sub_base->_opnds[1] = op_crx; 3339 n_sub_base->_opnds[2] = op_src; 3340 n_sub_base->_bottom_type = _bottom_type; 3341 3342 n_shift->add_req(n_region, n_sub_base); 3343 n_shift->_opnds[0] = op_dst; 3344 n_shift->_opnds[1] = op_dst; 3345 n_shift->_bottom_type = _bottom_type; 3346 3347 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3348 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3349 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3350 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3351 3352 nodes->push(n_move); 3353 nodes->push(n_compare); 3354 nodes->push(n_sub_base); 3355 nodes->push(n_shift); 3356 } 3357 3358 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3359 %} 3360 3361 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3362 3363 encodeP_subNode *n1 = new encodeP_subNode(); 3364 n1->add_req(n_region, n_src); 3365 n1->_opnds[0] = op_dst; 3366 n1->_opnds[1] = op_src; 3367 n1->_bottom_type = _bottom_type; 3368 3369 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3370 n2->add_req(n_region, n1); 3371 n2->_opnds[0] = op_dst; 3372 n2->_opnds[1] = op_dst; 3373 n2->_bottom_type = _bottom_type; 3374 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3375 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3376 3377 nodes->push(n1); 3378 nodes->push(n2); 3379 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3380 %} 3381 3382 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3383 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3384 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3385 3386 n_compare->add_req(n_region, n_src); 3387 n_compare->_opnds[0] = op_crx; 3388 n_compare->_opnds[1] = op_src; 3389 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3390 3391 n_shift->add_req(n_region, n_src); 3392 n_shift->_opnds[0] = op_dst; 3393 n_shift->_opnds[1] = op_src; 3394 n_shift->_bottom_type = _bottom_type; 3395 3396 if (VM_Version::has_isel()) { 3397 // use isel instruction with Power 7 3398 3399 decodeN_addNode *n_add_base = new decodeN_addNode(); 3400 n_add_base->add_req(n_region, n_shift); 3401 n_add_base->_opnds[0] = op_dst; 3402 n_add_base->_opnds[1] = op_dst; 3403 n_add_base->_bottom_type = _bottom_type; 3404 3405 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3406 n_cond_set->add_req(n_region, n_compare, n_add_base); 3407 n_cond_set->_opnds[0] = op_dst; 3408 n_cond_set->_opnds[1] = op_crx; 3409 n_cond_set->_opnds[2] = op_dst; 3410 n_cond_set->_bottom_type = _bottom_type; 3411 3412 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3413 ra_->set_oop(n_cond_set, true); 3414 3415 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3416 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3417 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3418 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3419 3420 nodes->push(n_compare); 3421 nodes->push(n_shift); 3422 nodes->push(n_add_base); 3423 nodes->push(n_cond_set); 3424 3425 } else { 3426 // before Power 7 3427 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3428 3429 n_add_base->add_req(n_region, n_compare, n_shift); 3430 n_add_base->_opnds[0] = op_dst; 3431 n_add_base->_opnds[1] = op_crx; 3432 n_add_base->_opnds[2] = op_dst; 3433 n_add_base->_bottom_type = _bottom_type; 3434 3435 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3436 ra_->set_oop(n_add_base, true); 3437 3438 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3439 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3440 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3441 3442 nodes->push(n_compare); 3443 nodes->push(n_shift); 3444 nodes->push(n_add_base); 3445 } 3446 %} 3447 3448 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3449 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3450 n1->add_req(n_region, n_src); 3451 n1->_opnds[0] = op_dst; 3452 n1->_opnds[1] = op_src; 3453 n1->_bottom_type = _bottom_type; 3454 3455 decodeN_addNode *n2 = new decodeN_addNode(); 3456 n2->add_req(n_region, n1); 3457 n2->_opnds[0] = op_dst; 3458 n2->_opnds[1] = op_dst; 3459 n2->_bottom_type = _bottom_type; 3460 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3461 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3462 3463 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3464 ra_->set_oop(n2, true); 3465 3466 nodes->push(n1); 3467 nodes->push(n2); 3468 %} 3469 3470 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3471 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3472 3473 C2_MacroAssembler _masm(&cbuf); 3474 int cc = $cmp$$cmpcode; 3475 int flags_reg = $crx$$reg; 3476 Label done; 3477 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3478 // Branch if not (cmp crx). 3479 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3480 __ mr($dst$$Register, $src$$Register); 3481 // TODO PPC port __ endgroup_if_needed(_size == 12); 3482 __ bind(done); 3483 %} 3484 3485 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3486 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3487 3488 C2_MacroAssembler _masm(&cbuf); 3489 Label done; 3490 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3491 // Branch if not (cmp crx). 3492 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3493 __ li($dst$$Register, $src$$constant); 3494 // TODO PPC port __ endgroup_if_needed(_size == 12); 3495 __ bind(done); 3496 %} 3497 3498 // This enc_class is needed so that scheduler gets proper 3499 // input mapping for latency computation. 3500 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3501 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3502 C2_MacroAssembler _masm(&cbuf); 3503 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3504 %} 3505 3506 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3507 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3508 3509 C2_MacroAssembler _masm(&cbuf); 3510 3511 Label done; 3512 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3513 __ li($dst$$Register, $zero$$constant); 3514 __ beq($crx$$CondRegister, done); 3515 __ li($dst$$Register, $notzero$$constant); 3516 __ bind(done); 3517 %} 3518 3519 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3520 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3521 3522 C2_MacroAssembler _masm(&cbuf); 3523 3524 Label done; 3525 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3526 __ li($dst$$Register, $zero$$constant); 3527 __ beq($crx$$CondRegister, done); 3528 __ li($dst$$Register, $notzero$$constant); 3529 __ bind(done); 3530 %} 3531 3532 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3533 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3534 3535 C2_MacroAssembler _masm(&cbuf); 3536 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3537 Label done; 3538 __ bso($crx$$CondRegister, done); 3539 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3540 // TODO PPC port __ endgroup_if_needed(_size == 12); 3541 __ bind(done); 3542 %} 3543 3544 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3545 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3546 3547 C2_MacroAssembler _masm(&cbuf); 3548 Label done; 3549 __ bso($crx$$CondRegister, done); 3550 __ mffprd($dst$$Register, $src$$FloatRegister); 3551 // TODO PPC port __ endgroup_if_needed(_size == 12); 3552 __ bind(done); 3553 %} 3554 3555 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3556 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3557 3558 C2_MacroAssembler _masm(&cbuf); 3559 Label d; // dummy 3560 __ bind(d); 3561 Label* p = ($lbl$$label); 3562 // `p' is `NULL' when this encoding class is used only to 3563 // determine the size of the encoded instruction. 3564 Label& l = (NULL == p)? d : *(p); 3565 int cc = $cmp$$cmpcode; 3566 int flags_reg = $crx$$reg; 3567 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3568 int bhint = Assembler::bhintNoHint; 3569 3570 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3571 if (_prob <= PROB_NEVER) { 3572 bhint = Assembler::bhintIsNotTaken; 3573 } else if (_prob >= PROB_ALWAYS) { 3574 bhint = Assembler::bhintIsTaken; 3575 } 3576 } 3577 3578 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3579 cc_to_biint(cc, flags_reg), 3580 l); 3581 %} 3582 3583 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3584 // The scheduler doesn't know about branch shortening, so we set the opcode 3585 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3586 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3587 3588 C2_MacroAssembler _masm(&cbuf); 3589 Label d; // dummy 3590 __ bind(d); 3591 Label* p = ($lbl$$label); 3592 // `p' is `NULL' when this encoding class is used only to 3593 // determine the size of the encoded instruction. 3594 Label& l = (NULL == p)? d : *(p); 3595 int cc = $cmp$$cmpcode; 3596 int flags_reg = $crx$$reg; 3597 int bhint = Assembler::bhintNoHint; 3598 3599 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3600 if (_prob <= PROB_NEVER) { 3601 bhint = Assembler::bhintIsNotTaken; 3602 } else if (_prob >= PROB_ALWAYS) { 3603 bhint = Assembler::bhintIsTaken; 3604 } 3605 } 3606 3607 // Tell the conditional far branch to optimize itself when being relocated. 3608 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3609 cc_to_biint(cc, flags_reg), 3610 l, 3611 MacroAssembler::bc_far_optimize_on_relocate); 3612 %} 3613 3614 // Branch used with Power6 scheduling (can be shortened without changing the node). 3615 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3616 // The scheduler doesn't know about branch shortening, so we set the opcode 3617 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3618 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3619 3620 C2_MacroAssembler _masm(&cbuf); 3621 Label d; // dummy 3622 __ bind(d); 3623 Label* p = ($lbl$$label); 3624 // `p' is `NULL' when this encoding class is used only to 3625 // determine the size of the encoded instruction. 3626 Label& l = (NULL == p)? d : *(p); 3627 int cc = $cmp$$cmpcode; 3628 int flags_reg = $crx$$reg; 3629 int bhint = Assembler::bhintNoHint; 3630 3631 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3632 if (_prob <= PROB_NEVER) { 3633 bhint = Assembler::bhintIsNotTaken; 3634 } else if (_prob >= PROB_ALWAYS) { 3635 bhint = Assembler::bhintIsTaken; 3636 } 3637 } 3638 3639 #if 0 // TODO: PPC port 3640 if (_size == 8) { 3641 // Tell the conditional far branch to optimize itself when being relocated. 3642 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3643 cc_to_biint(cc, flags_reg), 3644 l, 3645 MacroAssembler::bc_far_optimize_on_relocate); 3646 } else { 3647 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3648 cc_to_biint(cc, flags_reg), 3649 l); 3650 } 3651 #endif 3652 Unimplemented(); 3653 %} 3654 3655 // Postalloc expand emitter for loading a replicatef float constant from 3656 // the method's TOC. 3657 // Enc_class needed as consttanttablebase is not supported by postalloc 3658 // expand. 3659 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3660 // Create new nodes. 3661 3662 // Make an operand with the bit pattern to load as float. 3663 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3664 3665 loadConLNodesTuple loadConLNodes = 3666 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3667 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3668 3669 // Push new nodes. 3670 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3671 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3672 3673 assert(nodes->length() >= 1, "must have created at least 1 node"); 3674 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3675 %} 3676 3677 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3678 // Create new nodes. 3679 3680 // Make an operand with the bit pattern to load as float. 3681 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3682 immI_0Oper *op_zero = new immI_0Oper(0); 3683 3684 loadConLReplicatedNodesTuple loadConLNodes = 3685 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3686 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3687 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3688 3689 // Push new nodes. 3690 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3691 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3692 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3693 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3694 3695 assert(nodes->length() >= 1, "must have created at least 1 node"); 3696 %} 3697 3698 // This enc_class is needed so that scheduler gets proper 3699 // input mapping for latency computation. 3700 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3701 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3702 // Fake operand dst needed for PPC scheduler. 3703 assert($dst$$constant == 0x0, "dst must be 0x0"); 3704 3705 C2_MacroAssembler _masm(&cbuf); 3706 // Mark the code position where the load from the safepoint 3707 // polling page was emitted as relocInfo::poll_type. 3708 __ relocate(relocInfo::poll_type); 3709 __ load_from_polling_page($poll$$Register); 3710 %} 3711 3712 // A Java static call or a runtime call. 3713 // 3714 // Branch-and-link relative to a trampoline. 3715 // The trampoline loads the target address and does a long branch to there. 3716 // In case we call java, the trampoline branches to a interpreter_stub 3717 // which loads the inline cache and the real call target from the constant pool. 3718 // 3719 // This basically looks like this: 3720 // 3721 // >>>> consts -+ -+ 3722 // | |- offset1 3723 // [call target1] | <-+ 3724 // [IC cache] |- offset2 3725 // [call target2] <--+ 3726 // 3727 // <<<< consts 3728 // >>>> insts 3729 // 3730 // bl offset16 -+ -+ ??? // How many bits available? 3731 // | | 3732 // <<<< insts | | 3733 // >>>> stubs | | 3734 // | |- trampoline_stub_Reloc 3735 // trampoline stub: | <-+ 3736 // r2 = toc | 3737 // r2 = [r2 + offset1] | // Load call target1 from const section 3738 // mtctr r2 | 3739 // bctr |- static_stub_Reloc 3740 // comp_to_interp_stub: <---+ 3741 // r1 = toc 3742 // ICreg = [r1 + IC_offset] // Load IC from const section 3743 // r1 = [r1 + offset2] // Load call target2 from const section 3744 // mtctr r1 3745 // bctr 3746 // 3747 // <<<< stubs 3748 // 3749 // The call instruction in the code either 3750 // - Branches directly to a compiled method if the offset is encodable in instruction. 3751 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3752 // - Branches to the compiled_to_interp stub if the target is interpreted. 3753 // 3754 // Further there are three relocations from the loads to the constants in 3755 // the constant section. 3756 // 3757 // Usage of r1 and r2 in the stubs allows to distinguish them. 3758 enc_class enc_java_static_call(method meth) %{ 3759 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3760 3761 C2_MacroAssembler _masm(&cbuf); 3762 address entry_point = (address)$meth$$method; 3763 3764 if (!_method) { 3765 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3766 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3767 } else { 3768 // Remember the offset not the address. 3769 const int start_offset = __ offset(); 3770 3771 // The trampoline stub. 3772 // No entry point given, use the current pc. 3773 // Make sure branch fits into 3774 if (entry_point == 0) entry_point = __ pc(); 3775 3776 // Put the entry point as a constant into the constant pool. 3777 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3778 if (entry_point_toc_addr == NULL) { 3779 ciEnv::current()->record_out_of_memory_failure(); 3780 return; 3781 } 3782 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3783 3784 // Emit the trampoline stub which will be related to the branch-and-link below. 3785 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3786 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3787 int method_index = resolved_method_index(cbuf); 3788 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3789 : static_call_Relocation::spec(method_index)); 3790 3791 // The real call. 3792 // Note: At this point we do not have the address of the trampoline 3793 // stub, and the entry point might be too far away for bl, so __ pc() 3794 // serves as dummy and the bl will be patched later. 3795 cbuf.set_insts_mark(); 3796 __ bl(__ pc()); // Emits a relocation. 3797 3798 // The stub for call to interpreter. 3799 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3800 if (stub == NULL) { 3801 ciEnv::current()->record_failure("CodeCache is full"); 3802 return; 3803 } 3804 } 3805 %} 3806 3807 // Second node of expanded dynamic call - the call. 3808 enc_class enc_java_dynamic_call_sched(method meth) %{ 3809 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3810 3811 C2_MacroAssembler _masm(&cbuf); 3812 3813 if (!ra_->C->output()->in_scratch_emit_size()) { 3814 // Create a call trampoline stub for the given method. 3815 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3816 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3817 if (entry_point_const == NULL) { 3818 ciEnv::current()->record_out_of_memory_failure(); 3819 return; 3820 } 3821 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3822 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3823 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3824 3825 // Build relocation at call site with ic position as data. 3826 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3827 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3828 "must have one, but can't have both"); 3829 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3830 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3831 "must contain instruction offset"); 3832 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3833 ? _load_ic_hi_node->_cbuf_insts_offset 3834 : _load_ic_node->_cbuf_insts_offset; 3835 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3836 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3837 "should be load from TOC"); 3838 int method_index = resolved_method_index(cbuf); 3839 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3840 } 3841 3842 // At this point I do not have the address of the trampoline stub, 3843 // and the entry point might be too far away for bl. Pc() serves 3844 // as dummy and bl will be patched later. 3845 __ bl((address) __ pc()); 3846 %} 3847 3848 // postalloc expand emitter for virtual calls. 3849 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3850 3851 // Create the nodes for loading the IC from the TOC. 3852 loadConLNodesTuple loadConLNodes_IC = 3853 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3854 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3855 3856 // Create the call node. 3857 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3858 call->_method_handle_invoke = _method_handle_invoke; 3859 call->_vtable_index = _vtable_index; 3860 call->_method = _method; 3861 call->_bci = _bci; 3862 call->_optimized_virtual = _optimized_virtual; 3863 call->_tf = _tf; 3864 call->_entry_point = _entry_point; 3865 call->_cnt = _cnt; 3866 call->_argsize = _argsize; 3867 call->_oop_map = _oop_map; 3868 call->_jvms = _jvms; 3869 call->_jvmadj = _jvmadj; 3870 call->_in_rms = _in_rms; 3871 call->_nesting = _nesting; 3872 call->_override_symbolic_info = _override_symbolic_info; 3873 3874 // New call needs all inputs of old call. 3875 // Req... 3876 for (uint i = 0; i < req(); ++i) { 3877 // The expanded node does not need toc any more. 3878 // Add the inline cache constant here instead. This expresses the 3879 // register of the inline cache must be live at the call. 3880 // Else we would have to adapt JVMState by -1. 3881 if (i == mach_constant_base_node_input()) { 3882 call->add_req(loadConLNodes_IC._last); 3883 } else { 3884 call->add_req(in(i)); 3885 } 3886 } 3887 // ...as well as prec 3888 for (uint i = req(); i < len(); ++i) { 3889 call->add_prec(in(i)); 3890 } 3891 3892 // Remember nodes loading the inline cache into r19. 3893 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3894 call->_load_ic_node = loadConLNodes_IC._small; 3895 3896 // Operands for new nodes. 3897 call->_opnds[0] = _opnds[0]; 3898 call->_opnds[1] = _opnds[1]; 3899 3900 // Only the inline cache is associated with a register. 3901 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3902 3903 // Push new nodes. 3904 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3905 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3906 nodes->push(call); 3907 %} 3908 3909 // Compound version of call dynamic 3910 // Toc is only passed so that it can be used in ins_encode statement. 3911 // In the code we have to use $constanttablebase. 3912 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3913 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3914 C2_MacroAssembler _masm(&cbuf); 3915 int start_offset = __ offset(); 3916 3917 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3918 #if 0 3919 int vtable_index = this->_vtable_index; 3920 if (_vtable_index < 0) { 3921 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3922 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3923 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3924 3925 // Virtual call relocation will point to ic load. 3926 address virtual_call_meta_addr = __ pc(); 3927 // Load a clear inline cache. 3928 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3929 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3930 if (!success) { 3931 ciEnv::current()->record_out_of_memory_failure(); 3932 return; 3933 } 3934 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3935 // to determine who we intended to call. 3936 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3937 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3938 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3939 "Fix constant in ret_addr_offset()"); 3940 } else { 3941 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3942 // Go thru the vtable. Get receiver klass. Receiver already 3943 // checked for non-null. If we'll go thru a C2I adapter, the 3944 // interpreter expects method in R19_method. 3945 3946 __ load_klass(R11_scratch1, R3); 3947 3948 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3949 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3950 __ li(R19_method, v_off); 3951 __ ldx(R19_method/*method*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3952 // NOTE: for vtable dispatches, the vtable entry will never be 3953 // null. However it may very well end up in handle_wrong_method 3954 // if the method is abstract for the particular class. 3955 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3956 // Call target. Either compiled code or C2I adapter. 3957 __ mtctr(R11_scratch1); 3958 __ bctrl(); 3959 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3960 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3961 } 3962 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3963 "Fix constant in ret_addr_offset()"); 3964 } 3965 #endif 3966 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3967 %} 3968 3969 // a runtime call 3970 enc_class enc_java_to_runtime_call (method meth) %{ 3971 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3972 3973 C2_MacroAssembler _masm(&cbuf); 3974 const address start_pc = __ pc(); 3975 3976 #if defined(ABI_ELFv2) 3977 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3978 __ call_c(entry, relocInfo::runtime_call_type); 3979 #else 3980 // The function we're going to call. 3981 FunctionDescriptor fdtemp; 3982 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3983 3984 Register Rtoc = R12_scratch2; 3985 // Calculate the method's TOC. 3986 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3987 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3988 // pool entries; call_c_using_toc will optimize the call. 3989 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3990 if (!success) { 3991 ciEnv::current()->record_out_of_memory_failure(); 3992 return; 3993 } 3994 #endif 3995 3996 // Check the ret_addr_offset. 3997 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3998 "Fix constant in ret_addr_offset()"); 3999 %} 4000 4001 // Move to ctr for leaf call. 4002 // This enc_class is needed so that scheduler gets proper 4003 // input mapping for latency computation. 4004 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 4005 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 4006 C2_MacroAssembler _masm(&cbuf); 4007 __ mtctr($src$$Register); 4008 %} 4009 4010 // Postalloc expand emitter for runtime leaf calls. 4011 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 4012 loadConLNodesTuple loadConLNodes_Entry; 4013 #if defined(ABI_ELFv2) 4014 jlong entry_address = (jlong) this->entry_point(); 4015 assert(entry_address, "need address here"); 4016 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 4017 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 4018 #else 4019 // Get the struct that describes the function we are about to call. 4020 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 4021 assert(fd, "need fd here"); 4022 jlong entry_address = (jlong) fd->entry(); 4023 // new nodes 4024 loadConLNodesTuple loadConLNodes_Env; 4025 loadConLNodesTuple loadConLNodes_Toc; 4026 4027 // Create nodes and operands for loading the entry point. 4028 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 4029 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 4030 4031 4032 // Create nodes and operands for loading the env pointer. 4033 if (fd->env() != NULL) { 4034 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 4035 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 4036 } else { 4037 loadConLNodes_Env._large_hi = NULL; 4038 loadConLNodes_Env._large_lo = NULL; 4039 loadConLNodes_Env._small = NULL; 4040 loadConLNodes_Env._last = new loadConL16Node(); 4041 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 4042 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 4043 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 4044 } 4045 4046 // Create nodes and operands for loading the Toc point. 4047 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 4048 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 4049 #endif // ABI_ELFv2 4050 // mtctr node 4051 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 4052 4053 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 4054 mtctr->add_req(0, loadConLNodes_Entry._last); 4055 4056 mtctr->_opnds[0] = new iRegLdstOper(); 4057 mtctr->_opnds[1] = new iRegLdstOper(); 4058 4059 // call node 4060 MachCallLeafNode *call = new CallLeafDirectNode(); 4061 4062 call->_opnds[0] = _opnds[0]; 4063 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 4064 4065 // Make the new call node look like the old one. 4066 call->_name = _name; 4067 call->_tf = _tf; 4068 call->_entry_point = _entry_point; 4069 call->_cnt = _cnt; 4070 call->_argsize = _argsize; 4071 call->_oop_map = _oop_map; 4072 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 4073 call->_jvms = NULL; 4074 call->_jvmadj = _jvmadj; 4075 call->_in_rms = _in_rms; 4076 call->_nesting = _nesting; 4077 4078 4079 // New call needs all inputs of old call. 4080 // Req... 4081 for (uint i = 0; i < req(); ++i) { 4082 if (i != mach_constant_base_node_input()) { 4083 call->add_req(in(i)); 4084 } 4085 } 4086 4087 // These must be reqired edges, as the registers are live up to 4088 // the call. Else the constants are handled as kills. 4089 call->add_req(mtctr); 4090 #if !defined(ABI_ELFv2) 4091 call->add_req(loadConLNodes_Env._last); 4092 call->add_req(loadConLNodes_Toc._last); 4093 #endif 4094 4095 // ...as well as prec 4096 for (uint i = req(); i < len(); ++i) { 4097 call->add_prec(in(i)); 4098 } 4099 4100 // registers 4101 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 4102 4103 // Insert the new nodes. 4104 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 4105 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 4106 #if !defined(ABI_ELFv2) 4107 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 4108 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 4109 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 4110 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 4111 #endif 4112 nodes->push(mtctr); 4113 nodes->push(call); 4114 %} 4115 %} 4116 4117 //----------FRAME-------------------------------------------------------------- 4118 // Definition of frame structure and management information. 4119 4120 frame %{ 4121 // What direction does stack grow in (assumed to be same for native & Java). 4122 stack_direction(TOWARDS_LOW); 4123 4124 // These two registers define part of the calling convention between 4125 // compiled code and the interpreter. 4126 4127 // Inline Cache Register or method for I2C. 4128 inline_cache_reg(R19); // R19_method 4129 4130 // Method Oop Register when calling interpreter. 4131 interpreter_method_oop_reg(R19); // R19_method 4132 4133 // Optional: name the operand used by cisc-spilling to access 4134 // [stack_pointer + offset]. 4135 cisc_spilling_operand_name(indOffset); 4136 4137 // Number of stack slots consumed by a Monitor enter. 4138 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 4139 4140 // Compiled code's Frame Pointer. 4141 frame_pointer(R1); // R1_SP 4142 4143 // Interpreter stores its frame pointer in a register which is 4144 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 4145 // interpreted java to compiled java. 4146 // 4147 // R14_state holds pointer to caller's cInterpreter. 4148 interpreter_frame_pointer(R14); // R14_state 4149 4150 stack_alignment(frame::alignment_in_bytes); 4151 4152 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4153 4154 // Number of outgoing stack slots killed above the 4155 // out_preserve_stack_slots for calls to C. Supports the var-args 4156 // backing area for register parms. 4157 // 4158 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4159 4160 // The after-PROLOG location of the return address. Location of 4161 // return address specifies a type (REG or STACK) and a number 4162 // representing the register number (i.e. - use a register name) or 4163 // stack slot. 4164 // 4165 // A: Link register is stored in stack slot ... 4166 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4167 // J: Therefore, we make sure that the link register is also in R11_scratch1 4168 // at the end of the prolog. 4169 // B: We use R20, now. 4170 //return_addr(REG R20); 4171 4172 // G: After reading the comments made by all the luminaries on their 4173 // failure to tell the compiler where the return address really is, 4174 // I hardly dare to try myself. However, I'm convinced it's in slot 4175 // 4 what apparently works and saves us some spills. 4176 return_addr(STACK 4); 4177 4178 // This is the body of the function 4179 // 4180 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4181 // uint length, // length of array 4182 // bool is_outgoing) 4183 // 4184 // The `sig' array is to be updated. sig[j] represents the location 4185 // of the j-th argument, either a register or a stack slot. 4186 4187 // Comment taken from i486.ad: 4188 // Body of function which returns an integer array locating 4189 // arguments either in registers or in stack slots. Passed an array 4190 // of ideal registers called "sig" and a "length" count. Stack-slot 4191 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4192 // arguments for a CALLEE. Incoming stack arguments are 4193 // automatically biased by the preserve_stack_slots field above. 4194 calling_convention %{ 4195 // No difference between ingoing/outgoing. Just pass false. 4196 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4197 %} 4198 4199 // Comment taken from i486.ad: 4200 // Body of function which returns an integer array locating 4201 // arguments either in registers or in stack slots. Passed an array 4202 // of ideal registers called "sig" and a "length" count. Stack-slot 4203 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4204 // arguments for a CALLEE. Incoming stack arguments are 4205 // automatically biased by the preserve_stack_slots field above. 4206 c_calling_convention %{ 4207 // This is obviously always outgoing. 4208 // C argument in register AND stack slot. 4209 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4210 %} 4211 4212 // Location of native (C/C++) and interpreter return values. This 4213 // is specified to be the same as Java. In the 32-bit VM, long 4214 // values are actually returned from native calls in O0:O1 and 4215 // returned to the interpreter in I0:I1. The copying to and from 4216 // the register pairs is done by the appropriate call and epilog 4217 // opcodes. This simplifies the register allocator. 4218 c_return_value %{ 4219 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4220 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0), 4221 "only return normal values"); 4222 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4223 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4224 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4225 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4226 %} 4227 4228 // Location of compiled Java return values. Same as C 4229 return_value %{ 4230 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4231 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0), 4232 "only return normal values"); 4233 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4234 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4235 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4236 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4237 %} 4238 %} 4239 4240 4241 //----------ATTRIBUTES--------------------------------------------------------- 4242 4243 //----------Operand Attributes------------------------------------------------- 4244 op_attrib op_cost(1); // Required cost attribute. 4245 4246 //----------Instruction Attributes--------------------------------------------- 4247 4248 // Cost attribute. required. 4249 ins_attrib ins_cost(DEFAULT_COST); 4250 4251 // Is this instruction a non-matching short branch variant of some 4252 // long branch? Not required. 4253 ins_attrib ins_short_branch(0); 4254 4255 ins_attrib ins_is_TrapBasedCheckNode(true); 4256 4257 // Number of constants. 4258 // This instruction uses the given number of constants 4259 // (optional attribute). 4260 // This is needed to determine in time whether the constant pool will 4261 // exceed 4000 entries. Before postalloc_expand the overall number of constants 4262 // is determined. It's also used to compute the constant pool size 4263 // in Output(). 4264 ins_attrib ins_num_consts(0); 4265 4266 // Required alignment attribute (must be a power of 2) specifies the 4267 // alignment that some part of the instruction (not necessarily the 4268 // start) requires. If > 1, a compute_padding() function must be 4269 // provided for the instruction. 4270 ins_attrib ins_alignment(1); 4271 4272 // Enforce/prohibit rematerializations. 4273 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4274 // then rematerialization of that instruction is prohibited and the 4275 // instruction's value will be spilled if necessary. 4276 // Causes that MachNode::rematerialize() returns false. 4277 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 4278 // then rematerialization should be enforced and a copy of the instruction 4279 // should be inserted if possible; rematerialization is not guaranteed. 4280 // Note: this may result in rematerializations in front of every use. 4281 // Causes that MachNode::rematerialize() can return true. 4282 // (optional attribute) 4283 ins_attrib ins_cannot_rematerialize(false); 4284 ins_attrib ins_should_rematerialize(false); 4285 4286 // Instruction has variable size depending on alignment. 4287 ins_attrib ins_variable_size_depending_on_alignment(false); 4288 4289 // Instruction is a nop. 4290 ins_attrib ins_is_nop(false); 4291 4292 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4293 ins_attrib ins_use_mach_if_fast_lock_node(false); 4294 4295 // Field for the toc offset of a constant. 4296 // 4297 // This is needed if the toc offset is not encodable as an immediate in 4298 // the PPC load instruction. If so, the upper (hi) bits of the offset are 4299 // added to the toc, and from this a load with immediate is performed. 4300 // With postalloc expand, we get two nodes that require the same offset 4301 // but which don't know about each other. The offset is only known 4302 // when the constant is added to the constant pool during emitting. 4303 // It is generated in the 'hi'-node adding the upper bits, and saved 4304 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 4305 // the offset from there when it gets encoded. 4306 ins_attrib ins_field_const_toc_offset(0); 4307 ins_attrib ins_field_const_toc_offset_hi_node(0); 4308 4309 // A field that can hold the instructions offset in the code buffer. 4310 // Set in the nodes emitter. 4311 ins_attrib ins_field_cbuf_insts_offset(-1); 4312 4313 // Fields for referencing a call's load-IC-node. 4314 // If the toc offset can not be encoded as an immediate in a load, we 4315 // use two nodes. 4316 ins_attrib ins_field_load_ic_hi_node(0); 4317 ins_attrib ins_field_load_ic_node(0); 4318 4319 //----------OPERANDS----------------------------------------------------------- 4320 // Operand definitions must precede instruction definitions for correct 4321 // parsing in the ADLC because operands constitute user defined types 4322 // which are used in instruction definitions. 4323 // 4324 // Formats are generated automatically for constants and base registers. 4325 4326 operand vecX() %{ 4327 constraint(ALLOC_IN_RC(vs_reg)); 4328 match(VecX); 4329 4330 format %{ %} 4331 interface(REG_INTER); 4332 %} 4333 4334 //----------Simple Operands---------------------------------------------------- 4335 // Immediate Operands 4336 4337 // Integer Immediate: 32-bit 4338 operand immI() %{ 4339 match(ConI); 4340 op_cost(40); 4341 format %{ %} 4342 interface(CONST_INTER); 4343 %} 4344 4345 operand immI8() %{ 4346 predicate(Assembler::is_simm(n->get_int(), 8)); 4347 op_cost(0); 4348 match(ConI); 4349 format %{ %} 4350 interface(CONST_INTER); 4351 %} 4352 4353 // Integer Immediate: 16-bit 4354 operand immI16() %{ 4355 predicate(Assembler::is_simm(n->get_int(), 16)); 4356 op_cost(0); 4357 match(ConI); 4358 format %{ %} 4359 interface(CONST_INTER); 4360 %} 4361 4362 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4363 operand immIhi16() %{ 4364 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4365 match(ConI); 4366 op_cost(0); 4367 format %{ %} 4368 interface(CONST_INTER); 4369 %} 4370 4371 operand immInegpow2() %{ 4372 predicate(is_power_of_2((jlong) (julong) (juint) (-(n->get_int())))); 4373 match(ConI); 4374 op_cost(0); 4375 format %{ %} 4376 interface(CONST_INTER); 4377 %} 4378 4379 operand immIpow2minus1() %{ 4380 predicate(is_power_of_2((((jlong) (n->get_int()))+1))); 4381 match(ConI); 4382 op_cost(0); 4383 format %{ %} 4384 interface(CONST_INTER); 4385 %} 4386 4387 operand immIpowerOf2() %{ 4388 predicate(is_power_of_2((((jlong) (julong) (juint) (n->get_int()))))); 4389 match(ConI); 4390 op_cost(0); 4391 format %{ %} 4392 interface(CONST_INTER); 4393 %} 4394 4395 // Unsigned Integer Immediate: the values 0-31 4396 operand uimmI5() %{ 4397 predicate(Assembler::is_uimm(n->get_int(), 5)); 4398 match(ConI); 4399 op_cost(0); 4400 format %{ %} 4401 interface(CONST_INTER); 4402 %} 4403 4404 // Unsigned Integer Immediate: 6-bit 4405 operand uimmI6() %{ 4406 predicate(Assembler::is_uimm(n->get_int(), 6)); 4407 match(ConI); 4408 op_cost(0); 4409 format %{ %} 4410 interface(CONST_INTER); 4411 %} 4412 4413 // Unsigned Integer Immediate: 6-bit int, greater than 32 4414 operand uimmI6_ge32() %{ 4415 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4416 match(ConI); 4417 op_cost(0); 4418 format %{ %} 4419 interface(CONST_INTER); 4420 %} 4421 4422 // Unsigned Integer Immediate: 15-bit 4423 operand uimmI15() %{ 4424 predicate(Assembler::is_uimm(n->get_int(), 15)); 4425 match(ConI); 4426 op_cost(0); 4427 format %{ %} 4428 interface(CONST_INTER); 4429 %} 4430 4431 // Unsigned Integer Immediate: 16-bit 4432 operand uimmI16() %{ 4433 predicate(Assembler::is_uimm(n->get_int(), 16)); 4434 match(ConI); 4435 op_cost(0); 4436 format %{ %} 4437 interface(CONST_INTER); 4438 %} 4439 4440 // constant 'int 0'. 4441 operand immI_0() %{ 4442 predicate(n->get_int() == 0); 4443 match(ConI); 4444 op_cost(0); 4445 format %{ %} 4446 interface(CONST_INTER); 4447 %} 4448 4449 // constant 'int 1'. 4450 operand immI_1() %{ 4451 predicate(n->get_int() == 1); 4452 match(ConI); 4453 op_cost(0); 4454 format %{ %} 4455 interface(CONST_INTER); 4456 %} 4457 4458 // constant 'int -1'. 4459 operand immI_minus1() %{ 4460 predicate(n->get_int() == -1); 4461 match(ConI); 4462 op_cost(0); 4463 format %{ %} 4464 interface(CONST_INTER); 4465 %} 4466 4467 // int value 16. 4468 operand immI_16() %{ 4469 predicate(n->get_int() == 16); 4470 match(ConI); 4471 op_cost(0); 4472 format %{ %} 4473 interface(CONST_INTER); 4474 %} 4475 4476 // int value 24. 4477 operand immI_24() %{ 4478 predicate(n->get_int() == 24); 4479 match(ConI); 4480 op_cost(0); 4481 format %{ %} 4482 interface(CONST_INTER); 4483 %} 4484 4485 // Compressed oops constants 4486 // Pointer Immediate 4487 operand immN() %{ 4488 match(ConN); 4489 4490 op_cost(10); 4491 format %{ %} 4492 interface(CONST_INTER); 4493 %} 4494 4495 // NULL Pointer Immediate 4496 operand immN_0() %{ 4497 predicate(n->get_narrowcon() == 0); 4498 match(ConN); 4499 4500 op_cost(0); 4501 format %{ %} 4502 interface(CONST_INTER); 4503 %} 4504 4505 // Compressed klass constants 4506 operand immNKlass() %{ 4507 match(ConNKlass); 4508 4509 op_cost(0); 4510 format %{ %} 4511 interface(CONST_INTER); 4512 %} 4513 4514 // This operand can be used to avoid matching of an instruct 4515 // with chain rule. 4516 operand immNKlass_NM() %{ 4517 match(ConNKlass); 4518 predicate(false); 4519 op_cost(0); 4520 format %{ %} 4521 interface(CONST_INTER); 4522 %} 4523 4524 // Pointer Immediate: 64-bit 4525 operand immP() %{ 4526 match(ConP); 4527 op_cost(0); 4528 format %{ %} 4529 interface(CONST_INTER); 4530 %} 4531 4532 // Operand to avoid match of loadConP. 4533 // This operand can be used to avoid matching of an instruct 4534 // with chain rule. 4535 operand immP_NM() %{ 4536 match(ConP); 4537 predicate(false); 4538 op_cost(0); 4539 format %{ %} 4540 interface(CONST_INTER); 4541 %} 4542 4543 // costant 'pointer 0'. 4544 operand immP_0() %{ 4545 predicate(n->get_ptr() == 0); 4546 match(ConP); 4547 op_cost(0); 4548 format %{ %} 4549 interface(CONST_INTER); 4550 %} 4551 4552 // pointer 0x0 or 0x1 4553 operand immP_0or1() %{ 4554 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4555 match(ConP); 4556 op_cost(0); 4557 format %{ %} 4558 interface(CONST_INTER); 4559 %} 4560 4561 operand immL() %{ 4562 match(ConL); 4563 op_cost(40); 4564 format %{ %} 4565 interface(CONST_INTER); 4566 %} 4567 4568 operand immLmax30() %{ 4569 predicate((n->get_long() <= 30)); 4570 match(ConL); 4571 op_cost(0); 4572 format %{ %} 4573 interface(CONST_INTER); 4574 %} 4575 4576 // Long Immediate: 16-bit 4577 operand immL16() %{ 4578 predicate(Assembler::is_simm(n->get_long(), 16)); 4579 match(ConL); 4580 op_cost(0); 4581 format %{ %} 4582 interface(CONST_INTER); 4583 %} 4584 4585 // Long Immediate: 16-bit, 4-aligned 4586 operand immL16Alg4() %{ 4587 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4588 match(ConL); 4589 op_cost(0); 4590 format %{ %} 4591 interface(CONST_INTER); 4592 %} 4593 4594 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4595 operand immL32hi16() %{ 4596 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4597 match(ConL); 4598 op_cost(0); 4599 format %{ %} 4600 interface(CONST_INTER); 4601 %} 4602 4603 // Long Immediate: 32-bit 4604 operand immL32() %{ 4605 predicate(Assembler::is_simm(n->get_long(), 32)); 4606 match(ConL); 4607 op_cost(0); 4608 format %{ %} 4609 interface(CONST_INTER); 4610 %} 4611 4612 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4613 operand immLhighest16() %{ 4614 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4615 match(ConL); 4616 op_cost(0); 4617 format %{ %} 4618 interface(CONST_INTER); 4619 %} 4620 4621 operand immLnegpow2() %{ 4622 predicate(is_power_of_2((jlong)-(n->get_long()))); 4623 match(ConL); 4624 op_cost(0); 4625 format %{ %} 4626 interface(CONST_INTER); 4627 %} 4628 4629 operand immLpow2minus1() %{ 4630 predicate(is_power_of_2((((jlong) (n->get_long()))+1)) && 4631 (n->get_long() != (jlong)0xffffffffffffffffL)); 4632 match(ConL); 4633 op_cost(0); 4634 format %{ %} 4635 interface(CONST_INTER); 4636 %} 4637 4638 // constant 'long 0'. 4639 operand immL_0() %{ 4640 predicate(n->get_long() == 0L); 4641 match(ConL); 4642 op_cost(0); 4643 format %{ %} 4644 interface(CONST_INTER); 4645 %} 4646 4647 // constat ' long -1'. 4648 operand immL_minus1() %{ 4649 predicate(n->get_long() == -1L); 4650 match(ConL); 4651 op_cost(0); 4652 format %{ %} 4653 interface(CONST_INTER); 4654 %} 4655 4656 // Long Immediate: low 32-bit mask 4657 operand immL_32bits() %{ 4658 predicate(n->get_long() == 0xFFFFFFFFL); 4659 match(ConL); 4660 op_cost(0); 4661 format %{ %} 4662 interface(CONST_INTER); 4663 %} 4664 4665 // Unsigned Long Immediate: 16-bit 4666 operand uimmL16() %{ 4667 predicate(Assembler::is_uimm(n->get_long(), 16)); 4668 match(ConL); 4669 op_cost(0); 4670 format %{ %} 4671 interface(CONST_INTER); 4672 %} 4673 4674 // Float Immediate 4675 operand immF() %{ 4676 match(ConF); 4677 op_cost(40); 4678 format %{ %} 4679 interface(CONST_INTER); 4680 %} 4681 4682 // Float Immediate: +0.0f. 4683 operand immF_0() %{ 4684 predicate(jint_cast(n->getf()) == 0); 4685 match(ConF); 4686 4687 op_cost(0); 4688 format %{ %} 4689 interface(CONST_INTER); 4690 %} 4691 4692 // Double Immediate 4693 operand immD() %{ 4694 match(ConD); 4695 op_cost(40); 4696 format %{ %} 4697 interface(CONST_INTER); 4698 %} 4699 4700 // Double Immediate: +0.0d. 4701 operand immD_0() %{ 4702 predicate(jlong_cast(n->getd()) == 0); 4703 match(ConD); 4704 4705 op_cost(0); 4706 format %{ %} 4707 interface(CONST_INTER); 4708 %} 4709 4710 // Integer Register Operands 4711 // Integer Destination Register 4712 // See definition of reg_class bits32_reg_rw. 4713 operand iRegIdst() %{ 4714 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4715 match(RegI); 4716 match(rscratch1RegI); 4717 match(rscratch2RegI); 4718 match(rarg1RegI); 4719 match(rarg2RegI); 4720 match(rarg3RegI); 4721 match(rarg4RegI); 4722 format %{ %} 4723 interface(REG_INTER); 4724 %} 4725 4726 // Integer Source Register 4727 // See definition of reg_class bits32_reg_ro. 4728 operand iRegIsrc() %{ 4729 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4730 match(RegI); 4731 match(rscratch1RegI); 4732 match(rscratch2RegI); 4733 match(rarg1RegI); 4734 match(rarg2RegI); 4735 match(rarg3RegI); 4736 match(rarg4RegI); 4737 format %{ %} 4738 interface(REG_INTER); 4739 %} 4740 4741 operand rscratch1RegI() %{ 4742 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4743 match(iRegIdst); 4744 format %{ %} 4745 interface(REG_INTER); 4746 %} 4747 4748 operand rscratch2RegI() %{ 4749 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4750 match(iRegIdst); 4751 format %{ %} 4752 interface(REG_INTER); 4753 %} 4754 4755 operand rarg1RegI() %{ 4756 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4757 match(iRegIdst); 4758 format %{ %} 4759 interface(REG_INTER); 4760 %} 4761 4762 operand rarg2RegI() %{ 4763 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4764 match(iRegIdst); 4765 format %{ %} 4766 interface(REG_INTER); 4767 %} 4768 4769 operand rarg3RegI() %{ 4770 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4771 match(iRegIdst); 4772 format %{ %} 4773 interface(REG_INTER); 4774 %} 4775 4776 operand rarg4RegI() %{ 4777 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4778 match(iRegIdst); 4779 format %{ %} 4780 interface(REG_INTER); 4781 %} 4782 4783 operand rarg1RegL() %{ 4784 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4785 match(iRegLdst); 4786 format %{ %} 4787 interface(REG_INTER); 4788 %} 4789 4790 operand rarg2RegL() %{ 4791 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4792 match(iRegLdst); 4793 format %{ %} 4794 interface(REG_INTER); 4795 %} 4796 4797 operand rarg3RegL() %{ 4798 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4799 match(iRegLdst); 4800 format %{ %} 4801 interface(REG_INTER); 4802 %} 4803 4804 operand rarg4RegL() %{ 4805 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4806 match(iRegLdst); 4807 format %{ %} 4808 interface(REG_INTER); 4809 %} 4810 4811 // Pointer Destination Register 4812 // See definition of reg_class bits64_reg_rw. 4813 operand iRegPdst() %{ 4814 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4815 match(RegP); 4816 match(rscratch1RegP); 4817 match(rscratch2RegP); 4818 match(rarg1RegP); 4819 match(rarg2RegP); 4820 match(rarg3RegP); 4821 match(rarg4RegP); 4822 format %{ %} 4823 interface(REG_INTER); 4824 %} 4825 4826 // Pointer Destination Register 4827 // Operand not using r11 and r12 (killed in epilog). 4828 operand iRegPdstNoScratch() %{ 4829 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4830 match(RegP); 4831 match(rarg1RegP); 4832 match(rarg2RegP); 4833 match(rarg3RegP); 4834 match(rarg4RegP); 4835 format %{ %} 4836 interface(REG_INTER); 4837 %} 4838 4839 // Pointer Source Register 4840 // See definition of reg_class bits64_reg_ro. 4841 operand iRegPsrc() %{ 4842 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4843 match(RegP); 4844 match(iRegPdst); 4845 match(rscratch1RegP); 4846 match(rscratch2RegP); 4847 match(rarg1RegP); 4848 match(rarg2RegP); 4849 match(rarg3RegP); 4850 match(rarg4RegP); 4851 match(threadRegP); 4852 format %{ %} 4853 interface(REG_INTER); 4854 %} 4855 4856 // Thread operand. 4857 operand threadRegP() %{ 4858 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4859 match(iRegPdst); 4860 format %{ "R16" %} 4861 interface(REG_INTER); 4862 %} 4863 4864 operand rscratch1RegP() %{ 4865 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4866 match(iRegPdst); 4867 format %{ "R11" %} 4868 interface(REG_INTER); 4869 %} 4870 4871 operand rscratch2RegP() %{ 4872 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4873 match(iRegPdst); 4874 format %{ %} 4875 interface(REG_INTER); 4876 %} 4877 4878 operand rarg1RegP() %{ 4879 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4880 match(iRegPdst); 4881 format %{ %} 4882 interface(REG_INTER); 4883 %} 4884 4885 operand rarg2RegP() %{ 4886 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4887 match(iRegPdst); 4888 format %{ %} 4889 interface(REG_INTER); 4890 %} 4891 4892 operand rarg3RegP() %{ 4893 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4894 match(iRegPdst); 4895 format %{ %} 4896 interface(REG_INTER); 4897 %} 4898 4899 operand rarg4RegP() %{ 4900 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4901 match(iRegPdst); 4902 format %{ %} 4903 interface(REG_INTER); 4904 %} 4905 4906 operand iRegNsrc() %{ 4907 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4908 match(RegN); 4909 match(iRegNdst); 4910 4911 format %{ %} 4912 interface(REG_INTER); 4913 %} 4914 4915 operand iRegNdst() %{ 4916 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4917 match(RegN); 4918 4919 format %{ %} 4920 interface(REG_INTER); 4921 %} 4922 4923 // Long Destination Register 4924 // See definition of reg_class bits64_reg_rw. 4925 operand iRegLdst() %{ 4926 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4927 match(RegL); 4928 match(rscratch1RegL); 4929 match(rscratch2RegL); 4930 format %{ %} 4931 interface(REG_INTER); 4932 %} 4933 4934 // Long Source Register 4935 // See definition of reg_class bits64_reg_ro. 4936 operand iRegLsrc() %{ 4937 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4938 match(RegL); 4939 match(iRegLdst); 4940 match(rscratch1RegL); 4941 match(rscratch2RegL); 4942 format %{ %} 4943 interface(REG_INTER); 4944 %} 4945 4946 // Special operand for ConvL2I. 4947 operand iRegL2Isrc(iRegLsrc reg) %{ 4948 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4949 match(ConvL2I reg); 4950 format %{ "ConvL2I($reg)" %} 4951 interface(REG_INTER) 4952 %} 4953 4954 operand rscratch1RegL() %{ 4955 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4956 match(RegL); 4957 format %{ %} 4958 interface(REG_INTER); 4959 %} 4960 4961 operand rscratch2RegL() %{ 4962 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4963 match(RegL); 4964 format %{ %} 4965 interface(REG_INTER); 4966 %} 4967 4968 // Condition Code Flag Registers 4969 operand flagsReg() %{ 4970 constraint(ALLOC_IN_RC(int_flags)); 4971 match(RegFlags); 4972 format %{ %} 4973 interface(REG_INTER); 4974 %} 4975 4976 operand flagsRegSrc() %{ 4977 constraint(ALLOC_IN_RC(int_flags_ro)); 4978 match(RegFlags); 4979 match(flagsReg); 4980 match(flagsRegCR0); 4981 format %{ %} 4982 interface(REG_INTER); 4983 %} 4984 4985 // Condition Code Flag Register CR0 4986 operand flagsRegCR0() %{ 4987 constraint(ALLOC_IN_RC(int_flags_CR0)); 4988 match(RegFlags); 4989 format %{ "CR0" %} 4990 interface(REG_INTER); 4991 %} 4992 4993 operand flagsRegCR1() %{ 4994 constraint(ALLOC_IN_RC(int_flags_CR1)); 4995 match(RegFlags); 4996 format %{ "CR1" %} 4997 interface(REG_INTER); 4998 %} 4999 5000 operand flagsRegCR6() %{ 5001 constraint(ALLOC_IN_RC(int_flags_CR6)); 5002 match(RegFlags); 5003 format %{ "CR6" %} 5004 interface(REG_INTER); 5005 %} 5006 5007 operand regCTR() %{ 5008 constraint(ALLOC_IN_RC(ctr_reg)); 5009 // RegFlags should work. Introducing a RegSpecial type would cause a 5010 // lot of changes. 5011 match(RegFlags); 5012 format %{"SR_CTR" %} 5013 interface(REG_INTER); 5014 %} 5015 5016 operand regD() %{ 5017 constraint(ALLOC_IN_RC(dbl_reg)); 5018 match(RegD); 5019 format %{ %} 5020 interface(REG_INTER); 5021 %} 5022 5023 operand regF() %{ 5024 constraint(ALLOC_IN_RC(flt_reg)); 5025 match(RegF); 5026 format %{ %} 5027 interface(REG_INTER); 5028 %} 5029 5030 // Special Registers 5031 5032 // Method Register 5033 operand inline_cache_regP(iRegPdst reg) %{ 5034 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 5035 match(reg); 5036 format %{ %} 5037 interface(REG_INTER); 5038 %} 5039 5040 operand compiler_method_oop_regP(iRegPdst reg) %{ 5041 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 5042 match(reg); 5043 format %{ %} 5044 interface(REG_INTER); 5045 %} 5046 5047 operand interpreter_method_oop_regP(iRegPdst reg) %{ 5048 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 5049 match(reg); 5050 format %{ %} 5051 interface(REG_INTER); 5052 %} 5053 5054 // Operands to remove register moves in unscaled mode. 5055 // Match read/write registers with an EncodeP node if neither shift nor add are required. 5056 operand iRegP2N(iRegPsrc reg) %{ 5057 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0); 5058 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5059 match(EncodeP reg); 5060 format %{ "$reg" %} 5061 interface(REG_INTER) 5062 %} 5063 5064 operand iRegN2P(iRegNsrc reg) %{ 5065 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5066 constraint(ALLOC_IN_RC(bits32_reg_ro)); 5067 match(DecodeN reg); 5068 format %{ "$reg" %} 5069 interface(REG_INTER) 5070 %} 5071 5072 operand iRegN2P_klass(iRegNsrc reg) %{ 5073 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5074 constraint(ALLOC_IN_RC(bits32_reg_ro)); 5075 match(DecodeNKlass reg); 5076 format %{ "$reg" %} 5077 interface(REG_INTER) 5078 %} 5079 5080 //----------Complex Operands--------------------------------------------------- 5081 // Indirect Memory Reference 5082 operand indirect(iRegPsrc reg) %{ 5083 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5084 match(reg); 5085 op_cost(100); 5086 format %{ "[$reg]" %} 5087 interface(MEMORY_INTER) %{ 5088 base($reg); 5089 index(0x0); 5090 scale(0x0); 5091 disp(0x0); 5092 %} 5093 %} 5094 5095 // Indirect with Offset 5096 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 5097 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5098 match(AddP reg offset); 5099 op_cost(100); 5100 format %{ "[$reg + $offset]" %} 5101 interface(MEMORY_INTER) %{ 5102 base($reg); 5103 index(0x0); 5104 scale(0x0); 5105 disp($offset); 5106 %} 5107 %} 5108 5109 // Indirect with 4-aligned Offset 5110 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 5111 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5112 match(AddP reg offset); 5113 op_cost(100); 5114 format %{ "[$reg + $offset]" %} 5115 interface(MEMORY_INTER) %{ 5116 base($reg); 5117 index(0x0); 5118 scale(0x0); 5119 disp($offset); 5120 %} 5121 %} 5122 5123 //----------Complex Operands for Compressed OOPs------------------------------- 5124 // Compressed OOPs with narrow_oop_shift == 0. 5125 5126 // Indirect Memory Reference, compressed OOP 5127 operand indirectNarrow(iRegNsrc reg) %{ 5128 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5129 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5130 match(DecodeN reg); 5131 op_cost(100); 5132 format %{ "[$reg]" %} 5133 interface(MEMORY_INTER) %{ 5134 base($reg); 5135 index(0x0); 5136 scale(0x0); 5137 disp(0x0); 5138 %} 5139 %} 5140 5141 operand indirectNarrow_klass(iRegNsrc reg) %{ 5142 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5143 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5144 match(DecodeNKlass reg); 5145 op_cost(100); 5146 format %{ "[$reg]" %} 5147 interface(MEMORY_INTER) %{ 5148 base($reg); 5149 index(0x0); 5150 scale(0x0); 5151 disp(0x0); 5152 %} 5153 %} 5154 5155 // Indirect with Offset, compressed OOP 5156 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 5157 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5158 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5159 match(AddP (DecodeN reg) offset); 5160 op_cost(100); 5161 format %{ "[$reg + $offset]" %} 5162 interface(MEMORY_INTER) %{ 5163 base($reg); 5164 index(0x0); 5165 scale(0x0); 5166 disp($offset); 5167 %} 5168 %} 5169 5170 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5171 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5172 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5173 match(AddP (DecodeNKlass reg) offset); 5174 op_cost(100); 5175 format %{ "[$reg + $offset]" %} 5176 interface(MEMORY_INTER) %{ 5177 base($reg); 5178 index(0x0); 5179 scale(0x0); 5180 disp($offset); 5181 %} 5182 %} 5183 5184 // Indirect with 4-aligned Offset, compressed OOP 5185 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 5186 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5187 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5188 match(AddP (DecodeN reg) offset); 5189 op_cost(100); 5190 format %{ "[$reg + $offset]" %} 5191 interface(MEMORY_INTER) %{ 5192 base($reg); 5193 index(0x0); 5194 scale(0x0); 5195 disp($offset); 5196 %} 5197 %} 5198 5199 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5200 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5201 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5202 match(AddP (DecodeNKlass reg) offset); 5203 op_cost(100); 5204 format %{ "[$reg + $offset]" %} 5205 interface(MEMORY_INTER) %{ 5206 base($reg); 5207 index(0x0); 5208 scale(0x0); 5209 disp($offset); 5210 %} 5211 %} 5212 5213 //----------Special Memory Operands-------------------------------------------- 5214 // Stack Slot Operand 5215 // 5216 // This operand is used for loading and storing temporary values on 5217 // the stack where a match requires a value to flow through memory. 5218 operand stackSlotI(sRegI reg) %{ 5219 constraint(ALLOC_IN_RC(stack_slots)); 5220 op_cost(100); 5221 //match(RegI); 5222 format %{ "[sp+$reg]" %} 5223 interface(MEMORY_INTER) %{ 5224 base(0x1); // R1_SP 5225 index(0x0); 5226 scale(0x0); 5227 disp($reg); // Stack Offset 5228 %} 5229 %} 5230 5231 operand stackSlotL(sRegL reg) %{ 5232 constraint(ALLOC_IN_RC(stack_slots)); 5233 op_cost(100); 5234 //match(RegL); 5235 format %{ "[sp+$reg]" %} 5236 interface(MEMORY_INTER) %{ 5237 base(0x1); // R1_SP 5238 index(0x0); 5239 scale(0x0); 5240 disp($reg); // Stack Offset 5241 %} 5242 %} 5243 5244 operand stackSlotP(sRegP reg) %{ 5245 constraint(ALLOC_IN_RC(stack_slots)); 5246 op_cost(100); 5247 //match(RegP); 5248 format %{ "[sp+$reg]" %} 5249 interface(MEMORY_INTER) %{ 5250 base(0x1); // R1_SP 5251 index(0x0); 5252 scale(0x0); 5253 disp($reg); // Stack Offset 5254 %} 5255 %} 5256 5257 operand stackSlotF(sRegF reg) %{ 5258 constraint(ALLOC_IN_RC(stack_slots)); 5259 op_cost(100); 5260 //match(RegF); 5261 format %{ "[sp+$reg]" %} 5262 interface(MEMORY_INTER) %{ 5263 base(0x1); // R1_SP 5264 index(0x0); 5265 scale(0x0); 5266 disp($reg); // Stack Offset 5267 %} 5268 %} 5269 5270 operand stackSlotD(sRegD reg) %{ 5271 constraint(ALLOC_IN_RC(stack_slots)); 5272 op_cost(100); 5273 //match(RegD); 5274 format %{ "[sp+$reg]" %} 5275 interface(MEMORY_INTER) %{ 5276 base(0x1); // R1_SP 5277 index(0x0); 5278 scale(0x0); 5279 disp($reg); // Stack Offset 5280 %} 5281 %} 5282 5283 // Operands for expressing Control Flow 5284 // NOTE: Label is a predefined operand which should not be redefined in 5285 // the AD file. It is generically handled within the ADLC. 5286 5287 //----------Conditional Branch Operands---------------------------------------- 5288 // Comparison Op 5289 // 5290 // This is the operation of the comparison, and is limited to the 5291 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5292 // (!=). 5293 // 5294 // Other attributes of the comparison, such as unsignedness, are specified 5295 // by the comparison instruction that sets a condition code flags register. 5296 // That result is represented by a flags operand whose subtype is appropriate 5297 // to the unsignedness (etc.) of the comparison. 5298 // 5299 // Later, the instruction which matches both the Comparison Op (a Bool) and 5300 // the flags (produced by the Cmp) specifies the coding of the comparison op 5301 // by matching a specific subtype of Bool operand below. 5302 5303 // When used for floating point comparisons: unordered same as less. 5304 operand cmpOp() %{ 5305 match(Bool); 5306 format %{ "" %} 5307 interface(COND_INTER) %{ 5308 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5309 // BO & BI 5310 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5311 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5312 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5313 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5314 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5315 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5316 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5317 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5318 %} 5319 %} 5320 5321 //----------OPERAND CLASSES---------------------------------------------------- 5322 // Operand Classes are groups of operands that are used to simplify 5323 // instruction definitions by not requiring the AD writer to specify 5324 // seperate instructions for every form of operand when the 5325 // instruction accepts multiple operand types with the same basic 5326 // encoding and format. The classic case of this is memory operands. 5327 // Indirect is not included since its use is limited to Compare & Swap. 5328 5329 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5330 // Memory operand where offsets are 4-aligned. Required for ld, std. 5331 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5332 opclass indirectMemory(indirect, indirectNarrow); 5333 5334 // Special opclass for I and ConvL2I. 5335 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5336 5337 // Operand classes to match encode and decode. iRegN_P2N is only used 5338 // for storeN. I have never seen an encode node elsewhere. 5339 opclass iRegN_P2N(iRegNsrc, iRegP2N); 5340 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5341 5342 //----------PIPELINE----------------------------------------------------------- 5343 5344 pipeline %{ 5345 5346 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5347 // J. Res. & Dev., No. 1, Jan. 2002. 5348 5349 //----------ATTRIBUTES--------------------------------------------------------- 5350 attributes %{ 5351 5352 // Power4 instructions are of fixed length. 5353 fixed_size_instructions; 5354 5355 // TODO: if `bundle' means number of instructions fetched 5356 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5357 // max instructions issued per cycle, this is 5. 5358 max_instructions_per_bundle = 8; 5359 5360 // A Power4 instruction is 4 bytes long. 5361 instruction_unit_size = 4; 5362 5363 // The Power4 processor fetches 64 bytes... 5364 instruction_fetch_unit_size = 64; 5365 5366 // ...in one line 5367 instruction_fetch_units = 1 5368 5369 // Unused, list one so that array generated by adlc is not empty. 5370 // Aix compiler chokes if _nop_count = 0. 5371 nops(fxNop); 5372 %} 5373 5374 //----------RESOURCES---------------------------------------------------------- 5375 // Resources are the functional units available to the machine 5376 resources( 5377 PPC_BR, // branch unit 5378 PPC_CR, // condition unit 5379 PPC_FX1, // integer arithmetic unit 1 5380 PPC_FX2, // integer arithmetic unit 2 5381 PPC_LDST1, // load/store unit 1 5382 PPC_LDST2, // load/store unit 2 5383 PPC_FP1, // float arithmetic unit 1 5384 PPC_FP2, // float arithmetic unit 2 5385 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5386 PPC_FX = PPC_FX1 | PPC_FX2, 5387 PPC_FP = PPC_FP1 | PPC_FP2 5388 ); 5389 5390 //----------PIPELINE DESCRIPTION----------------------------------------------- 5391 // Pipeline Description specifies the stages in the machine's pipeline 5392 pipe_desc( 5393 // Power4 longest pipeline path 5394 PPC_IF, // instruction fetch 5395 PPC_IC, 5396 //PPC_BP, // branch prediction 5397 PPC_D0, // decode 5398 PPC_D1, // decode 5399 PPC_D2, // decode 5400 PPC_D3, // decode 5401 PPC_Xfer1, 5402 PPC_GD, // group definition 5403 PPC_MP, // map 5404 PPC_ISS, // issue 5405 PPC_RF, // resource fetch 5406 PPC_EX1, // execute (all units) 5407 PPC_EX2, // execute (FP, LDST) 5408 PPC_EX3, // execute (FP, LDST) 5409 PPC_EX4, // execute (FP) 5410 PPC_EX5, // execute (FP) 5411 PPC_EX6, // execute (FP) 5412 PPC_WB, // write back 5413 PPC_Xfer2, 5414 PPC_CP 5415 ); 5416 5417 //----------PIPELINE CLASSES--------------------------------------------------- 5418 // Pipeline Classes describe the stages in which input and output are 5419 // referenced by the hardware pipeline. 5420 5421 // Simple pipeline classes. 5422 5423 // Default pipeline class. 5424 pipe_class pipe_class_default() %{ 5425 single_instruction; 5426 fixed_latency(2); 5427 %} 5428 5429 // Pipeline class for empty instructions. 5430 pipe_class pipe_class_empty() %{ 5431 single_instruction; 5432 fixed_latency(0); 5433 %} 5434 5435 // Pipeline class for compares. 5436 pipe_class pipe_class_compare() %{ 5437 single_instruction; 5438 fixed_latency(16); 5439 %} 5440 5441 // Pipeline class for traps. 5442 pipe_class pipe_class_trap() %{ 5443 single_instruction; 5444 fixed_latency(100); 5445 %} 5446 5447 // Pipeline class for memory operations. 5448 pipe_class pipe_class_memory() %{ 5449 single_instruction; 5450 fixed_latency(16); 5451 %} 5452 5453 // Pipeline class for call. 5454 pipe_class pipe_class_call() %{ 5455 single_instruction; 5456 fixed_latency(100); 5457 %} 5458 5459 // Define the class for the Nop node. 5460 define %{ 5461 MachNop = pipe_class_default; 5462 %} 5463 5464 %} 5465 5466 //----------INSTRUCTIONS------------------------------------------------------- 5467 5468 // Naming of instructions: 5469 // opA_operB / opA_operB_operC: 5470 // Operation 'op' with one or two source operands 'oper'. Result 5471 // type is A, source operand types are B and C. 5472 // Iff A == B == C, B and C are left out. 5473 // 5474 // The instructions are ordered according to the following scheme: 5475 // - loads 5476 // - load constants 5477 // - prefetch 5478 // - store 5479 // - encode/decode 5480 // - membar 5481 // - conditional moves 5482 // - compare & swap 5483 // - arithmetic and logic operations 5484 // * int: Add, Sub, Mul, Div, Mod 5485 // * int: lShift, arShift, urShift, rot 5486 // * float: Add, Sub, Mul, Div 5487 // * and, or, xor ... 5488 // - register moves: float <-> int, reg <-> stack, repl 5489 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5490 // - conv (low level type cast requiring bit changes (sign extend etc) 5491 // - compares, range & zero checks. 5492 // - branches 5493 // - complex operations, intrinsics, min, max, replicate 5494 // - lock 5495 // - Calls 5496 // 5497 // If there are similar instructions with different types they are sorted: 5498 // int before float 5499 // small before big 5500 // signed before unsigned 5501 // e.g., loadS before loadUS before loadI before loadF. 5502 5503 5504 //----------Load/Store Instructions-------------------------------------------- 5505 5506 //----------Load Instructions-------------------------------------------------- 5507 5508 // Converts byte to int. 5509 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5510 // reuses the 'amount' operand, but adlc expects that operand specification 5511 // and operands in match rule are equivalent. 5512 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5513 effect(DEF dst, USE src); 5514 format %{ "EXTSB $dst, $src \t// byte->int" %} 5515 size(4); 5516 ins_encode %{ 5517 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5518 __ extsb($dst$$Register, $src$$Register); 5519 %} 5520 ins_pipe(pipe_class_default); 5521 %} 5522 5523 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5524 // match-rule, false predicate 5525 match(Set dst (LoadB mem)); 5526 predicate(false); 5527 5528 format %{ "LBZ $dst, $mem" %} 5529 size(4); 5530 ins_encode( enc_lbz(dst, mem) ); 5531 ins_pipe(pipe_class_memory); 5532 %} 5533 5534 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5535 // match-rule, false predicate 5536 match(Set dst (LoadB mem)); 5537 predicate(false); 5538 5539 format %{ "LBZ $dst, $mem\n\t" 5540 "TWI $dst\n\t" 5541 "ISYNC" %} 5542 size(12); 5543 ins_encode( enc_lbz_ac(dst, mem) ); 5544 ins_pipe(pipe_class_memory); 5545 %} 5546 5547 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5548 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5549 match(Set dst (LoadB mem)); 5550 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5551 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5552 expand %{ 5553 iRegIdst tmp; 5554 loadUB_indirect(tmp, mem); 5555 convB2I_reg_2(dst, tmp); 5556 %} 5557 %} 5558 5559 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5560 match(Set dst (LoadB mem)); 5561 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5562 expand %{ 5563 iRegIdst tmp; 5564 loadUB_indirect_ac(tmp, mem); 5565 convB2I_reg_2(dst, tmp); 5566 %} 5567 %} 5568 5569 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5570 // match-rule, false predicate 5571 match(Set dst (LoadB mem)); 5572 predicate(false); 5573 5574 format %{ "LBZ $dst, $mem" %} 5575 size(4); 5576 ins_encode( enc_lbz(dst, mem) ); 5577 ins_pipe(pipe_class_memory); 5578 %} 5579 5580 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5581 // match-rule, false predicate 5582 match(Set dst (LoadB mem)); 5583 predicate(false); 5584 5585 format %{ "LBZ $dst, $mem\n\t" 5586 "TWI $dst\n\t" 5587 "ISYNC" %} 5588 size(12); 5589 ins_encode( enc_lbz_ac(dst, mem) ); 5590 ins_pipe(pipe_class_memory); 5591 %} 5592 5593 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5594 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5595 match(Set dst (LoadB mem)); 5596 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5597 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5598 5599 expand %{ 5600 iRegIdst tmp; 5601 loadUB_indOffset16(tmp, mem); 5602 convB2I_reg_2(dst, tmp); 5603 %} 5604 %} 5605 5606 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5607 match(Set dst (LoadB mem)); 5608 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5609 5610 expand %{ 5611 iRegIdst tmp; 5612 loadUB_indOffset16_ac(tmp, mem); 5613 convB2I_reg_2(dst, tmp); 5614 %} 5615 %} 5616 5617 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5618 instruct loadUB(iRegIdst dst, memory mem) %{ 5619 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5620 match(Set dst (LoadUB mem)); 5621 ins_cost(MEMORY_REF_COST); 5622 5623 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5624 size(4); 5625 ins_encode( enc_lbz(dst, mem) ); 5626 ins_pipe(pipe_class_memory); 5627 %} 5628 5629 // Load Unsigned Byte (8bit UNsigned) acquire. 5630 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5631 match(Set dst (LoadUB mem)); 5632 ins_cost(3*MEMORY_REF_COST); 5633 5634 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5635 "TWI $dst\n\t" 5636 "ISYNC" %} 5637 size(12); 5638 ins_encode( enc_lbz_ac(dst, mem) ); 5639 ins_pipe(pipe_class_memory); 5640 %} 5641 5642 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5643 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5644 match(Set dst (ConvI2L (LoadUB mem))); 5645 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5646 ins_cost(MEMORY_REF_COST); 5647 5648 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5649 size(4); 5650 ins_encode( enc_lbz(dst, mem) ); 5651 ins_pipe(pipe_class_memory); 5652 %} 5653 5654 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5655 match(Set dst (ConvI2L (LoadUB mem))); 5656 ins_cost(3*MEMORY_REF_COST); 5657 5658 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5659 "TWI $dst\n\t" 5660 "ISYNC" %} 5661 size(12); 5662 ins_encode( enc_lbz_ac(dst, mem) ); 5663 ins_pipe(pipe_class_memory); 5664 %} 5665 5666 // Load Short (16bit signed) 5667 instruct loadS(iRegIdst dst, memory mem) %{ 5668 match(Set dst (LoadS mem)); 5669 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5670 ins_cost(MEMORY_REF_COST); 5671 5672 format %{ "LHA $dst, $mem" %} 5673 size(4); 5674 ins_encode %{ 5675 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5676 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5677 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5678 %} 5679 ins_pipe(pipe_class_memory); 5680 %} 5681 5682 // Load Short (16bit signed) acquire. 5683 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5684 match(Set dst (LoadS mem)); 5685 ins_cost(3*MEMORY_REF_COST); 5686 5687 format %{ "LHA $dst, $mem\t acquire\n\t" 5688 "TWI $dst\n\t" 5689 "ISYNC" %} 5690 size(12); 5691 ins_encode %{ 5692 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5693 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5694 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5695 __ twi_0($dst$$Register); 5696 __ isync(); 5697 %} 5698 ins_pipe(pipe_class_memory); 5699 %} 5700 5701 // Load Char (16bit unsigned) 5702 instruct loadUS(iRegIdst dst, memory mem) %{ 5703 match(Set dst (LoadUS mem)); 5704 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5705 ins_cost(MEMORY_REF_COST); 5706 5707 format %{ "LHZ $dst, $mem" %} 5708 size(4); 5709 ins_encode( enc_lhz(dst, mem) ); 5710 ins_pipe(pipe_class_memory); 5711 %} 5712 5713 // Load Char (16bit unsigned) acquire. 5714 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5715 match(Set dst (LoadUS mem)); 5716 ins_cost(3*MEMORY_REF_COST); 5717 5718 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5719 "TWI $dst\n\t" 5720 "ISYNC" %} 5721 size(12); 5722 ins_encode( enc_lhz_ac(dst, mem) ); 5723 ins_pipe(pipe_class_memory); 5724 %} 5725 5726 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5727 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5728 match(Set dst (ConvI2L (LoadUS mem))); 5729 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5730 ins_cost(MEMORY_REF_COST); 5731 5732 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5733 size(4); 5734 ins_encode( enc_lhz(dst, mem) ); 5735 ins_pipe(pipe_class_memory); 5736 %} 5737 5738 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5739 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5740 match(Set dst (ConvI2L (LoadUS mem))); 5741 ins_cost(3*MEMORY_REF_COST); 5742 5743 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5744 "TWI $dst\n\t" 5745 "ISYNC" %} 5746 size(12); 5747 ins_encode( enc_lhz_ac(dst, mem) ); 5748 ins_pipe(pipe_class_memory); 5749 %} 5750 5751 // Load Integer. 5752 instruct loadI(iRegIdst dst, memory mem) %{ 5753 match(Set dst (LoadI mem)); 5754 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5755 ins_cost(MEMORY_REF_COST); 5756 5757 format %{ "LWZ $dst, $mem" %} 5758 size(4); 5759 ins_encode( enc_lwz(dst, mem) ); 5760 ins_pipe(pipe_class_memory); 5761 %} 5762 5763 // Load Integer acquire. 5764 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5765 match(Set dst (LoadI mem)); 5766 ins_cost(3*MEMORY_REF_COST); 5767 5768 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5769 "TWI $dst\n\t" 5770 "ISYNC" %} 5771 size(12); 5772 ins_encode( enc_lwz_ac(dst, mem) ); 5773 ins_pipe(pipe_class_memory); 5774 %} 5775 5776 // Match loading integer and casting it to unsigned int in 5777 // long register. 5778 // LoadI + ConvI2L + AndL 0xffffffff. 5779 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5780 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5781 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5782 ins_cost(MEMORY_REF_COST); 5783 5784 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5785 size(4); 5786 ins_encode( enc_lwz(dst, mem) ); 5787 ins_pipe(pipe_class_memory); 5788 %} 5789 5790 // Match loading integer and casting it to long. 5791 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5792 match(Set dst (ConvI2L (LoadI mem))); 5793 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5794 ins_cost(MEMORY_REF_COST); 5795 5796 format %{ "LWA $dst, $mem \t// loadI2L" %} 5797 size(4); 5798 ins_encode %{ 5799 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5800 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5801 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5802 %} 5803 ins_pipe(pipe_class_memory); 5804 %} 5805 5806 // Match loading integer and casting it to long - acquire. 5807 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5808 match(Set dst (ConvI2L (LoadI mem))); 5809 ins_cost(3*MEMORY_REF_COST); 5810 5811 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5812 "TWI $dst\n\t" 5813 "ISYNC" %} 5814 size(12); 5815 ins_encode %{ 5816 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5817 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5818 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5819 __ twi_0($dst$$Register); 5820 __ isync(); 5821 %} 5822 ins_pipe(pipe_class_memory); 5823 %} 5824 5825 // Load Long - aligned 5826 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5827 match(Set dst (LoadL mem)); 5828 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5829 ins_cost(MEMORY_REF_COST); 5830 5831 format %{ "LD $dst, $mem \t// long" %} 5832 size(4); 5833 ins_encode( enc_ld(dst, mem) ); 5834 ins_pipe(pipe_class_memory); 5835 %} 5836 5837 // Load Long - aligned acquire. 5838 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5839 match(Set dst (LoadL mem)); 5840 ins_cost(3*MEMORY_REF_COST); 5841 5842 format %{ "LD $dst, $mem \t// long acquire\n\t" 5843 "TWI $dst\n\t" 5844 "ISYNC" %} 5845 size(12); 5846 ins_encode( enc_ld_ac(dst, mem) ); 5847 ins_pipe(pipe_class_memory); 5848 %} 5849 5850 // Load Long - UNaligned 5851 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5852 match(Set dst (LoadL_unaligned mem)); 5853 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5854 ins_cost(MEMORY_REF_COST); 5855 5856 format %{ "LD $dst, $mem \t// unaligned long" %} 5857 size(4); 5858 ins_encode( enc_ld(dst, mem) ); 5859 ins_pipe(pipe_class_memory); 5860 %} 5861 5862 // Load nodes for superwords 5863 5864 // Load Aligned Packed Byte 5865 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5866 predicate(n->as_LoadVector()->memory_size() == 8); 5867 match(Set dst (LoadVector mem)); 5868 ins_cost(MEMORY_REF_COST); 5869 5870 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5871 size(4); 5872 ins_encode( enc_ld(dst, mem) ); 5873 ins_pipe(pipe_class_memory); 5874 %} 5875 5876 // Load Aligned Packed Byte 5877 instruct loadV16(vecX dst, indirect mem) %{ 5878 predicate(n->as_LoadVector()->memory_size() == 16); 5879 match(Set dst (LoadVector mem)); 5880 ins_cost(MEMORY_REF_COST); 5881 5882 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5883 size(4); 5884 ins_encode %{ 5885 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5886 %} 5887 ins_pipe(pipe_class_default); 5888 %} 5889 5890 // Load Range, range = array length (=jint) 5891 instruct loadRange(iRegIdst dst, memory mem) %{ 5892 match(Set dst (LoadRange mem)); 5893 ins_cost(MEMORY_REF_COST); 5894 5895 format %{ "LWZ $dst, $mem \t// range" %} 5896 size(4); 5897 ins_encode( enc_lwz(dst, mem) ); 5898 ins_pipe(pipe_class_memory); 5899 %} 5900 5901 // Load Compressed Pointer 5902 instruct loadN(iRegNdst dst, memory mem) %{ 5903 match(Set dst (LoadN mem)); 5904 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5905 ins_cost(MEMORY_REF_COST); 5906 5907 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5908 size(4); 5909 ins_encode( enc_lwz(dst, mem) ); 5910 ins_pipe(pipe_class_memory); 5911 %} 5912 5913 // Load Compressed Pointer acquire. 5914 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5915 match(Set dst (LoadN mem)); 5916 ins_cost(3*MEMORY_REF_COST); 5917 5918 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5919 "TWI $dst\n\t" 5920 "ISYNC" %} 5921 size(12); 5922 ins_encode( enc_lwz_ac(dst, mem) ); 5923 ins_pipe(pipe_class_memory); 5924 %} 5925 5926 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5927 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5928 match(Set dst (DecodeN (LoadN mem))); 5929 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0); 5930 ins_cost(MEMORY_REF_COST); 5931 5932 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5933 size(4); 5934 ins_encode( enc_lwz(dst, mem) ); 5935 ins_pipe(pipe_class_memory); 5936 %} 5937 5938 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5939 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5940 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0 && 5941 _kids[0]->_leaf->as_Load()->is_unordered()); 5942 ins_cost(MEMORY_REF_COST); 5943 5944 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5945 size(4); 5946 ins_encode( enc_lwz(dst, mem) ); 5947 ins_pipe(pipe_class_memory); 5948 %} 5949 5950 // Load Pointer 5951 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5952 match(Set dst (LoadP mem)); 5953 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5954 ins_cost(MEMORY_REF_COST); 5955 5956 format %{ "LD $dst, $mem \t// ptr" %} 5957 size(4); 5958 ins_encode( enc_ld(dst, mem) ); 5959 ins_pipe(pipe_class_memory); 5960 %} 5961 5962 // Load Pointer acquire. 5963 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5964 match(Set dst (LoadP mem)); 5965 ins_cost(3*MEMORY_REF_COST); 5966 5967 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5968 "TWI $dst\n\t" 5969 "ISYNC" %} 5970 size(12); 5971 ins_encode( enc_ld_ac(dst, mem) ); 5972 ins_pipe(pipe_class_memory); 5973 %} 5974 5975 // LoadP + CastP2L 5976 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5977 match(Set dst (CastP2X (LoadP mem))); 5978 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5979 ins_cost(MEMORY_REF_COST); 5980 5981 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5982 size(4); 5983 ins_encode( enc_ld(dst, mem) ); 5984 ins_pipe(pipe_class_memory); 5985 %} 5986 5987 // Load compressed klass pointer. 5988 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5989 match(Set dst (LoadNKlass mem)); 5990 ins_cost(MEMORY_REF_COST); 5991 5992 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5993 size(4); 5994 ins_encode( enc_lwz(dst, mem) ); 5995 ins_pipe(pipe_class_memory); 5996 %} 5997 5998 // Load Klass Pointer 5999 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 6000 match(Set dst (LoadKlass mem)); 6001 ins_cost(MEMORY_REF_COST); 6002 6003 format %{ "LD $dst, $mem \t// klass ptr" %} 6004 size(4); 6005 ins_encode( enc_ld(dst, mem) ); 6006 ins_pipe(pipe_class_memory); 6007 %} 6008 6009 // Load Float 6010 instruct loadF(regF dst, memory mem) %{ 6011 match(Set dst (LoadF mem)); 6012 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 6013 ins_cost(MEMORY_REF_COST); 6014 6015 format %{ "LFS $dst, $mem" %} 6016 size(4); 6017 ins_encode %{ 6018 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6019 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6020 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 6021 %} 6022 ins_pipe(pipe_class_memory); 6023 %} 6024 6025 // Load Float acquire. 6026 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 6027 match(Set dst (LoadF mem)); 6028 effect(TEMP cr0); 6029 ins_cost(3*MEMORY_REF_COST); 6030 6031 format %{ "LFS $dst, $mem \t// acquire\n\t" 6032 "FCMPU cr0, $dst, $dst\n\t" 6033 "BNE cr0, next\n" 6034 "next:\n\t" 6035 "ISYNC" %} 6036 size(16); 6037 ins_encode %{ 6038 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6039 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6040 Label next; 6041 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 6042 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 6043 __ bne(CCR0, next); 6044 __ bind(next); 6045 __ isync(); 6046 %} 6047 ins_pipe(pipe_class_memory); 6048 %} 6049 6050 // Load Double - aligned 6051 instruct loadD(regD dst, memory mem) %{ 6052 match(Set dst (LoadD mem)); 6053 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 6054 ins_cost(MEMORY_REF_COST); 6055 6056 format %{ "LFD $dst, $mem" %} 6057 size(4); 6058 ins_encode( enc_lfd(dst, mem) ); 6059 ins_pipe(pipe_class_memory); 6060 %} 6061 6062 // Load Double - aligned acquire. 6063 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 6064 match(Set dst (LoadD mem)); 6065 effect(TEMP cr0); 6066 ins_cost(3*MEMORY_REF_COST); 6067 6068 format %{ "LFD $dst, $mem \t// acquire\n\t" 6069 "FCMPU cr0, $dst, $dst\n\t" 6070 "BNE cr0, next\n" 6071 "next:\n\t" 6072 "ISYNC" %} 6073 size(16); 6074 ins_encode %{ 6075 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6076 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6077 Label next; 6078 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 6079 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 6080 __ bne(CCR0, next); 6081 __ bind(next); 6082 __ isync(); 6083 %} 6084 ins_pipe(pipe_class_memory); 6085 %} 6086 6087 // Load Double - UNaligned 6088 instruct loadD_unaligned(regD dst, memory mem) %{ 6089 match(Set dst (LoadD_unaligned mem)); 6090 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 6091 ins_cost(MEMORY_REF_COST); 6092 6093 format %{ "LFD $dst, $mem" %} 6094 size(4); 6095 ins_encode( enc_lfd(dst, mem) ); 6096 ins_pipe(pipe_class_memory); 6097 %} 6098 6099 //----------Constants-------------------------------------------------------- 6100 6101 // Load MachConstantTableBase: add hi offset to global toc. 6102 // TODO: Handle hidden register r29 in bundler! 6103 instruct loadToc_hi(iRegLdst dst) %{ 6104 effect(DEF dst); 6105 ins_cost(DEFAULT_COST); 6106 6107 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 6108 size(4); 6109 ins_encode %{ 6110 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6111 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 6112 %} 6113 ins_pipe(pipe_class_default); 6114 %} 6115 6116 // Load MachConstantTableBase: add lo offset to global toc. 6117 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 6118 effect(DEF dst, USE src); 6119 ins_cost(DEFAULT_COST); 6120 6121 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 6122 size(4); 6123 ins_encode %{ 6124 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6125 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 6126 %} 6127 ins_pipe(pipe_class_default); 6128 %} 6129 6130 // Load 16-bit integer constant 0xssss???? 6131 instruct loadConI16(iRegIdst dst, immI16 src) %{ 6132 match(Set dst src); 6133 6134 format %{ "LI $dst, $src" %} 6135 size(4); 6136 ins_encode %{ 6137 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6138 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6139 %} 6140 ins_pipe(pipe_class_default); 6141 %} 6142 6143 // Load integer constant 0x????0000 6144 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 6145 match(Set dst src); 6146 ins_cost(DEFAULT_COST); 6147 6148 format %{ "LIS $dst, $src.hi" %} 6149 size(4); 6150 ins_encode %{ 6151 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6152 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 6153 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6154 %} 6155 ins_pipe(pipe_class_default); 6156 %} 6157 6158 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 6159 // and sign extended), this adds the low 16 bits. 6160 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6161 // no match-rule, false predicate 6162 effect(DEF dst, USE src1, USE src2); 6163 predicate(false); 6164 6165 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6166 size(4); 6167 ins_encode %{ 6168 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6169 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6170 %} 6171 ins_pipe(pipe_class_default); 6172 %} 6173 6174 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6175 match(Set dst src); 6176 ins_cost(DEFAULT_COST*2); 6177 6178 expand %{ 6179 // Would like to use $src$$constant. 6180 immI16 srcLo %{ _opnds[1]->constant() %} 6181 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6182 immIhi16 srcHi %{ _opnds[1]->constant() %} 6183 iRegIdst tmpI; 6184 loadConIhi16(tmpI, srcHi); 6185 loadConI32_lo16(dst, tmpI, srcLo); 6186 %} 6187 %} 6188 6189 // No constant pool entries required. 6190 instruct loadConL16(iRegLdst dst, immL16 src) %{ 6191 match(Set dst src); 6192 6193 format %{ "LI $dst, $src \t// long" %} 6194 size(4); 6195 ins_encode %{ 6196 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6197 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6198 %} 6199 ins_pipe(pipe_class_default); 6200 %} 6201 6202 // Load long constant 0xssssssss????0000 6203 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6204 match(Set dst src); 6205 ins_cost(DEFAULT_COST); 6206 6207 format %{ "LIS $dst, $src.hi \t// long" %} 6208 size(4); 6209 ins_encode %{ 6210 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6211 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6212 %} 6213 ins_pipe(pipe_class_default); 6214 %} 6215 6216 // To load a 32 bit constant: merge lower 16 bits into already loaded 6217 // high 16 bits. 6218 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6219 // no match-rule, false predicate 6220 effect(DEF dst, USE src1, USE src2); 6221 predicate(false); 6222 6223 format %{ "ORI $dst, $src1, $src2.lo" %} 6224 size(4); 6225 ins_encode %{ 6226 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6227 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6228 %} 6229 ins_pipe(pipe_class_default); 6230 %} 6231 6232 // Load 32-bit long constant 6233 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6234 match(Set dst src); 6235 ins_cost(DEFAULT_COST*2); 6236 6237 expand %{ 6238 // Would like to use $src$$constant. 6239 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6240 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6241 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6242 iRegLdst tmpL; 6243 loadConL32hi16(tmpL, srcHi); 6244 loadConL32_lo16(dst, tmpL, srcLo); 6245 %} 6246 %} 6247 6248 // Load long constant 0x????000000000000. 6249 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6250 match(Set dst src); 6251 ins_cost(DEFAULT_COST); 6252 6253 expand %{ 6254 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6255 immI shift32 %{ 32 %} 6256 iRegLdst tmpL; 6257 loadConL32hi16(tmpL, srcHi); 6258 lshiftL_regL_immI(dst, tmpL, shift32); 6259 %} 6260 %} 6261 6262 // Expand node for constant pool load: small offset. 6263 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6264 effect(DEF dst, USE src, USE toc); 6265 ins_cost(MEMORY_REF_COST); 6266 6267 ins_num_consts(1); 6268 // Needed so that CallDynamicJavaDirect can compute the address of this 6269 // instruction for relocation. 6270 ins_field_cbuf_insts_offset(int); 6271 6272 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6273 size(4); 6274 ins_encode( enc_load_long_constL(dst, src, toc) ); 6275 ins_pipe(pipe_class_memory); 6276 %} 6277 6278 // Expand node for constant pool load: large offset. 6279 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6280 effect(DEF dst, USE src, USE toc); 6281 predicate(false); 6282 6283 ins_num_consts(1); 6284 ins_field_const_toc_offset(int); 6285 // Needed so that CallDynamicJavaDirect can compute the address of this 6286 // instruction for relocation. 6287 ins_field_cbuf_insts_offset(int); 6288 6289 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6290 size(4); 6291 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6292 ins_pipe(pipe_class_default); 6293 %} 6294 6295 // Expand node for constant pool load: large offset. 6296 // No constant pool entries required. 6297 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6298 effect(DEF dst, USE src, USE base); 6299 predicate(false); 6300 6301 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6302 6303 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6304 size(4); 6305 ins_encode %{ 6306 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6307 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6308 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6309 %} 6310 ins_pipe(pipe_class_memory); 6311 %} 6312 6313 // Load long constant from constant table. Expand in case of 6314 // offset > 16 bit is needed. 6315 // Adlc adds toc node MachConstantTableBase. 6316 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6317 match(Set dst src); 6318 ins_cost(MEMORY_REF_COST); 6319 6320 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6321 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6322 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6323 %} 6324 6325 // Load NULL as compressed oop. 6326 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6327 match(Set dst src); 6328 ins_cost(DEFAULT_COST); 6329 6330 format %{ "LI $dst, $src \t// compressed ptr" %} 6331 size(4); 6332 ins_encode %{ 6333 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6334 __ li($dst$$Register, 0); 6335 %} 6336 ins_pipe(pipe_class_default); 6337 %} 6338 6339 // Load hi part of compressed oop constant. 6340 instruct loadConN_hi(iRegNdst dst, immN src) %{ 6341 effect(DEF dst, USE src); 6342 ins_cost(DEFAULT_COST); 6343 6344 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6345 size(4); 6346 ins_encode %{ 6347 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6348 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6349 %} 6350 ins_pipe(pipe_class_default); 6351 %} 6352 6353 // Add lo part of compressed oop constant to already loaded hi part. 6354 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6355 effect(DEF dst, USE src1, USE src2); 6356 ins_cost(DEFAULT_COST); 6357 6358 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6359 size(4); 6360 ins_encode %{ 6361 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6362 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6363 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6364 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6365 __ relocate(rspec, 1); 6366 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6367 %} 6368 ins_pipe(pipe_class_default); 6369 %} 6370 6371 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6372 effect(DEF dst, USE src, USE shift, USE mask_begin); 6373 6374 size(4); 6375 ins_encode %{ 6376 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6377 %} 6378 ins_pipe(pipe_class_default); 6379 %} 6380 6381 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6382 // leaving the upper 32 bits with sign-extension bits. 6383 // This clears these bits: dst = src & 0xFFFFFFFF. 6384 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6385 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6386 effect(DEF dst, USE src); 6387 predicate(false); 6388 6389 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6390 size(4); 6391 ins_encode %{ 6392 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6393 __ clrldi($dst$$Register, $src$$Register, 0x20); 6394 %} 6395 ins_pipe(pipe_class_default); 6396 %} 6397 6398 // Optimize DecodeN for disjoint base. 6399 // Load base of compressed oops into a register 6400 instruct loadBase(iRegLdst dst) %{ 6401 effect(DEF dst); 6402 6403 format %{ "LoadConst $dst, heapbase" %} 6404 ins_encode %{ 6405 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6406 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0); 6407 %} 6408 ins_pipe(pipe_class_default); 6409 %} 6410 6411 // Loading ConN must be postalloc expanded so that edges between 6412 // the nodes are safe. They may not interfere with a safepoint. 6413 // GL TODO: This needs three instructions: better put this into the constant pool. 6414 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6415 match(Set dst src); 6416 ins_cost(DEFAULT_COST*2); 6417 6418 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6419 postalloc_expand %{ 6420 MachNode *m1 = new loadConN_hiNode(); 6421 MachNode *m2 = new loadConN_loNode(); 6422 MachNode *m3 = new clearMs32bNode(); 6423 m1->add_req(NULL); 6424 m2->add_req(NULL, m1); 6425 m3->add_req(NULL, m2); 6426 m1->_opnds[0] = op_dst; 6427 m1->_opnds[1] = op_src; 6428 m2->_opnds[0] = op_dst; 6429 m2->_opnds[1] = op_dst; 6430 m2->_opnds[2] = op_src; 6431 m3->_opnds[0] = op_dst; 6432 m3->_opnds[1] = op_dst; 6433 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6434 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6435 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6436 nodes->push(m1); 6437 nodes->push(m2); 6438 nodes->push(m3); 6439 %} 6440 %} 6441 6442 // We have seen a safepoint between the hi and lo parts, and this node was handled 6443 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6444 // not a narrow oop. 6445 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6446 match(Set dst src); 6447 effect(DEF dst, USE src); 6448 ins_cost(DEFAULT_COST); 6449 6450 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6451 size(4); 6452 ins_encode %{ 6453 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6454 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant); 6455 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6456 %} 6457 ins_pipe(pipe_class_default); 6458 %} 6459 6460 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6461 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6462 match(Set dst src1); 6463 effect(TEMP src2); 6464 ins_cost(DEFAULT_COST); 6465 6466 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6467 size(4); 6468 ins_encode %{ 6469 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6470 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6471 %} 6472 ins_pipe(pipe_class_default); 6473 %} 6474 6475 // This needs a match rule so that build_oop_map knows this is 6476 // not a narrow oop. 6477 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6478 match(Set dst src1); 6479 effect(TEMP src2); 6480 ins_cost(DEFAULT_COST); 6481 6482 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6483 size(4); 6484 ins_encode %{ 6485 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6486 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src1$$constant); 6487 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6488 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6489 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6490 6491 __ relocate(rspec, 1); 6492 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6493 %} 6494 ins_pipe(pipe_class_default); 6495 %} 6496 6497 // Loading ConNKlass must be postalloc expanded so that edges between 6498 // the nodes are safe. They may not interfere with a safepoint. 6499 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6500 match(Set dst src); 6501 ins_cost(DEFAULT_COST*2); 6502 6503 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6504 postalloc_expand %{ 6505 // Load high bits into register. Sign extended. 6506 MachNode *m1 = new loadConNKlass_hiNode(); 6507 m1->add_req(NULL); 6508 m1->_opnds[0] = op_dst; 6509 m1->_opnds[1] = op_src; 6510 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6511 nodes->push(m1); 6512 6513 MachNode *m2 = m1; 6514 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) { 6515 // Value might be 1-extended. Mask out these bits. 6516 m2 = new loadConNKlass_maskNode(); 6517 m2->add_req(NULL, m1); 6518 m2->_opnds[0] = op_dst; 6519 m2->_opnds[1] = op_src; 6520 m2->_opnds[2] = op_dst; 6521 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6522 nodes->push(m2); 6523 } 6524 6525 MachNode *m3 = new loadConNKlass_loNode(); 6526 m3->add_req(NULL, m2); 6527 m3->_opnds[0] = op_dst; 6528 m3->_opnds[1] = op_src; 6529 m3->_opnds[2] = op_dst; 6530 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6531 nodes->push(m3); 6532 %} 6533 %} 6534 6535 // 0x1 is used in object initialization (initial object header). 6536 // No constant pool entries required. 6537 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6538 match(Set dst src); 6539 6540 format %{ "LI $dst, $src \t// ptr" %} 6541 size(4); 6542 ins_encode %{ 6543 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6544 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6545 %} 6546 ins_pipe(pipe_class_default); 6547 %} 6548 6549 // Expand node for constant pool load: small offset. 6550 // The match rule is needed to generate the correct bottom_type(), 6551 // however this node should never match. The use of predicate is not 6552 // possible since ADLC forbids predicates for chain rules. The higher 6553 // costs do not prevent matching in this case. For that reason the 6554 // operand immP_NM with predicate(false) is used. 6555 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6556 match(Set dst src); 6557 effect(TEMP toc); 6558 6559 ins_num_consts(1); 6560 6561 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6562 size(4); 6563 ins_encode( enc_load_long_constP(dst, src, toc) ); 6564 ins_pipe(pipe_class_memory); 6565 %} 6566 6567 // Expand node for constant pool load: large offset. 6568 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6569 effect(DEF dst, USE src, USE toc); 6570 predicate(false); 6571 6572 ins_num_consts(1); 6573 ins_field_const_toc_offset(int); 6574 6575 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6576 size(4); 6577 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6578 ins_pipe(pipe_class_default); 6579 %} 6580 6581 // Expand node for constant pool load: large offset. 6582 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6583 match(Set dst src); 6584 effect(TEMP base); 6585 6586 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6587 6588 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6589 size(4); 6590 ins_encode %{ 6591 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6592 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6593 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6594 %} 6595 ins_pipe(pipe_class_memory); 6596 %} 6597 6598 // Load pointer constant from constant table. Expand in case an 6599 // offset > 16 bit is needed. 6600 // Adlc adds toc node MachConstantTableBase. 6601 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6602 match(Set dst src); 6603 ins_cost(MEMORY_REF_COST); 6604 6605 // This rule does not use "expand" because then 6606 // the result type is not known to be an Oop. An ADLC 6607 // enhancement will be needed to make that work - not worth it! 6608 6609 // If this instruction rematerializes, it prolongs the live range 6610 // of the toc node, causing illegal graphs. 6611 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6612 ins_cannot_rematerialize(true); 6613 6614 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6615 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6616 %} 6617 6618 // Expand node for constant pool load: small offset. 6619 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6620 effect(DEF dst, USE src, USE toc); 6621 ins_cost(MEMORY_REF_COST); 6622 6623 ins_num_consts(1); 6624 6625 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6626 size(4); 6627 ins_encode %{ 6628 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6629 address float_address = __ float_constant($src$$constant); 6630 if (float_address == NULL) { 6631 ciEnv::current()->record_out_of_memory_failure(); 6632 return; 6633 } 6634 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6635 %} 6636 ins_pipe(pipe_class_memory); 6637 %} 6638 6639 // Expand node for constant pool load: large offset. 6640 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6641 effect(DEF dst, USE src, USE toc); 6642 ins_cost(MEMORY_REF_COST); 6643 6644 ins_num_consts(1); 6645 6646 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6647 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6648 "ADDIS $toc, $toc, -offset_hi"%} 6649 size(12); 6650 ins_encode %{ 6651 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6652 FloatRegister Rdst = $dst$$FloatRegister; 6653 Register Rtoc = $toc$$Register; 6654 address float_address = __ float_constant($src$$constant); 6655 if (float_address == NULL) { 6656 ciEnv::current()->record_out_of_memory_failure(); 6657 return; 6658 } 6659 int offset = __ offset_to_method_toc(float_address); 6660 int hi = (offset + (1<<15))>>16; 6661 int lo = offset - hi * (1<<16); 6662 6663 __ addis(Rtoc, Rtoc, hi); 6664 __ lfs(Rdst, lo, Rtoc); 6665 __ addis(Rtoc, Rtoc, -hi); 6666 %} 6667 ins_pipe(pipe_class_memory); 6668 %} 6669 6670 // Adlc adds toc node MachConstantTableBase. 6671 instruct loadConF_Ex(regF dst, immF src) %{ 6672 match(Set dst src); 6673 ins_cost(MEMORY_REF_COST); 6674 6675 // See loadConP. 6676 ins_cannot_rematerialize(true); 6677 6678 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6679 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6680 %} 6681 6682 // Expand node for constant pool load: small offset. 6683 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6684 effect(DEF dst, USE src, USE toc); 6685 ins_cost(MEMORY_REF_COST); 6686 6687 ins_num_consts(1); 6688 6689 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6690 size(4); 6691 ins_encode %{ 6692 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6693 address float_address = __ double_constant($src$$constant); 6694 if (float_address == NULL) { 6695 ciEnv::current()->record_out_of_memory_failure(); 6696 return; 6697 } 6698 int offset = __ offset_to_method_toc(float_address); 6699 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6700 %} 6701 ins_pipe(pipe_class_memory); 6702 %} 6703 6704 // Expand node for constant pool load: large offset. 6705 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6706 effect(DEF dst, USE src, USE toc); 6707 ins_cost(MEMORY_REF_COST); 6708 6709 ins_num_consts(1); 6710 6711 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6712 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6713 "ADDIS $toc, $toc, -offset_hi" %} 6714 size(12); 6715 ins_encode %{ 6716 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6717 FloatRegister Rdst = $dst$$FloatRegister; 6718 Register Rtoc = $toc$$Register; 6719 address float_address = __ double_constant($src$$constant); 6720 if (float_address == NULL) { 6721 ciEnv::current()->record_out_of_memory_failure(); 6722 return; 6723 } 6724 int offset = __ offset_to_method_toc(float_address); 6725 int hi = (offset + (1<<15))>>16; 6726 int lo = offset - hi * (1<<16); 6727 6728 __ addis(Rtoc, Rtoc, hi); 6729 __ lfd(Rdst, lo, Rtoc); 6730 __ addis(Rtoc, Rtoc, -hi); 6731 %} 6732 ins_pipe(pipe_class_memory); 6733 %} 6734 6735 // Adlc adds toc node MachConstantTableBase. 6736 instruct loadConD_Ex(regD dst, immD src) %{ 6737 match(Set dst src); 6738 ins_cost(MEMORY_REF_COST); 6739 6740 // See loadConP. 6741 ins_cannot_rematerialize(true); 6742 6743 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6744 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6745 %} 6746 6747 // Prefetch instructions. 6748 // Must be safe to execute with invalid address (cannot fault). 6749 6750 // Special prefetch versions which use the dcbz instruction. 6751 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6752 match(PrefetchAllocation (AddP mem src)); 6753 predicate(AllocatePrefetchStyle == 3); 6754 ins_cost(MEMORY_REF_COST); 6755 6756 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6757 size(4); 6758 ins_encode %{ 6759 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6760 __ dcbz($src$$Register, $mem$$base$$Register); 6761 %} 6762 ins_pipe(pipe_class_memory); 6763 %} 6764 6765 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6766 match(PrefetchAllocation mem); 6767 predicate(AllocatePrefetchStyle == 3); 6768 ins_cost(MEMORY_REF_COST); 6769 6770 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6771 size(4); 6772 ins_encode %{ 6773 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6774 __ dcbz($mem$$base$$Register); 6775 %} 6776 ins_pipe(pipe_class_memory); 6777 %} 6778 6779 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6780 match(PrefetchAllocation (AddP mem src)); 6781 predicate(AllocatePrefetchStyle != 3); 6782 ins_cost(MEMORY_REF_COST); 6783 6784 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6785 size(4); 6786 ins_encode %{ 6787 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6788 __ dcbtst($src$$Register, $mem$$base$$Register); 6789 %} 6790 ins_pipe(pipe_class_memory); 6791 %} 6792 6793 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6794 match(PrefetchAllocation mem); 6795 predicate(AllocatePrefetchStyle != 3); 6796 ins_cost(MEMORY_REF_COST); 6797 6798 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6799 size(4); 6800 ins_encode %{ 6801 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6802 __ dcbtst($mem$$base$$Register); 6803 %} 6804 ins_pipe(pipe_class_memory); 6805 %} 6806 6807 //----------Store Instructions------------------------------------------------- 6808 6809 // Store Byte 6810 instruct storeB(memory mem, iRegIsrc src) %{ 6811 match(Set mem (StoreB mem src)); 6812 ins_cost(MEMORY_REF_COST); 6813 6814 format %{ "STB $src, $mem \t// byte" %} 6815 size(4); 6816 ins_encode %{ 6817 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6818 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6819 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6820 %} 6821 ins_pipe(pipe_class_memory); 6822 %} 6823 6824 // Store Char/Short 6825 instruct storeC(memory mem, iRegIsrc src) %{ 6826 match(Set mem (StoreC mem src)); 6827 ins_cost(MEMORY_REF_COST); 6828 6829 format %{ "STH $src, $mem \t// short" %} 6830 size(4); 6831 ins_encode %{ 6832 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6833 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6834 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6835 %} 6836 ins_pipe(pipe_class_memory); 6837 %} 6838 6839 // Store Integer 6840 instruct storeI(memory mem, iRegIsrc src) %{ 6841 match(Set mem (StoreI mem src)); 6842 ins_cost(MEMORY_REF_COST); 6843 6844 format %{ "STW $src, $mem" %} 6845 size(4); 6846 ins_encode( enc_stw(src, mem) ); 6847 ins_pipe(pipe_class_memory); 6848 %} 6849 6850 // ConvL2I + StoreI. 6851 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6852 match(Set mem (StoreI mem (ConvL2I src))); 6853 ins_cost(MEMORY_REF_COST); 6854 6855 format %{ "STW l2i($src), $mem" %} 6856 size(4); 6857 ins_encode( enc_stw(src, mem) ); 6858 ins_pipe(pipe_class_memory); 6859 %} 6860 6861 // Store Long 6862 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6863 match(Set mem (StoreL mem src)); 6864 ins_cost(MEMORY_REF_COST); 6865 6866 format %{ "STD $src, $mem \t// long" %} 6867 size(4); 6868 ins_encode( enc_std(src, mem) ); 6869 ins_pipe(pipe_class_memory); 6870 %} 6871 6872 // Store super word nodes. 6873 6874 // Store Aligned Packed Byte long register to memory 6875 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6876 predicate(n->as_StoreVector()->memory_size() == 8); 6877 match(Set mem (StoreVector mem src)); 6878 ins_cost(MEMORY_REF_COST); 6879 6880 format %{ "STD $mem, $src \t// packed8B" %} 6881 size(4); 6882 ins_encode( enc_std(src, mem) ); 6883 ins_pipe(pipe_class_memory); 6884 %} 6885 6886 // Store Packed Byte long register to memory 6887 instruct storeV16(indirect mem, vecX src) %{ 6888 predicate(n->as_StoreVector()->memory_size() == 16); 6889 match(Set mem (StoreVector mem src)); 6890 ins_cost(MEMORY_REF_COST); 6891 6892 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6893 size(4); 6894 ins_encode %{ 6895 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6896 %} 6897 ins_pipe(pipe_class_default); 6898 %} 6899 6900 // Store Compressed Oop 6901 instruct storeN(memory dst, iRegN_P2N src) %{ 6902 match(Set dst (StoreN dst src)); 6903 ins_cost(MEMORY_REF_COST); 6904 6905 format %{ "STW $src, $dst \t// compressed oop" %} 6906 size(4); 6907 ins_encode( enc_stw(src, dst) ); 6908 ins_pipe(pipe_class_memory); 6909 %} 6910 6911 // Store Compressed KLass 6912 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6913 match(Set dst (StoreNKlass dst src)); 6914 ins_cost(MEMORY_REF_COST); 6915 6916 format %{ "STW $src, $dst \t// compressed klass" %} 6917 size(4); 6918 ins_encode( enc_stw(src, dst) ); 6919 ins_pipe(pipe_class_memory); 6920 %} 6921 6922 // Store Pointer 6923 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6924 match(Set dst (StoreP dst src)); 6925 ins_cost(MEMORY_REF_COST); 6926 6927 format %{ "STD $src, $dst \t// ptr" %} 6928 size(4); 6929 ins_encode( enc_std(src, dst) ); 6930 ins_pipe(pipe_class_memory); 6931 %} 6932 6933 // Store Float 6934 instruct storeF(memory mem, regF src) %{ 6935 match(Set mem (StoreF mem src)); 6936 ins_cost(MEMORY_REF_COST); 6937 6938 format %{ "STFS $src, $mem" %} 6939 size(4); 6940 ins_encode( enc_stfs(src, mem) ); 6941 ins_pipe(pipe_class_memory); 6942 %} 6943 6944 // Store Double 6945 instruct storeD(memory mem, regD src) %{ 6946 match(Set mem (StoreD mem src)); 6947 ins_cost(MEMORY_REF_COST); 6948 6949 format %{ "STFD $src, $mem" %} 6950 size(4); 6951 ins_encode( enc_stfd(src, mem) ); 6952 ins_pipe(pipe_class_memory); 6953 %} 6954 6955 //----------Store Instructions With Zeros-------------------------------------- 6956 6957 // Card-mark for CMS garbage collection. 6958 // This cardmark does an optimization so that it must not always 6959 // do a releasing store. For this, it gets the address of 6960 // CMSCollectorCardTableBarrierSetBSExt::_requires_release as input. 6961 // (Using releaseFieldAddr in the match rule is a hack.) 6962 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6963 match(Set mem (StoreCM mem releaseFieldAddr)); 6964 effect(TEMP crx); 6965 predicate(false); 6966 ins_cost(MEMORY_REF_COST); 6967 6968 // See loadConP. 6969 ins_cannot_rematerialize(true); 6970 6971 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6972 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6973 ins_pipe(pipe_class_memory); 6974 %} 6975 6976 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6977 match(Set mem (StoreCM mem zero)); 6978 predicate(UseG1GC); 6979 ins_cost(MEMORY_REF_COST); 6980 6981 ins_cannot_rematerialize(true); 6982 6983 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6984 size(8); 6985 ins_encode %{ 6986 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6987 __ li(R0, 0); 6988 //__ release(); // G1: oops are allowed to get visible after dirty marking 6989 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6990 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6991 %} 6992 ins_pipe(pipe_class_memory); 6993 %} 6994 6995 // Convert oop pointer into compressed form. 6996 6997 // Nodes for postalloc expand. 6998 6999 // Shift node for expand. 7000 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 7001 // The match rule is needed to make it a 'MachTypeNode'! 7002 match(Set dst (EncodeP src)); 7003 predicate(false); 7004 7005 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7006 size(4); 7007 ins_encode %{ 7008 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7009 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 7010 %} 7011 ins_pipe(pipe_class_default); 7012 %} 7013 7014 // Add node for expand. 7015 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 7016 // The match rule is needed to make it a 'MachTypeNode'! 7017 match(Set dst (EncodeP src)); 7018 predicate(false); 7019 7020 format %{ "SUB $dst, $src, oop_base \t// encode" %} 7021 ins_encode %{ 7022 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7023 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 7024 %} 7025 ins_pipe(pipe_class_default); 7026 %} 7027 7028 // Conditional sub base. 7029 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7030 // The match rule is needed to make it a 'MachTypeNode'! 7031 match(Set dst (EncodeP (Binary crx src1))); 7032 predicate(false); 7033 7034 format %{ "BEQ $crx, done\n\t" 7035 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 7036 "done:" %} 7037 ins_encode %{ 7038 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7039 Label done; 7040 __ beq($crx$$CondRegister, done); 7041 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0); 7042 __ bind(done); 7043 %} 7044 ins_pipe(pipe_class_default); 7045 %} 7046 7047 // Power 7 can use isel instruction 7048 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7049 // The match rule is needed to make it a 'MachTypeNode'! 7050 match(Set dst (EncodeP (Binary crx src1))); 7051 predicate(false); 7052 7053 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 7054 size(4); 7055 ins_encode %{ 7056 // This is a Power7 instruction for which no machine description exists. 7057 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7058 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7059 %} 7060 ins_pipe(pipe_class_default); 7061 %} 7062 7063 // Disjoint narrow oop base. 7064 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7065 match(Set dst (EncodeP src)); 7066 predicate(CompressedOops::base_disjoint()); 7067 7068 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7069 size(4); 7070 ins_encode %{ 7071 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7072 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32); 7073 %} 7074 ins_pipe(pipe_class_default); 7075 %} 7076 7077 // shift != 0, base != 0 7078 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 7079 match(Set dst (EncodeP src)); 7080 effect(TEMP crx); 7081 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 7082 CompressedOops::shift() != 0 && 7083 CompressedOops::base_overlaps()); 7084 7085 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 7086 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 7087 %} 7088 7089 // shift != 0, base != 0 7090 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 7091 match(Set dst (EncodeP src)); 7092 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 7093 CompressedOops::shift() != 0 && 7094 CompressedOops::base_overlaps()); 7095 7096 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 7097 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 7098 %} 7099 7100 // shift != 0, base == 0 7101 // TODO: This is the same as encodeP_shift. Merge! 7102 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 7103 match(Set dst (EncodeP src)); 7104 predicate(CompressedOops::shift() != 0 && 7105 CompressedOops::base() ==0); 7106 7107 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 7108 size(4); 7109 ins_encode %{ 7110 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7111 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 7112 %} 7113 ins_pipe(pipe_class_default); 7114 %} 7115 7116 // Compressed OOPs with narrow_oop_shift == 0. 7117 // shift == 0, base == 0 7118 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 7119 match(Set dst (EncodeP src)); 7120 predicate(CompressedOops::shift() == 0); 7121 7122 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 7123 // variable size, 0 or 4. 7124 ins_encode %{ 7125 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7126 __ mr_if_needed($dst$$Register, $src$$Register); 7127 %} 7128 ins_pipe(pipe_class_default); 7129 %} 7130 7131 // Decode nodes. 7132 7133 // Shift node for expand. 7134 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 7135 // The match rule is needed to make it a 'MachTypeNode'! 7136 match(Set dst (DecodeN src)); 7137 predicate(false); 7138 7139 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 7140 size(4); 7141 ins_encode %{ 7142 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7143 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 7144 %} 7145 ins_pipe(pipe_class_default); 7146 %} 7147 7148 // Add node for expand. 7149 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7150 // The match rule is needed to make it a 'MachTypeNode'! 7151 match(Set dst (DecodeN src)); 7152 predicate(false); 7153 7154 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7155 ins_encode %{ 7156 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7157 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 7158 %} 7159 ins_pipe(pipe_class_default); 7160 %} 7161 7162 // conditianal add base for expand 7163 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7164 // The match rule is needed to make it a 'MachTypeNode'! 7165 // NOTICE that the rule is nonsense - we just have to make sure that: 7166 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7167 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7168 match(Set dst (DecodeN (Binary crx src))); 7169 predicate(false); 7170 7171 format %{ "BEQ $crx, done\n\t" 7172 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7173 "done:" %} 7174 ins_encode %{ 7175 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7176 Label done; 7177 __ beq($crx$$CondRegister, done); 7178 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 7179 __ bind(done); 7180 %} 7181 ins_pipe(pipe_class_default); 7182 %} 7183 7184 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7185 // The match rule is needed to make it a 'MachTypeNode'! 7186 // NOTICE that the rule is nonsense - we just have to make sure that: 7187 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7188 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7189 match(Set dst (DecodeN (Binary crx src1))); 7190 predicate(false); 7191 7192 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7193 size(4); 7194 ins_encode %{ 7195 // This is a Power7 instruction for which no machine description exists. 7196 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7197 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7198 %} 7199 ins_pipe(pipe_class_default); 7200 %} 7201 7202 // shift != 0, base != 0 7203 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7204 match(Set dst (DecodeN src)); 7205 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7206 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7207 CompressedOops::shift() != 0 && 7208 CompressedOops::base() != 0); 7209 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7210 effect(TEMP crx); 7211 7212 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7213 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7214 %} 7215 7216 // shift != 0, base == 0 7217 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7218 match(Set dst (DecodeN src)); 7219 predicate(CompressedOops::shift() != 0 && 7220 CompressedOops::base() == 0); 7221 7222 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7223 size(4); 7224 ins_encode %{ 7225 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7226 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 7227 %} 7228 ins_pipe(pipe_class_default); 7229 %} 7230 7231 // Optimize DecodeN for disjoint base. 7232 // Shift narrow oop and or it into register that already contains the heap base. 7233 // Base == dst must hold, and is assured by construction in postaloc_expand. 7234 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7235 match(Set dst (DecodeN src)); 7236 effect(TEMP base); 7237 predicate(false); 7238 7239 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7240 size(4); 7241 ins_encode %{ 7242 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7243 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift()); 7244 %} 7245 ins_pipe(pipe_class_default); 7246 %} 7247 7248 // Optimize DecodeN for disjoint base. 7249 // This node requires only one cycle on the critical path. 7250 // We must postalloc_expand as we can not express use_def effects where 7251 // the used register is L and the def'ed register P. 7252 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7253 match(Set dst (DecodeN src)); 7254 effect(TEMP_DEF dst); 7255 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7256 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7257 CompressedOops::base_disjoint()); 7258 ins_cost(DEFAULT_COST); 7259 7260 format %{ "MOV $dst, heapbase \t\n" 7261 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7262 postalloc_expand %{ 7263 loadBaseNode *n1 = new loadBaseNode(); 7264 n1->add_req(NULL); 7265 n1->_opnds[0] = op_dst; 7266 7267 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7268 n2->add_req(n_region, n_src, n1); 7269 n2->_opnds[0] = op_dst; 7270 n2->_opnds[1] = op_src; 7271 n2->_opnds[2] = op_dst; 7272 n2->_bottom_type = _bottom_type; 7273 7274 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7275 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7276 7277 nodes->push(n1); 7278 nodes->push(n2); 7279 %} 7280 %} 7281 7282 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7283 match(Set dst (DecodeN src)); 7284 effect(TEMP_DEF dst, TEMP crx); 7285 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7286 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7287 CompressedOops::base_disjoint() && VM_Version::has_isel()); 7288 ins_cost(3 * DEFAULT_COST); 7289 7290 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7291 postalloc_expand %{ 7292 loadBaseNode *n1 = new loadBaseNode(); 7293 n1->add_req(NULL); 7294 n1->_opnds[0] = op_dst; 7295 7296 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7297 n_compare->add_req(n_region, n_src); 7298 n_compare->_opnds[0] = op_crx; 7299 n_compare->_opnds[1] = op_src; 7300 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7301 7302 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7303 n2->add_req(n_region, n_src, n1); 7304 n2->_opnds[0] = op_dst; 7305 n2->_opnds[1] = op_src; 7306 n2->_opnds[2] = op_dst; 7307 n2->_bottom_type = _bottom_type; 7308 7309 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7310 n_cond_set->add_req(n_region, n_compare, n2); 7311 n_cond_set->_opnds[0] = op_dst; 7312 n_cond_set->_opnds[1] = op_crx; 7313 n_cond_set->_opnds[2] = op_dst; 7314 n_cond_set->_bottom_type = _bottom_type; 7315 7316 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7317 ra_->set_oop(n_cond_set, true); 7318 7319 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7320 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7321 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7322 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7323 7324 nodes->push(n1); 7325 nodes->push(n_compare); 7326 nodes->push(n2); 7327 nodes->push(n_cond_set); 7328 %} 7329 %} 7330 7331 // src != 0, shift != 0, base != 0 7332 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7333 match(Set dst (DecodeN src)); 7334 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7335 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7336 CompressedOops::shift() != 0 && 7337 CompressedOops::base() != 0); 7338 ins_cost(2 * DEFAULT_COST); 7339 7340 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7341 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7342 %} 7343 7344 // Compressed OOPs with narrow_oop_shift == 0. 7345 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7346 match(Set dst (DecodeN src)); 7347 predicate(CompressedOops::shift() == 0); 7348 ins_cost(DEFAULT_COST); 7349 7350 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7351 // variable size, 0 or 4. 7352 ins_encode %{ 7353 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7354 __ mr_if_needed($dst$$Register, $src$$Register); 7355 %} 7356 ins_pipe(pipe_class_default); 7357 %} 7358 7359 // Convert compressed oop into int for vectors alignment masking. 7360 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7361 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7362 predicate(CompressedOops::shift() == 0); 7363 ins_cost(DEFAULT_COST); 7364 7365 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7366 // variable size, 0 or 4. 7367 ins_encode %{ 7368 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7369 __ mr_if_needed($dst$$Register, $src$$Register); 7370 %} 7371 ins_pipe(pipe_class_default); 7372 %} 7373 7374 // Convert klass pointer into compressed form. 7375 7376 // Nodes for postalloc expand. 7377 7378 // Shift node for expand. 7379 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7380 // The match rule is needed to make it a 'MachTypeNode'! 7381 match(Set dst (EncodePKlass src)); 7382 predicate(false); 7383 7384 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7385 size(4); 7386 ins_encode %{ 7387 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7388 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 7389 %} 7390 ins_pipe(pipe_class_default); 7391 %} 7392 7393 // Add node for expand. 7394 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7395 // The match rule is needed to make it a 'MachTypeNode'! 7396 match(Set dst (EncodePKlass (Binary base src))); 7397 predicate(false); 7398 7399 format %{ "SUB $dst, $base, $src \t// encode" %} 7400 size(4); 7401 ins_encode %{ 7402 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7403 __ subf($dst$$Register, $base$$Register, $src$$Register); 7404 %} 7405 ins_pipe(pipe_class_default); 7406 %} 7407 7408 // Disjoint narrow oop base. 7409 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7410 match(Set dst (EncodePKlass src)); 7411 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/); 7412 7413 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7414 size(4); 7415 ins_encode %{ 7416 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7417 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32); 7418 %} 7419 ins_pipe(pipe_class_default); 7420 %} 7421 7422 // shift != 0, base != 0 7423 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7424 match(Set dst (EncodePKlass (Binary base src))); 7425 predicate(false); 7426 7427 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7428 postalloc_expand %{ 7429 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7430 n1->add_req(n_region, n_base, n_src); 7431 n1->_opnds[0] = op_dst; 7432 n1->_opnds[1] = op_base; 7433 n1->_opnds[2] = op_src; 7434 n1->_bottom_type = _bottom_type; 7435 7436 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7437 n2->add_req(n_region, n1); 7438 n2->_opnds[0] = op_dst; 7439 n2->_opnds[1] = op_dst; 7440 n2->_bottom_type = _bottom_type; 7441 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7442 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7443 7444 nodes->push(n1); 7445 nodes->push(n2); 7446 %} 7447 %} 7448 7449 // shift != 0, base != 0 7450 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7451 match(Set dst (EncodePKlass src)); 7452 //predicate(CompressedKlassPointers::shift() != 0 && 7453 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/); 7454 7455 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7456 ins_cost(DEFAULT_COST*2); // Don't count constant. 7457 expand %{ 7458 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %} 7459 iRegLdst base; 7460 loadConL_Ex(base, baseImm); 7461 encodePKlass_not_null_Ex(dst, base, src); 7462 %} 7463 %} 7464 7465 // Decode nodes. 7466 7467 // Shift node for expand. 7468 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7469 // The match rule is needed to make it a 'MachTypeNode'! 7470 match(Set dst (DecodeNKlass src)); 7471 predicate(false); 7472 7473 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7474 size(4); 7475 ins_encode %{ 7476 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7477 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 7478 %} 7479 ins_pipe(pipe_class_default); 7480 %} 7481 7482 // Add node for expand. 7483 7484 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7485 // The match rule is needed to make it a 'MachTypeNode'! 7486 match(Set dst (DecodeNKlass (Binary base src))); 7487 predicate(false); 7488 7489 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7490 size(4); 7491 ins_encode %{ 7492 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7493 __ add($dst$$Register, $base$$Register, $src$$Register); 7494 %} 7495 ins_pipe(pipe_class_default); 7496 %} 7497 7498 // src != 0, shift != 0, base != 0 7499 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7500 match(Set dst (DecodeNKlass (Binary base src))); 7501 //effect(kill src); // We need a register for the immediate result after shifting. 7502 predicate(false); 7503 7504 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7505 postalloc_expand %{ 7506 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7507 n1->add_req(n_region, n_base, n_src); 7508 n1->_opnds[0] = op_dst; 7509 n1->_opnds[1] = op_base; 7510 n1->_opnds[2] = op_src; 7511 n1->_bottom_type = _bottom_type; 7512 7513 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7514 n2->add_req(n_region, n1); 7515 n2->_opnds[0] = op_dst; 7516 n2->_opnds[1] = op_dst; 7517 n2->_bottom_type = _bottom_type; 7518 7519 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7520 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7521 7522 nodes->push(n1); 7523 nodes->push(n2); 7524 %} 7525 %} 7526 7527 // src != 0, shift != 0, base != 0 7528 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7529 match(Set dst (DecodeNKlass src)); 7530 // predicate(CompressedKlassPointers::shift() != 0 && 7531 // CompressedKlassPointers::base() != 0); 7532 7533 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7534 7535 ins_cost(DEFAULT_COST*2); // Don't count constant. 7536 expand %{ 7537 // We add first, then we shift. Like this, we can get along with one register less. 7538 // But we have to load the base pre-shifted. 7539 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %} 7540 iRegLdst base; 7541 loadConL_Ex(base, baseImm); 7542 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7543 %} 7544 %} 7545 7546 //----------MemBar Instructions----------------------------------------------- 7547 // Memory barrier flavors 7548 7549 instruct membar_acquire() %{ 7550 match(LoadFence); 7551 ins_cost(4*MEMORY_REF_COST); 7552 7553 format %{ "MEMBAR-acquire" %} 7554 size(4); 7555 ins_encode %{ 7556 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7557 __ acquire(); 7558 %} 7559 ins_pipe(pipe_class_default); 7560 %} 7561 7562 instruct unnecessary_membar_acquire() %{ 7563 match(MemBarAcquire); 7564 ins_cost(0); 7565 7566 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7567 size(0); 7568 ins_encode( /*empty*/ ); 7569 ins_pipe(pipe_class_default); 7570 %} 7571 7572 instruct membar_acquire_lock() %{ 7573 match(MemBarAcquireLock); 7574 ins_cost(0); 7575 7576 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7577 size(0); 7578 ins_encode( /*empty*/ ); 7579 ins_pipe(pipe_class_default); 7580 %} 7581 7582 instruct membar_release() %{ 7583 match(MemBarRelease); 7584 match(StoreFence); 7585 ins_cost(4*MEMORY_REF_COST); 7586 7587 format %{ "MEMBAR-release" %} 7588 size(4); 7589 ins_encode %{ 7590 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7591 __ release(); 7592 %} 7593 ins_pipe(pipe_class_default); 7594 %} 7595 7596 instruct membar_storestore() %{ 7597 match(MemBarStoreStore); 7598 ins_cost(4*MEMORY_REF_COST); 7599 7600 format %{ "MEMBAR-store-store" %} 7601 size(4); 7602 ins_encode %{ 7603 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7604 __ membar(Assembler::StoreStore); 7605 %} 7606 ins_pipe(pipe_class_default); 7607 %} 7608 7609 instruct membar_release_lock() %{ 7610 match(MemBarReleaseLock); 7611 ins_cost(0); 7612 7613 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7614 size(0); 7615 ins_encode( /*empty*/ ); 7616 ins_pipe(pipe_class_default); 7617 %} 7618 7619 instruct membar_volatile() %{ 7620 match(MemBarVolatile); 7621 ins_cost(4*MEMORY_REF_COST); 7622 7623 format %{ "MEMBAR-volatile" %} 7624 size(4); 7625 ins_encode %{ 7626 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7627 __ fence(); 7628 %} 7629 ins_pipe(pipe_class_default); 7630 %} 7631 7632 // This optimization is wrong on PPC. The following pattern is not supported: 7633 // MemBarVolatile 7634 // ^ ^ 7635 // | | 7636 // CtrlProj MemProj 7637 // ^ ^ 7638 // | | 7639 // | Load 7640 // | 7641 // MemBarVolatile 7642 // 7643 // The first MemBarVolatile could get optimized out! According to 7644 // Vladimir, this pattern can not occur on Oracle platforms. 7645 // However, it does occur on PPC64 (because of membars in 7646 // inline_unsafe_load_store). 7647 // 7648 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7649 // Don't forget to look at the implementation of post_store_load_barrier again, 7650 // we did other fixes in that method. 7651 //instruct unnecessary_membar_volatile() %{ 7652 // match(MemBarVolatile); 7653 // predicate(Matcher::post_store_load_barrier(n)); 7654 // ins_cost(0); 7655 // 7656 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7657 // size(0); 7658 // ins_encode( /*empty*/ ); 7659 // ins_pipe(pipe_class_default); 7660 //%} 7661 7662 instruct membar_CPUOrder() %{ 7663 match(MemBarCPUOrder); 7664 ins_cost(0); 7665 7666 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7667 size(0); 7668 ins_encode( /*empty*/ ); 7669 ins_pipe(pipe_class_default); 7670 %} 7671 7672 //----------Conditional Move--------------------------------------------------- 7673 7674 // Cmove using isel. 7675 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7676 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7677 predicate(VM_Version::has_isel()); 7678 ins_cost(DEFAULT_COST); 7679 7680 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7681 size(4); 7682 ins_encode %{ 7683 // This is a Power7 instruction for which no machine description 7684 // exists. Anyways, the scheduler should be off on Power7. 7685 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7686 int cc = $cmp$$cmpcode; 7687 __ isel($dst$$Register, $crx$$CondRegister, 7688 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7689 %} 7690 ins_pipe(pipe_class_default); 7691 %} 7692 7693 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7694 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7695 predicate(!VM_Version::has_isel()); 7696 ins_cost(DEFAULT_COST+BRANCH_COST); 7697 7698 ins_variable_size_depending_on_alignment(true); 7699 7700 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7701 // Worst case is branch + move + stop, no stop without scheduler 7702 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7703 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7704 ins_pipe(pipe_class_default); 7705 %} 7706 7707 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7708 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7709 ins_cost(DEFAULT_COST+BRANCH_COST); 7710 7711 ins_variable_size_depending_on_alignment(true); 7712 7713 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7714 // Worst case is branch + move + stop, no stop without scheduler 7715 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7716 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7717 ins_pipe(pipe_class_default); 7718 %} 7719 7720 // Cmove using isel. 7721 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7722 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7723 predicate(VM_Version::has_isel()); 7724 ins_cost(DEFAULT_COST); 7725 7726 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7727 size(4); 7728 ins_encode %{ 7729 // This is a Power7 instruction for which no machine description 7730 // exists. Anyways, the scheduler should be off on Power7. 7731 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7732 int cc = $cmp$$cmpcode; 7733 __ isel($dst$$Register, $crx$$CondRegister, 7734 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7735 %} 7736 ins_pipe(pipe_class_default); 7737 %} 7738 7739 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7740 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7741 predicate(!VM_Version::has_isel()); 7742 ins_cost(DEFAULT_COST+BRANCH_COST); 7743 7744 ins_variable_size_depending_on_alignment(true); 7745 7746 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7747 // Worst case is branch + move + stop, no stop without scheduler. 7748 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7749 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7750 ins_pipe(pipe_class_default); 7751 %} 7752 7753 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7754 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7755 ins_cost(DEFAULT_COST+BRANCH_COST); 7756 7757 ins_variable_size_depending_on_alignment(true); 7758 7759 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7760 // Worst case is branch + move + stop, no stop without scheduler. 7761 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7762 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7763 ins_pipe(pipe_class_default); 7764 %} 7765 7766 // Cmove using isel. 7767 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7768 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7769 predicate(VM_Version::has_isel()); 7770 ins_cost(DEFAULT_COST); 7771 7772 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7773 size(4); 7774 ins_encode %{ 7775 // This is a Power7 instruction for which no machine description 7776 // exists. Anyways, the scheduler should be off on Power7. 7777 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7778 int cc = $cmp$$cmpcode; 7779 __ isel($dst$$Register, $crx$$CondRegister, 7780 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7781 %} 7782 ins_pipe(pipe_class_default); 7783 %} 7784 7785 // Conditional move for RegN. Only cmov(reg, reg). 7786 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7787 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7788 predicate(!VM_Version::has_isel()); 7789 ins_cost(DEFAULT_COST+BRANCH_COST); 7790 7791 ins_variable_size_depending_on_alignment(true); 7792 7793 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7794 // Worst case is branch + move + stop, no stop without scheduler. 7795 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7796 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7797 ins_pipe(pipe_class_default); 7798 %} 7799 7800 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7801 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7802 ins_cost(DEFAULT_COST+BRANCH_COST); 7803 7804 ins_variable_size_depending_on_alignment(true); 7805 7806 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7807 // Worst case is branch + move + stop, no stop without scheduler. 7808 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7809 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7810 ins_pipe(pipe_class_default); 7811 %} 7812 7813 // Cmove using isel. 7814 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7815 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7816 predicate(VM_Version::has_isel()); 7817 ins_cost(DEFAULT_COST); 7818 7819 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7820 size(4); 7821 ins_encode %{ 7822 // This is a Power7 instruction for which no machine description 7823 // exists. Anyways, the scheduler should be off on Power7. 7824 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7825 int cc = $cmp$$cmpcode; 7826 __ isel($dst$$Register, $crx$$CondRegister, 7827 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7828 %} 7829 ins_pipe(pipe_class_default); 7830 %} 7831 7832 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7833 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7834 predicate(!VM_Version::has_isel()); 7835 ins_cost(DEFAULT_COST+BRANCH_COST); 7836 7837 ins_variable_size_depending_on_alignment(true); 7838 7839 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7840 // Worst case is branch + move + stop, no stop without scheduler. 7841 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7842 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7843 ins_pipe(pipe_class_default); 7844 %} 7845 7846 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7847 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7848 ins_cost(DEFAULT_COST+BRANCH_COST); 7849 7850 ins_variable_size_depending_on_alignment(true); 7851 7852 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7853 // Worst case is branch + move + stop, no stop without scheduler. 7854 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7855 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7856 ins_pipe(pipe_class_default); 7857 %} 7858 7859 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7860 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7861 ins_cost(DEFAULT_COST+BRANCH_COST); 7862 7863 ins_variable_size_depending_on_alignment(true); 7864 7865 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7866 // Worst case is branch + move + stop, no stop without scheduler. 7867 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7868 ins_encode %{ 7869 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7870 Label done; 7871 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7872 // Branch if not (cmp crx). 7873 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7874 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7875 // TODO PPC port __ endgroup_if_needed(_size == 12); 7876 __ bind(done); 7877 %} 7878 ins_pipe(pipe_class_default); 7879 %} 7880 7881 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7882 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7883 ins_cost(DEFAULT_COST+BRANCH_COST); 7884 7885 ins_variable_size_depending_on_alignment(true); 7886 7887 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7888 // Worst case is branch + move + stop, no stop without scheduler. 7889 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7890 ins_encode %{ 7891 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7892 Label done; 7893 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7894 // Branch if not (cmp crx). 7895 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7896 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7897 // TODO PPC port __ endgroup_if_needed(_size == 12); 7898 __ bind(done); 7899 %} 7900 ins_pipe(pipe_class_default); 7901 %} 7902 7903 //----------Conditional_store-------------------------------------------------- 7904 // Conditional-store of the updated heap-top. 7905 // Used during allocation of the shared heap. 7906 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7907 7908 // As compareAndSwapL, but return flag register instead of boolean value in 7909 // int register. 7910 // Used by sun/misc/AtomicLongCSImpl.java. 7911 // Mem_ptr must be a memory operand, else this node does not get 7912 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7913 // can be rematerialized which leads to errors. 7914 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7915 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7916 effect(TEMP cr0); 7917 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7918 ins_encode %{ 7919 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7920 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7921 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7922 noreg, NULL, true); 7923 %} 7924 ins_pipe(pipe_class_default); 7925 %} 7926 7927 // As compareAndSwapP, but return flag register instead of boolean value in 7928 // int register. 7929 // This instruction is matched if UseTLAB is off. 7930 // Mem_ptr must be a memory operand, else this node does not get 7931 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7932 // can be rematerialized which leads to errors. 7933 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7934 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7935 ins_cost(2*MEMORY_REF_COST); 7936 7937 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7938 ins_encode %{ 7939 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7940 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7941 %} 7942 ins_pipe(pipe_class_memory); 7943 %} 7944 7945 // Implement LoadPLocked. Must be ordered against changes of the memory location 7946 // by storePConditional. 7947 // Don't know whether this is ever used. 7948 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7949 match(Set dst (LoadPLocked mem)); 7950 ins_cost(2*MEMORY_REF_COST); 7951 7952 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7953 size(4); 7954 ins_encode %{ 7955 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7956 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7957 %} 7958 ins_pipe(pipe_class_memory); 7959 %} 7960 7961 //----------Compare-And-Swap--------------------------------------------------- 7962 7963 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7964 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7965 // matched. 7966 7967 // Strong versions: 7968 7969 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7970 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7971 predicate(VM_Version::has_lqarx()); 7972 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7973 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7974 ins_encode %{ 7975 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7976 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7977 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7978 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7979 $res$$Register, true); 7980 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7981 __ isync(); 7982 } else { 7983 __ sync(); 7984 } 7985 %} 7986 ins_pipe(pipe_class_default); 7987 %} 7988 7989 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7990 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7991 predicate(!VM_Version::has_lqarx()); 7992 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7993 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7994 ins_encode %{ 7995 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7996 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7997 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7998 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7999 $res$$Register, true); 8000 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8001 __ isync(); 8002 } else { 8003 __ sync(); 8004 } 8005 %} 8006 ins_pipe(pipe_class_default); 8007 %} 8008 8009 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8010 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 8011 predicate(VM_Version::has_lqarx()); 8012 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8013 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8014 ins_encode %{ 8015 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8016 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8017 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8018 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8019 $res$$Register, true); 8020 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8021 __ isync(); 8022 } else { 8023 __ sync(); 8024 } 8025 %} 8026 ins_pipe(pipe_class_default); 8027 %} 8028 8029 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8030 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 8031 predicate(!VM_Version::has_lqarx()); 8032 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8033 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8034 ins_encode %{ 8035 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8036 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8037 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8038 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8039 $res$$Register, true); 8040 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8041 __ isync(); 8042 } else { 8043 __ sync(); 8044 } 8045 %} 8046 ins_pipe(pipe_class_default); 8047 %} 8048 8049 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8050 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 8051 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8052 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8053 ins_encode %{ 8054 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8055 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8056 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8057 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8058 $res$$Register, true); 8059 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8060 __ isync(); 8061 } else { 8062 __ sync(); 8063 } 8064 %} 8065 ins_pipe(pipe_class_default); 8066 %} 8067 8068 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8069 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 8070 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8071 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8072 ins_encode %{ 8073 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8074 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8075 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8076 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8077 $res$$Register, true); 8078 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8079 __ isync(); 8080 } else { 8081 __ sync(); 8082 } 8083 %} 8084 ins_pipe(pipe_class_default); 8085 %} 8086 8087 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8088 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 8089 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8090 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8091 ins_encode %{ 8092 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8093 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8094 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8095 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8096 $res$$Register, NULL, true); 8097 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8098 __ isync(); 8099 } else { 8100 __ sync(); 8101 } 8102 %} 8103 ins_pipe(pipe_class_default); 8104 %} 8105 8106 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8107 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 8108 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8109 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8110 ins_encode %{ 8111 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8112 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8113 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8114 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8115 $res$$Register, NULL, true); 8116 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8117 __ isync(); 8118 } else { 8119 __ sync(); 8120 } 8121 %} 8122 ins_pipe(pipe_class_default); 8123 %} 8124 8125 // Weak versions: 8126 8127 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8128 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8129 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8130 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8131 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8132 ins_encode %{ 8133 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8134 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8135 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8136 MacroAssembler::MemBarNone, 8137 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8138 %} 8139 ins_pipe(pipe_class_default); 8140 %} 8141 8142 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8143 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8144 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8145 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8146 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8147 ins_encode %{ 8148 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8149 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8150 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8151 MacroAssembler::MemBarNone, 8152 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8153 %} 8154 ins_pipe(pipe_class_default); 8155 %} 8156 8157 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8158 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8159 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8160 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8161 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8162 ins_encode %{ 8163 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8164 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8165 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8166 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8167 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8168 %} 8169 ins_pipe(pipe_class_default); 8170 %} 8171 8172 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8173 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8174 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8175 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8176 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8177 ins_encode %{ 8178 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8179 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8180 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8181 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8182 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8183 %} 8184 ins_pipe(pipe_class_default); 8185 %} 8186 8187 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8188 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8189 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8190 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8191 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8192 ins_encode %{ 8193 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8194 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8195 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8196 MacroAssembler::MemBarNone, 8197 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8198 %} 8199 ins_pipe(pipe_class_default); 8200 %} 8201 8202 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8203 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8204 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8205 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8206 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8207 ins_encode %{ 8208 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8209 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8210 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8211 MacroAssembler::MemBarNone, 8212 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8213 %} 8214 ins_pipe(pipe_class_default); 8215 %} 8216 8217 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8218 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8219 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8220 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8221 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8222 ins_encode %{ 8223 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8224 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8225 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8226 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8227 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8228 %} 8229 ins_pipe(pipe_class_default); 8230 %} 8231 8232 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8233 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8234 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8235 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8236 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8237 ins_encode %{ 8238 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8239 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8240 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8241 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8242 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8243 %} 8244 ins_pipe(pipe_class_default); 8245 %} 8246 8247 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8248 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8249 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8250 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8251 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8252 ins_encode %{ 8253 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8254 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8255 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8256 MacroAssembler::MemBarNone, 8257 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8258 %} 8259 ins_pipe(pipe_class_default); 8260 %} 8261 8262 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8263 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8264 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8265 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8266 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8267 ins_encode %{ 8268 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8269 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8270 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8271 // value is never passed to caller. 8272 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8273 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8274 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8275 %} 8276 ins_pipe(pipe_class_default); 8277 %} 8278 8279 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8280 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8281 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8282 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8283 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8284 ins_encode %{ 8285 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8286 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8287 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8288 MacroAssembler::MemBarNone, 8289 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8290 %} 8291 ins_pipe(pipe_class_default); 8292 %} 8293 8294 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8295 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8296 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8297 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8298 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8299 ins_encode %{ 8300 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8301 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8302 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8303 // value is never passed to caller. 8304 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8305 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8306 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8307 %} 8308 ins_pipe(pipe_class_default); 8309 %} 8310 8311 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8312 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8313 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8314 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8315 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8316 ins_encode %{ 8317 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8318 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8319 // value is never passed to caller. 8320 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8321 MacroAssembler::MemBarNone, 8322 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8323 %} 8324 ins_pipe(pipe_class_default); 8325 %} 8326 8327 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8328 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8329 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8330 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8331 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 8332 ins_encode %{ 8333 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8334 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8335 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8336 // value is never passed to caller. 8337 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8338 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8339 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8340 %} 8341 ins_pipe(pipe_class_default); 8342 %} 8343 8344 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8345 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8346 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8347 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8348 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8349 ins_encode %{ 8350 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8351 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8352 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8353 MacroAssembler::MemBarNone, 8354 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8355 %} 8356 ins_pipe(pipe_class_default); 8357 %} 8358 8359 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8360 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8361 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8362 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8363 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8364 ins_encode %{ 8365 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8366 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8367 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8368 // value is never passed to caller. 8369 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8370 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8371 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8372 %} 8373 ins_pipe(pipe_class_default); 8374 %} 8375 8376 // CompareAndExchange 8377 8378 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8379 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8380 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8381 effect(TEMP_DEF res, TEMP cr0); 8382 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8383 ins_encode %{ 8384 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8385 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8386 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8387 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8388 noreg, true); 8389 %} 8390 ins_pipe(pipe_class_default); 8391 %} 8392 8393 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8394 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8395 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8396 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8397 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8398 ins_encode %{ 8399 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8400 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8401 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8402 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8403 noreg, true); 8404 %} 8405 ins_pipe(pipe_class_default); 8406 %} 8407 8408 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8409 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8410 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8411 effect(TEMP_DEF res, TEMP cr0); 8412 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8413 ins_encode %{ 8414 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8415 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8416 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8417 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8418 noreg, true); 8419 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8420 __ isync(); 8421 } else { 8422 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8423 __ sync(); 8424 } 8425 %} 8426 ins_pipe(pipe_class_default); 8427 %} 8428 8429 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8430 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8431 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8432 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8433 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8434 ins_encode %{ 8435 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8436 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8437 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8438 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8439 noreg, true); 8440 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8441 __ isync(); 8442 } else { 8443 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8444 __ sync(); 8445 } 8446 %} 8447 ins_pipe(pipe_class_default); 8448 %} 8449 8450 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8451 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8452 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8453 effect(TEMP_DEF res, TEMP cr0); 8454 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8455 ins_encode %{ 8456 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8457 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8458 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8459 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8460 noreg, true); 8461 %} 8462 ins_pipe(pipe_class_default); 8463 %} 8464 8465 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8466 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8467 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8468 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8469 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8470 ins_encode %{ 8471 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8472 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8473 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8474 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8475 noreg, true); 8476 %} 8477 ins_pipe(pipe_class_default); 8478 %} 8479 8480 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8481 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8482 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8483 effect(TEMP_DEF res, TEMP cr0); 8484 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8485 ins_encode %{ 8486 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8487 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8488 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8489 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8490 noreg, true); 8491 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8492 __ isync(); 8493 } else { 8494 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8495 __ sync(); 8496 } 8497 %} 8498 ins_pipe(pipe_class_default); 8499 %} 8500 8501 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8502 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8503 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8504 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8505 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8506 ins_encode %{ 8507 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8508 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8509 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8510 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8511 noreg, true); 8512 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8513 __ isync(); 8514 } else { 8515 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8516 __ sync(); 8517 } 8518 %} 8519 ins_pipe(pipe_class_default); 8520 %} 8521 8522 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8523 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8524 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8525 effect(TEMP_DEF res, TEMP cr0); 8526 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8527 ins_encode %{ 8528 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8529 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8530 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8531 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8532 noreg, true); 8533 %} 8534 ins_pipe(pipe_class_default); 8535 %} 8536 8537 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8538 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8539 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8540 effect(TEMP_DEF res, TEMP cr0); 8541 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8542 ins_encode %{ 8543 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8544 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8545 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8546 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8547 noreg, true); 8548 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8549 __ isync(); 8550 } else { 8551 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8552 __ sync(); 8553 } 8554 %} 8555 ins_pipe(pipe_class_default); 8556 %} 8557 8558 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8559 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8560 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8561 effect(TEMP_DEF res, TEMP cr0); 8562 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8563 ins_encode %{ 8564 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8565 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8566 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8567 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8568 noreg, true); 8569 %} 8570 ins_pipe(pipe_class_default); 8571 %} 8572 8573 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8574 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8575 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8576 effect(TEMP_DEF res, TEMP cr0); 8577 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8578 ins_encode %{ 8579 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8580 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8581 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8582 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8583 noreg, true); 8584 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8585 __ isync(); 8586 } else { 8587 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8588 __ sync(); 8589 } 8590 %} 8591 ins_pipe(pipe_class_default); 8592 %} 8593 8594 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8595 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8596 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8597 effect(TEMP_DEF res, TEMP cr0); 8598 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8599 ins_encode %{ 8600 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8601 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8602 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8603 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8604 noreg, NULL, true); 8605 %} 8606 ins_pipe(pipe_class_default); 8607 %} 8608 8609 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8610 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8611 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8612 effect(TEMP_DEF res, TEMP cr0); 8613 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8614 ins_encode %{ 8615 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8616 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8617 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8618 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8619 noreg, NULL, true); 8620 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8621 __ isync(); 8622 } else { 8623 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8624 __ sync(); 8625 } 8626 %} 8627 ins_pipe(pipe_class_default); 8628 %} 8629 8630 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8631 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8632 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8633 effect(TEMP_DEF res, TEMP cr0); 8634 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8635 ins_encode %{ 8636 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8637 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8638 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8639 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8640 noreg, NULL, true); 8641 %} 8642 ins_pipe(pipe_class_default); 8643 %} 8644 8645 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8646 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8647 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8648 effect(TEMP_DEF res, TEMP cr0); 8649 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8650 ins_encode %{ 8651 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8652 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8653 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8654 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8655 noreg, NULL, true); 8656 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8657 __ isync(); 8658 } else { 8659 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8660 __ sync(); 8661 } 8662 %} 8663 ins_pipe(pipe_class_default); 8664 %} 8665 8666 // Special RMW 8667 8668 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8669 match(Set res (GetAndAddB mem_ptr src)); 8670 predicate(VM_Version::has_lqarx()); 8671 effect(TEMP_DEF res, TEMP cr0); 8672 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8673 ins_encode %{ 8674 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8675 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8676 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8677 __ isync(); 8678 } else { 8679 __ sync(); 8680 } 8681 %} 8682 ins_pipe(pipe_class_default); 8683 %} 8684 8685 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8686 match(Set res (GetAndAddB mem_ptr src)); 8687 predicate(!VM_Version::has_lqarx()); 8688 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8689 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8690 ins_encode %{ 8691 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8692 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8693 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8694 __ isync(); 8695 } else { 8696 __ sync(); 8697 } 8698 %} 8699 ins_pipe(pipe_class_default); 8700 %} 8701 8702 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8703 match(Set res (GetAndAddS mem_ptr src)); 8704 predicate(VM_Version::has_lqarx()); 8705 effect(TEMP_DEF res, TEMP cr0); 8706 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8707 ins_encode %{ 8708 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8709 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8710 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8711 __ isync(); 8712 } else { 8713 __ sync(); 8714 } 8715 %} 8716 ins_pipe(pipe_class_default); 8717 %} 8718 8719 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8720 match(Set res (GetAndAddS mem_ptr src)); 8721 predicate(!VM_Version::has_lqarx()); 8722 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8723 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8724 ins_encode %{ 8725 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8726 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8727 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8728 __ isync(); 8729 } else { 8730 __ sync(); 8731 } 8732 %} 8733 ins_pipe(pipe_class_default); 8734 %} 8735 8736 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8737 match(Set res (GetAndAddI mem_ptr src)); 8738 effect(TEMP_DEF res, TEMP cr0); 8739 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8740 ins_encode %{ 8741 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8742 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8743 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8744 __ isync(); 8745 } else { 8746 __ sync(); 8747 } 8748 %} 8749 ins_pipe(pipe_class_default); 8750 %} 8751 8752 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8753 match(Set res (GetAndAddL mem_ptr src)); 8754 effect(TEMP_DEF res, TEMP cr0); 8755 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8756 ins_encode %{ 8757 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8758 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8759 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8760 __ isync(); 8761 } else { 8762 __ sync(); 8763 } 8764 %} 8765 ins_pipe(pipe_class_default); 8766 %} 8767 8768 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8769 match(Set res (GetAndSetB mem_ptr src)); 8770 predicate(VM_Version::has_lqarx()); 8771 effect(TEMP_DEF res, TEMP cr0); 8772 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8773 ins_encode %{ 8774 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8775 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8776 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8777 __ isync(); 8778 } else { 8779 __ sync(); 8780 } 8781 %} 8782 ins_pipe(pipe_class_default); 8783 %} 8784 8785 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8786 match(Set res (GetAndSetB mem_ptr src)); 8787 predicate(!VM_Version::has_lqarx()); 8788 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8789 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8790 ins_encode %{ 8791 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8792 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8793 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8794 __ isync(); 8795 } else { 8796 __ sync(); 8797 } 8798 %} 8799 ins_pipe(pipe_class_default); 8800 %} 8801 8802 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8803 match(Set res (GetAndSetS mem_ptr src)); 8804 predicate(VM_Version::has_lqarx()); 8805 effect(TEMP_DEF res, TEMP cr0); 8806 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8807 ins_encode %{ 8808 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8809 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8810 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8811 __ isync(); 8812 } else { 8813 __ sync(); 8814 } 8815 %} 8816 ins_pipe(pipe_class_default); 8817 %} 8818 8819 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8820 match(Set res (GetAndSetS mem_ptr src)); 8821 predicate(!VM_Version::has_lqarx()); 8822 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8823 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8824 ins_encode %{ 8825 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8826 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8827 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8828 __ isync(); 8829 } else { 8830 __ sync(); 8831 } 8832 %} 8833 ins_pipe(pipe_class_default); 8834 %} 8835 8836 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8837 match(Set res (GetAndSetI mem_ptr src)); 8838 effect(TEMP_DEF res, TEMP cr0); 8839 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8840 ins_encode %{ 8841 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8842 MacroAssembler::cmpxchgx_hint_atomic_update()); 8843 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8844 __ isync(); 8845 } else { 8846 __ sync(); 8847 } 8848 %} 8849 ins_pipe(pipe_class_default); 8850 %} 8851 8852 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8853 match(Set res (GetAndSetL mem_ptr src)); 8854 effect(TEMP_DEF res, TEMP cr0); 8855 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8856 ins_encode %{ 8857 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8858 MacroAssembler::cmpxchgx_hint_atomic_update()); 8859 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8860 __ isync(); 8861 } else { 8862 __ sync(); 8863 } 8864 %} 8865 ins_pipe(pipe_class_default); 8866 %} 8867 8868 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8869 match(Set res (GetAndSetP mem_ptr src)); 8870 effect(TEMP_DEF res, TEMP cr0); 8871 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8872 ins_encode %{ 8873 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8874 MacroAssembler::cmpxchgx_hint_atomic_update()); 8875 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8876 __ isync(); 8877 } else { 8878 __ sync(); 8879 } 8880 %} 8881 ins_pipe(pipe_class_default); 8882 %} 8883 8884 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8885 match(Set res (GetAndSetN mem_ptr src)); 8886 effect(TEMP_DEF res, TEMP cr0); 8887 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8888 ins_encode %{ 8889 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8890 MacroAssembler::cmpxchgx_hint_atomic_update()); 8891 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8892 __ isync(); 8893 } else { 8894 __ sync(); 8895 } 8896 %} 8897 ins_pipe(pipe_class_default); 8898 %} 8899 8900 //----------Arithmetic Instructions-------------------------------------------- 8901 // Addition Instructions 8902 8903 // Register Addition 8904 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8905 match(Set dst (AddI src1 src2)); 8906 format %{ "ADD $dst, $src1, $src2" %} 8907 size(4); 8908 ins_encode %{ 8909 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8910 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8911 %} 8912 ins_pipe(pipe_class_default); 8913 %} 8914 8915 // Expand does not work with above instruct. (??) 8916 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8917 // no match-rule 8918 effect(DEF dst, USE src1, USE src2); 8919 format %{ "ADD $dst, $src1, $src2" %} 8920 size(4); 8921 ins_encode %{ 8922 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8923 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8924 %} 8925 ins_pipe(pipe_class_default); 8926 %} 8927 8928 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8929 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8930 ins_cost(DEFAULT_COST*3); 8931 8932 expand %{ 8933 // FIXME: we should do this in the ideal world. 8934 iRegIdst tmp1; 8935 iRegIdst tmp2; 8936 addI_reg_reg(tmp1, src1, src2); 8937 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8938 addI_reg_reg(dst, tmp1, tmp2); 8939 %} 8940 %} 8941 8942 // Immediate Addition 8943 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8944 match(Set dst (AddI src1 src2)); 8945 format %{ "ADDI $dst, $src1, $src2" %} 8946 size(4); 8947 ins_encode %{ 8948 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8949 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8950 %} 8951 ins_pipe(pipe_class_default); 8952 %} 8953 8954 // Immediate Addition with 16-bit shifted operand 8955 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8956 match(Set dst (AddI src1 src2)); 8957 format %{ "ADDIS $dst, $src1, $src2" %} 8958 size(4); 8959 ins_encode %{ 8960 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8961 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8962 %} 8963 ins_pipe(pipe_class_default); 8964 %} 8965 8966 // Long Addition 8967 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8968 match(Set dst (AddL src1 src2)); 8969 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8970 size(4); 8971 ins_encode %{ 8972 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8973 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8974 %} 8975 ins_pipe(pipe_class_default); 8976 %} 8977 8978 // Expand does not work with above instruct. (??) 8979 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8980 // no match-rule 8981 effect(DEF dst, USE src1, USE src2); 8982 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8983 size(4); 8984 ins_encode %{ 8985 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8986 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8987 %} 8988 ins_pipe(pipe_class_default); 8989 %} 8990 8991 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8992 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8993 ins_cost(DEFAULT_COST*3); 8994 8995 expand %{ 8996 // FIXME: we should do this in the ideal world. 8997 iRegLdst tmp1; 8998 iRegLdst tmp2; 8999 addL_reg_reg(tmp1, src1, src2); 9000 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 9001 addL_reg_reg(dst, tmp1, tmp2); 9002 %} 9003 %} 9004 9005 // AddL + ConvL2I. 9006 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9007 match(Set dst (ConvL2I (AddL src1 src2))); 9008 9009 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 9010 size(4); 9011 ins_encode %{ 9012 // TODO: PPC port $archOpcode(ppc64Opcode_add); 9013 __ add($dst$$Register, $src1$$Register, $src2$$Register); 9014 %} 9015 ins_pipe(pipe_class_default); 9016 %} 9017 9018 // No constant pool entries required. 9019 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9020 match(Set dst (AddL src1 src2)); 9021 9022 format %{ "ADDI $dst, $src1, $src2" %} 9023 size(4); 9024 ins_encode %{ 9025 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 9026 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 9027 %} 9028 ins_pipe(pipe_class_default); 9029 %} 9030 9031 // Long Immediate Addition with 16-bit shifted operand. 9032 // No constant pool entries required. 9033 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 9034 match(Set dst (AddL src1 src2)); 9035 9036 format %{ "ADDIS $dst, $src1, $src2" %} 9037 size(4); 9038 ins_encode %{ 9039 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 9040 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 9041 %} 9042 ins_pipe(pipe_class_default); 9043 %} 9044 9045 // Pointer Register Addition 9046 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 9047 match(Set dst (AddP src1 src2)); 9048 format %{ "ADD $dst, $src1, $src2" %} 9049 size(4); 9050 ins_encode %{ 9051 // TODO: PPC port $archOpcode(ppc64Opcode_add); 9052 __ add($dst$$Register, $src1$$Register, $src2$$Register); 9053 %} 9054 ins_pipe(pipe_class_default); 9055 %} 9056 9057 // Pointer Immediate Addition 9058 // No constant pool entries required. 9059 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 9060 match(Set dst (AddP src1 src2)); 9061 9062 format %{ "ADDI $dst, $src1, $src2" %} 9063 size(4); 9064 ins_encode %{ 9065 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 9066 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 9067 %} 9068 ins_pipe(pipe_class_default); 9069 %} 9070 9071 // Pointer Immediate Addition with 16-bit shifted operand. 9072 // No constant pool entries required. 9073 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 9074 match(Set dst (AddP src1 src2)); 9075 9076 format %{ "ADDIS $dst, $src1, $src2" %} 9077 size(4); 9078 ins_encode %{ 9079 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 9080 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 9081 %} 9082 ins_pipe(pipe_class_default); 9083 %} 9084 9085 //--------------------- 9086 // Subtraction Instructions 9087 9088 // Register Subtraction 9089 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9090 match(Set dst (SubI src1 src2)); 9091 format %{ "SUBF $dst, $src2, $src1" %} 9092 size(4); 9093 ins_encode %{ 9094 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9095 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9096 %} 9097 ins_pipe(pipe_class_default); 9098 %} 9099 9100 // Immediate Subtraction 9101 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 9102 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 9103 9104 // SubI from constant (using subfic). 9105 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 9106 match(Set dst (SubI src1 src2)); 9107 format %{ "SUBI $dst, $src1, $src2" %} 9108 9109 size(4); 9110 ins_encode %{ 9111 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 9112 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 9113 %} 9114 ins_pipe(pipe_class_default); 9115 %} 9116 9117 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 9118 // positive integers and 0xF...F for negative ones. 9119 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 9120 // no match-rule, false predicate 9121 effect(DEF dst, USE src); 9122 predicate(false); 9123 9124 format %{ "SRAWI $dst, $src, #31" %} 9125 size(4); 9126 ins_encode %{ 9127 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9128 __ srawi($dst$$Register, $src$$Register, 0x1f); 9129 %} 9130 ins_pipe(pipe_class_default); 9131 %} 9132 9133 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 9134 match(Set dst (AbsI src)); 9135 ins_cost(DEFAULT_COST*3); 9136 9137 expand %{ 9138 iRegIdst tmp1; 9139 iRegIdst tmp2; 9140 signmask32I_regI(tmp1, src); 9141 xorI_reg_reg(tmp2, tmp1, src); 9142 subI_reg_reg(dst, tmp2, tmp1); 9143 %} 9144 %} 9145 9146 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9147 match(Set dst (SubI zero src2)); 9148 format %{ "NEG $dst, $src2" %} 9149 size(4); 9150 ins_encode %{ 9151 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9152 __ neg($dst$$Register, $src2$$Register); 9153 %} 9154 ins_pipe(pipe_class_default); 9155 %} 9156 9157 // Long subtraction 9158 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9159 match(Set dst (SubL src1 src2)); 9160 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9161 size(4); 9162 ins_encode %{ 9163 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9164 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9165 %} 9166 ins_pipe(pipe_class_default); 9167 %} 9168 9169 // SubL + convL2I. 9170 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9171 match(Set dst (ConvL2I (SubL src1 src2))); 9172 9173 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9174 size(4); 9175 ins_encode %{ 9176 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9177 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9178 %} 9179 ins_pipe(pipe_class_default); 9180 %} 9181 9182 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9183 // positive longs and 0xF...F for negative ones. 9184 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9185 // no match-rule, false predicate 9186 effect(DEF dst, USE src); 9187 predicate(false); 9188 9189 format %{ "SRADI $dst, $src, #63" %} 9190 size(4); 9191 ins_encode %{ 9192 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9193 __ sradi($dst$$Register, $src$$Register, 0x3f); 9194 %} 9195 ins_pipe(pipe_class_default); 9196 %} 9197 9198 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9199 // positive longs and 0xF...F for negative ones. 9200 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9201 // no match-rule, false predicate 9202 effect(DEF dst, USE src); 9203 predicate(false); 9204 9205 format %{ "SRADI $dst, $src, #63" %} 9206 size(4); 9207 ins_encode %{ 9208 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9209 __ sradi($dst$$Register, $src$$Register, 0x3f); 9210 %} 9211 ins_pipe(pipe_class_default); 9212 %} 9213 9214 instruct absL_reg_Ex(iRegLdst dst, iRegLsrc src) %{ 9215 match(Set dst (AbsL src)); 9216 ins_cost(DEFAULT_COST*3); 9217 9218 expand %{ 9219 iRegLdst tmp1; 9220 iRegLdst tmp2; 9221 signmask64L_regL(tmp1, src); 9222 xorL_reg_reg(tmp2, tmp1, src); 9223 subL_reg_reg(dst, tmp2, tmp1); 9224 %} 9225 %} 9226 9227 // Long negation 9228 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9229 match(Set dst (SubL zero src2)); 9230 format %{ "NEG $dst, $src2 \t// long" %} 9231 size(4); 9232 ins_encode %{ 9233 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9234 __ neg($dst$$Register, $src2$$Register); 9235 %} 9236 ins_pipe(pipe_class_default); 9237 %} 9238 9239 // NegL + ConvL2I. 9240 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9241 match(Set dst (ConvL2I (SubL zero src2))); 9242 9243 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9244 size(4); 9245 ins_encode %{ 9246 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9247 __ neg($dst$$Register, $src2$$Register); 9248 %} 9249 ins_pipe(pipe_class_default); 9250 %} 9251 9252 // Multiplication Instructions 9253 // Integer Multiplication 9254 9255 // Register Multiplication 9256 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9257 match(Set dst (MulI src1 src2)); 9258 ins_cost(DEFAULT_COST); 9259 9260 format %{ "MULLW $dst, $src1, $src2" %} 9261 size(4); 9262 ins_encode %{ 9263 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9264 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9265 %} 9266 ins_pipe(pipe_class_default); 9267 %} 9268 9269 // Immediate Multiplication 9270 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9271 match(Set dst (MulI src1 src2)); 9272 ins_cost(DEFAULT_COST); 9273 9274 format %{ "MULLI $dst, $src1, $src2" %} 9275 size(4); 9276 ins_encode %{ 9277 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9278 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9279 %} 9280 ins_pipe(pipe_class_default); 9281 %} 9282 9283 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9284 match(Set dst (MulL src1 src2)); 9285 ins_cost(DEFAULT_COST); 9286 9287 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9288 size(4); 9289 ins_encode %{ 9290 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9291 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9292 %} 9293 ins_pipe(pipe_class_default); 9294 %} 9295 9296 // Multiply high for optimized long division by constant. 9297 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9298 match(Set dst (MulHiL src1 src2)); 9299 ins_cost(DEFAULT_COST); 9300 9301 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9302 size(4); 9303 ins_encode %{ 9304 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9305 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9306 %} 9307 ins_pipe(pipe_class_default); 9308 %} 9309 9310 // Immediate Multiplication 9311 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9312 match(Set dst (MulL src1 src2)); 9313 ins_cost(DEFAULT_COST); 9314 9315 format %{ "MULLI $dst, $src1, $src2" %} 9316 size(4); 9317 ins_encode %{ 9318 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9319 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9320 %} 9321 ins_pipe(pipe_class_default); 9322 %} 9323 9324 // Integer Division with Immediate -1: Negate. 9325 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9326 match(Set dst (DivI src1 src2)); 9327 ins_cost(DEFAULT_COST); 9328 9329 format %{ "NEG $dst, $src1 \t// /-1" %} 9330 size(4); 9331 ins_encode %{ 9332 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9333 __ neg($dst$$Register, $src1$$Register); 9334 %} 9335 ins_pipe(pipe_class_default); 9336 %} 9337 9338 // Integer Division with constant, but not -1. 9339 // We should be able to improve this by checking the type of src2. 9340 // It might well be that src2 is known to be positive. 9341 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9342 match(Set dst (DivI src1 src2)); 9343 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9344 ins_cost(2*DEFAULT_COST); 9345 9346 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9347 size(4); 9348 ins_encode %{ 9349 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9350 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9351 %} 9352 ins_pipe(pipe_class_default); 9353 %} 9354 9355 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9356 effect(USE_DEF dst, USE src1, USE crx); 9357 predicate(false); 9358 9359 ins_variable_size_depending_on_alignment(true); 9360 9361 format %{ "CMOVE $dst, neg($src1), $crx" %} 9362 // Worst case is branch + move + stop, no stop without scheduler. 9363 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9364 ins_encode %{ 9365 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9366 Label done; 9367 __ bne($crx$$CondRegister, done); 9368 __ neg($dst$$Register, $src1$$Register); 9369 // TODO PPC port __ endgroup_if_needed(_size == 12); 9370 __ bind(done); 9371 %} 9372 ins_pipe(pipe_class_default); 9373 %} 9374 9375 // Integer Division with Registers not containing constants. 9376 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9377 match(Set dst (DivI src1 src2)); 9378 ins_cost(10*DEFAULT_COST); 9379 9380 expand %{ 9381 immI16 imm %{ (int)-1 %} 9382 flagsReg tmp1; 9383 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9384 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9385 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9386 %} 9387 %} 9388 9389 // Long Division with Immediate -1: Negate. 9390 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9391 match(Set dst (DivL src1 src2)); 9392 ins_cost(DEFAULT_COST); 9393 9394 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9395 size(4); 9396 ins_encode %{ 9397 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9398 __ neg($dst$$Register, $src1$$Register); 9399 %} 9400 ins_pipe(pipe_class_default); 9401 %} 9402 9403 // Long Division with constant, but not -1. 9404 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9405 match(Set dst (DivL src1 src2)); 9406 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9407 ins_cost(2*DEFAULT_COST); 9408 9409 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9410 size(4); 9411 ins_encode %{ 9412 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9413 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9414 %} 9415 ins_pipe(pipe_class_default); 9416 %} 9417 9418 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9419 effect(USE_DEF dst, USE src1, USE crx); 9420 predicate(false); 9421 9422 ins_variable_size_depending_on_alignment(true); 9423 9424 format %{ "CMOVE $dst, neg($src1), $crx" %} 9425 // Worst case is branch + move + stop, no stop without scheduler. 9426 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9427 ins_encode %{ 9428 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9429 Label done; 9430 __ bne($crx$$CondRegister, done); 9431 __ neg($dst$$Register, $src1$$Register); 9432 // TODO PPC port __ endgroup_if_needed(_size == 12); 9433 __ bind(done); 9434 %} 9435 ins_pipe(pipe_class_default); 9436 %} 9437 9438 // Long Division with Registers not containing constants. 9439 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9440 match(Set dst (DivL src1 src2)); 9441 ins_cost(10*DEFAULT_COST); 9442 9443 expand %{ 9444 immL16 imm %{ (int)-1 %} 9445 flagsReg tmp1; 9446 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9447 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9448 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9449 %} 9450 %} 9451 9452 // Integer Remainder with registers. 9453 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9454 match(Set dst (ModI src1 src2)); 9455 ins_cost(10*DEFAULT_COST); 9456 9457 expand %{ 9458 immI16 imm %{ (int)-1 %} 9459 flagsReg tmp1; 9460 iRegIdst tmp2; 9461 iRegIdst tmp3; 9462 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9463 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9464 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9465 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9466 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9467 %} 9468 %} 9469 9470 // Long Remainder with registers 9471 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9472 match(Set dst (ModL src1 src2)); 9473 ins_cost(10*DEFAULT_COST); 9474 9475 expand %{ 9476 immL16 imm %{ (int)-1 %} 9477 flagsReg tmp1; 9478 iRegLdst tmp2; 9479 iRegLdst tmp3; 9480 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9481 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9482 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9483 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9484 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9485 %} 9486 %} 9487 9488 // Integer Shift Instructions 9489 9490 // Register Shift Left 9491 9492 // Clear all but the lowest #mask bits. 9493 // Used to normalize shift amounts in registers. 9494 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9495 // no match-rule, false predicate 9496 effect(DEF dst, USE src, USE mask); 9497 predicate(false); 9498 9499 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9500 size(4); 9501 ins_encode %{ 9502 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9503 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9504 %} 9505 ins_pipe(pipe_class_default); 9506 %} 9507 9508 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9509 // no match-rule, false predicate 9510 effect(DEF dst, USE src1, USE src2); 9511 predicate(false); 9512 9513 format %{ "SLW $dst, $src1, $src2" %} 9514 size(4); 9515 ins_encode %{ 9516 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9517 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9518 %} 9519 ins_pipe(pipe_class_default); 9520 %} 9521 9522 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9523 match(Set dst (LShiftI src1 src2)); 9524 ins_cost(DEFAULT_COST*2); 9525 expand %{ 9526 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9527 iRegIdst tmpI; 9528 maskI_reg_imm(tmpI, src2, mask); 9529 lShiftI_reg_reg(dst, src1, tmpI); 9530 %} 9531 %} 9532 9533 // Register Shift Left Immediate 9534 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9535 match(Set dst (LShiftI src1 src2)); 9536 9537 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9538 size(4); 9539 ins_encode %{ 9540 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9541 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9542 %} 9543 ins_pipe(pipe_class_default); 9544 %} 9545 9546 // AndI with negpow2-constant + LShiftI 9547 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9548 match(Set dst (LShiftI (AndI src1 src2) src3)); 9549 predicate(UseRotateAndMaskInstructionsPPC64); 9550 9551 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9552 size(4); 9553 ins_encode %{ 9554 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9555 long src2 = $src2$$constant; 9556 long src3 = $src3$$constant; 9557 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9558 if (maskbits >= 32) { 9559 __ li($dst$$Register, 0); // addi 9560 } else { 9561 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9562 } 9563 %} 9564 ins_pipe(pipe_class_default); 9565 %} 9566 9567 // RShiftI + AndI with negpow2-constant + LShiftI 9568 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9569 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9570 predicate(UseRotateAndMaskInstructionsPPC64); 9571 9572 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9573 size(4); 9574 ins_encode %{ 9575 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9576 long src2 = $src2$$constant; 9577 long src3 = $src3$$constant; 9578 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9579 if (maskbits >= 32) { 9580 __ li($dst$$Register, 0); // addi 9581 } else { 9582 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9583 } 9584 %} 9585 ins_pipe(pipe_class_default); 9586 %} 9587 9588 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9589 // no match-rule, false predicate 9590 effect(DEF dst, USE src1, USE src2); 9591 predicate(false); 9592 9593 format %{ "SLD $dst, $src1, $src2" %} 9594 size(4); 9595 ins_encode %{ 9596 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9597 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9598 %} 9599 ins_pipe(pipe_class_default); 9600 %} 9601 9602 // Register Shift Left 9603 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9604 match(Set dst (LShiftL src1 src2)); 9605 ins_cost(DEFAULT_COST*2); 9606 expand %{ 9607 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9608 iRegIdst tmpI; 9609 maskI_reg_imm(tmpI, src2, mask); 9610 lShiftL_regL_regI(dst, src1, tmpI); 9611 %} 9612 %} 9613 9614 // Register Shift Left Immediate 9615 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9616 match(Set dst (LShiftL src1 src2)); 9617 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9618 size(4); 9619 ins_encode %{ 9620 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9621 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9622 %} 9623 ins_pipe(pipe_class_default); 9624 %} 9625 9626 // If we shift more than 32 bits, we need not convert I2L. 9627 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9628 match(Set dst (LShiftL (ConvI2L src1) src2)); 9629 ins_cost(DEFAULT_COST); 9630 9631 size(4); 9632 format %{ "SLDI $dst, i2l($src1), $src2" %} 9633 ins_encode %{ 9634 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9635 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9636 %} 9637 ins_pipe(pipe_class_default); 9638 %} 9639 9640 // Shift a postivie int to the left. 9641 // Clrlsldi clears the upper 32 bits and shifts. 9642 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9643 match(Set dst (LShiftL (ConvI2L src1) src2)); 9644 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9645 9646 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9647 size(4); 9648 ins_encode %{ 9649 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9650 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9651 %} 9652 ins_pipe(pipe_class_default); 9653 %} 9654 9655 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9656 // no match-rule, false predicate 9657 effect(DEF dst, USE src1, USE src2); 9658 predicate(false); 9659 9660 format %{ "SRAW $dst, $src1, $src2" %} 9661 size(4); 9662 ins_encode %{ 9663 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9664 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9665 %} 9666 ins_pipe(pipe_class_default); 9667 %} 9668 9669 // Register Arithmetic Shift Right 9670 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9671 match(Set dst (RShiftI src1 src2)); 9672 ins_cost(DEFAULT_COST*2); 9673 expand %{ 9674 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9675 iRegIdst tmpI; 9676 maskI_reg_imm(tmpI, src2, mask); 9677 arShiftI_reg_reg(dst, src1, tmpI); 9678 %} 9679 %} 9680 9681 // Register Arithmetic Shift Right Immediate 9682 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9683 match(Set dst (RShiftI src1 src2)); 9684 9685 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9686 size(4); 9687 ins_encode %{ 9688 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9689 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9690 %} 9691 ins_pipe(pipe_class_default); 9692 %} 9693 9694 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9695 // no match-rule, false predicate 9696 effect(DEF dst, USE src1, USE src2); 9697 predicate(false); 9698 9699 format %{ "SRAD $dst, $src1, $src2" %} 9700 size(4); 9701 ins_encode %{ 9702 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9703 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9704 %} 9705 ins_pipe(pipe_class_default); 9706 %} 9707 9708 // Register Shift Right Arithmetic Long 9709 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9710 match(Set dst (RShiftL src1 src2)); 9711 ins_cost(DEFAULT_COST*2); 9712 9713 expand %{ 9714 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9715 iRegIdst tmpI; 9716 maskI_reg_imm(tmpI, src2, mask); 9717 arShiftL_regL_regI(dst, src1, tmpI); 9718 %} 9719 %} 9720 9721 // Register Shift Right Immediate 9722 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9723 match(Set dst (RShiftL src1 src2)); 9724 9725 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9726 size(4); 9727 ins_encode %{ 9728 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9729 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9730 %} 9731 ins_pipe(pipe_class_default); 9732 %} 9733 9734 // RShiftL + ConvL2I 9735 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9736 match(Set dst (ConvL2I (RShiftL src1 src2))); 9737 9738 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9739 size(4); 9740 ins_encode %{ 9741 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9742 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9743 %} 9744 ins_pipe(pipe_class_default); 9745 %} 9746 9747 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9748 // no match-rule, false predicate 9749 effect(DEF dst, USE src1, USE src2); 9750 predicate(false); 9751 9752 format %{ "SRW $dst, $src1, $src2" %} 9753 size(4); 9754 ins_encode %{ 9755 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9756 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9757 %} 9758 ins_pipe(pipe_class_default); 9759 %} 9760 9761 // Register Shift Right 9762 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9763 match(Set dst (URShiftI src1 src2)); 9764 ins_cost(DEFAULT_COST*2); 9765 9766 expand %{ 9767 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9768 iRegIdst tmpI; 9769 maskI_reg_imm(tmpI, src2, mask); 9770 urShiftI_reg_reg(dst, src1, tmpI); 9771 %} 9772 %} 9773 9774 // Register Shift Right Immediate 9775 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9776 match(Set dst (URShiftI src1 src2)); 9777 9778 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9779 size(4); 9780 ins_encode %{ 9781 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9782 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9783 %} 9784 ins_pipe(pipe_class_default); 9785 %} 9786 9787 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9788 // no match-rule, false predicate 9789 effect(DEF dst, USE src1, USE src2); 9790 predicate(false); 9791 9792 format %{ "SRD $dst, $src1, $src2" %} 9793 size(4); 9794 ins_encode %{ 9795 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9796 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9797 %} 9798 ins_pipe(pipe_class_default); 9799 %} 9800 9801 // Register Shift Right 9802 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9803 match(Set dst (URShiftL src1 src2)); 9804 ins_cost(DEFAULT_COST*2); 9805 9806 expand %{ 9807 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9808 iRegIdst tmpI; 9809 maskI_reg_imm(tmpI, src2, mask); 9810 urShiftL_regL_regI(dst, src1, tmpI); 9811 %} 9812 %} 9813 9814 // Register Shift Right Immediate 9815 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9816 match(Set dst (URShiftL src1 src2)); 9817 9818 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9819 size(4); 9820 ins_encode %{ 9821 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9822 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9823 %} 9824 ins_pipe(pipe_class_default); 9825 %} 9826 9827 // URShiftL + ConvL2I. 9828 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9829 match(Set dst (ConvL2I (URShiftL src1 src2))); 9830 9831 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9832 size(4); 9833 ins_encode %{ 9834 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9835 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9836 %} 9837 ins_pipe(pipe_class_default); 9838 %} 9839 9840 // Register Shift Right Immediate with a CastP2X 9841 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9842 match(Set dst (URShiftL (CastP2X src1) src2)); 9843 9844 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9845 size(4); 9846 ins_encode %{ 9847 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9848 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9849 %} 9850 ins_pipe(pipe_class_default); 9851 %} 9852 9853 // Bitfield Extract: URShiftI + AndI 9854 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9855 match(Set dst (AndI (URShiftI src1 src2) src3)); 9856 9857 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9858 size(4); 9859 ins_encode %{ 9860 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9861 int rshift = ($src2$$constant) & 0x1f; 9862 int length = log2_long(((jlong) $src3$$constant) + 1); 9863 if (rshift + length > 32) { 9864 // if necessary, adjust mask to omit rotated bits. 9865 length = 32 - rshift; 9866 } 9867 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9868 %} 9869 ins_pipe(pipe_class_default); 9870 %} 9871 9872 // Bitfield Extract: URShiftL + AndL 9873 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9874 match(Set dst (AndL (URShiftL src1 src2) src3)); 9875 9876 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9877 size(4); 9878 ins_encode %{ 9879 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9880 int rshift = ($src2$$constant) & 0x3f; 9881 int length = log2_long(((jlong) $src3$$constant) + 1); 9882 if (rshift + length > 64) { 9883 // if necessary, adjust mask to omit rotated bits. 9884 length = 64 - rshift; 9885 } 9886 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9887 %} 9888 ins_pipe(pipe_class_default); 9889 %} 9890 9891 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9892 match(Set dst (ConvL2I (ConvI2L src))); 9893 9894 format %{ "EXTSW $dst, $src \t// int->int" %} 9895 size(4); 9896 ins_encode %{ 9897 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9898 __ extsw($dst$$Register, $src$$Register); 9899 %} 9900 ins_pipe(pipe_class_default); 9901 %} 9902 9903 //----------Rotate Instructions------------------------------------------------ 9904 9905 // Rotate Left by 8-bit immediate 9906 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9907 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9908 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9909 9910 format %{ "ROTLWI $dst, $src, $lshift" %} 9911 size(4); 9912 ins_encode %{ 9913 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9914 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9915 %} 9916 ins_pipe(pipe_class_default); 9917 %} 9918 9919 // Rotate Right by 8-bit immediate 9920 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9921 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9922 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9923 9924 format %{ "ROTRWI $dst, $rshift" %} 9925 size(4); 9926 ins_encode %{ 9927 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9928 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9929 %} 9930 ins_pipe(pipe_class_default); 9931 %} 9932 9933 //----------Floating Point Arithmetic Instructions----------------------------- 9934 9935 // Add float single precision 9936 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9937 match(Set dst (AddF src1 src2)); 9938 9939 format %{ "FADDS $dst, $src1, $src2" %} 9940 size(4); 9941 ins_encode %{ 9942 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9943 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9944 %} 9945 ins_pipe(pipe_class_default); 9946 %} 9947 9948 // Add float double precision 9949 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9950 match(Set dst (AddD src1 src2)); 9951 9952 format %{ "FADD $dst, $src1, $src2" %} 9953 size(4); 9954 ins_encode %{ 9955 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9956 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9957 %} 9958 ins_pipe(pipe_class_default); 9959 %} 9960 9961 // Sub float single precision 9962 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9963 match(Set dst (SubF src1 src2)); 9964 9965 format %{ "FSUBS $dst, $src1, $src2" %} 9966 size(4); 9967 ins_encode %{ 9968 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9969 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9970 %} 9971 ins_pipe(pipe_class_default); 9972 %} 9973 9974 // Sub float double precision 9975 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9976 match(Set dst (SubD src1 src2)); 9977 format %{ "FSUB $dst, $src1, $src2" %} 9978 size(4); 9979 ins_encode %{ 9980 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9981 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9982 %} 9983 ins_pipe(pipe_class_default); 9984 %} 9985 9986 // Mul float single precision 9987 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9988 match(Set dst (MulF src1 src2)); 9989 format %{ "FMULS $dst, $src1, $src2" %} 9990 size(4); 9991 ins_encode %{ 9992 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9993 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9994 %} 9995 ins_pipe(pipe_class_default); 9996 %} 9997 9998 // Mul float double precision 9999 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 10000 match(Set dst (MulD src1 src2)); 10001 format %{ "FMUL $dst, $src1, $src2" %} 10002 size(4); 10003 ins_encode %{ 10004 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 10005 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 10006 %} 10007 ins_pipe(pipe_class_default); 10008 %} 10009 10010 // Div float single precision 10011 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 10012 match(Set dst (DivF src1 src2)); 10013 format %{ "FDIVS $dst, $src1, $src2" %} 10014 size(4); 10015 ins_encode %{ 10016 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 10017 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 10018 %} 10019 ins_pipe(pipe_class_default); 10020 %} 10021 10022 // Div float double precision 10023 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 10024 match(Set dst (DivD src1 src2)); 10025 format %{ "FDIV $dst, $src1, $src2" %} 10026 size(4); 10027 ins_encode %{ 10028 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 10029 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 10030 %} 10031 ins_pipe(pipe_class_default); 10032 %} 10033 10034 // Absolute float single precision 10035 instruct absF_reg(regF dst, regF src) %{ 10036 match(Set dst (AbsF src)); 10037 format %{ "FABS $dst, $src \t// float" %} 10038 size(4); 10039 ins_encode %{ 10040 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 10041 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 10042 %} 10043 ins_pipe(pipe_class_default); 10044 %} 10045 10046 // Absolute float double precision 10047 instruct absD_reg(regD dst, regD src) %{ 10048 match(Set dst (AbsD src)); 10049 format %{ "FABS $dst, $src \t// double" %} 10050 size(4); 10051 ins_encode %{ 10052 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 10053 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 10054 %} 10055 ins_pipe(pipe_class_default); 10056 %} 10057 10058 instruct negF_reg(regF dst, regF src) %{ 10059 match(Set dst (NegF src)); 10060 format %{ "FNEG $dst, $src \t// float" %} 10061 size(4); 10062 ins_encode %{ 10063 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 10064 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 10065 %} 10066 ins_pipe(pipe_class_default); 10067 %} 10068 10069 instruct negD_reg(regD dst, regD src) %{ 10070 match(Set dst (NegD src)); 10071 format %{ "FNEG $dst, $src \t// double" %} 10072 size(4); 10073 ins_encode %{ 10074 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 10075 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 10076 %} 10077 ins_pipe(pipe_class_default); 10078 %} 10079 10080 // AbsF + NegF. 10081 instruct negF_absF_reg(regF dst, regF src) %{ 10082 match(Set dst (NegF (AbsF src))); 10083 format %{ "FNABS $dst, $src \t// float" %} 10084 size(4); 10085 ins_encode %{ 10086 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10087 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10088 %} 10089 ins_pipe(pipe_class_default); 10090 %} 10091 10092 // AbsD + NegD. 10093 instruct negD_absD_reg(regD dst, regD src) %{ 10094 match(Set dst (NegD (AbsD src))); 10095 format %{ "FNABS $dst, $src \t// double" %} 10096 size(4); 10097 ins_encode %{ 10098 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10099 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10100 %} 10101 ins_pipe(pipe_class_default); 10102 %} 10103 10104 // VM_Version::has_fsqrt() decides if this node will be used. 10105 // Sqrt float double precision 10106 instruct sqrtD_reg(regD dst, regD src) %{ 10107 match(Set dst (SqrtD src)); 10108 format %{ "FSQRT $dst, $src" %} 10109 size(4); 10110 ins_encode %{ 10111 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 10112 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 10113 %} 10114 ins_pipe(pipe_class_default); 10115 %} 10116 10117 // Single-precision sqrt. 10118 instruct sqrtF_reg(regF dst, regF src) %{ 10119 match(Set dst (SqrtF src)); 10120 predicate(VM_Version::has_fsqrts()); 10121 ins_cost(DEFAULT_COST); 10122 10123 format %{ "FSQRTS $dst, $src" %} 10124 size(4); 10125 ins_encode %{ 10126 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 10127 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 10128 %} 10129 ins_pipe(pipe_class_default); 10130 %} 10131 10132 instruct roundDouble_nop(regD dst) %{ 10133 match(Set dst (RoundDouble dst)); 10134 ins_cost(0); 10135 10136 format %{ " -- \t// RoundDouble not needed - empty" %} 10137 size(0); 10138 // PPC results are already "rounded" (i.e., normal-format IEEE). 10139 ins_encode( /*empty*/ ); 10140 ins_pipe(pipe_class_default); 10141 %} 10142 10143 instruct roundFloat_nop(regF dst) %{ 10144 match(Set dst (RoundFloat dst)); 10145 ins_cost(0); 10146 10147 format %{ " -- \t// RoundFloat not needed - empty" %} 10148 size(0); 10149 // PPC results are already "rounded" (i.e., normal-format IEEE). 10150 ins_encode( /*empty*/ ); 10151 ins_pipe(pipe_class_default); 10152 %} 10153 10154 10155 // Multiply-Accumulate 10156 // src1 * src2 + src3 10157 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10158 match(Set dst (FmaF src3 (Binary src1 src2))); 10159 10160 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10161 size(4); 10162 ins_encode %{ 10163 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10164 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10165 %} 10166 ins_pipe(pipe_class_default); 10167 %} 10168 10169 // src1 * src2 + src3 10170 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10171 match(Set dst (FmaD src3 (Binary src1 src2))); 10172 10173 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10174 size(4); 10175 ins_encode %{ 10176 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10177 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10178 %} 10179 ins_pipe(pipe_class_default); 10180 %} 10181 10182 // -src1 * src2 + src3 = -(src1*src2-src3) 10183 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10184 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10185 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10186 10187 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10188 size(4); 10189 ins_encode %{ 10190 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10191 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10192 %} 10193 ins_pipe(pipe_class_default); 10194 %} 10195 10196 // -src1 * src2 + src3 = -(src1*src2-src3) 10197 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10198 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10199 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10200 10201 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10202 size(4); 10203 ins_encode %{ 10204 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10205 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10206 %} 10207 ins_pipe(pipe_class_default); 10208 %} 10209 10210 // -src1 * src2 - src3 = -(src1*src2+src3) 10211 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10212 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10213 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10214 10215 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10216 size(4); 10217 ins_encode %{ 10218 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10219 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10220 %} 10221 ins_pipe(pipe_class_default); 10222 %} 10223 10224 // -src1 * src2 - src3 = -(src1*src2+src3) 10225 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10226 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10227 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10228 10229 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10230 size(4); 10231 ins_encode %{ 10232 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10233 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10234 %} 10235 ins_pipe(pipe_class_default); 10236 %} 10237 10238 // src1 * src2 - src3 10239 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10240 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10241 10242 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10243 size(4); 10244 ins_encode %{ 10245 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10246 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10247 %} 10248 ins_pipe(pipe_class_default); 10249 %} 10250 10251 // src1 * src2 - src3 10252 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10253 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10254 10255 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10256 size(4); 10257 ins_encode %{ 10258 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10259 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10260 %} 10261 ins_pipe(pipe_class_default); 10262 %} 10263 10264 10265 //----------Logical Instructions----------------------------------------------- 10266 10267 // And Instructions 10268 10269 // Register And 10270 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10271 match(Set dst (AndI src1 src2)); 10272 format %{ "AND $dst, $src1, $src2" %} 10273 size(4); 10274 ins_encode %{ 10275 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10276 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10277 %} 10278 ins_pipe(pipe_class_default); 10279 %} 10280 10281 // Left shifted Immediate And 10282 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10283 match(Set dst (AndI src1 src2)); 10284 effect(KILL cr0); 10285 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10286 size(4); 10287 ins_encode %{ 10288 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10289 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10290 %} 10291 ins_pipe(pipe_class_default); 10292 %} 10293 10294 // Immediate And 10295 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10296 match(Set dst (AndI src1 src2)); 10297 effect(KILL cr0); 10298 10299 format %{ "ANDI $dst, $src1, $src2" %} 10300 size(4); 10301 ins_encode %{ 10302 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10303 // FIXME: avoid andi_ ? 10304 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10305 %} 10306 ins_pipe(pipe_class_default); 10307 %} 10308 10309 // Immediate And where the immediate is a negative power of 2. 10310 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10311 match(Set dst (AndI src1 src2)); 10312 format %{ "ANDWI $dst, $src1, $src2" %} 10313 size(4); 10314 ins_encode %{ 10315 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10316 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10317 %} 10318 ins_pipe(pipe_class_default); 10319 %} 10320 10321 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10322 match(Set dst (AndI src1 src2)); 10323 format %{ "ANDWI $dst, $src1, $src2" %} 10324 size(4); 10325 ins_encode %{ 10326 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10327 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10328 %} 10329 ins_pipe(pipe_class_default); 10330 %} 10331 10332 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10333 match(Set dst (AndI src1 src2)); 10334 predicate(UseRotateAndMaskInstructionsPPC64); 10335 format %{ "ANDWI $dst, $src1, $src2" %} 10336 size(4); 10337 ins_encode %{ 10338 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10339 __ rlwinm($dst$$Register, $src1$$Register, 0, 10340 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10341 %} 10342 ins_pipe(pipe_class_default); 10343 %} 10344 10345 // Register And Long 10346 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10347 match(Set dst (AndL src1 src2)); 10348 ins_cost(DEFAULT_COST); 10349 10350 format %{ "AND $dst, $src1, $src2 \t// long" %} 10351 size(4); 10352 ins_encode %{ 10353 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10354 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10355 %} 10356 ins_pipe(pipe_class_default); 10357 %} 10358 10359 // Immediate And long 10360 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10361 match(Set dst (AndL src1 src2)); 10362 effect(KILL cr0); 10363 10364 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10365 size(4); 10366 ins_encode %{ 10367 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10368 // FIXME: avoid andi_ ? 10369 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10370 %} 10371 ins_pipe(pipe_class_default); 10372 %} 10373 10374 // Immediate And Long where the immediate is a negative power of 2. 10375 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10376 match(Set dst (AndL src1 src2)); 10377 format %{ "ANDDI $dst, $src1, $src2" %} 10378 size(4); 10379 ins_encode %{ 10380 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10381 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10382 %} 10383 ins_pipe(pipe_class_default); 10384 %} 10385 10386 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10387 match(Set dst (AndL src1 src2)); 10388 format %{ "ANDDI $dst, $src1, $src2" %} 10389 size(4); 10390 ins_encode %{ 10391 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10392 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10393 %} 10394 ins_pipe(pipe_class_default); 10395 %} 10396 10397 // AndL + ConvL2I. 10398 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10399 match(Set dst (ConvL2I (AndL src1 src2))); 10400 ins_cost(DEFAULT_COST); 10401 10402 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10403 size(4); 10404 ins_encode %{ 10405 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10406 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10407 %} 10408 ins_pipe(pipe_class_default); 10409 %} 10410 10411 // Or Instructions 10412 10413 // Register Or 10414 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10415 match(Set dst (OrI src1 src2)); 10416 format %{ "OR $dst, $src1, $src2" %} 10417 size(4); 10418 ins_encode %{ 10419 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10420 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10421 %} 10422 ins_pipe(pipe_class_default); 10423 %} 10424 10425 // Expand does not work with above instruct. (??) 10426 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10427 // no match-rule 10428 effect(DEF dst, USE src1, USE src2); 10429 format %{ "OR $dst, $src1, $src2" %} 10430 size(4); 10431 ins_encode %{ 10432 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10433 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10434 %} 10435 ins_pipe(pipe_class_default); 10436 %} 10437 10438 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10439 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10440 ins_cost(DEFAULT_COST*3); 10441 10442 expand %{ 10443 // FIXME: we should do this in the ideal world. 10444 iRegIdst tmp1; 10445 iRegIdst tmp2; 10446 orI_reg_reg(tmp1, src1, src2); 10447 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10448 orI_reg_reg(dst, tmp1, tmp2); 10449 %} 10450 %} 10451 10452 // Immediate Or 10453 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10454 match(Set dst (OrI src1 src2)); 10455 format %{ "ORI $dst, $src1, $src2" %} 10456 size(4); 10457 ins_encode %{ 10458 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10459 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10460 %} 10461 ins_pipe(pipe_class_default); 10462 %} 10463 10464 // Register Or Long 10465 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10466 match(Set dst (OrL src1 src2)); 10467 ins_cost(DEFAULT_COST); 10468 10469 size(4); 10470 format %{ "OR $dst, $src1, $src2 \t// long" %} 10471 ins_encode %{ 10472 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10473 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10474 %} 10475 ins_pipe(pipe_class_default); 10476 %} 10477 10478 // OrL + ConvL2I. 10479 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10480 match(Set dst (ConvL2I (OrL src1 src2))); 10481 ins_cost(DEFAULT_COST); 10482 10483 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10484 size(4); 10485 ins_encode %{ 10486 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10487 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10488 %} 10489 ins_pipe(pipe_class_default); 10490 %} 10491 10492 // Immediate Or long 10493 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10494 match(Set dst (OrL src1 con)); 10495 ins_cost(DEFAULT_COST); 10496 10497 format %{ "ORI $dst, $src1, $con \t// long" %} 10498 size(4); 10499 ins_encode %{ 10500 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10501 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10502 %} 10503 ins_pipe(pipe_class_default); 10504 %} 10505 10506 // Xor Instructions 10507 10508 // Register Xor 10509 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10510 match(Set dst (XorI src1 src2)); 10511 format %{ "XOR $dst, $src1, $src2" %} 10512 size(4); 10513 ins_encode %{ 10514 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10515 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10516 %} 10517 ins_pipe(pipe_class_default); 10518 %} 10519 10520 // Expand does not work with above instruct. (??) 10521 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10522 // no match-rule 10523 effect(DEF dst, USE src1, USE src2); 10524 format %{ "XOR $dst, $src1, $src2" %} 10525 size(4); 10526 ins_encode %{ 10527 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10528 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10529 %} 10530 ins_pipe(pipe_class_default); 10531 %} 10532 10533 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10534 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10535 ins_cost(DEFAULT_COST*3); 10536 10537 expand %{ 10538 // FIXME: we should do this in the ideal world. 10539 iRegIdst tmp1; 10540 iRegIdst tmp2; 10541 xorI_reg_reg(tmp1, src1, src2); 10542 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10543 xorI_reg_reg(dst, tmp1, tmp2); 10544 %} 10545 %} 10546 10547 // Immediate Xor 10548 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10549 match(Set dst (XorI src1 src2)); 10550 format %{ "XORI $dst, $src1, $src2" %} 10551 size(4); 10552 ins_encode %{ 10553 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10554 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10555 %} 10556 ins_pipe(pipe_class_default); 10557 %} 10558 10559 // Register Xor Long 10560 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10561 match(Set dst (XorL src1 src2)); 10562 ins_cost(DEFAULT_COST); 10563 10564 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10565 size(4); 10566 ins_encode %{ 10567 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10568 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10569 %} 10570 ins_pipe(pipe_class_default); 10571 %} 10572 10573 // XorL + ConvL2I. 10574 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10575 match(Set dst (ConvL2I (XorL src1 src2))); 10576 ins_cost(DEFAULT_COST); 10577 10578 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10579 size(4); 10580 ins_encode %{ 10581 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10582 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10583 %} 10584 ins_pipe(pipe_class_default); 10585 %} 10586 10587 // Immediate Xor Long 10588 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10589 match(Set dst (XorL src1 src2)); 10590 ins_cost(DEFAULT_COST); 10591 10592 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10593 size(4); 10594 ins_encode %{ 10595 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10596 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10597 %} 10598 ins_pipe(pipe_class_default); 10599 %} 10600 10601 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10602 match(Set dst (XorI src1 src2)); 10603 ins_cost(DEFAULT_COST); 10604 10605 format %{ "NOT $dst, $src1 ($src2)" %} 10606 size(4); 10607 ins_encode %{ 10608 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10609 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10610 %} 10611 ins_pipe(pipe_class_default); 10612 %} 10613 10614 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10615 match(Set dst (XorL src1 src2)); 10616 ins_cost(DEFAULT_COST); 10617 10618 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10619 size(4); 10620 ins_encode %{ 10621 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10622 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10623 %} 10624 ins_pipe(pipe_class_default); 10625 %} 10626 10627 // And-complement 10628 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10629 match(Set dst (AndI (XorI src1 src2) src3)); 10630 ins_cost(DEFAULT_COST); 10631 10632 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10633 size(4); 10634 ins_encode( enc_andc(dst, src3, src1) ); 10635 ins_pipe(pipe_class_default); 10636 %} 10637 10638 // And-complement 10639 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10640 // no match-rule, false predicate 10641 effect(DEF dst, USE src1, USE src2); 10642 predicate(false); 10643 10644 format %{ "ANDC $dst, $src1, $src2" %} 10645 size(4); 10646 ins_encode %{ 10647 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10648 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10649 %} 10650 ins_pipe(pipe_class_default); 10651 %} 10652 10653 //----------Moves between int/long and float/double---------------------------- 10654 // 10655 // The following rules move values from int/long registers/stack-locations 10656 // to float/double registers/stack-locations and vice versa, without doing any 10657 // conversions. These rules are used to implement the bit-conversion methods 10658 // of java.lang.Float etc., e.g. 10659 // int floatToIntBits(float value) 10660 // float intBitsToFloat(int bits) 10661 // 10662 // Notes on the implementation on ppc64: 10663 // For Power7 and earlier, the rules are limited to those which move between a 10664 // register and a stack-location, because we always have to go through memory 10665 // when moving between a float register and an integer register. 10666 // This restriction is removed in Power8 with the introduction of the mtfprd 10667 // and mffprd instructions. 10668 10669 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10670 match(Set dst (MoveL2D src)); 10671 predicate(VM_Version::has_mtfprd()); 10672 10673 format %{ "MTFPRD $dst, $src" %} 10674 size(4); 10675 ins_encode %{ 10676 __ mtfprd($dst$$FloatRegister, $src$$Register); 10677 %} 10678 ins_pipe(pipe_class_default); 10679 %} 10680 10681 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10682 // no match-rule, false predicate 10683 effect(DEF dst, USE src); 10684 predicate(false); 10685 10686 format %{ "MTFPRWA $dst, $src" %} 10687 size(4); 10688 ins_encode %{ 10689 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10690 %} 10691 ins_pipe(pipe_class_default); 10692 %} 10693 10694 //---------- Chain stack slots between similar types -------- 10695 10696 // These are needed so that the rules below can match. 10697 10698 // Load integer from stack slot 10699 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10700 match(Set dst src); 10701 ins_cost(MEMORY_REF_COST); 10702 10703 format %{ "LWZ $dst, $src" %} 10704 size(4); 10705 ins_encode( enc_lwz(dst, src) ); 10706 ins_pipe(pipe_class_memory); 10707 %} 10708 10709 // Store integer to stack slot 10710 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10711 match(Set dst src); 10712 ins_cost(MEMORY_REF_COST); 10713 10714 format %{ "STW $src, $dst \t// stk" %} 10715 size(4); 10716 ins_encode( enc_stw(src, dst) ); // rs=rt 10717 ins_pipe(pipe_class_memory); 10718 %} 10719 10720 // Load long from stack slot 10721 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10722 match(Set dst src); 10723 ins_cost(MEMORY_REF_COST); 10724 10725 format %{ "LD $dst, $src \t// long" %} 10726 size(4); 10727 ins_encode( enc_ld(dst, src) ); 10728 ins_pipe(pipe_class_memory); 10729 %} 10730 10731 // Store long to stack slot 10732 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10733 match(Set dst src); 10734 ins_cost(MEMORY_REF_COST); 10735 10736 format %{ "STD $src, $dst \t// long" %} 10737 size(4); 10738 ins_encode( enc_std(src, dst) ); // rs=rt 10739 ins_pipe(pipe_class_memory); 10740 %} 10741 10742 //----------Moves between int and float 10743 10744 // Move float value from float stack-location to integer register. 10745 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10746 match(Set dst (MoveF2I src)); 10747 ins_cost(MEMORY_REF_COST); 10748 10749 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10750 size(4); 10751 ins_encode( enc_lwz(dst, src) ); 10752 ins_pipe(pipe_class_memory); 10753 %} 10754 10755 // Move float value from float register to integer stack-location. 10756 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10757 match(Set dst (MoveF2I src)); 10758 ins_cost(MEMORY_REF_COST); 10759 10760 format %{ "STFS $src, $dst \t// MoveF2I" %} 10761 size(4); 10762 ins_encode( enc_stfs(src, dst) ); 10763 ins_pipe(pipe_class_memory); 10764 %} 10765 10766 // Move integer value from integer stack-location to float register. 10767 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10768 match(Set dst (MoveI2F src)); 10769 ins_cost(MEMORY_REF_COST); 10770 10771 format %{ "LFS $dst, $src \t// MoveI2F" %} 10772 size(4); 10773 ins_encode %{ 10774 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10775 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10776 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10777 %} 10778 ins_pipe(pipe_class_memory); 10779 %} 10780 10781 // Move integer value from integer register to float stack-location. 10782 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10783 match(Set dst (MoveI2F src)); 10784 ins_cost(MEMORY_REF_COST); 10785 10786 format %{ "STW $src, $dst \t// MoveI2F" %} 10787 size(4); 10788 ins_encode( enc_stw(src, dst) ); 10789 ins_pipe(pipe_class_memory); 10790 %} 10791 10792 //----------Moves between long and float 10793 10794 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10795 // no match-rule, false predicate 10796 effect(DEF dst, USE src); 10797 predicate(false); 10798 10799 format %{ "storeD $src, $dst \t// STACK" %} 10800 size(4); 10801 ins_encode( enc_stfd(src, dst) ); 10802 ins_pipe(pipe_class_default); 10803 %} 10804 10805 //----------Moves between long and double 10806 10807 // Move double value from double stack-location to long register. 10808 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10809 match(Set dst (MoveD2L src)); 10810 ins_cost(MEMORY_REF_COST); 10811 size(4); 10812 format %{ "LD $dst, $src \t// MoveD2L" %} 10813 ins_encode( enc_ld(dst, src) ); 10814 ins_pipe(pipe_class_memory); 10815 %} 10816 10817 // Move double value from double register to long stack-location. 10818 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10819 match(Set dst (MoveD2L src)); 10820 effect(DEF dst, USE src); 10821 ins_cost(MEMORY_REF_COST); 10822 10823 format %{ "STFD $src, $dst \t// MoveD2L" %} 10824 size(4); 10825 ins_encode( enc_stfd(src, dst) ); 10826 ins_pipe(pipe_class_memory); 10827 %} 10828 10829 // Move long value from long stack-location to double register. 10830 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10831 match(Set dst (MoveL2D src)); 10832 ins_cost(MEMORY_REF_COST); 10833 10834 format %{ "LFD $dst, $src \t// MoveL2D" %} 10835 size(4); 10836 ins_encode( enc_lfd(dst, src) ); 10837 ins_pipe(pipe_class_memory); 10838 %} 10839 10840 // Move long value from long register to double stack-location. 10841 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10842 match(Set dst (MoveL2D src)); 10843 ins_cost(MEMORY_REF_COST); 10844 10845 format %{ "STD $src, $dst \t// MoveL2D" %} 10846 size(4); 10847 ins_encode( enc_std(src, dst) ); 10848 ins_pipe(pipe_class_memory); 10849 %} 10850 10851 //----------Register Move Instructions----------------------------------------- 10852 10853 // Replicate for Superword 10854 10855 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10856 predicate(false); 10857 effect(DEF dst, USE src); 10858 10859 format %{ "MR $dst, $src \t// replicate " %} 10860 // variable size, 0 or 4. 10861 ins_encode %{ 10862 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10863 __ mr_if_needed($dst$$Register, $src$$Register); 10864 %} 10865 ins_pipe(pipe_class_default); 10866 %} 10867 10868 //----------Cast instructions (Java-level type cast)--------------------------- 10869 10870 // Cast Long to Pointer for unsafe natives. 10871 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10872 match(Set dst (CastX2P src)); 10873 10874 format %{ "MR $dst, $src \t// Long->Ptr" %} 10875 // variable size, 0 or 4. 10876 ins_encode %{ 10877 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10878 __ mr_if_needed($dst$$Register, $src$$Register); 10879 %} 10880 ins_pipe(pipe_class_default); 10881 %} 10882 10883 // Cast Pointer to Long for unsafe natives. 10884 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10885 match(Set dst (CastP2X src)); 10886 10887 format %{ "MR $dst, $src \t// Ptr->Long" %} 10888 // variable size, 0 or 4. 10889 ins_encode %{ 10890 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10891 __ mr_if_needed($dst$$Register, $src$$Register); 10892 %} 10893 ins_pipe(pipe_class_default); 10894 %} 10895 10896 instruct castPP(iRegPdst dst) %{ 10897 match(Set dst (CastPP dst)); 10898 format %{ " -- \t// castPP of $dst" %} 10899 size(0); 10900 ins_encode( /*empty*/ ); 10901 ins_pipe(pipe_class_default); 10902 %} 10903 10904 instruct castII(iRegIdst dst) %{ 10905 match(Set dst (CastII dst)); 10906 format %{ " -- \t// castII of $dst" %} 10907 size(0); 10908 ins_encode( /*empty*/ ); 10909 ins_pipe(pipe_class_default); 10910 %} 10911 10912 instruct checkCastPP(iRegPdst dst) %{ 10913 match(Set dst (CheckCastPP dst)); 10914 format %{ " -- \t// checkcastPP of $dst" %} 10915 size(0); 10916 ins_encode( /*empty*/ ); 10917 ins_pipe(pipe_class_default); 10918 %} 10919 10920 //----------Convert instructions----------------------------------------------- 10921 10922 // Convert to boolean. 10923 10924 // int_to_bool(src) : { 1 if src != 0 10925 // { 0 else 10926 // 10927 // strategy: 10928 // 1) Count leading zeros of 32 bit-value src, 10929 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10930 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10931 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10932 10933 // convI2Bool 10934 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10935 match(Set dst (Conv2B src)); 10936 predicate(UseCountLeadingZerosInstructionsPPC64); 10937 ins_cost(DEFAULT_COST); 10938 10939 expand %{ 10940 immI shiftAmount %{ 0x5 %} 10941 uimmI16 mask %{ 0x1 %} 10942 iRegIdst tmp1; 10943 iRegIdst tmp2; 10944 countLeadingZerosI(tmp1, src); 10945 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10946 xorI_reg_uimm16(dst, tmp2, mask); 10947 %} 10948 %} 10949 10950 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10951 match(Set dst (Conv2B src)); 10952 effect(TEMP crx); 10953 predicate(!UseCountLeadingZerosInstructionsPPC64); 10954 ins_cost(DEFAULT_COST); 10955 10956 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10957 "LI $dst, #0\n\t" 10958 "BEQ $crx, done\n\t" 10959 "LI $dst, #1\n" 10960 "done:" %} 10961 size(16); 10962 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10963 ins_pipe(pipe_class_compare); 10964 %} 10965 10966 // ConvI2B + XorI 10967 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10968 match(Set dst (XorI (Conv2B src) mask)); 10969 predicate(UseCountLeadingZerosInstructionsPPC64); 10970 ins_cost(DEFAULT_COST); 10971 10972 expand %{ 10973 immI shiftAmount %{ 0x5 %} 10974 iRegIdst tmp1; 10975 countLeadingZerosI(tmp1, src); 10976 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10977 %} 10978 %} 10979 10980 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10981 match(Set dst (XorI (Conv2B src) mask)); 10982 effect(TEMP crx); 10983 predicate(!UseCountLeadingZerosInstructionsPPC64); 10984 ins_cost(DEFAULT_COST); 10985 10986 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10987 "LI $dst, #1\n\t" 10988 "BEQ $crx, done\n\t" 10989 "LI $dst, #0\n" 10990 "done:" %} 10991 size(16); 10992 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10993 ins_pipe(pipe_class_compare); 10994 %} 10995 10996 // AndI 0b0..010..0 + ConvI2B 10997 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10998 match(Set dst (Conv2B (AndI src mask))); 10999 predicate(UseRotateAndMaskInstructionsPPC64); 11000 ins_cost(DEFAULT_COST); 11001 11002 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 11003 size(4); 11004 ins_encode %{ 11005 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 11006 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 11007 %} 11008 ins_pipe(pipe_class_default); 11009 %} 11010 11011 // Convert pointer to boolean. 11012 // 11013 // ptr_to_bool(src) : { 1 if src != 0 11014 // { 0 else 11015 // 11016 // strategy: 11017 // 1) Count leading zeros of 64 bit-value src, 11018 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 11019 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 11020 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 11021 11022 // ConvP2B 11023 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 11024 match(Set dst (Conv2B src)); 11025 predicate(UseCountLeadingZerosInstructionsPPC64); 11026 ins_cost(DEFAULT_COST); 11027 11028 expand %{ 11029 immI shiftAmount %{ 0x6 %} 11030 uimmI16 mask %{ 0x1 %} 11031 iRegIdst tmp1; 11032 iRegIdst tmp2; 11033 countLeadingZerosP(tmp1, src); 11034 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 11035 xorI_reg_uimm16(dst, tmp2, mask); 11036 %} 11037 %} 11038 11039 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 11040 match(Set dst (Conv2B src)); 11041 effect(TEMP crx); 11042 predicate(!UseCountLeadingZerosInstructionsPPC64); 11043 ins_cost(DEFAULT_COST); 11044 11045 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 11046 "LI $dst, #0\n\t" 11047 "BEQ $crx, done\n\t" 11048 "LI $dst, #1\n" 11049 "done:" %} 11050 size(16); 11051 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 11052 ins_pipe(pipe_class_compare); 11053 %} 11054 11055 // ConvP2B + XorI 11056 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 11057 match(Set dst (XorI (Conv2B src) mask)); 11058 predicate(UseCountLeadingZerosInstructionsPPC64); 11059 ins_cost(DEFAULT_COST); 11060 11061 expand %{ 11062 immI shiftAmount %{ 0x6 %} 11063 iRegIdst tmp1; 11064 countLeadingZerosP(tmp1, src); 11065 urShiftI_reg_imm(dst, tmp1, shiftAmount); 11066 %} 11067 %} 11068 11069 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 11070 match(Set dst (XorI (Conv2B src) mask)); 11071 effect(TEMP crx); 11072 predicate(!UseCountLeadingZerosInstructionsPPC64); 11073 ins_cost(DEFAULT_COST); 11074 11075 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 11076 "LI $dst, #1\n\t" 11077 "BEQ $crx, done\n\t" 11078 "LI $dst, #0\n" 11079 "done:" %} 11080 size(16); 11081 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 11082 ins_pipe(pipe_class_compare); 11083 %} 11084 11085 // if src1 < src2, return -1 else return 0 11086 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 11087 match(Set dst (CmpLTMask src1 src2)); 11088 ins_cost(DEFAULT_COST*4); 11089 11090 expand %{ 11091 iRegLdst src1s; 11092 iRegLdst src2s; 11093 iRegLdst diff; 11094 convI2L_reg(src1s, src1); // Ensure proper sign extension. 11095 convI2L_reg(src2s, src2); // Ensure proper sign extension. 11096 subL_reg_reg(diff, src1s, src2s); 11097 // Need to consider >=33 bit result, therefore we need signmaskL. 11098 signmask64I_regL(dst, diff); 11099 %} 11100 %} 11101 11102 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 11103 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 11104 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 11105 size(4); 11106 ins_encode %{ 11107 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 11108 __ srawi($dst$$Register, $src1$$Register, 0x1f); 11109 %} 11110 ins_pipe(pipe_class_default); 11111 %} 11112 11113 //----------Arithmetic Conversion Instructions--------------------------------- 11114 11115 // Convert to Byte -- nop 11116 // Convert to Short -- nop 11117 11118 // Convert to Int 11119 11120 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 11121 match(Set dst (RShiftI (LShiftI src amount) amount)); 11122 format %{ "EXTSB $dst, $src \t// byte->int" %} 11123 size(4); 11124 ins_encode %{ 11125 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 11126 __ extsb($dst$$Register, $src$$Register); 11127 %} 11128 ins_pipe(pipe_class_default); 11129 %} 11130 11131 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 11132 effect(DEF dst, USE src); 11133 11134 size(4); 11135 ins_encode %{ 11136 __ extsh($dst$$Register, $src$$Register); 11137 %} 11138 ins_pipe(pipe_class_default); 11139 %} 11140 11141 // LShiftI 16 + RShiftI 16 converts short to int. 11142 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 11143 match(Set dst (RShiftI (LShiftI src amount) amount)); 11144 format %{ "EXTSH $dst, $src \t// short->int" %} 11145 size(4); 11146 ins_encode %{ 11147 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 11148 __ extsh($dst$$Register, $src$$Register); 11149 %} 11150 ins_pipe(pipe_class_default); 11151 %} 11152 11153 // ConvL2I + ConvI2L: Sign extend int in long register. 11154 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11155 match(Set dst (ConvI2L (ConvL2I src))); 11156 11157 format %{ "EXTSW $dst, $src \t// long->long" %} 11158 size(4); 11159 ins_encode %{ 11160 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11161 __ extsw($dst$$Register, $src$$Register); 11162 %} 11163 ins_pipe(pipe_class_default); 11164 %} 11165 11166 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11167 match(Set dst (ConvL2I src)); 11168 format %{ "MR $dst, $src \t// long->int" %} 11169 // variable size, 0 or 4 11170 ins_encode %{ 11171 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11172 __ mr_if_needed($dst$$Register, $src$$Register); 11173 %} 11174 ins_pipe(pipe_class_default); 11175 %} 11176 11177 instruct convD2IRaw_regD(regD dst, regD src) %{ 11178 // no match-rule, false predicate 11179 effect(DEF dst, USE src); 11180 predicate(false); 11181 11182 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11183 size(4); 11184 ins_encode %{ 11185 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11186 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11187 %} 11188 ins_pipe(pipe_class_default); 11189 %} 11190 11191 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 11192 // no match-rule, false predicate 11193 effect(DEF dst, USE crx, USE src); 11194 predicate(false); 11195 11196 ins_variable_size_depending_on_alignment(true); 11197 11198 format %{ "cmovI $crx, $dst, $src" %} 11199 // Worst case is branch + move + stop, no stop without scheduler. 11200 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11201 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11202 ins_pipe(pipe_class_default); 11203 %} 11204 11205 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11206 // no match-rule, false predicate 11207 effect(DEF dst, USE crx, USE src); 11208 predicate(false); 11209 11210 ins_variable_size_depending_on_alignment(true); 11211 11212 format %{ "cmovI $crx, $dst, $src" %} 11213 // Worst case is branch + move + stop, no stop without scheduler. 11214 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11215 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11216 ins_pipe(pipe_class_default); 11217 %} 11218 11219 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11220 // no match-rule, false predicate 11221 effect(DEF dst, USE crx, USE mem); 11222 predicate(false); 11223 11224 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11225 postalloc_expand %{ 11226 // 11227 // replaces 11228 // 11229 // region dst crx mem 11230 // \ | | / 11231 // dst=cmovI_bso_stackSlotL_conLvalue0 11232 // 11233 // with 11234 // 11235 // region dst 11236 // \ / 11237 // dst=loadConI16(0) 11238 // | 11239 // ^ region dst crx mem 11240 // | \ | | / 11241 // dst=cmovI_bso_stackSlotL 11242 // 11243 11244 // Create new nodes. 11245 MachNode *m1 = new loadConI16Node(); 11246 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11247 11248 // inputs for new nodes 11249 m1->add_req(n_region); 11250 m2->add_req(n_region, n_crx, n_mem); 11251 11252 // precedences for new nodes 11253 m2->add_prec(m1); 11254 11255 // operands for new nodes 11256 m1->_opnds[0] = op_dst; 11257 m1->_opnds[1] = new immI16Oper(0); 11258 11259 m2->_opnds[0] = op_dst; 11260 m2->_opnds[1] = op_crx; 11261 m2->_opnds[2] = op_mem; 11262 11263 // registers for new nodes 11264 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11265 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11266 11267 // Insert new nodes. 11268 nodes->push(m1); 11269 nodes->push(m2); 11270 %} 11271 %} 11272 11273 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11274 // no match-rule, false predicate 11275 effect(DEF dst, USE crx, USE src); 11276 predicate(false); 11277 11278 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11279 postalloc_expand %{ 11280 // 11281 // replaces 11282 // 11283 // region dst crx src 11284 // \ | | / 11285 // dst=cmovI_bso_reg_conLvalue0 11286 // 11287 // with 11288 // 11289 // region dst 11290 // \ / 11291 // dst=loadConI16(0) 11292 // | 11293 // ^ region dst crx src 11294 // | \ | | / 11295 // dst=cmovI_bso_reg 11296 // 11297 11298 // Create new nodes. 11299 MachNode *m1 = new loadConI16Node(); 11300 MachNode *m2 = new cmovI_bso_regNode(); 11301 11302 // inputs for new nodes 11303 m1->add_req(n_region); 11304 m2->add_req(n_region, n_crx, n_src); 11305 11306 // precedences for new nodes 11307 m2->add_prec(m1); 11308 11309 // operands for new nodes 11310 m1->_opnds[0] = op_dst; 11311 m1->_opnds[1] = new immI16Oper(0); 11312 11313 m2->_opnds[0] = op_dst; 11314 m2->_opnds[1] = op_crx; 11315 m2->_opnds[2] = op_src; 11316 11317 // registers for new nodes 11318 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11319 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11320 11321 // Insert new nodes. 11322 nodes->push(m1); 11323 nodes->push(m2); 11324 %} 11325 %} 11326 11327 // Double to Int conversion, NaN is mapped to 0. 11328 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11329 match(Set dst (ConvD2I src)); 11330 predicate(!VM_Version::has_mtfprd()); 11331 ins_cost(DEFAULT_COST); 11332 11333 expand %{ 11334 regD tmpD; 11335 stackSlotL tmpS; 11336 flagsReg crx; 11337 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11338 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11339 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11340 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11341 %} 11342 %} 11343 11344 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11345 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11346 match(Set dst (ConvD2I src)); 11347 predicate(VM_Version::has_mtfprd()); 11348 ins_cost(DEFAULT_COST); 11349 11350 expand %{ 11351 regD tmpD; 11352 flagsReg crx; 11353 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11354 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11355 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11356 %} 11357 %} 11358 11359 instruct convF2IRaw_regF(regF dst, regF src) %{ 11360 // no match-rule, false predicate 11361 effect(DEF dst, USE src); 11362 predicate(false); 11363 11364 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11365 size(4); 11366 ins_encode %{ 11367 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11368 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11369 %} 11370 ins_pipe(pipe_class_default); 11371 %} 11372 11373 // Float to Int conversion, NaN is mapped to 0. 11374 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11375 match(Set dst (ConvF2I src)); 11376 predicate(!VM_Version::has_mtfprd()); 11377 ins_cost(DEFAULT_COST); 11378 11379 expand %{ 11380 regF tmpF; 11381 stackSlotL tmpS; 11382 flagsReg crx; 11383 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11384 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11385 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11386 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11387 %} 11388 %} 11389 11390 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11391 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11392 match(Set dst (ConvF2I src)); 11393 predicate(VM_Version::has_mtfprd()); 11394 ins_cost(DEFAULT_COST); 11395 11396 expand %{ 11397 regF tmpF; 11398 flagsReg crx; 11399 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11400 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11401 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11402 %} 11403 %} 11404 11405 // Convert to Long 11406 11407 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11408 match(Set dst (ConvI2L src)); 11409 format %{ "EXTSW $dst, $src \t// int->long" %} 11410 size(4); 11411 ins_encode %{ 11412 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11413 __ extsw($dst$$Register, $src$$Register); 11414 %} 11415 ins_pipe(pipe_class_default); 11416 %} 11417 11418 // Zero-extend: convert unsigned int to long (convUI2L). 11419 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11420 match(Set dst (AndL (ConvI2L src) mask)); 11421 ins_cost(DEFAULT_COST); 11422 11423 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11424 size(4); 11425 ins_encode %{ 11426 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11427 __ clrldi($dst$$Register, $src$$Register, 32); 11428 %} 11429 ins_pipe(pipe_class_default); 11430 %} 11431 11432 // Zero-extend: convert unsigned int to long in long register. 11433 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11434 match(Set dst (AndL src mask)); 11435 ins_cost(DEFAULT_COST); 11436 11437 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11438 size(4); 11439 ins_encode %{ 11440 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11441 __ clrldi($dst$$Register, $src$$Register, 32); 11442 %} 11443 ins_pipe(pipe_class_default); 11444 %} 11445 11446 instruct convF2LRaw_regF(regF dst, regF src) %{ 11447 // no match-rule, false predicate 11448 effect(DEF dst, USE src); 11449 predicate(false); 11450 11451 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11452 size(4); 11453 ins_encode %{ 11454 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11455 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11456 %} 11457 ins_pipe(pipe_class_default); 11458 %} 11459 11460 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 11461 // no match-rule, false predicate 11462 effect(DEF dst, USE crx, USE src); 11463 predicate(false); 11464 11465 ins_variable_size_depending_on_alignment(true); 11466 11467 format %{ "cmovL $crx, $dst, $src" %} 11468 // Worst case is branch + move + stop, no stop without scheduler. 11469 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11470 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11471 ins_pipe(pipe_class_default); 11472 %} 11473 11474 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11475 // no match-rule, false predicate 11476 effect(DEF dst, USE crx, USE src); 11477 predicate(false); 11478 11479 ins_variable_size_depending_on_alignment(true); 11480 11481 format %{ "cmovL $crx, $dst, $src" %} 11482 // Worst case is branch + move + stop, no stop without scheduler. 11483 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11484 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11485 ins_pipe(pipe_class_default); 11486 %} 11487 11488 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11489 // no match-rule, false predicate 11490 effect(DEF dst, USE crx, USE mem); 11491 predicate(false); 11492 11493 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11494 postalloc_expand %{ 11495 // 11496 // replaces 11497 // 11498 // region dst crx mem 11499 // \ | | / 11500 // dst=cmovL_bso_stackSlotL_conLvalue0 11501 // 11502 // with 11503 // 11504 // region dst 11505 // \ / 11506 // dst=loadConL16(0) 11507 // | 11508 // ^ region dst crx mem 11509 // | \ | | / 11510 // dst=cmovL_bso_stackSlotL 11511 // 11512 11513 // Create new nodes. 11514 MachNode *m1 = new loadConL16Node(); 11515 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11516 11517 // inputs for new nodes 11518 m1->add_req(n_region); 11519 m2->add_req(n_region, n_crx, n_mem); 11520 m2->add_prec(m1); 11521 11522 // operands for new nodes 11523 m1->_opnds[0] = op_dst; 11524 m1->_opnds[1] = new immL16Oper(0); 11525 m2->_opnds[0] = op_dst; 11526 m2->_opnds[1] = op_crx; 11527 m2->_opnds[2] = op_mem; 11528 11529 // registers for new nodes 11530 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11531 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11532 11533 // Insert new nodes. 11534 nodes->push(m1); 11535 nodes->push(m2); 11536 %} 11537 %} 11538 11539 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11540 // no match-rule, false predicate 11541 effect(DEF dst, USE crx, USE src); 11542 predicate(false); 11543 11544 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11545 postalloc_expand %{ 11546 // 11547 // replaces 11548 // 11549 // region dst crx src 11550 // \ | | / 11551 // dst=cmovL_bso_reg_conLvalue0 11552 // 11553 // with 11554 // 11555 // region dst 11556 // \ / 11557 // dst=loadConL16(0) 11558 // | 11559 // ^ region dst crx src 11560 // | \ | | / 11561 // dst=cmovL_bso_reg 11562 // 11563 11564 // Create new nodes. 11565 MachNode *m1 = new loadConL16Node(); 11566 MachNode *m2 = new cmovL_bso_regNode(); 11567 11568 // inputs for new nodes 11569 m1->add_req(n_region); 11570 m2->add_req(n_region, n_crx, n_src); 11571 m2->add_prec(m1); 11572 11573 // operands for new nodes 11574 m1->_opnds[0] = op_dst; 11575 m1->_opnds[1] = new immL16Oper(0); 11576 m2->_opnds[0] = op_dst; 11577 m2->_opnds[1] = op_crx; 11578 m2->_opnds[2] = op_src; 11579 11580 // registers for new nodes 11581 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11582 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11583 11584 // Insert new nodes. 11585 nodes->push(m1); 11586 nodes->push(m2); 11587 %} 11588 %} 11589 11590 // Float to Long conversion, NaN is mapped to 0. 11591 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11592 match(Set dst (ConvF2L src)); 11593 predicate(!VM_Version::has_mtfprd()); 11594 ins_cost(DEFAULT_COST); 11595 11596 expand %{ 11597 regF tmpF; 11598 stackSlotL tmpS; 11599 flagsReg crx; 11600 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11601 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11602 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11603 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11604 %} 11605 %} 11606 11607 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11608 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11609 match(Set dst (ConvF2L src)); 11610 predicate(VM_Version::has_mtfprd()); 11611 ins_cost(DEFAULT_COST); 11612 11613 expand %{ 11614 regF tmpF; 11615 flagsReg crx; 11616 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11617 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11618 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11619 %} 11620 %} 11621 11622 instruct convD2LRaw_regD(regD dst, regD src) %{ 11623 // no match-rule, false predicate 11624 effect(DEF dst, USE src); 11625 predicate(false); 11626 11627 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11628 size(4); 11629 ins_encode %{ 11630 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11631 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11632 %} 11633 ins_pipe(pipe_class_default); 11634 %} 11635 11636 // Double to Long conversion, NaN is mapped to 0. 11637 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11638 match(Set dst (ConvD2L src)); 11639 predicate(!VM_Version::has_mtfprd()); 11640 ins_cost(DEFAULT_COST); 11641 11642 expand %{ 11643 regD tmpD; 11644 stackSlotL tmpS; 11645 flagsReg crx; 11646 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11647 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11648 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11649 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11650 %} 11651 %} 11652 11653 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11654 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11655 match(Set dst (ConvD2L src)); 11656 predicate(VM_Version::has_mtfprd()); 11657 ins_cost(DEFAULT_COST); 11658 11659 expand %{ 11660 regD tmpD; 11661 flagsReg crx; 11662 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11663 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11664 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11665 %} 11666 %} 11667 11668 // Convert to Float 11669 11670 // Placed here as needed in expand. 11671 instruct convL2DRaw_regD(regD dst, regD src) %{ 11672 // no match-rule, false predicate 11673 effect(DEF dst, USE src); 11674 predicate(false); 11675 11676 format %{ "FCFID $dst, $src \t// convL2D" %} 11677 size(4); 11678 ins_encode %{ 11679 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11680 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11681 %} 11682 ins_pipe(pipe_class_default); 11683 %} 11684 11685 // Placed here as needed in expand. 11686 instruct convD2F_reg(regF dst, regD src) %{ 11687 match(Set dst (ConvD2F src)); 11688 format %{ "FRSP $dst, $src \t// convD2F" %} 11689 size(4); 11690 ins_encode %{ 11691 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11692 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11693 %} 11694 ins_pipe(pipe_class_default); 11695 %} 11696 11697 // Integer to Float conversion. 11698 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11699 match(Set dst (ConvI2F src)); 11700 predicate(!VM_Version::has_fcfids()); 11701 ins_cost(DEFAULT_COST); 11702 11703 expand %{ 11704 iRegLdst tmpL; 11705 stackSlotL tmpS; 11706 regD tmpD; 11707 regD tmpD2; 11708 convI2L_reg(tmpL, src); // Sign-extension int to long. 11709 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11710 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11711 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11712 convD2F_reg(dst, tmpD2); // Convert double to float. 11713 %} 11714 %} 11715 11716 instruct convL2FRaw_regF(regF dst, regD src) %{ 11717 // no match-rule, false predicate 11718 effect(DEF dst, USE src); 11719 predicate(false); 11720 11721 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11722 size(4); 11723 ins_encode %{ 11724 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11725 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11726 %} 11727 ins_pipe(pipe_class_default); 11728 %} 11729 11730 // Integer to Float conversion. Special version for Power7. 11731 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11732 match(Set dst (ConvI2F src)); 11733 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11734 ins_cost(DEFAULT_COST); 11735 11736 expand %{ 11737 iRegLdst tmpL; 11738 stackSlotL tmpS; 11739 regD tmpD; 11740 convI2L_reg(tmpL, src); // Sign-extension int to long. 11741 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11742 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11743 convL2FRaw_regF(dst, tmpD); // Convert to float. 11744 %} 11745 %} 11746 11747 // Integer to Float conversion. Special version for Power8. 11748 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11749 match(Set dst (ConvI2F src)); 11750 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11751 ins_cost(DEFAULT_COST); 11752 11753 expand %{ 11754 regD tmpD; 11755 moveI2D_reg(tmpD, src); 11756 convL2FRaw_regF(dst, tmpD); // Convert to float. 11757 %} 11758 %} 11759 11760 // L2F to avoid runtime call. 11761 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11762 match(Set dst (ConvL2F src)); 11763 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11764 ins_cost(DEFAULT_COST); 11765 11766 expand %{ 11767 stackSlotL tmpS; 11768 regD tmpD; 11769 regL_to_stkL(tmpS, src); // Store long to stack. 11770 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11771 convL2FRaw_regF(dst, tmpD); // Convert to float. 11772 %} 11773 %} 11774 11775 // L2F to avoid runtime call. Special version for Power8. 11776 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11777 match(Set dst (ConvL2F src)); 11778 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11779 ins_cost(DEFAULT_COST); 11780 11781 expand %{ 11782 regD tmpD; 11783 moveL2D_reg(tmpD, src); 11784 convL2FRaw_regF(dst, tmpD); // Convert to float. 11785 %} 11786 %} 11787 11788 // Moved up as used in expand. 11789 //instruct convD2F_reg(regF dst, regD src) %{%} 11790 11791 // Convert to Double 11792 11793 // Integer to Double conversion. 11794 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11795 match(Set dst (ConvI2D src)); 11796 predicate(!VM_Version::has_mtfprd()); 11797 ins_cost(DEFAULT_COST); 11798 11799 expand %{ 11800 iRegLdst tmpL; 11801 stackSlotL tmpS; 11802 regD tmpD; 11803 convI2L_reg(tmpL, src); // Sign-extension int to long. 11804 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11805 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11806 convL2DRaw_regD(dst, tmpD); // Convert to double. 11807 %} 11808 %} 11809 11810 // Integer to Double conversion. Special version for Power8. 11811 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11812 match(Set dst (ConvI2D src)); 11813 predicate(VM_Version::has_mtfprd()); 11814 ins_cost(DEFAULT_COST); 11815 11816 expand %{ 11817 regD tmpD; 11818 moveI2D_reg(tmpD, src); 11819 convL2DRaw_regD(dst, tmpD); // Convert to double. 11820 %} 11821 %} 11822 11823 // Long to Double conversion 11824 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11825 match(Set dst (ConvL2D src)); 11826 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11827 11828 expand %{ 11829 regD tmpD; 11830 moveL2D_stack_reg(tmpD, src); 11831 convL2DRaw_regD(dst, tmpD); 11832 %} 11833 %} 11834 11835 // Long to Double conversion. Special version for Power8. 11836 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11837 match(Set dst (ConvL2D src)); 11838 predicate(VM_Version::has_mtfprd()); 11839 ins_cost(DEFAULT_COST); 11840 11841 expand %{ 11842 regD tmpD; 11843 moveL2D_reg(tmpD, src); 11844 convL2DRaw_regD(dst, tmpD); // Convert to double. 11845 %} 11846 %} 11847 11848 instruct convF2D_reg(regD dst, regF src) %{ 11849 match(Set dst (ConvF2D src)); 11850 format %{ "FMR $dst, $src \t// float->double" %} 11851 // variable size, 0 or 4 11852 ins_encode %{ 11853 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11854 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11855 %} 11856 ins_pipe(pipe_class_default); 11857 %} 11858 11859 //----------Control Flow Instructions------------------------------------------ 11860 // Compare Instructions 11861 11862 // Compare Integers 11863 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11864 match(Set crx (CmpI src1 src2)); 11865 size(4); 11866 format %{ "CMPW $crx, $src1, $src2" %} 11867 ins_encode %{ 11868 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11869 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11870 %} 11871 ins_pipe(pipe_class_compare); 11872 %} 11873 11874 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11875 match(Set crx (CmpI src1 src2)); 11876 format %{ "CMPWI $crx, $src1, $src2" %} 11877 size(4); 11878 ins_encode %{ 11879 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11880 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11881 %} 11882 ins_pipe(pipe_class_compare); 11883 %} 11884 11885 // (src1 & src2) == 0? 11886 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11887 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11888 // r0 is killed 11889 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11890 size(4); 11891 ins_encode %{ 11892 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11893 __ andi_(R0, $src1$$Register, $src2$$constant); 11894 %} 11895 ins_pipe(pipe_class_compare); 11896 %} 11897 11898 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11899 match(Set crx (CmpL src1 src2)); 11900 format %{ "CMPD $crx, $src1, $src2" %} 11901 size(4); 11902 ins_encode %{ 11903 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11904 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11905 %} 11906 ins_pipe(pipe_class_compare); 11907 %} 11908 11909 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11910 match(Set crx (CmpL src1 src2)); 11911 format %{ "CMPDI $crx, $src1, $src2" %} 11912 size(4); 11913 ins_encode %{ 11914 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11915 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11916 %} 11917 ins_pipe(pipe_class_compare); 11918 %} 11919 11920 // Added CmpUL for LoopPredicate. 11921 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11922 match(Set crx (CmpUL src1 src2)); 11923 format %{ "CMPLD $crx, $src1, $src2" %} 11924 size(4); 11925 ins_encode %{ 11926 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11927 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11928 %} 11929 ins_pipe(pipe_class_compare); 11930 %} 11931 11932 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11933 match(Set crx (CmpUL src1 src2)); 11934 format %{ "CMPLDI $crx, $src1, $src2" %} 11935 size(4); 11936 ins_encode %{ 11937 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11938 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11939 %} 11940 ins_pipe(pipe_class_compare); 11941 %} 11942 11943 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11944 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11945 // r0 is killed 11946 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11947 size(4); 11948 ins_encode %{ 11949 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11950 __ and_(R0, $src1$$Register, $src2$$Register); 11951 %} 11952 ins_pipe(pipe_class_compare); 11953 %} 11954 11955 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11956 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11957 // r0 is killed 11958 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11959 size(4); 11960 ins_encode %{ 11961 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11962 __ andi_(R0, $src1$$Register, $src2$$constant); 11963 %} 11964 ins_pipe(pipe_class_compare); 11965 %} 11966 11967 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11968 // no match-rule, false predicate 11969 effect(DEF dst, USE crx); 11970 predicate(false); 11971 11972 ins_variable_size_depending_on_alignment(true); 11973 11974 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11975 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11976 size((false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16)); 11977 ins_encode %{ 11978 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11979 Label done; 11980 // li(Rdst, 0); // equal -> 0 11981 __ beq($crx$$CondRegister, done); 11982 __ li($dst$$Register, 1); // greater -> +1 11983 __ bgt($crx$$CondRegister, done); 11984 __ li($dst$$Register, -1); // unordered or less -> -1 11985 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11986 __ bind(done); 11987 %} 11988 ins_pipe(pipe_class_compare); 11989 %} 11990 11991 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11992 // no match-rule, false predicate 11993 effect(DEF dst, USE crx); 11994 predicate(false); 11995 11996 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11997 postalloc_expand %{ 11998 // 11999 // replaces 12000 // 12001 // region crx 12002 // \ | 12003 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 12004 // 12005 // with 12006 // 12007 // region 12008 // \ 12009 // dst=loadConI16(0) 12010 // | 12011 // ^ region crx 12012 // | \ | 12013 // dst=cmovI_conIvalueMinus1_conIvalue1 12014 // 12015 12016 // Create new nodes. 12017 MachNode *m1 = new loadConI16Node(); 12018 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 12019 12020 // inputs for new nodes 12021 m1->add_req(n_region); 12022 m2->add_req(n_region, n_crx); 12023 m2->add_prec(m1); 12024 12025 // operands for new nodes 12026 m1->_opnds[0] = op_dst; 12027 m1->_opnds[1] = new immI16Oper(0); 12028 m2->_opnds[0] = op_dst; 12029 m2->_opnds[1] = op_crx; 12030 12031 // registers for new nodes 12032 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 12033 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 12034 12035 // Insert new nodes. 12036 nodes->push(m1); 12037 nodes->push(m2); 12038 %} 12039 %} 12040 12041 // Manifest a CmpL3 result in an integer register. Very painful. 12042 // This is the test to avoid. 12043 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 12044 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 12045 match(Set dst (CmpL3 src1 src2)); 12046 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12047 12048 expand %{ 12049 flagsReg tmp1; 12050 cmpL_reg_reg(tmp1, src1, src2); 12051 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12052 %} 12053 %} 12054 12055 // Implicit range checks. 12056 // A range check in the ideal world has one of the following shapes: 12057 // - (If le (CmpU length index)), (IfTrue throw exception) 12058 // - (If lt (CmpU index length)), (IfFalse throw exception) 12059 // 12060 // Match range check 'If le (CmpU length index)'. 12061 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 12062 match(If cmp (CmpU src_length index)); 12063 effect(USE labl); 12064 predicate(TrapBasedRangeChecks && 12065 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 12066 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 12067 (Matcher::branches_to_uncommon_trap(_leaf))); 12068 12069 ins_is_TrapBasedCheckNode(true); 12070 12071 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 12072 size(4); 12073 ins_encode %{ 12074 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12075 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 12076 __ trap_range_check_le($src_length$$Register, $index$$constant); 12077 } else { 12078 // Both successors are uncommon traps, probability is 0. 12079 // Node got flipped during fixup flow. 12080 assert($cmp$$cmpcode == 0x9, "must be greater"); 12081 __ trap_range_check_g($src_length$$Register, $index$$constant); 12082 } 12083 %} 12084 ins_pipe(pipe_class_trap); 12085 %} 12086 12087 // Match range check 'If lt (CmpU index length)'. 12088 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 12089 match(If cmp (CmpU src_index src_length)); 12090 effect(USE labl); 12091 predicate(TrapBasedRangeChecks && 12092 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12093 _leaf->as_If()->_prob >= PROB_ALWAYS && 12094 (Matcher::branches_to_uncommon_trap(_leaf))); 12095 12096 ins_is_TrapBasedCheckNode(true); 12097 12098 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 12099 size(4); 12100 ins_encode %{ 12101 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 12102 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12103 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 12104 } else { 12105 // Both successors are uncommon traps, probability is 0. 12106 // Node got flipped during fixup flow. 12107 assert($cmp$$cmpcode == 0x8, "must be less"); 12108 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 12109 } 12110 %} 12111 ins_pipe(pipe_class_trap); 12112 %} 12113 12114 // Match range check 'If lt (CmpU index length)'. 12115 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 12116 match(If cmp (CmpU src_index length)); 12117 effect(USE labl); 12118 predicate(TrapBasedRangeChecks && 12119 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12120 _leaf->as_If()->_prob >= PROB_ALWAYS && 12121 (Matcher::branches_to_uncommon_trap(_leaf))); 12122 12123 ins_is_TrapBasedCheckNode(true); 12124 12125 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 12126 size(4); 12127 ins_encode %{ 12128 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12129 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12130 __ trap_range_check_ge($src_index$$Register, $length$$constant); 12131 } else { 12132 // Both successors are uncommon traps, probability is 0. 12133 // Node got flipped during fixup flow. 12134 assert($cmp$$cmpcode == 0x8, "must be less"); 12135 __ trap_range_check_l($src_index$$Register, $length$$constant); 12136 } 12137 %} 12138 ins_pipe(pipe_class_trap); 12139 %} 12140 12141 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 12142 match(Set crx (CmpU src1 src2)); 12143 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 12144 size(4); 12145 ins_encode %{ 12146 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12147 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12148 %} 12149 ins_pipe(pipe_class_compare); 12150 %} 12151 12152 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 12153 match(Set crx (CmpU src1 src2)); 12154 size(4); 12155 format %{ "CMPLWI $crx, $src1, $src2" %} 12156 ins_encode %{ 12157 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12158 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12159 %} 12160 ins_pipe(pipe_class_compare); 12161 %} 12162 12163 // Implicit zero checks (more implicit null checks). 12164 // No constant pool entries required. 12165 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12166 match(If cmp (CmpN value zero)); 12167 effect(USE labl); 12168 predicate(TrapBasedNullChecks && 12169 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12170 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12171 Matcher::branches_to_uncommon_trap(_leaf)); 12172 ins_cost(1); 12173 12174 ins_is_TrapBasedCheckNode(true); 12175 12176 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12177 size(4); 12178 ins_encode %{ 12179 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12180 if ($cmp$$cmpcode == 0xA) { 12181 __ trap_null_check($value$$Register); 12182 } else { 12183 // Both successors are uncommon traps, probability is 0. 12184 // Node got flipped during fixup flow. 12185 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12186 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12187 } 12188 %} 12189 ins_pipe(pipe_class_trap); 12190 %} 12191 12192 // Compare narrow oops. 12193 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12194 match(Set crx (CmpN src1 src2)); 12195 12196 size(4); 12197 ins_cost(2); 12198 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12199 ins_encode %{ 12200 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12201 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12202 %} 12203 ins_pipe(pipe_class_compare); 12204 %} 12205 12206 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12207 match(Set crx (CmpN src1 src2)); 12208 // Make this more expensive than zeroCheckN_iReg_imm0. 12209 ins_cost(2); 12210 12211 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12212 size(4); 12213 ins_encode %{ 12214 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12215 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12216 %} 12217 ins_pipe(pipe_class_compare); 12218 %} 12219 12220 // Implicit zero checks (more implicit null checks). 12221 // No constant pool entries required. 12222 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12223 match(If cmp (CmpP value zero)); 12224 effect(USE labl); 12225 predicate(TrapBasedNullChecks && 12226 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12227 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12228 Matcher::branches_to_uncommon_trap(_leaf)); 12229 ins_cost(1); // Should not be cheaper than zeroCheckN. 12230 12231 ins_is_TrapBasedCheckNode(true); 12232 12233 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12234 size(4); 12235 ins_encode %{ 12236 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12237 if ($cmp$$cmpcode == 0xA) { 12238 __ trap_null_check($value$$Register); 12239 } else { 12240 // Both successors are uncommon traps, probability is 0. 12241 // Node got flipped during fixup flow. 12242 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12243 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12244 } 12245 %} 12246 ins_pipe(pipe_class_trap); 12247 %} 12248 12249 // Compare Pointers 12250 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12251 match(Set crx (CmpP src1 src2)); 12252 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12253 size(4); 12254 ins_encode %{ 12255 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12256 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12257 %} 12258 ins_pipe(pipe_class_compare); 12259 %} 12260 12261 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12262 match(Set crx (CmpP src1 src2)); 12263 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12264 size(4); 12265 ins_encode %{ 12266 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12267 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12268 %} 12269 ins_pipe(pipe_class_compare); 12270 %} 12271 12272 // Used in postalloc expand. 12273 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12274 // This match rule prevents reordering of node before a safepoint. 12275 // This only makes sense if this instructions is used exclusively 12276 // for the expansion of EncodeP! 12277 match(Set crx (CmpP src1 src2)); 12278 predicate(false); 12279 12280 format %{ "CMPDI $crx, $src1, $src2" %} 12281 size(4); 12282 ins_encode %{ 12283 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12284 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12285 %} 12286 ins_pipe(pipe_class_compare); 12287 %} 12288 12289 //----------Float Compares---------------------------------------------------- 12290 12291 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12292 // Needs matchrule, see cmpDUnordered. 12293 match(Set crx (CmpF src1 src2)); 12294 // no match-rule, false predicate 12295 predicate(false); 12296 12297 format %{ "cmpFUrd $crx, $src1, $src2" %} 12298 size(4); 12299 ins_encode %{ 12300 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12301 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12302 %} 12303 ins_pipe(pipe_class_default); 12304 %} 12305 12306 instruct cmov_bns_less(flagsReg crx) %{ 12307 // no match-rule, false predicate 12308 effect(DEF crx); 12309 predicate(false); 12310 12311 ins_variable_size_depending_on_alignment(true); 12312 12313 format %{ "cmov $crx" %} 12314 // Worst case is branch + move + stop, no stop without scheduler. 12315 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12)); 12316 ins_encode %{ 12317 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12318 Label done; 12319 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12320 __ li(R0, 0); 12321 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12322 // TODO PPC port __ endgroup_if_needed(_size == 16); 12323 __ bind(done); 12324 %} 12325 ins_pipe(pipe_class_default); 12326 %} 12327 12328 // Compare floating, generate condition code. 12329 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12330 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12331 // 12332 // The following code sequence occurs a lot in mpegaudio: 12333 // 12334 // block BXX: 12335 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12336 // cmpFUrd CCR6, F11, F9 12337 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12338 // cmov CCR6 12339 // 8: instruct branchConSched: 12340 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12341 match(Set crx (CmpF src1 src2)); 12342 ins_cost(DEFAULT_COST+BRANCH_COST); 12343 12344 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12345 postalloc_expand %{ 12346 // 12347 // replaces 12348 // 12349 // region src1 src2 12350 // \ | | 12351 // crx=cmpF_reg_reg 12352 // 12353 // with 12354 // 12355 // region src1 src2 12356 // \ | | 12357 // crx=cmpFUnordered_reg_reg 12358 // | 12359 // ^ region 12360 // | \ 12361 // crx=cmov_bns_less 12362 // 12363 12364 // Create new nodes. 12365 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12366 MachNode *m2 = new cmov_bns_lessNode(); 12367 12368 // inputs for new nodes 12369 m1->add_req(n_region, n_src1, n_src2); 12370 m2->add_req(n_region); 12371 m2->add_prec(m1); 12372 12373 // operands for new nodes 12374 m1->_opnds[0] = op_crx; 12375 m1->_opnds[1] = op_src1; 12376 m1->_opnds[2] = op_src2; 12377 m2->_opnds[0] = op_crx; 12378 12379 // registers for new nodes 12380 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12381 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12382 12383 // Insert new nodes. 12384 nodes->push(m1); 12385 nodes->push(m2); 12386 %} 12387 %} 12388 12389 // Compare float, generate -1,0,1 12390 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12391 match(Set dst (CmpF3 src1 src2)); 12392 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12393 12394 expand %{ 12395 flagsReg tmp1; 12396 cmpFUnordered_reg_reg(tmp1, src1, src2); 12397 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12398 %} 12399 %} 12400 12401 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12402 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12403 // node right before the conditional move using it. 12404 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12405 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12406 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12407 // conditional move was supposed to be spilled. 12408 match(Set crx (CmpD src1 src2)); 12409 // False predicate, shall not be matched. 12410 predicate(false); 12411 12412 format %{ "cmpFUrd $crx, $src1, $src2" %} 12413 size(4); 12414 ins_encode %{ 12415 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12416 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12417 %} 12418 ins_pipe(pipe_class_default); 12419 %} 12420 12421 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12422 match(Set crx (CmpD src1 src2)); 12423 ins_cost(DEFAULT_COST+BRANCH_COST); 12424 12425 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12426 postalloc_expand %{ 12427 // 12428 // replaces 12429 // 12430 // region src1 src2 12431 // \ | | 12432 // crx=cmpD_reg_reg 12433 // 12434 // with 12435 // 12436 // region src1 src2 12437 // \ | | 12438 // crx=cmpDUnordered_reg_reg 12439 // | 12440 // ^ region 12441 // | \ 12442 // crx=cmov_bns_less 12443 // 12444 12445 // create new nodes 12446 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12447 MachNode *m2 = new cmov_bns_lessNode(); 12448 12449 // inputs for new nodes 12450 m1->add_req(n_region, n_src1, n_src2); 12451 m2->add_req(n_region); 12452 m2->add_prec(m1); 12453 12454 // operands for new nodes 12455 m1->_opnds[0] = op_crx; 12456 m1->_opnds[1] = op_src1; 12457 m1->_opnds[2] = op_src2; 12458 m2->_opnds[0] = op_crx; 12459 12460 // registers for new nodes 12461 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12462 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12463 12464 // Insert new nodes. 12465 nodes->push(m1); 12466 nodes->push(m2); 12467 %} 12468 %} 12469 12470 // Compare double, generate -1,0,1 12471 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12472 match(Set dst (CmpD3 src1 src2)); 12473 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12474 12475 expand %{ 12476 flagsReg tmp1; 12477 cmpDUnordered_reg_reg(tmp1, src1, src2); 12478 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12479 %} 12480 %} 12481 12482 // Compare char 12483 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12484 match(Set dst (Digit src1)); 12485 effect(TEMP src2, TEMP crx); 12486 ins_cost(3 * DEFAULT_COST); 12487 12488 format %{ "LI $src2, 0x3930\n\t" 12489 "CMPRB $crx, 0, $src1, $src2\n\t" 12490 "SETB $dst, $crx" %} 12491 size(12); 12492 ins_encode %{ 12493 // 0x30: 0, 0x39: 9 12494 __ li($src2$$Register, 0x3930); 12495 // compare src1 with ranges 0x30 to 0x39 12496 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12497 __ setb($dst$$Register, $crx$$CondRegister); 12498 %} 12499 ins_pipe(pipe_class_default); 12500 %} 12501 12502 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12503 match(Set dst (LowerCase src1)); 12504 effect(TEMP src2, TEMP crx); 12505 ins_cost(12 * DEFAULT_COST); 12506 12507 format %{ "LI $src2, 0x7A61\n\t" 12508 "CMPRB $crx, 0, $src1, $src2\n\t" 12509 "BGT $crx, done\n\t" 12510 "LIS $src2, (signed short)0xF6DF\n\t" 12511 "ORI $src2, $src2, 0xFFF8\n\t" 12512 "CMPRB $crx, 1, $src1, $src2\n\t" 12513 "BGT $crx, done\n\t" 12514 "LIS $src2, (signed short)0xAAB5\n\t" 12515 "ORI $src2, $src2, 0xBABA\n\t" 12516 "INSRDI $src2, $src2, 32, 0\n\t" 12517 "CMPEQB $crx, 1, $src1, $src2\n" 12518 "done:\n\t" 12519 "SETB $dst, $crx" %} 12520 12521 size(48); 12522 ins_encode %{ 12523 Label done; 12524 // 0x61: a, 0x7A: z 12525 __ li($src2$$Register, 0x7A61); 12526 // compare src1 with ranges 0x61 to 0x7A 12527 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12528 __ bgt($crx$$CondRegister, done); 12529 12530 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case 12531 __ lis($src2$$Register, (signed short)0xF6DF); 12532 __ ori($src2$$Register, $src2$$Register, 0xFFF8); 12533 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF 12534 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12535 __ bgt($crx$$CondRegister, done); 12536 12537 // 0xAA: feminine ordinal indicator 12538 // 0xB5: micro sign 12539 // 0xBA: masculine ordinal indicator 12540 __ lis($src2$$Register, (signed short)0xAAB5); 12541 __ ori($src2$$Register, $src2$$Register, 0xBABA); 12542 __ insrdi($src2$$Register, $src2$$Register, 32, 0); 12543 // compare src1 with 0xAA, 0xB5, and 0xBA 12544 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register); 12545 12546 __ bind(done); 12547 __ setb($dst$$Register, $crx$$CondRegister); 12548 %} 12549 ins_pipe(pipe_class_default); 12550 %} 12551 12552 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12553 match(Set dst (UpperCase src1)); 12554 effect(TEMP src2, TEMP crx); 12555 ins_cost(7 * DEFAULT_COST); 12556 12557 format %{ "LI $src2, 0x5A41\n\t" 12558 "CMPRB $crx, 0, $src1, $src2\n\t" 12559 "BGT $crx, done\n\t" 12560 "LIS $src2, (signed short)0xD6C0\n\t" 12561 "ORI $src2, $src2, 0xDED8\n\t" 12562 "CMPRB $crx, 1, $src1, $src2\n" 12563 "done:\n\t" 12564 "SETB $dst, $crx" %} 12565 12566 size(28); 12567 ins_encode %{ 12568 Label done; 12569 // 0x41: A, 0x5A: Z 12570 __ li($src2$$Register, 0x5A41); 12571 // compare src1 with a range 0x41 to 0x5A 12572 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12573 __ bgt($crx$$CondRegister, done); 12574 12575 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case 12576 __ lis($src2$$Register, (signed short)0xD6C0); 12577 __ ori($src2$$Register, $src2$$Register, 0xDED8); 12578 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE 12579 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12580 12581 __ bind(done); 12582 __ setb($dst$$Register, $crx$$CondRegister); 12583 %} 12584 ins_pipe(pipe_class_default); 12585 %} 12586 12587 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12588 match(Set dst (Whitespace src1)); 12589 effect(TEMP src2, TEMP crx); 12590 ins_cost(4 * DEFAULT_COST); 12591 12592 format %{ "LI $src2, 0x0D09\n\t" 12593 "ADDIS $src2, 0x201C\n\t" 12594 "CMPRB $crx, 1, $src1, $src2\n\t" 12595 "SETB $dst, $crx" %} 12596 size(16); 12597 ins_encode %{ 12598 // 0x09 to 0x0D, 0x1C to 0x20 12599 __ li($src2$$Register, 0x0D09); 12600 __ addis($src2$$Register, $src2$$Register, 0x0201C); 12601 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20 12602 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12603 __ setb($dst$$Register, $crx$$CondRegister); 12604 %} 12605 ins_pipe(pipe_class_default); 12606 %} 12607 12608 //----------Branches--------------------------------------------------------- 12609 // Jump 12610 12611 // Direct Branch. 12612 instruct branch(label labl) %{ 12613 match(Goto); 12614 effect(USE labl); 12615 ins_cost(BRANCH_COST); 12616 12617 format %{ "B $labl" %} 12618 size(4); 12619 ins_encode %{ 12620 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12621 Label d; // dummy 12622 __ bind(d); 12623 Label* p = $labl$$label; 12624 // `p' is `NULL' when this encoding class is used only to 12625 // determine the size of the encoded instruction. 12626 Label& l = (NULL == p)? d : *(p); 12627 __ b(l); 12628 %} 12629 ins_pipe(pipe_class_default); 12630 %} 12631 12632 // Conditional Near Branch 12633 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12634 // Same match rule as `branchConFar'. 12635 match(If cmp crx); 12636 effect(USE lbl); 12637 ins_cost(BRANCH_COST); 12638 12639 // If set to 1 this indicates that the current instruction is a 12640 // short variant of a long branch. This avoids using this 12641 // instruction in first-pass matching. It will then only be used in 12642 // the `Shorten_branches' pass. 12643 ins_short_branch(1); 12644 12645 format %{ "B$cmp $crx, $lbl" %} 12646 size(4); 12647 ins_encode( enc_bc(crx, cmp, lbl) ); 12648 ins_pipe(pipe_class_default); 12649 %} 12650 12651 // This is for cases when the ppc64 `bc' instruction does not 12652 // reach far enough. So we emit a far branch here, which is more 12653 // expensive. 12654 // 12655 // Conditional Far Branch 12656 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12657 // Same match rule as `branchCon'. 12658 match(If cmp crx); 12659 effect(USE crx, USE lbl); 12660 predicate(!false /* TODO: PPC port HB_Schedule*/); 12661 // Higher cost than `branchCon'. 12662 ins_cost(5*BRANCH_COST); 12663 12664 // This is not a short variant of a branch, but the long variant. 12665 ins_short_branch(0); 12666 12667 format %{ "B_FAR$cmp $crx, $lbl" %} 12668 size(8); 12669 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12670 ins_pipe(pipe_class_default); 12671 %} 12672 12673 // Conditional Branch used with Power6 scheduler (can be far or short). 12674 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12675 // Same match rule as `branchCon'. 12676 match(If cmp crx); 12677 effect(USE crx, USE lbl); 12678 predicate(false /* TODO: PPC port HB_Schedule*/); 12679 // Higher cost than `branchCon'. 12680 ins_cost(5*BRANCH_COST); 12681 12682 // Actually size doesn't depend on alignment but on shortening. 12683 ins_variable_size_depending_on_alignment(true); 12684 // long variant. 12685 ins_short_branch(0); 12686 12687 format %{ "B_FAR$cmp $crx, $lbl" %} 12688 size(8); // worst case 12689 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12690 ins_pipe(pipe_class_default); 12691 %} 12692 12693 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12694 match(CountedLoopEnd cmp crx); 12695 effect(USE labl); 12696 ins_cost(BRANCH_COST); 12697 12698 // short variant. 12699 ins_short_branch(1); 12700 12701 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12702 size(4); 12703 ins_encode( enc_bc(crx, cmp, labl) ); 12704 ins_pipe(pipe_class_default); 12705 %} 12706 12707 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12708 match(CountedLoopEnd cmp crx); 12709 effect(USE labl); 12710 predicate(!false /* TODO: PPC port HB_Schedule */); 12711 ins_cost(BRANCH_COST); 12712 12713 // Long variant. 12714 ins_short_branch(0); 12715 12716 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12717 size(8); 12718 ins_encode( enc_bc_far(crx, cmp, labl) ); 12719 ins_pipe(pipe_class_default); 12720 %} 12721 12722 // Conditional Branch used with Power6 scheduler (can be far or short). 12723 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12724 match(CountedLoopEnd cmp crx); 12725 effect(USE labl); 12726 predicate(false /* TODO: PPC port HB_Schedule */); 12727 // Higher cost than `branchCon'. 12728 ins_cost(5*BRANCH_COST); 12729 12730 // Actually size doesn't depend on alignment but on shortening. 12731 ins_variable_size_depending_on_alignment(true); 12732 // Long variant. 12733 ins_short_branch(0); 12734 12735 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12736 size(8); // worst case 12737 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12738 ins_pipe(pipe_class_default); 12739 %} 12740 12741 // ============================================================================ 12742 // Java runtime operations, intrinsics and other complex operations. 12743 12744 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12745 // array for an instance of the superklass. Set a hidden internal cache on a 12746 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12747 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12748 // 12749 // GL TODO: Improve this. 12750 // - result should not be a TEMP 12751 // - Add match rule as on sparc avoiding additional Cmp. 12752 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12753 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12754 match(Set result (PartialSubtypeCheck subklass superklass)); 12755 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12756 ins_cost(DEFAULT_COST*10); 12757 12758 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12759 ins_encode %{ 12760 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12761 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12762 $tmp_klass$$Register, NULL, $result$$Register); 12763 %} 12764 ins_pipe(pipe_class_default); 12765 %} 12766 12767 // inlined locking and unlocking 12768 12769 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12770 match(Set crx (FastLock oop box)); 12771 effect(TEMP tmp1, TEMP tmp2); 12772 predicate(!Compile::current()->use_rtm()); 12773 12774 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12775 ins_encode %{ 12776 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12777 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12778 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12779 UseBiasedLocking && !UseOptoBiasInlining); 12780 // If locking was successfull, crx should indicate 'EQ'. 12781 // The compiler generates a branch to the runtime call to 12782 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12783 %} 12784 ins_pipe(pipe_class_compare); 12785 %} 12786 12787 // Separate version for TM. Use bound register for box to enable USE_KILL. 12788 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12789 match(Set crx (FastLock oop box)); 12790 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12791 predicate(Compile::current()->use_rtm()); 12792 12793 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12794 ins_encode %{ 12795 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12796 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12797 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12798 /*Biased Locking*/ false, 12799 _rtm_counters, _stack_rtm_counters, 12800 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12801 /*TM*/ true, ra_->C->profile_rtm()); 12802 // If locking was successfull, crx should indicate 'EQ'. 12803 // The compiler generates a branch to the runtime call to 12804 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12805 %} 12806 ins_pipe(pipe_class_compare); 12807 %} 12808 12809 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12810 match(Set crx (FastUnlock oop box)); 12811 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12812 predicate(!Compile::current()->use_rtm()); 12813 12814 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12815 ins_encode %{ 12816 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12817 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12818 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12819 UseBiasedLocking && !UseOptoBiasInlining, 12820 false); 12821 // If unlocking was successfull, crx should indicate 'EQ'. 12822 // The compiler generates a branch to the runtime call to 12823 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12824 %} 12825 ins_pipe(pipe_class_compare); 12826 %} 12827 12828 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12829 match(Set crx (FastUnlock oop box)); 12830 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12831 predicate(Compile::current()->use_rtm()); 12832 12833 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12834 ins_encode %{ 12835 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12836 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12837 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12838 /*Biased Locking*/ false, /*TM*/ true); 12839 // If unlocking was successfull, crx should indicate 'EQ'. 12840 // The compiler generates a branch to the runtime call to 12841 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12842 %} 12843 ins_pipe(pipe_class_compare); 12844 %} 12845 12846 // Align address. 12847 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12848 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12849 12850 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12851 size(4); 12852 ins_encode %{ 12853 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12854 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12855 %} 12856 ins_pipe(pipe_class_default); 12857 %} 12858 12859 // Array size computation. 12860 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12861 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12862 12863 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12864 size(4); 12865 ins_encode %{ 12866 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12867 __ subf($dst$$Register, $start$$Register, $end$$Register); 12868 %} 12869 ins_pipe(pipe_class_default); 12870 %} 12871 12872 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12873 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12874 match(Set dummy (ClearArray cnt base)); 12875 effect(USE_KILL base, KILL ctr); 12876 ins_cost(2 * MEMORY_REF_COST); 12877 12878 format %{ "ClearArray $cnt, $base" %} 12879 ins_encode %{ 12880 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12881 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12882 %} 12883 ins_pipe(pipe_class_default); 12884 %} 12885 12886 // Clear-array with constant large array length. 12887 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12888 match(Set dummy (ClearArray cnt base)); 12889 effect(USE_KILL base, TEMP tmp, KILL ctr); 12890 ins_cost(3 * MEMORY_REF_COST); 12891 12892 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12893 ins_encode %{ 12894 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12895 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12896 %} 12897 ins_pipe(pipe_class_default); 12898 %} 12899 12900 // Clear-array with dynamic array length. 12901 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12902 match(Set dummy (ClearArray cnt base)); 12903 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12904 ins_cost(4 * MEMORY_REF_COST); 12905 12906 format %{ "ClearArray $cnt, $base" %} 12907 ins_encode %{ 12908 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12909 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12910 %} 12911 ins_pipe(pipe_class_default); 12912 %} 12913 12914 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12915 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12916 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12917 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12918 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12919 ins_cost(300); 12920 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12921 ins_encode %{ 12922 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12923 __ string_compare($str1$$Register, $str2$$Register, 12924 $cnt1$$Register, $cnt2$$Register, 12925 $tmp$$Register, 12926 $result$$Register, StrIntrinsicNode::LL); 12927 %} 12928 ins_pipe(pipe_class_default); 12929 %} 12930 12931 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12932 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12933 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12934 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12935 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12936 ins_cost(300); 12937 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12938 ins_encode %{ 12939 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12940 __ string_compare($str1$$Register, $str2$$Register, 12941 $cnt1$$Register, $cnt2$$Register, 12942 $tmp$$Register, 12943 $result$$Register, StrIntrinsicNode::UU); 12944 %} 12945 ins_pipe(pipe_class_default); 12946 %} 12947 12948 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12949 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12950 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12951 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12952 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12953 ins_cost(300); 12954 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12955 ins_encode %{ 12956 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12957 __ string_compare($str1$$Register, $str2$$Register, 12958 $cnt1$$Register, $cnt2$$Register, 12959 $tmp$$Register, 12960 $result$$Register, StrIntrinsicNode::LU); 12961 %} 12962 ins_pipe(pipe_class_default); 12963 %} 12964 12965 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12966 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12967 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12968 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12969 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12970 ins_cost(300); 12971 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12972 ins_encode %{ 12973 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12974 __ string_compare($str2$$Register, $str1$$Register, 12975 $cnt2$$Register, $cnt1$$Register, 12976 $tmp$$Register, 12977 $result$$Register, StrIntrinsicNode::UL); 12978 %} 12979 ins_pipe(pipe_class_default); 12980 %} 12981 12982 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12983 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12984 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12985 match(Set result (StrEquals (Binary str1 str2) cnt)); 12986 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12987 ins_cost(300); 12988 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12989 ins_encode %{ 12990 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12991 __ array_equals(false, $str1$$Register, $str2$$Register, 12992 $cnt$$Register, $tmp$$Register, 12993 $result$$Register, true /* byte */); 12994 %} 12995 ins_pipe(pipe_class_default); 12996 %} 12997 12998 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12999 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 13000 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 13001 match(Set result (StrEquals (Binary str1 str2) cnt)); 13002 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 13003 ins_cost(300); 13004 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 13005 ins_encode %{ 13006 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13007 __ array_equals(false, $str1$$Register, $str2$$Register, 13008 $cnt$$Register, $tmp$$Register, 13009 $result$$Register, false /* byte */); 13010 %} 13011 ins_pipe(pipe_class_default); 13012 %} 13013 13014 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 13015 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 13016 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 13017 match(Set result (AryEq ary1 ary2)); 13018 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 13019 ins_cost(300); 13020 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 13021 ins_encode %{ 13022 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13023 __ array_equals(true, $ary1$$Register, $ary2$$Register, 13024 $tmp1$$Register, $tmp2$$Register, 13025 $result$$Register, true /* byte */); 13026 %} 13027 ins_pipe(pipe_class_default); 13028 %} 13029 13030 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 13031 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 13032 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 13033 match(Set result (AryEq ary1 ary2)); 13034 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 13035 ins_cost(300); 13036 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 13037 ins_encode %{ 13038 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13039 __ array_equals(true, $ary1$$Register, $ary2$$Register, 13040 $tmp1$$Register, $tmp2$$Register, 13041 $result$$Register, false /* byte */); 13042 %} 13043 ins_pipe(pipe_class_default); 13044 %} 13045 13046 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13047 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13048 iRegIdst tmp1, iRegIdst tmp2, 13049 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13050 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13051 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13052 // Required for EA: check if it is still a type_array. 13053 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13054 ins_cost(150); 13055 13056 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13057 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13058 13059 ins_encode %{ 13060 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13061 immPOper *needleOper = (immPOper *)$needleImm; 13062 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13063 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13064 jchar chr; 13065 #ifdef VM_LITTLE_ENDIAN 13066 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 13067 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 13068 #else 13069 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 13070 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 13071 #endif 13072 __ string_indexof_char($result$$Register, 13073 $haystack$$Register, $haycnt$$Register, 13074 R0, chr, 13075 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13076 %} 13077 ins_pipe(pipe_class_compare); 13078 %} 13079 13080 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13081 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13082 iRegIdst tmp1, iRegIdst tmp2, 13083 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13084 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13085 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13086 // Required for EA: check if it is still a type_array. 13087 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13088 ins_cost(150); 13089 13090 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13091 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13092 13093 ins_encode %{ 13094 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13095 immPOper *needleOper = (immPOper *)$needleImm; 13096 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13097 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13098 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13099 __ string_indexof_char($result$$Register, 13100 $haystack$$Register, $haycnt$$Register, 13101 R0, chr, 13102 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13103 %} 13104 ins_pipe(pipe_class_compare); 13105 %} 13106 13107 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13108 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13109 iRegIdst tmp1, iRegIdst tmp2, 13110 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13111 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13112 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13113 // Required for EA: check if it is still a type_array. 13114 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13115 ins_cost(150); 13116 13117 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13118 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13119 13120 ins_encode %{ 13121 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13122 immPOper *needleOper = (immPOper *)$needleImm; 13123 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13124 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13125 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13126 __ string_indexof_char($result$$Register, 13127 $haystack$$Register, $haycnt$$Register, 13128 R0, chr, 13129 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13130 %} 13131 ins_pipe(pipe_class_compare); 13132 %} 13133 13134 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13135 rscratch2RegP needle, immI_1 needlecntImm, 13136 iRegIdst tmp1, iRegIdst tmp2, 13137 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13138 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13139 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13140 // Required for EA: check if it is still a type_array. 13141 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13142 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13143 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13144 ins_cost(180); 13145 13146 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13147 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13148 ins_encode %{ 13149 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13150 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13151 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13152 guarantee(needle_values, "sanity"); 13153 jchar chr; 13154 #ifdef VM_LITTLE_ENDIAN 13155 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 13156 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 13157 #else 13158 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 13159 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 13160 #endif 13161 __ string_indexof_char($result$$Register, 13162 $haystack$$Register, $haycnt$$Register, 13163 R0, chr, 13164 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13165 %} 13166 ins_pipe(pipe_class_compare); 13167 %} 13168 13169 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13170 rscratch2RegP needle, immI_1 needlecntImm, 13171 iRegIdst tmp1, iRegIdst tmp2, 13172 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13173 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13174 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13175 // Required for EA: check if it is still a type_array. 13176 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13177 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13178 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13179 ins_cost(180); 13180 13181 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13182 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13183 ins_encode %{ 13184 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13185 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13186 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13187 guarantee(needle_values, "sanity"); 13188 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13189 __ string_indexof_char($result$$Register, 13190 $haystack$$Register, $haycnt$$Register, 13191 R0, chr, 13192 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13193 %} 13194 ins_pipe(pipe_class_compare); 13195 %} 13196 13197 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13198 rscratch2RegP needle, immI_1 needlecntImm, 13199 iRegIdst tmp1, iRegIdst tmp2, 13200 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13201 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13202 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13203 // Required for EA: check if it is still a type_array. 13204 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13205 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13206 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13207 ins_cost(180); 13208 13209 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13210 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13211 ins_encode %{ 13212 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13213 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13214 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13215 guarantee(needle_values, "sanity"); 13216 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13217 __ string_indexof_char($result$$Register, 13218 $haystack$$Register, $haycnt$$Register, 13219 R0, chr, 13220 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13221 %} 13222 ins_pipe(pipe_class_compare); 13223 %} 13224 13225 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13226 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 13227 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13228 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 13229 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13230 ins_cost(180); 13231 13232 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 13233 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13234 ins_encode %{ 13235 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13236 __ string_indexof_char($result$$Register, 13237 $haystack$$Register, $haycnt$$Register, 13238 $ch$$Register, 0 /* this is not used if the character is already in a register */, 13239 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13240 %} 13241 ins_pipe(pipe_class_compare); 13242 %} 13243 13244 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13245 iRegPsrc needle, uimmI15 needlecntImm, 13246 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13247 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13248 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13249 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13250 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13251 // Required for EA: check if it is still a type_array. 13252 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13253 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13254 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13255 ins_cost(250); 13256 13257 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13258 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13259 ins_encode %{ 13260 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13261 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13262 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13263 13264 __ string_indexof($result$$Register, 13265 $haystack$$Register, $haycnt$$Register, 13266 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13267 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13268 %} 13269 ins_pipe(pipe_class_compare); 13270 %} 13271 13272 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13273 iRegPsrc needle, uimmI15 needlecntImm, 13274 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13275 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13276 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13277 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13278 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13279 // Required for EA: check if it is still a type_array. 13280 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13281 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13282 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13283 ins_cost(250); 13284 13285 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13286 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13287 ins_encode %{ 13288 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13289 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13290 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13291 13292 __ string_indexof($result$$Register, 13293 $haystack$$Register, $haycnt$$Register, 13294 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13295 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13296 %} 13297 ins_pipe(pipe_class_compare); 13298 %} 13299 13300 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13301 iRegPsrc needle, uimmI15 needlecntImm, 13302 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13303 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13304 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13305 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13306 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13307 // Required for EA: check if it is still a type_array. 13308 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13309 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13310 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13311 ins_cost(250); 13312 13313 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13314 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13315 ins_encode %{ 13316 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13317 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13318 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13319 13320 __ string_indexof($result$$Register, 13321 $haystack$$Register, $haycnt$$Register, 13322 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13323 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13324 %} 13325 ins_pipe(pipe_class_compare); 13326 %} 13327 13328 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13329 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13330 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13331 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13332 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13333 TEMP_DEF result, 13334 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13335 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13336 ins_cost(300); 13337 13338 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13339 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13340 ins_encode %{ 13341 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13342 __ string_indexof($result$$Register, 13343 $haystack$$Register, $haycnt$$Register, 13344 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13345 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13346 %} 13347 ins_pipe(pipe_class_compare); 13348 %} 13349 13350 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13351 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13352 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13353 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13354 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13355 TEMP_DEF result, 13356 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13357 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13358 ins_cost(300); 13359 13360 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13361 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13362 ins_encode %{ 13363 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13364 __ string_indexof($result$$Register, 13365 $haystack$$Register, $haycnt$$Register, 13366 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13367 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13368 %} 13369 ins_pipe(pipe_class_compare); 13370 %} 13371 13372 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13373 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13374 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13375 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13376 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13377 TEMP_DEF result, 13378 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13379 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13380 ins_cost(300); 13381 13382 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13383 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13384 ins_encode %{ 13385 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13386 __ string_indexof($result$$Register, 13387 $haystack$$Register, $haycnt$$Register, 13388 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13389 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13390 %} 13391 ins_pipe(pipe_class_compare); 13392 %} 13393 13394 // char[] to byte[] compression 13395 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13396 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13397 match(Set result (StrCompressedCopy src (Binary dst len))); 13398 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13399 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13400 ins_cost(300); 13401 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13402 ins_encode %{ 13403 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13404 Label Lskip, Ldone; 13405 __ li($result$$Register, 0); 13406 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13407 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13408 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13409 __ beq(CCR0, Lskip); 13410 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13411 __ bind(Lskip); 13412 __ mr($result$$Register, $len$$Register); 13413 __ bind(Ldone); 13414 %} 13415 ins_pipe(pipe_class_default); 13416 %} 13417 13418 // byte[] to char[] inflation 13419 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13420 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13421 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13422 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13423 ins_cost(300); 13424 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13425 ins_encode %{ 13426 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13427 Label Ldone; 13428 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13429 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13430 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13431 __ beq(CCR0, Ldone); 13432 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13433 __ bind(Ldone); 13434 %} 13435 ins_pipe(pipe_class_default); 13436 %} 13437 13438 // StringCoding.java intrinsics 13439 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13440 regCTR ctr, flagsRegCR0 cr0) 13441 %{ 13442 match(Set result (HasNegatives ary1 len)); 13443 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13444 ins_cost(300); 13445 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13446 ins_encode %{ 13447 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13448 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13449 $tmp1$$Register, $tmp2$$Register); 13450 %} 13451 ins_pipe(pipe_class_default); 13452 %} 13453 13454 // encode char[] to byte[] in ISO_8859_1 13455 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13456 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13457 match(Set result (EncodeISOArray src (Binary dst len))); 13458 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13459 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13460 ins_cost(300); 13461 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13462 ins_encode %{ 13463 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13464 Label Lslow, Lfailure1, Lfailure2, Ldone; 13465 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13466 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13467 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13468 __ beq(CCR0, Ldone); 13469 __ bind(Lslow); 13470 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13471 __ li($result$$Register, 0); 13472 __ b(Ldone); 13473 13474 __ bind(Lfailure1); 13475 __ mr($result$$Register, $len$$Register); 13476 __ mfctr($tmp1$$Register); 13477 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13478 __ beq(CCR0, Ldone); 13479 __ b(Lslow); 13480 13481 __ bind(Lfailure2); 13482 __ mfctr($result$$Register); // Remaining characters. 13483 13484 __ bind(Ldone); 13485 __ subf($result$$Register, $result$$Register, $len$$Register); 13486 %} 13487 ins_pipe(pipe_class_default); 13488 %} 13489 13490 13491 //---------- Min/Max Instructions --------------------------------------------- 13492 13493 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13494 match(Set dst (MinI src1 src2)); 13495 ins_cost(DEFAULT_COST*6); 13496 13497 expand %{ 13498 iRegLdst src1s; 13499 iRegLdst src2s; 13500 iRegLdst diff; 13501 iRegLdst sm; 13502 iRegLdst doz; // difference or zero 13503 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13504 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13505 subL_reg_reg(diff, src2s, src1s); 13506 // Need to consider >=33 bit result, therefore we need signmaskL. 13507 signmask64L_regL(sm, diff); 13508 andL_reg_reg(doz, diff, sm); // <=0 13509 addI_regL_regL(dst, doz, src1s); 13510 %} 13511 %} 13512 13513 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13514 match(Set dst (MinI src1 src2)); 13515 effect(KILL cr0); 13516 predicate(VM_Version::has_isel()); 13517 ins_cost(DEFAULT_COST*2); 13518 13519 ins_encode %{ 13520 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13521 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13522 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13523 %} 13524 ins_pipe(pipe_class_default); 13525 %} 13526 13527 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13528 match(Set dst (MaxI src1 src2)); 13529 ins_cost(DEFAULT_COST*6); 13530 13531 expand %{ 13532 iRegLdst src1s; 13533 iRegLdst src2s; 13534 iRegLdst diff; 13535 iRegLdst sm; 13536 iRegLdst doz; // difference or zero 13537 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13538 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13539 subL_reg_reg(diff, src2s, src1s); 13540 // Need to consider >=33 bit result, therefore we need signmaskL. 13541 signmask64L_regL(sm, diff); 13542 andcL_reg_reg(doz, diff, sm); // >=0 13543 addI_regL_regL(dst, doz, src1s); 13544 %} 13545 %} 13546 13547 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13548 match(Set dst (MaxI src1 src2)); 13549 effect(KILL cr0); 13550 predicate(VM_Version::has_isel()); 13551 ins_cost(DEFAULT_COST*2); 13552 13553 ins_encode %{ 13554 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13555 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13556 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13557 %} 13558 ins_pipe(pipe_class_default); 13559 %} 13560 13561 //---------- Population Count Instructions ------------------------------------ 13562 13563 // Popcnt for Power7. 13564 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13565 match(Set dst (PopCountI src)); 13566 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13567 ins_cost(DEFAULT_COST); 13568 13569 format %{ "POPCNTW $dst, $src" %} 13570 size(4); 13571 ins_encode %{ 13572 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13573 __ popcntw($dst$$Register, $src$$Register); 13574 %} 13575 ins_pipe(pipe_class_default); 13576 %} 13577 13578 // Popcnt for Power7. 13579 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13580 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13581 match(Set dst (PopCountL src)); 13582 ins_cost(DEFAULT_COST); 13583 13584 format %{ "POPCNTD $dst, $src" %} 13585 size(4); 13586 ins_encode %{ 13587 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13588 __ popcntd($dst$$Register, $src$$Register); 13589 %} 13590 ins_pipe(pipe_class_default); 13591 %} 13592 13593 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13594 match(Set dst (CountLeadingZerosI src)); 13595 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13596 ins_cost(DEFAULT_COST); 13597 13598 format %{ "CNTLZW $dst, $src" %} 13599 size(4); 13600 ins_encode %{ 13601 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13602 __ cntlzw($dst$$Register, $src$$Register); 13603 %} 13604 ins_pipe(pipe_class_default); 13605 %} 13606 13607 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13608 match(Set dst (CountLeadingZerosL src)); 13609 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13610 ins_cost(DEFAULT_COST); 13611 13612 format %{ "CNTLZD $dst, $src" %} 13613 size(4); 13614 ins_encode %{ 13615 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13616 __ cntlzd($dst$$Register, $src$$Register); 13617 %} 13618 ins_pipe(pipe_class_default); 13619 %} 13620 13621 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13622 // no match-rule, false predicate 13623 effect(DEF dst, USE src); 13624 predicate(false); 13625 13626 format %{ "CNTLZD $dst, $src" %} 13627 size(4); 13628 ins_encode %{ 13629 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13630 __ cntlzd($dst$$Register, $src$$Register); 13631 %} 13632 ins_pipe(pipe_class_default); 13633 %} 13634 13635 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13636 match(Set dst (CountTrailingZerosI src)); 13637 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13638 ins_cost(DEFAULT_COST); 13639 13640 expand %{ 13641 immI16 imm1 %{ (int)-1 %} 13642 immI16 imm2 %{ (int)32 %} 13643 immI_minus1 m1 %{ -1 %} 13644 iRegIdst tmpI1; 13645 iRegIdst tmpI2; 13646 iRegIdst tmpI3; 13647 addI_reg_imm16(tmpI1, src, imm1); 13648 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13649 countLeadingZerosI(tmpI3, tmpI2); 13650 subI_imm16_reg(dst, imm2, tmpI3); 13651 %} 13652 %} 13653 13654 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{ 13655 match(Set dst (CountTrailingZerosI src)); 13656 predicate(UseCountTrailingZerosInstructionsPPC64); 13657 ins_cost(DEFAULT_COST); 13658 13659 format %{ "CNTTZW $dst, $src" %} 13660 size(4); 13661 ins_encode %{ 13662 __ cnttzw($dst$$Register, $src$$Register); 13663 %} 13664 ins_pipe(pipe_class_default); 13665 %} 13666 13667 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13668 match(Set dst (CountTrailingZerosL src)); 13669 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13670 ins_cost(DEFAULT_COST); 13671 13672 expand %{ 13673 immL16 imm1 %{ (long)-1 %} 13674 immI16 imm2 %{ (int)64 %} 13675 iRegLdst tmpL1; 13676 iRegLdst tmpL2; 13677 iRegIdst tmpL3; 13678 addL_reg_imm16(tmpL1, src, imm1); 13679 andcL_reg_reg(tmpL2, tmpL1, src); 13680 countLeadingZerosL(tmpL3, tmpL2); 13681 subI_imm16_reg(dst, imm2, tmpL3); 13682 %} 13683 %} 13684 13685 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{ 13686 match(Set dst (CountTrailingZerosL src)); 13687 predicate(UseCountTrailingZerosInstructionsPPC64); 13688 ins_cost(DEFAULT_COST); 13689 13690 format %{ "CNTTZD $dst, $src" %} 13691 size(4); 13692 ins_encode %{ 13693 __ cnttzd($dst$$Register, $src$$Register); 13694 %} 13695 ins_pipe(pipe_class_default); 13696 %} 13697 13698 // Expand nodes for byte_reverse_int. 13699 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13700 effect(DEF dst, USE src, USE pos, USE shift); 13701 predicate(false); 13702 13703 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13704 size(4); 13705 ins_encode %{ 13706 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13707 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13708 %} 13709 ins_pipe(pipe_class_default); 13710 %} 13711 13712 // As insrwi_a, but with USE_DEF. 13713 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13714 effect(USE_DEF dst, USE src, USE pos, USE shift); 13715 predicate(false); 13716 13717 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13718 size(4); 13719 ins_encode %{ 13720 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13721 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13722 %} 13723 ins_pipe(pipe_class_default); 13724 %} 13725 13726 // Just slightly faster than java implementation. 13727 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13728 match(Set dst (ReverseBytesI src)); 13729 ins_cost(7*DEFAULT_COST); 13730 13731 expand %{ 13732 immI16 imm24 %{ (int) 24 %} 13733 immI16 imm16 %{ (int) 16 %} 13734 immI16 imm8 %{ (int) 8 %} 13735 immI16 imm4 %{ (int) 4 %} 13736 immI16 imm0 %{ (int) 0 %} 13737 iRegLdst tmpI1; 13738 iRegLdst tmpI2; 13739 iRegLdst tmpI3; 13740 13741 urShiftI_reg_imm(tmpI1, src, imm24); 13742 insrwi_a(dst, tmpI1, imm24, imm8); 13743 urShiftI_reg_imm(tmpI2, src, imm16); 13744 insrwi(dst, tmpI2, imm8, imm16); 13745 urShiftI_reg_imm(tmpI3, src, imm8); 13746 insrwi(dst, tmpI3, imm8, imm8); 13747 insrwi(dst, src, imm0, imm8); 13748 %} 13749 %} 13750 13751 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{ 13752 match(Set dst (ReverseBytesI src)); 13753 predicate(UseVectorByteReverseInstructionsPPC64); 13754 effect(TEMP tmpV); 13755 ins_cost(DEFAULT_COST*3); 13756 size(12); 13757 format %{ "MTVSRWZ $tmpV, $src\n" 13758 "\tXXBRW $tmpV, $tmpV\n" 13759 "\tMFVSRWZ $dst, $tmpV" %} 13760 13761 ins_encode %{ 13762 __ mtvsrwz($tmpV$$VectorSRegister, $src$$Register); 13763 __ xxbrw($tmpV$$VectorSRegister, $tmpV$$VectorSRegister); 13764 __ mfvsrwz($dst$$Register, $tmpV$$VectorSRegister); 13765 %} 13766 ins_pipe(pipe_class_default); 13767 %} 13768 13769 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13770 match(Set dst (ReverseBytesL src)); 13771 ins_cost(15*DEFAULT_COST); 13772 13773 expand %{ 13774 immI16 imm56 %{ (int) 56 %} 13775 immI16 imm48 %{ (int) 48 %} 13776 immI16 imm40 %{ (int) 40 %} 13777 immI16 imm32 %{ (int) 32 %} 13778 immI16 imm24 %{ (int) 24 %} 13779 immI16 imm16 %{ (int) 16 %} 13780 immI16 imm8 %{ (int) 8 %} 13781 immI16 imm0 %{ (int) 0 %} 13782 iRegLdst tmpL1; 13783 iRegLdst tmpL2; 13784 iRegLdst tmpL3; 13785 iRegLdst tmpL4; 13786 iRegLdst tmpL5; 13787 iRegLdst tmpL6; 13788 13789 // src : |a|b|c|d|e|f|g|h| 13790 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13791 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13792 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13793 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13794 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13795 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13796 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13797 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13798 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13799 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13800 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13801 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13802 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13803 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13804 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13805 %} 13806 %} 13807 13808 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{ 13809 match(Set dst (ReverseBytesL src)); 13810 predicate(UseVectorByteReverseInstructionsPPC64); 13811 effect(TEMP tmpV); 13812 ins_cost(DEFAULT_COST*3); 13813 size(12); 13814 format %{ "MTVSRD $tmpV, $src\n" 13815 "\tXXBRD $tmpV, $tmpV\n" 13816 "\tMFVSRD $dst, $tmpV" %} 13817 13818 ins_encode %{ 13819 __ mtvsrd($tmpV$$VectorSRegister, $src$$Register); 13820 __ xxbrd($tmpV$$VectorSRegister, $tmpV$$VectorSRegister); 13821 __ mfvsrd($dst$$Register, $tmpV$$VectorSRegister); 13822 %} 13823 ins_pipe(pipe_class_default); 13824 %} 13825 13826 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13827 match(Set dst (ReverseBytesUS src)); 13828 ins_cost(2*DEFAULT_COST); 13829 13830 expand %{ 13831 immI16 imm16 %{ (int) 16 %} 13832 immI16 imm8 %{ (int) 8 %} 13833 13834 urShiftI_reg_imm(dst, src, imm8); 13835 insrwi(dst, src, imm16, imm8); 13836 %} 13837 %} 13838 13839 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13840 match(Set dst (ReverseBytesS src)); 13841 ins_cost(3*DEFAULT_COST); 13842 13843 expand %{ 13844 immI16 imm16 %{ (int) 16 %} 13845 immI16 imm8 %{ (int) 8 %} 13846 iRegLdst tmpI1; 13847 13848 urShiftI_reg_imm(tmpI1, src, imm8); 13849 insrwi(tmpI1, src, imm16, imm8); 13850 extsh(dst, tmpI1); 13851 %} 13852 %} 13853 13854 // Load Integer reversed byte order 13855 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13856 match(Set dst (ReverseBytesI (LoadI mem))); 13857 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13858 ins_cost(MEMORY_REF_COST); 13859 13860 size(4); 13861 ins_encode %{ 13862 __ lwbrx($dst$$Register, $mem$$Register); 13863 %} 13864 ins_pipe(pipe_class_default); 13865 %} 13866 13867 instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{ 13868 match(Set dst (ReverseBytesI (LoadI mem))); 13869 ins_cost(2 * MEMORY_REF_COST); 13870 13871 size(12); 13872 ins_encode %{ 13873 __ lwbrx($dst$$Register, $mem$$Register); 13874 __ twi_0($dst$$Register); 13875 __ isync(); 13876 %} 13877 ins_pipe(pipe_class_default); 13878 %} 13879 13880 // Load Long - aligned and reversed 13881 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13882 match(Set dst (ReverseBytesL (LoadL mem))); 13883 predicate(VM_Version::has_ldbrx() && (n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)))); 13884 ins_cost(MEMORY_REF_COST); 13885 13886 size(4); 13887 ins_encode %{ 13888 __ ldbrx($dst$$Register, $mem$$Register); 13889 %} 13890 ins_pipe(pipe_class_default); 13891 %} 13892 13893 instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{ 13894 match(Set dst (ReverseBytesL (LoadL mem))); 13895 predicate(VM_Version::has_ldbrx()); 13896 ins_cost(2 * MEMORY_REF_COST); 13897 13898 size(12); 13899 ins_encode %{ 13900 __ ldbrx($dst$$Register, $mem$$Register); 13901 __ twi_0($dst$$Register); 13902 __ isync(); 13903 %} 13904 ins_pipe(pipe_class_default); 13905 %} 13906 13907 // Load unsigned short / char reversed byte order 13908 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13909 match(Set dst (ReverseBytesUS (LoadUS mem))); 13910 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13911 ins_cost(MEMORY_REF_COST); 13912 13913 size(4); 13914 ins_encode %{ 13915 __ lhbrx($dst$$Register, $mem$$Register); 13916 %} 13917 ins_pipe(pipe_class_default); 13918 %} 13919 13920 instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{ 13921 match(Set dst (ReverseBytesUS (LoadUS mem))); 13922 ins_cost(2 * MEMORY_REF_COST); 13923 13924 size(12); 13925 ins_encode %{ 13926 __ lhbrx($dst$$Register, $mem$$Register); 13927 __ twi_0($dst$$Register); 13928 __ isync(); 13929 %} 13930 ins_pipe(pipe_class_default); 13931 %} 13932 13933 // Load short reversed byte order 13934 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13935 match(Set dst (ReverseBytesS (LoadS mem))); 13936 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13937 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13938 13939 size(8); 13940 ins_encode %{ 13941 __ lhbrx($dst$$Register, $mem$$Register); 13942 __ extsh($dst$$Register, $dst$$Register); 13943 %} 13944 ins_pipe(pipe_class_default); 13945 %} 13946 13947 instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{ 13948 match(Set dst (ReverseBytesS (LoadS mem))); 13949 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13950 13951 size(16); 13952 ins_encode %{ 13953 __ lhbrx($dst$$Register, $mem$$Register); 13954 __ twi_0($dst$$Register); 13955 __ extsh($dst$$Register, $dst$$Register); 13956 __ isync(); 13957 %} 13958 ins_pipe(pipe_class_default); 13959 %} 13960 13961 // Store Integer reversed byte order 13962 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13963 match(Set mem (StoreI mem (ReverseBytesI src))); 13964 ins_cost(MEMORY_REF_COST); 13965 13966 size(4); 13967 ins_encode %{ 13968 __ stwbrx($src$$Register, $mem$$Register); 13969 %} 13970 ins_pipe(pipe_class_default); 13971 %} 13972 13973 // Store Long reversed byte order 13974 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13975 match(Set mem (StoreL mem (ReverseBytesL src))); 13976 predicate(VM_Version::has_stdbrx()); 13977 ins_cost(MEMORY_REF_COST); 13978 13979 size(4); 13980 ins_encode %{ 13981 __ stdbrx($src$$Register, $mem$$Register); 13982 %} 13983 ins_pipe(pipe_class_default); 13984 %} 13985 13986 // Store unsigned short / char reversed byte order 13987 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13988 match(Set mem (StoreC mem (ReverseBytesUS src))); 13989 ins_cost(MEMORY_REF_COST); 13990 13991 size(4); 13992 ins_encode %{ 13993 __ sthbrx($src$$Register, $mem$$Register); 13994 %} 13995 ins_pipe(pipe_class_default); 13996 %} 13997 13998 // Store short reversed byte order 13999 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 14000 match(Set mem (StoreC mem (ReverseBytesS src))); 14001 ins_cost(MEMORY_REF_COST); 14002 14003 size(4); 14004 ins_encode %{ 14005 __ sthbrx($src$$Register, $mem$$Register); 14006 %} 14007 ins_pipe(pipe_class_default); 14008 %} 14009 14010 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 14011 effect(DEF temp1, USE src); 14012 14013 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %} 14014 size(4); 14015 ins_encode %{ 14016 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 14017 %} 14018 ins_pipe(pipe_class_default); 14019 %} 14020 14021 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 14022 effect(DEF dst, USE src, USE imm1); 14023 14024 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %} 14025 size(4); 14026 ins_encode %{ 14027 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 14028 %} 14029 ins_pipe(pipe_class_default); 14030 %} 14031 14032 instruct xscvdpspn_regF(vecX dst, regF src) %{ 14033 effect(DEF dst, USE src); 14034 14035 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %} 14036 size(4); 14037 ins_encode %{ 14038 __ xscvdpspn($dst$$VectorSRegister, $src$$FloatRegister->to_vsr()); 14039 %} 14040 ins_pipe(pipe_class_default); 14041 %} 14042 14043 //---------- Replicate Vector Instructions ------------------------------------ 14044 14045 // Insrdi does replicate if src == dst. 14046 instruct repl32(iRegLdst dst) %{ 14047 predicate(false); 14048 effect(USE_DEF dst); 14049 14050 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 14051 size(4); 14052 ins_encode %{ 14053 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 14054 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 14055 %} 14056 ins_pipe(pipe_class_default); 14057 %} 14058 14059 // Insrdi does replicate if src == dst. 14060 instruct repl48(iRegLdst dst) %{ 14061 predicate(false); 14062 effect(USE_DEF dst); 14063 14064 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 14065 size(4); 14066 ins_encode %{ 14067 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 14068 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 14069 %} 14070 ins_pipe(pipe_class_default); 14071 %} 14072 14073 // Insrdi does replicate if src == dst. 14074 instruct repl56(iRegLdst dst) %{ 14075 predicate(false); 14076 effect(USE_DEF dst); 14077 14078 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 14079 size(4); 14080 ins_encode %{ 14081 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 14082 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 14083 %} 14084 ins_pipe(pipe_class_default); 14085 %} 14086 14087 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14088 match(Set dst (ReplicateB src)); 14089 predicate(n->as_Vector()->length() == 8); 14090 expand %{ 14091 moveReg(dst, src); 14092 repl56(dst); 14093 repl48(dst); 14094 repl32(dst); 14095 %} 14096 %} 14097 14098 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 14099 match(Set dst (ReplicateB zero)); 14100 predicate(n->as_Vector()->length() == 8); 14101 format %{ "LI $dst, #0 \t// replicate8B" %} 14102 size(4); 14103 ins_encode %{ 14104 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14105 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14106 %} 14107 ins_pipe(pipe_class_default); 14108 %} 14109 14110 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14111 match(Set dst (ReplicateB src)); 14112 predicate(n->as_Vector()->length() == 8); 14113 format %{ "LI $dst, #-1 \t// replicate8B" %} 14114 size(4); 14115 ins_encode %{ 14116 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14117 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14118 %} 14119 ins_pipe(pipe_class_default); 14120 %} 14121 14122 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 14123 match(Set dst (ReplicateB src)); 14124 predicate(n->as_Vector()->length() == 16); 14125 14126 expand %{ 14127 iRegLdst tmpL; 14128 vecX tmpV; 14129 immI8 imm1 %{ (int) 1 %} 14130 moveReg(tmpL, src); 14131 repl56(tmpL); 14132 repl48(tmpL); 14133 mtvsrwz(tmpV, tmpL); 14134 xxspltw(dst, tmpV, imm1); 14135 %} 14136 %} 14137 14138 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 14139 match(Set dst (ReplicateB zero)); 14140 predicate(n->as_Vector()->length() == 16); 14141 14142 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 14143 size(4); 14144 ins_encode %{ 14145 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14146 %} 14147 ins_pipe(pipe_class_default); 14148 %} 14149 14150 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 14151 match(Set dst (ReplicateB src)); 14152 predicate(n->as_Vector()->length() == 16); 14153 14154 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14155 size(4); 14156 ins_encode %{ 14157 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14158 %} 14159 ins_pipe(pipe_class_default); 14160 %} 14161 14162 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14163 match(Set dst (ReplicateS src)); 14164 predicate(n->as_Vector()->length() == 4); 14165 expand %{ 14166 moveReg(dst, src); 14167 repl48(dst); 14168 repl32(dst); 14169 %} 14170 %} 14171 14172 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 14173 match(Set dst (ReplicateS zero)); 14174 predicate(n->as_Vector()->length() == 4); 14175 format %{ "LI $dst, #0 \t// replicate4S" %} 14176 size(4); 14177 ins_encode %{ 14178 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14179 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14180 %} 14181 ins_pipe(pipe_class_default); 14182 %} 14183 14184 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14185 match(Set dst (ReplicateS src)); 14186 predicate(n->as_Vector()->length() == 4); 14187 format %{ "LI $dst, -1 \t// replicate4S" %} 14188 size(4); 14189 ins_encode %{ 14190 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14191 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14192 %} 14193 ins_pipe(pipe_class_default); 14194 %} 14195 14196 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 14197 match(Set dst (ReplicateS src)); 14198 predicate(n->as_Vector()->length() == 8); 14199 14200 expand %{ 14201 iRegLdst tmpL; 14202 vecX tmpV; 14203 immI8 zero %{ (int) 0 %} 14204 moveReg(tmpL, src); 14205 repl48(tmpL); 14206 repl32(tmpL); 14207 mtvsrd(tmpV, tmpL); 14208 xxpermdi(dst, tmpV, tmpV, zero); 14209 %} 14210 %} 14211 14212 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 14213 match(Set dst (ReplicateS zero)); 14214 predicate(n->as_Vector()->length() == 8); 14215 14216 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 14217 size(4); 14218 ins_encode %{ 14219 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14220 %} 14221 ins_pipe(pipe_class_default); 14222 %} 14223 14224 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 14225 match(Set dst (ReplicateS src)); 14226 predicate(n->as_Vector()->length() == 8); 14227 14228 format %{ "XXLEQV $dst, $src \t// replicate8S" %} 14229 size(4); 14230 ins_encode %{ 14231 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14232 %} 14233 ins_pipe(pipe_class_default); 14234 %} 14235 14236 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14237 match(Set dst (ReplicateI src)); 14238 predicate(n->as_Vector()->length() == 2); 14239 ins_cost(2 * DEFAULT_COST); 14240 expand %{ 14241 moveReg(dst, src); 14242 repl32(dst); 14243 %} 14244 %} 14245 14246 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 14247 match(Set dst (ReplicateI zero)); 14248 predicate(n->as_Vector()->length() == 2); 14249 format %{ "LI $dst, #0 \t// replicate2I" %} 14250 size(4); 14251 ins_encode %{ 14252 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14253 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14254 %} 14255 ins_pipe(pipe_class_default); 14256 %} 14257 14258 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14259 match(Set dst (ReplicateI src)); 14260 predicate(n->as_Vector()->length() == 2); 14261 format %{ "LI $dst, -1 \t// replicate2I" %} 14262 size(4); 14263 ins_encode %{ 14264 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14265 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14266 %} 14267 ins_pipe(pipe_class_default); 14268 %} 14269 14270 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 14271 match(Set dst (ReplicateI src)); 14272 predicate(n->as_Vector()->length() == 4); 14273 ins_cost(2 * DEFAULT_COST); 14274 14275 expand %{ 14276 iRegLdst tmpL; 14277 vecX tmpV; 14278 immI8 zero %{ (int) 0 %} 14279 moveReg(tmpL, src); 14280 repl32(tmpL); 14281 mtvsrd(tmpV, tmpL); 14282 xxpermdi(dst, tmpV, tmpV, zero); 14283 %} 14284 %} 14285 14286 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 14287 match(Set dst (ReplicateI zero)); 14288 predicate(n->as_Vector()->length() == 4); 14289 14290 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 14291 size(4); 14292 ins_encode %{ 14293 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14294 %} 14295 ins_pipe(pipe_class_default); 14296 %} 14297 14298 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 14299 match(Set dst (ReplicateI src)); 14300 predicate(n->as_Vector()->length() == 4); 14301 14302 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 14303 size(4); 14304 ins_encode %{ 14305 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14306 %} 14307 ins_pipe(pipe_class_default); 14308 %} 14309 14310 // Move float to int register via stack, replicate. 14311 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 14312 match(Set dst (ReplicateF src)); 14313 predicate(n->as_Vector()->length() == 2); 14314 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14315 expand %{ 14316 stackSlotL tmpS; 14317 iRegIdst tmpI; 14318 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14319 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14320 moveReg(dst, tmpI); // Move int to long reg. 14321 repl32(dst); // Replicate bitpattern. 14322 %} 14323 %} 14324 14325 // Replicate scalar constant to packed float values in Double register 14326 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 14327 match(Set dst (ReplicateF src)); 14328 predicate(n->as_Vector()->length() == 2); 14329 ins_cost(5 * DEFAULT_COST); 14330 14331 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 14332 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 14333 %} 14334 14335 // Replicate scalar zero constant to packed float values in Double register 14336 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 14337 match(Set dst (ReplicateF zero)); 14338 predicate(n->as_Vector()->length() == 2); 14339 14340 format %{ "LI $dst, #0 \t// replicate2F" %} 14341 ins_encode %{ 14342 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14343 __ li($dst$$Register, 0x0); 14344 %} 14345 ins_pipe(pipe_class_default); 14346 %} 14347 14348 14349 //----------Vector Arithmetic Instructions-------------------------------------- 14350 14351 // Vector Addition Instructions 14352 14353 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{ 14354 match(Set dst (AddVB src1 src2)); 14355 predicate(n->as_Vector()->length() == 16); 14356 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %} 14357 size(4); 14358 ins_encode %{ 14359 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14360 %} 14361 ins_pipe(pipe_class_default); 14362 %} 14363 14364 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{ 14365 match(Set dst (AddVS src1 src2)); 14366 predicate(n->as_Vector()->length() == 8); 14367 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %} 14368 size(4); 14369 ins_encode %{ 14370 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14371 %} 14372 ins_pipe(pipe_class_default); 14373 %} 14374 14375 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{ 14376 match(Set dst (AddVI src1 src2)); 14377 predicate(n->as_Vector()->length() == 4); 14378 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %} 14379 size(4); 14380 ins_encode %{ 14381 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14382 %} 14383 ins_pipe(pipe_class_default); 14384 %} 14385 14386 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{ 14387 match(Set dst (AddVF src1 src2)); 14388 predicate(n->as_Vector()->length() == 4); 14389 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %} 14390 size(4); 14391 ins_encode %{ 14392 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14393 %} 14394 ins_pipe(pipe_class_default); 14395 %} 14396 14397 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{ 14398 match(Set dst (AddVL src1 src2)); 14399 predicate(n->as_Vector()->length() == 2); 14400 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %} 14401 size(4); 14402 ins_encode %{ 14403 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14404 %} 14405 ins_pipe(pipe_class_default); 14406 %} 14407 14408 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{ 14409 match(Set dst (AddVD src1 src2)); 14410 predicate(n->as_Vector()->length() == 2); 14411 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %} 14412 size(4); 14413 ins_encode %{ 14414 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14415 %} 14416 ins_pipe(pipe_class_default); 14417 %} 14418 14419 // Vector Subtraction Instructions 14420 14421 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{ 14422 match(Set dst (SubVB src1 src2)); 14423 predicate(n->as_Vector()->length() == 16); 14424 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %} 14425 size(4); 14426 ins_encode %{ 14427 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14428 %} 14429 ins_pipe(pipe_class_default); 14430 %} 14431 14432 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{ 14433 match(Set dst (SubVS src1 src2)); 14434 predicate(n->as_Vector()->length() == 8); 14435 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %} 14436 size(4); 14437 ins_encode %{ 14438 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14439 %} 14440 ins_pipe(pipe_class_default); 14441 %} 14442 14443 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{ 14444 match(Set dst (SubVI src1 src2)); 14445 predicate(n->as_Vector()->length() == 4); 14446 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %} 14447 size(4); 14448 ins_encode %{ 14449 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14450 %} 14451 ins_pipe(pipe_class_default); 14452 %} 14453 14454 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{ 14455 match(Set dst (SubVF src1 src2)); 14456 predicate(n->as_Vector()->length() == 4); 14457 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %} 14458 size(4); 14459 ins_encode %{ 14460 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14461 %} 14462 ins_pipe(pipe_class_default); 14463 %} 14464 14465 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{ 14466 match(Set dst (SubVL src1 src2)); 14467 predicate(n->as_Vector()->length() == 2); 14468 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %} 14469 size(4); 14470 ins_encode %{ 14471 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14472 %} 14473 ins_pipe(pipe_class_default); 14474 %} 14475 14476 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{ 14477 match(Set dst (SubVD src1 src2)); 14478 predicate(n->as_Vector()->length() == 2); 14479 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %} 14480 size(4); 14481 ins_encode %{ 14482 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14483 %} 14484 ins_pipe(pipe_class_default); 14485 %} 14486 14487 // Vector Multiplication Instructions 14488 14489 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 14490 match(Set dst (MulVS src1 src2)); 14491 predicate(n->as_Vector()->length() == 8); 14492 effect(TEMP tmp); 14493 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %} 14494 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %} 14495 size(8); 14496 ins_encode %{ 14497 __ vspltish($tmp$$VectorSRegister->to_vr(), 0); 14498 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr()); 14499 %} 14500 ins_pipe(pipe_class_default); 14501 %} 14502 14503 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{ 14504 match(Set dst (MulVI src1 src2)); 14505 predicate(n->as_Vector()->length() == 4); 14506 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %} 14507 size(4); 14508 ins_encode %{ 14509 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14510 %} 14511 ins_pipe(pipe_class_default); 14512 %} 14513 14514 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{ 14515 match(Set dst (MulVF src1 src2)); 14516 predicate(n->as_Vector()->length() == 4); 14517 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %} 14518 size(4); 14519 ins_encode %{ 14520 __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14521 %} 14522 ins_pipe(pipe_class_default); 14523 %} 14524 14525 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{ 14526 match(Set dst (MulVD src1 src2)); 14527 predicate(n->as_Vector()->length() == 2); 14528 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %} 14529 size(4); 14530 ins_encode %{ 14531 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14532 %} 14533 ins_pipe(pipe_class_default); 14534 %} 14535 14536 // Vector Division Instructions 14537 14538 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{ 14539 match(Set dst (DivVF src1 src2)); 14540 predicate(n->as_Vector()->length() == 4); 14541 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %} 14542 size(4); 14543 ins_encode %{ 14544 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14545 %} 14546 ins_pipe(pipe_class_default); 14547 %} 14548 14549 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ 14550 match(Set dst (DivVD src1 src2)); 14551 predicate(n->as_Vector()->length() == 2); 14552 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %} 14553 size(4); 14554 ins_encode %{ 14555 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14556 %} 14557 ins_pipe(pipe_class_default); 14558 %} 14559 14560 // Vector Absolute Instructions 14561 14562 instruct vabs4F_reg(vecX dst, vecX src) %{ 14563 match(Set dst (AbsVF src)); 14564 predicate(n->as_Vector()->length() == 4); 14565 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %} 14566 size(4); 14567 ins_encode %{ 14568 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister); 14569 %} 14570 ins_pipe(pipe_class_default); 14571 %} 14572 14573 instruct vabs2D_reg(vecX dst, vecX src) %{ 14574 match(Set dst (AbsVD src)); 14575 predicate(n->as_Vector()->length() == 2); 14576 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %} 14577 size(4); 14578 ins_encode %{ 14579 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister); 14580 %} 14581 ins_pipe(pipe_class_default); 14582 %} 14583 14584 // Round Instructions 14585 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{ 14586 match(Set dst (RoundDoubleMode src rmode)); 14587 format %{ "RoundDoubleMode $src,$rmode" %} 14588 size(4); 14589 ins_encode %{ 14590 switch ($rmode$$constant) { 14591 case RoundDoubleModeNode::rmode_rint: 14592 __ frin($dst$$FloatRegister, $src$$FloatRegister); 14593 break; 14594 case RoundDoubleModeNode::rmode_floor: 14595 __ frim($dst$$FloatRegister, $src$$FloatRegister); 14596 break; 14597 case RoundDoubleModeNode::rmode_ceil: 14598 __ frip($dst$$FloatRegister, $src$$FloatRegister); 14599 break; 14600 default: 14601 ShouldNotReachHere(); 14602 } 14603 %} 14604 ins_pipe(pipe_class_default); 14605 %} 14606 14607 // Vector Round Instructions 14608 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{ 14609 match(Set dst (RoundDoubleModeV src rmode)); 14610 predicate(n->as_Vector()->length() == 2); 14611 format %{ "RoundDoubleModeV $src,$rmode" %} 14612 size(4); 14613 ins_encode %{ 14614 switch ($rmode$$constant) { 14615 case RoundDoubleModeNode::rmode_rint: 14616 __ xvrdpi($dst$$VectorSRegister, $src$$VectorSRegister); 14617 break; 14618 case RoundDoubleModeNode::rmode_floor: 14619 __ xvrdpim($dst$$VectorSRegister, $src$$VectorSRegister); 14620 break; 14621 case RoundDoubleModeNode::rmode_ceil: 14622 __ xvrdpip($dst$$VectorSRegister, $src$$VectorSRegister); 14623 break; 14624 default: 14625 ShouldNotReachHere(); 14626 } 14627 %} 14628 ins_pipe(pipe_class_default); 14629 %} 14630 14631 // Vector Negate Instructions 14632 14633 instruct vneg4F_reg(vecX dst, vecX src) %{ 14634 match(Set dst (NegVF src)); 14635 predicate(n->as_Vector()->length() == 4); 14636 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %} 14637 size(4); 14638 ins_encode %{ 14639 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister); 14640 %} 14641 ins_pipe(pipe_class_default); 14642 %} 14643 14644 instruct vneg2D_reg(vecX dst, vecX src) %{ 14645 match(Set dst (NegVD src)); 14646 predicate(n->as_Vector()->length() == 2); 14647 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %} 14648 size(4); 14649 ins_encode %{ 14650 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister); 14651 %} 14652 ins_pipe(pipe_class_default); 14653 %} 14654 14655 // Vector Square Root Instructions 14656 14657 instruct vsqrt4F_reg(vecX dst, vecX src) %{ 14658 match(Set dst (SqrtVF src)); 14659 predicate(n->as_Vector()->length() == 4); 14660 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %} 14661 size(4); 14662 ins_encode %{ 14663 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister); 14664 %} 14665 ins_pipe(pipe_class_default); 14666 %} 14667 14668 instruct vsqrt2D_reg(vecX dst, vecX src) %{ 14669 match(Set dst (SqrtVD src)); 14670 predicate(n->as_Vector()->length() == 2); 14671 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %} 14672 size(4); 14673 ins_encode %{ 14674 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister); 14675 %} 14676 ins_pipe(pipe_class_default); 14677 %} 14678 14679 // Vector Population Count Instructions 14680 14681 instruct vpopcnt4I_reg(vecX dst, vecX src) %{ 14682 match(Set dst (PopCountVI src)); 14683 predicate(n->as_Vector()->length() == 4); 14684 format %{ "VPOPCNTW $dst,$src\t// pop count packed4I" %} 14685 size(4); 14686 ins_encode %{ 14687 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14688 %} 14689 ins_pipe(pipe_class_default); 14690 %} 14691 14692 // --------------------------------- FMA -------------------------------------- 14693 // dst + src1 * src2 14694 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{ 14695 match(Set dst (FmaVF dst (Binary src1 src2))); 14696 predicate(n->as_Vector()->length() == 4); 14697 14698 format %{ "XVMADDASP $dst, $src1, $src2" %} 14699 14700 size(4); 14701 ins_encode %{ 14702 __ xvmaddasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14703 %} 14704 ins_pipe(pipe_class_default); 14705 %} 14706 14707 // dst - src1 * src2 14708 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{ 14709 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 14710 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 14711 predicate(n->as_Vector()->length() == 4); 14712 14713 format %{ "XVNMSUBASP $dst, $src1, $src2" %} 14714 14715 size(4); 14716 ins_encode %{ 14717 __ xvnmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14718 %} 14719 ins_pipe(pipe_class_default); 14720 %} 14721 14722 // - dst + src1 * src2 14723 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{ 14724 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2))); 14725 predicate(n->as_Vector()->length() == 4); 14726 14727 format %{ "XVMSUBASP $dst, $src1, $src2" %} 14728 14729 size(4); 14730 ins_encode %{ 14731 __ xvmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14732 %} 14733 ins_pipe(pipe_class_default); 14734 %} 14735 14736 // dst + src1 * src2 14737 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{ 14738 match(Set dst (FmaVD dst (Binary src1 src2))); 14739 predicate(n->as_Vector()->length() == 2); 14740 14741 format %{ "XVMADDADP $dst, $src1, $src2" %} 14742 14743 size(4); 14744 ins_encode %{ 14745 __ xvmaddadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14746 %} 14747 ins_pipe(pipe_class_default); 14748 %} 14749 14750 // dst - src1 * src2 14751 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{ 14752 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 14753 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 14754 predicate(n->as_Vector()->length() == 2); 14755 14756 format %{ "XVNMSUBADP $dst, $src1, $src2" %} 14757 14758 size(4); 14759 ins_encode %{ 14760 __ xvnmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14761 %} 14762 ins_pipe(pipe_class_default); 14763 %} 14764 14765 // - dst + src1 * src2 14766 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{ 14767 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2))); 14768 predicate(n->as_Vector()->length() == 2); 14769 14770 format %{ "XVMSUBADP $dst, $src1, $src2" %} 14771 14772 size(4); 14773 ins_encode %{ 14774 __ xvmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14775 %} 14776 ins_pipe(pipe_class_default); 14777 %} 14778 14779 //----------Overflow Math Instructions----------------------------------------- 14780 14781 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 14782 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14783 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14784 14785 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14786 match(Set cr0 (OverflowAddL op1 op2)); 14787 14788 format %{ "add_ $op1, $op2\t# overflow check long" %} 14789 ins_encode %{ 14790 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14791 __ li(R0, 0); 14792 __ mtxer(R0); // clear XER.SO 14793 __ addo_(R0, $op1$$Register, $op2$$Register); 14794 %} 14795 ins_pipe(pipe_class_default); 14796 %} 14797 14798 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14799 match(Set cr0 (OverflowSubL op1 op2)); 14800 14801 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14802 ins_encode %{ 14803 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14804 __ li(R0, 0); 14805 __ mtxer(R0); // clear XER.SO 14806 __ subfo_(R0, $op2$$Register, $op1$$Register); 14807 %} 14808 ins_pipe(pipe_class_default); 14809 %} 14810 14811 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14812 match(Set cr0 (OverflowSubL zero op2)); 14813 14814 format %{ "nego_ R0, $op2\t# overflow check long" %} 14815 ins_encode %{ 14816 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14817 __ li(R0, 0); 14818 __ mtxer(R0); // clear XER.SO 14819 __ nego_(R0, $op2$$Register); 14820 %} 14821 ins_pipe(pipe_class_default); 14822 %} 14823 14824 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14825 match(Set cr0 (OverflowMulL op1 op2)); 14826 14827 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14828 ins_encode %{ 14829 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14830 __ li(R0, 0); 14831 __ mtxer(R0); // clear XER.SO 14832 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14833 %} 14834 ins_pipe(pipe_class_default); 14835 %} 14836 14837 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14838 match(Set dst (ReplicateF src)); 14839 predicate(n->as_Vector()->length() == 4); 14840 ins_cost(DEFAULT_COST); 14841 expand %{ 14842 vecX tmpV; 14843 immI8 zero %{ (int) 0 %} 14844 14845 xscvdpspn_regF(tmpV, src); 14846 xxspltw(dst, tmpV, zero); 14847 %} 14848 %} 14849 14850 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14851 match(Set dst (ReplicateF src)); 14852 predicate(n->as_Vector()->length() == 4); 14853 effect(TEMP tmp); 14854 ins_cost(10 * DEFAULT_COST); 14855 14856 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14857 %} 14858 14859 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14860 match(Set dst (ReplicateF zero)); 14861 predicate(n->as_Vector()->length() == 4); 14862 14863 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14864 ins_encode %{ 14865 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14866 %} 14867 ins_pipe(pipe_class_default); 14868 %} 14869 14870 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14871 match(Set dst (ReplicateD src)); 14872 predicate(n->as_Vector()->length() == 2); 14873 14874 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %} 14875 size(4); 14876 ins_encode %{ 14877 __ xxpermdi($dst$$VectorSRegister, $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0); 14878 %} 14879 ins_pipe(pipe_class_default); 14880 %} 14881 14882 instruct repl2D_immD0(vecX dst, immD_0 zero) %{ 14883 match(Set dst (ReplicateD zero)); 14884 predicate(n->as_Vector()->length() == 2); 14885 14886 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14887 size(4); 14888 ins_encode %{ 14889 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14890 %} 14891 ins_pipe(pipe_class_default); 14892 %} 14893 14894 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14895 predicate(false); 14896 effect(DEF dst, USE src); 14897 14898 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %} 14899 size(4); 14900 ins_encode %{ 14901 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14902 %} 14903 ins_pipe(pipe_class_default); 14904 %} 14905 14906 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14907 effect(DEF dst, USE src, USE zero); 14908 14909 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %} 14910 size(4); 14911 ins_encode %{ 14912 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14913 %} 14914 ins_pipe(pipe_class_default); 14915 %} 14916 14917 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14918 effect(DEF dst, USE src1, USE src2, USE zero); 14919 14920 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %} 14921 size(4); 14922 ins_encode %{ 14923 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14924 %} 14925 ins_pipe(pipe_class_default); 14926 %} 14927 14928 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14929 match(Set dst (ReplicateL src)); 14930 predicate(n->as_Vector()->length() == 2); 14931 expand %{ 14932 vecX tmpV; 14933 immI8 zero %{ (int) 0 %} 14934 mtvsrd(tmpV, src); 14935 xxpermdi(dst, tmpV, tmpV, zero); 14936 %} 14937 %} 14938 14939 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14940 match(Set dst (ReplicateL zero)); 14941 predicate(n->as_Vector()->length() == 2); 14942 14943 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14944 size(4); 14945 ins_encode %{ 14946 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14947 %} 14948 ins_pipe(pipe_class_default); 14949 %} 14950 14951 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14952 match(Set dst (ReplicateL src)); 14953 predicate(n->as_Vector()->length() == 2); 14954 14955 format %{ "XXLEQV $dst, $src \t// replicate2L" %} 14956 size(4); 14957 ins_encode %{ 14958 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14959 %} 14960 ins_pipe(pipe_class_default); 14961 %} 14962 14963 // ============================================================================ 14964 // Safepoint Instruction 14965 14966 instruct safePoint_poll(iRegPdst poll) %{ 14967 match(SafePoint poll); 14968 14969 // It caused problems to add the effect that r0 is killed, but this 14970 // effect no longer needs to be mentioned, since r0 is not contained 14971 // in a reg_class. 14972 14973 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14974 size(4); 14975 ins_encode( enc_poll(0x0, poll) ); 14976 ins_pipe(pipe_class_default); 14977 %} 14978 14979 // ============================================================================ 14980 // Call Instructions 14981 14982 // Call Java Static Instruction 14983 14984 // Schedulable version of call static node. 14985 instruct CallStaticJavaDirect(method meth) %{ 14986 match(CallStaticJava); 14987 effect(USE meth); 14988 ins_cost(CALL_COST); 14989 14990 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14991 14992 format %{ "CALL,static $meth \t// ==> " %} 14993 size(4); 14994 ins_encode( enc_java_static_call(meth) ); 14995 ins_pipe(pipe_class_call); 14996 %} 14997 14998 // Call Java Dynamic Instruction 14999 15000 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 15001 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 15002 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 15003 // The call destination must still be placed in the constant pool. 15004 instruct CallDynamicJavaDirectSched(method meth) %{ 15005 match(CallDynamicJava); // To get all the data fields we need ... 15006 effect(USE meth); 15007 predicate(false); // ... but never match. 15008 15009 ins_field_load_ic_hi_node(loadConL_hiNode*); 15010 ins_field_load_ic_node(loadConLNode*); 15011 ins_num_consts(1 /* 1 patchable constant: call destination */); 15012 15013 format %{ "BL \t// dynamic $meth ==> " %} 15014 size(4); 15015 ins_encode( enc_java_dynamic_call_sched(meth) ); 15016 ins_pipe(pipe_class_call); 15017 %} 15018 15019 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 15020 // We use postalloc expanded calls if we use inline caches 15021 // and do not update method data. 15022 // 15023 // This instruction has two constants: inline cache (IC) and call destination. 15024 // Loading the inline cache will be postalloc expanded, thus leaving a call with 15025 // one constant. 15026 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 15027 match(CallDynamicJava); 15028 effect(USE meth); 15029 predicate(UseInlineCaches); 15030 ins_cost(CALL_COST); 15031 15032 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 15033 15034 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 15035 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 15036 %} 15037 15038 // Compound version of call dynamic java 15039 // We use postalloc expanded calls if we use inline caches 15040 // and do not update method data. 15041 instruct CallDynamicJavaDirect(method meth) %{ 15042 match(CallDynamicJava); 15043 effect(USE meth); 15044 predicate(!UseInlineCaches); 15045 ins_cost(CALL_COST); 15046 15047 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 15048 ins_num_consts(4); 15049 15050 format %{ "CALL,dynamic $meth \t// ==> " %} 15051 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 15052 ins_pipe(pipe_class_call); 15053 %} 15054 15055 // Call Runtime Instruction 15056 15057 instruct CallRuntimeDirect(method meth) %{ 15058 match(CallRuntime); 15059 effect(USE meth); 15060 ins_cost(CALL_COST); 15061 15062 // Enc_java_to_runtime_call needs up to 3 constants: call target, 15063 // env for callee, C-toc. 15064 ins_num_consts(3); 15065 15066 format %{ "CALL,runtime" %} 15067 ins_encode( enc_java_to_runtime_call(meth) ); 15068 ins_pipe(pipe_class_call); 15069 %} 15070 15071 // Call Leaf 15072 15073 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 15074 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 15075 effect(DEF dst, USE src); 15076 15077 ins_num_consts(1); 15078 15079 format %{ "MTCTR $src" %} 15080 size(4); 15081 ins_encode( enc_leaf_call_mtctr(src) ); 15082 ins_pipe(pipe_class_default); 15083 %} 15084 15085 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 15086 instruct CallLeafDirect(method meth) %{ 15087 match(CallLeaf); // To get the data all the data fields we need ... 15088 effect(USE meth); 15089 predicate(false); // but never match. 15090 15091 format %{ "BCTRL \t// leaf call $meth ==> " %} 15092 size(4); 15093 ins_encode %{ 15094 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 15095 __ bctrl(); 15096 %} 15097 ins_pipe(pipe_class_call); 15098 %} 15099 15100 // postalloc expand of CallLeafDirect. 15101 // Load adress to call from TOC, then bl to it. 15102 instruct CallLeafDirect_Ex(method meth) %{ 15103 match(CallLeaf); 15104 effect(USE meth); 15105 ins_cost(CALL_COST); 15106 15107 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 15108 // env for callee, C-toc. 15109 ins_num_consts(3); 15110 15111 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 15112 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 15113 %} 15114 15115 // Call runtime without safepoint - same as CallLeaf. 15116 // postalloc expand of CallLeafNoFPDirect. 15117 // Load adress to call from TOC, then bl to it. 15118 instruct CallLeafNoFPDirect_Ex(method meth) %{ 15119 match(CallLeafNoFP); 15120 effect(USE meth); 15121 ins_cost(CALL_COST); 15122 15123 // Enc_java_to_runtime_call needs up to 3 constants: call target, 15124 // env for callee, C-toc. 15125 ins_num_consts(3); 15126 15127 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 15128 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 15129 %} 15130 15131 // Tail Call; Jump from runtime stub to Java code. 15132 // Also known as an 'interprocedural jump'. 15133 // Target of jump will eventually return to caller. 15134 // TailJump below removes the return address. 15135 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_ptr) %{ 15136 match(TailCall jump_target method_ptr); 15137 ins_cost(CALL_COST); 15138 15139 format %{ "MTCTR $jump_target \t// $method_ptr holds method\n\t" 15140 "BCTR \t// tail call" %} 15141 size(8); 15142 ins_encode %{ 15143 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 15144 __ mtctr($jump_target$$Register); 15145 __ bctr(); 15146 %} 15147 ins_pipe(pipe_class_call); 15148 %} 15149 15150 // Return Instruction 15151 instruct Ret() %{ 15152 match(Return); 15153 format %{ "BLR \t// branch to link register" %} 15154 size(4); 15155 ins_encode %{ 15156 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 15157 // LR is restored in MachEpilogNode. Just do the RET here. 15158 __ blr(); 15159 %} 15160 ins_pipe(pipe_class_default); 15161 %} 15162 15163 // Tail Jump; remove the return address; jump to target. 15164 // TailCall above leaves the return address around. 15165 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 15166 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 15167 // "restore" before this instruction (in Epilogue), we need to materialize it 15168 // in %i0. 15169 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 15170 match(TailJump jump_target ex_oop); 15171 ins_cost(CALL_COST); 15172 15173 format %{ "LD R4_ARG2 = LR\n\t" 15174 "MTCTR $jump_target\n\t" 15175 "BCTR \t// TailJump, exception oop: $ex_oop" %} 15176 size(12); 15177 ins_encode %{ 15178 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 15179 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 15180 __ mtctr($jump_target$$Register); 15181 __ bctr(); 15182 %} 15183 ins_pipe(pipe_class_call); 15184 %} 15185 15186 // Create exception oop: created by stack-crawling runtime code. 15187 // Created exception is now available to this handler, and is setup 15188 // just prior to jumping to this handler. No code emitted. 15189 instruct CreateException(rarg1RegP ex_oop) %{ 15190 match(Set ex_oop (CreateEx)); 15191 ins_cost(0); 15192 15193 format %{ " -- \t// exception oop; no code emitted" %} 15194 size(0); 15195 ins_encode( /*empty*/ ); 15196 ins_pipe(pipe_class_default); 15197 %} 15198 15199 // Rethrow exception: The exception oop will come in the first 15200 // argument position. Then JUMP (not call) to the rethrow stub code. 15201 instruct RethrowException() %{ 15202 match(Rethrow); 15203 ins_cost(CALL_COST); 15204 15205 format %{ "Jmp rethrow_stub" %} 15206 ins_encode %{ 15207 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 15208 cbuf.set_insts_mark(); 15209 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 15210 %} 15211 ins_pipe(pipe_class_call); 15212 %} 15213 15214 // Die now. 15215 instruct ShouldNotReachHere() %{ 15216 match(Halt); 15217 ins_cost(CALL_COST); 15218 15219 format %{ "ShouldNotReachHere" %} 15220 ins_encode %{ 15221 if (is_reachable()) { 15222 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 15223 __ stop(_halt_reason); 15224 } 15225 %} 15226 ins_pipe(pipe_class_default); 15227 %} 15228 15229 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 15230 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 15231 // Get a DEF on threadRegP, no costs, no encoding, use 15232 // 'ins_should_rematerialize(true)' to avoid spilling. 15233 instruct tlsLoadP(threadRegP dst) %{ 15234 match(Set dst (ThreadLocal)); 15235 ins_cost(0); 15236 15237 ins_should_rematerialize(true); 15238 15239 format %{ " -- \t// $dst=Thread::current(), empty" %} 15240 size(0); 15241 ins_encode( /*empty*/ ); 15242 ins_pipe(pipe_class_empty); 15243 %} 15244 15245 //---Some PPC specific nodes--------------------------------------------------- 15246 15247 // Stop a group. 15248 instruct endGroup() %{ 15249 ins_cost(0); 15250 15251 ins_is_nop(true); 15252 15253 format %{ "End Bundle (ori r1, r1, 0)" %} 15254 size(4); 15255 ins_encode %{ 15256 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 15257 __ endgroup(); 15258 %} 15259 ins_pipe(pipe_class_default); 15260 %} 15261 15262 // Nop instructions 15263 15264 instruct fxNop() %{ 15265 ins_cost(0); 15266 15267 ins_is_nop(true); 15268 15269 format %{ "fxNop" %} 15270 size(4); 15271 ins_encode %{ 15272 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15273 __ nop(); 15274 %} 15275 ins_pipe(pipe_class_default); 15276 %} 15277 15278 instruct fpNop0() %{ 15279 ins_cost(0); 15280 15281 ins_is_nop(true); 15282 15283 format %{ "fpNop0" %} 15284 size(4); 15285 ins_encode %{ 15286 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15287 __ fpnop0(); 15288 %} 15289 ins_pipe(pipe_class_default); 15290 %} 15291 15292 instruct fpNop1() %{ 15293 ins_cost(0); 15294 15295 ins_is_nop(true); 15296 15297 format %{ "fpNop1" %} 15298 size(4); 15299 ins_encode %{ 15300 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15301 __ fpnop1(); 15302 %} 15303 ins_pipe(pipe_class_default); 15304 %} 15305 15306 instruct brNop0() %{ 15307 ins_cost(0); 15308 size(4); 15309 format %{ "brNop0" %} 15310 ins_encode %{ 15311 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15312 __ brnop0(); 15313 %} 15314 ins_is_nop(true); 15315 ins_pipe(pipe_class_default); 15316 %} 15317 15318 instruct brNop1() %{ 15319 ins_cost(0); 15320 15321 ins_is_nop(true); 15322 15323 format %{ "brNop1" %} 15324 size(4); 15325 ins_encode %{ 15326 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15327 __ brnop1(); 15328 %} 15329 ins_pipe(pipe_class_default); 15330 %} 15331 15332 instruct brNop2() %{ 15333 ins_cost(0); 15334 15335 ins_is_nop(true); 15336 15337 format %{ "brNop2" %} 15338 size(4); 15339 ins_encode %{ 15340 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15341 __ brnop2(); 15342 %} 15343 ins_pipe(pipe_class_default); 15344 %} 15345 15346 instruct cacheWB(indirect addr) 15347 %{ 15348 match(CacheWB addr); 15349 15350 ins_cost(100); 15351 format %{ "cache writeback, address = $addr" %} 15352 ins_encode %{ 15353 assert($addr->index_position() < 0, "should be"); 15354 assert($addr$$disp == 0, "should be"); 15355 __ cache_wb(Address($addr$$base$$Register)); 15356 %} 15357 ins_pipe(pipe_class_default); 15358 %} 15359 15360 instruct cacheWBPreSync() 15361 %{ 15362 match(CacheWBPreSync); 15363 15364 ins_cost(0); 15365 format %{ "cache writeback presync" %} 15366 ins_encode %{ 15367 __ cache_wbsync(true); 15368 %} 15369 ins_pipe(pipe_class_default); 15370 %} 15371 15372 instruct cacheWBPostSync() 15373 %{ 15374 match(CacheWBPostSync); 15375 15376 ins_cost(100); 15377 format %{ "cache writeback postsync" %} 15378 ins_encode %{ 15379 __ cache_wbsync(false); 15380 %} 15381 ins_pipe(pipe_class_default); 15382 %} 15383 15384 //----------PEEPHOLE RULES----------------------------------------------------- 15385 // These must follow all instruction definitions as they use the names 15386 // defined in the instructions definitions. 15387 // 15388 // peepmatch ( root_instr_name [preceeding_instruction]* ); 15389 // 15390 // peepconstraint %{ 15391 // (instruction_number.operand_name relational_op instruction_number.operand_name 15392 // [, ...] ); 15393 // // instruction numbers are zero-based using left to right order in peepmatch 15394 // 15395 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 15396 // // provide an instruction_number.operand_name for each operand that appears 15397 // // in the replacement instruction's match rule 15398 // 15399 // ---------VM FLAGS--------------------------------------------------------- 15400 // 15401 // All peephole optimizations can be turned off using -XX:-OptoPeephole 15402 // 15403 // Each peephole rule is given an identifying number starting with zero and 15404 // increasing by one in the order seen by the parser. An individual peephole 15405 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 15406 // on the command-line. 15407 // 15408 // ---------CURRENT LIMITATIONS---------------------------------------------- 15409 // 15410 // Only match adjacent instructions in same basic block 15411 // Only equality constraints 15412 // Only constraints between operands, not (0.dest_reg == EAX_enc) 15413 // Only one replacement instruction 15414 // 15415 // ---------EXAMPLE---------------------------------------------------------- 15416 // 15417 // // pertinent parts of existing instructions in architecture description 15418 // instruct movI(eRegI dst, eRegI src) %{ 15419 // match(Set dst (CopyI src)); 15420 // %} 15421 // 15422 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 15423 // match(Set dst (AddI dst src)); 15424 // effect(KILL cr); 15425 // %} 15426 // 15427 // // Change (inc mov) to lea 15428 // peephole %{ 15429 // // increment preceeded by register-register move 15430 // peepmatch ( incI_eReg movI ); 15431 // // require that the destination register of the increment 15432 // // match the destination register of the move 15433 // peepconstraint ( 0.dst == 1.dst ); 15434 // // construct a replacement instruction that sets 15435 // // the destination to ( move's source register + one ) 15436 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15437 // %} 15438 // 15439 // Implementation no longer uses movX instructions since 15440 // machine-independent system no longer uses CopyX nodes. 15441 // 15442 // peephole %{ 15443 // peepmatch ( incI_eReg movI ); 15444 // peepconstraint ( 0.dst == 1.dst ); 15445 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15446 // %} 15447 // 15448 // peephole %{ 15449 // peepmatch ( decI_eReg movI ); 15450 // peepconstraint ( 0.dst == 1.dst ); 15451 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15452 // %} 15453 // 15454 // peephole %{ 15455 // peepmatch ( addI_eReg_imm movI ); 15456 // peepconstraint ( 0.dst == 1.dst ); 15457 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15458 // %} 15459 // 15460 // peephole %{ 15461 // peepmatch ( addP_eReg_imm movP ); 15462 // peepconstraint ( 0.dst == 1.dst ); 15463 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 15464 // %} 15465 15466 // // Change load of spilled value to only a spill 15467 // instruct storeI(memory mem, eRegI src) %{ 15468 // match(Set mem (StoreI mem src)); 15469 // %} 15470 // 15471 // instruct loadI(eRegI dst, memory mem) %{ 15472 // match(Set dst (LoadI mem)); 15473 // %} 15474 // 15475 peephole %{ 15476 peepmatch ( loadI storeI ); 15477 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15478 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 15479 %} 15480 15481 peephole %{ 15482 peepmatch ( loadL storeL ); 15483 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15484 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 15485 %} 15486 15487 peephole %{ 15488 peepmatch ( loadP storeP ); 15489 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 15490 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 15491 %} 15492 15493 //----------SMARTSPILL RULES--------------------------------------------------- 15494 // These must follow all instruction definitions as they use the names 15495 // defined in the instructions definitions.