1 // 2 // Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2017 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 // Returns true if Node n is followed by a MemBar node that 976 // will do an acquire. If so, this node must not do the acquire 977 // operation. 978 bool followed_by_acquire(const Node *n); 979 %} 980 981 source %{ 982 983 // Should the Matcher clone shifts on addressing modes, expecting them 984 // to be subsumed into complex addressing expressions or compute them 985 // into registers? 986 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 987 return clone_base_plus_offset_address(m, mstack, address_visited); 988 } 989 990 void Compile::reshape_address(AddPNode* addp) { 991 } 992 993 // Optimize load-acquire. 994 // 995 // Check if acquire is unnecessary due to following operation that does 996 // acquire anyways. 997 // Walk the pattern: 998 // 999 // n: Load.acq 1000 // | 1001 // MemBarAcquire 1002 // | | 1003 // Proj(ctrl) Proj(mem) 1004 // | | 1005 // MemBarRelease/Volatile 1006 // 1007 bool followed_by_acquire(const Node *load) { 1008 assert(load->is_Load(), "So far implemented only for loads."); 1009 1010 // Find MemBarAcquire. 1011 const Node *mba = NULL; 1012 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 1013 const Node *out = load->fast_out(i); 1014 if (out->Opcode() == Op_MemBarAcquire) { 1015 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 1016 mba = out; 1017 break; 1018 } 1019 } 1020 if (!mba) return false; 1021 1022 // Find following MemBar node. 1023 // 1024 // The following node must be reachable by control AND memory 1025 // edge to assure no other operations are in between the two nodes. 1026 // 1027 // So first get the Proj node, mem_proj, to use it to iterate forward. 1028 Node *mem_proj = NULL; 1029 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 1030 mem_proj = mba->fast_out(i); // Runs out of bounds and asserts if Proj not found. 1031 assert(mem_proj->is_Proj(), "only projections here"); 1032 ProjNode *proj = mem_proj->as_Proj(); 1033 if (proj->_con == TypeFunc::Memory && 1034 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 1035 break; 1036 } 1037 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 1038 1039 // Search MemBar behind Proj. If there are other memory operations 1040 // behind the Proj we lost. 1041 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 1042 Node *x = mem_proj->fast_out(j); 1043 // Proj might have an edge to a store or load node which precedes the membar. 1044 if (x->is_Mem()) return false; 1045 1046 // On PPC64 release and volatile are implemented by an instruction 1047 // that also has acquire semantics. I.e. there is no need for an 1048 // acquire before these. 1049 int xop = x->Opcode(); 1050 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 1051 // Make sure we're not missing Call/Phi/MergeMem by checking 1052 // control edges. The control edge must directly lead back 1053 // to the MemBarAcquire 1054 Node *ctrl_proj = x->in(0); 1055 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 1056 return true; 1057 } 1058 } 1059 } 1060 1061 return false; 1062 } 1063 1064 #define __ _masm. 1065 1066 // Tertiary op of a LoadP or StoreP encoding. 1067 #define REGP_OP true 1068 1069 // **************************************************************************** 1070 1071 // REQUIRED FUNCTIONALITY 1072 1073 // !!!!! Special hack to get all type of calls to specify the byte offset 1074 // from the start of the call to the point where the return address 1075 // will point. 1076 1077 // PPC port: Removed use of lazy constant construct. 1078 1079 int MachCallStaticJavaNode::ret_addr_offset() { 1080 // It's only a single branch-and-link instruction. 1081 return 4; 1082 } 1083 1084 int MachCallDynamicJavaNode::ret_addr_offset() { 1085 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 1086 // postalloc expanded calls if we use inline caches and do not update method data. 1087 if (UseInlineCaches) 1088 return 4; 1089 1090 int vtable_index = this->_vtable_index; 1091 if (vtable_index < 0) { 1092 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 1093 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 1094 return 12; 1095 } else { 1096 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 1097 return 24; 1098 } 1099 } 1100 1101 int MachCallRuntimeNode::ret_addr_offset() { 1102 #if defined(ABI_ELFv2) 1103 return 28; 1104 #else 1105 return 40; 1106 #endif 1107 } 1108 1109 //============================================================================= 1110 1111 // condition code conversions 1112 1113 static int cc_to_boint(int cc) { 1114 return Assembler::bcondCRbiIs0 | (cc & 8); 1115 } 1116 1117 static int cc_to_inverse_boint(int cc) { 1118 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 1119 } 1120 1121 static int cc_to_biint(int cc, int flags_reg) { 1122 return (flags_reg << 2) | (cc & 3); 1123 } 1124 1125 //============================================================================= 1126 1127 // Compute padding required for nodes which need alignment. The padding 1128 // is the number of bytes (not instructions) which will be inserted before 1129 // the instruction. The padding must match the size of a NOP instruction. 1130 1131 // Currently not used on this platform. 1132 1133 //============================================================================= 1134 1135 // Indicate if the safepoint node needs the polling page as an input. 1136 bool SafePointNode::needs_polling_address_input() { 1137 // The address is loaded from thread by a seperate node. 1138 return true; 1139 } 1140 1141 //============================================================================= 1142 1143 // Emit an interrupt that is caught by the debugger (for debugging compiler). 1144 void emit_break(CodeBuffer &cbuf) { 1145 MacroAssembler _masm(&cbuf); 1146 __ illtrap(); 1147 } 1148 1149 #ifndef PRODUCT 1150 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1151 st->print("BREAKPOINT"); 1152 } 1153 #endif 1154 1155 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1156 emit_break(cbuf); 1157 } 1158 1159 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1160 return MachNode::size(ra_); 1161 } 1162 1163 //============================================================================= 1164 1165 void emit_nop(CodeBuffer &cbuf) { 1166 MacroAssembler _masm(&cbuf); 1167 __ nop(); 1168 } 1169 1170 static inline void emit_long(CodeBuffer &cbuf, int value) { 1171 *((int*)(cbuf.insts_end())) = value; 1172 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1173 } 1174 1175 //============================================================================= 1176 1177 %} // interrupt source 1178 1179 source_hpp %{ // Header information of the source block. 1180 1181 //-------------------------------------------------------------- 1182 //---< Used for optimization in Compile::Shorten_branches >--- 1183 //-------------------------------------------------------------- 1184 1185 class CallStubImpl { 1186 1187 public: 1188 1189 // Emit call stub, compiled java to interpreter. 1190 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1191 1192 // Size of call trampoline stub. 1193 // This doesn't need to be accurate to the byte, but it 1194 // must be larger than or equal to the real size of the stub. 1195 static uint size_call_trampoline() { 1196 return MacroAssembler::trampoline_stub_size; 1197 } 1198 1199 // number of relocations needed by a call trampoline stub 1200 static uint reloc_call_trampoline() { 1201 return 5; 1202 } 1203 1204 }; 1205 1206 %} // end source_hpp 1207 1208 source %{ 1209 1210 // Emit a trampoline stub for a call to a target which is too far away. 1211 // 1212 // code sequences: 1213 // 1214 // call-site: 1215 // branch-and-link to <destination> or <trampoline stub> 1216 // 1217 // Related trampoline stub for this call-site in the stub section: 1218 // load the call target from the constant pool 1219 // branch via CTR (LR/link still points to the call-site above) 1220 1221 void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1222 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1223 if (stub == NULL) { 1224 ciEnv::current()->record_out_of_memory_failure(); 1225 } 1226 } 1227 1228 //============================================================================= 1229 1230 // Emit an inline branch-and-link call and a related trampoline stub. 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 1242 typedef struct { 1243 int insts_call_instruction_offset; 1244 int ret_addr_offset; 1245 } EmitCallOffsets; 1246 1247 // Emit a branch-and-link instruction that branches to a trampoline. 1248 // - Remember the offset of the branch-and-link instruction. 1249 // - Add a relocation at the branch-and-link instruction. 1250 // - Emit a branch-and-link. 1251 // - Remember the return pc offset. 1252 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1253 EmitCallOffsets offsets = { -1, -1 }; 1254 const int start_offset = __ offset(); 1255 offsets.insts_call_instruction_offset = __ offset(); 1256 1257 // No entry point given, use the current pc. 1258 if (entry_point == NULL) entry_point = __ pc(); 1259 1260 // Put the entry point as a constant into the constant pool. 1261 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1262 if (entry_point_toc_addr == NULL) { 1263 ciEnv::current()->record_out_of_memory_failure(); 1264 return offsets; 1265 } 1266 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1267 1268 // Emit the trampoline stub which will be related to the branch-and-link below. 1269 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1270 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1271 __ relocate(rtype); 1272 1273 // Note: At this point we do not have the address of the trampoline 1274 // stub, and the entry point might be too far away for bl, so __ pc() 1275 // serves as dummy and the bl will be patched later. 1276 __ bl((address) __ pc()); 1277 1278 offsets.ret_addr_offset = __ offset() - start_offset; 1279 1280 return offsets; 1281 } 1282 1283 //============================================================================= 1284 1285 // Factory for creating loadConL* nodes for large/small constant pool. 1286 1287 static inline jlong replicate_immF(float con) { 1288 // Replicate float con 2 times and pack into vector. 1289 int val = *((int*)&con); 1290 jlong lval = val; 1291 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1292 return lval; 1293 } 1294 1295 //============================================================================= 1296 1297 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1298 int Compile::ConstantTable::calculate_table_base_offset() const { 1299 return 0; // absolute addressing, no offset 1300 } 1301 1302 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1303 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1304 iRegPdstOper *op_dst = new iRegPdstOper(); 1305 MachNode *m1 = new loadToc_hiNode(); 1306 MachNode *m2 = new loadToc_loNode(); 1307 1308 m1->add_req(NULL); 1309 m2->add_req(NULL, m1); 1310 m1->_opnds[0] = op_dst; 1311 m2->_opnds[0] = op_dst; 1312 m2->_opnds[1] = op_dst; 1313 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1314 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1315 nodes->push(m1); 1316 nodes->push(m2); 1317 } 1318 1319 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1320 // Is postalloc expanded. 1321 ShouldNotReachHere(); 1322 } 1323 1324 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1325 return 0; 1326 } 1327 1328 #ifndef PRODUCT 1329 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1330 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1331 } 1332 #endif 1333 1334 //============================================================================= 1335 1336 #ifndef PRODUCT 1337 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1338 Compile* C = ra_->C; 1339 const long framesize = C->frame_slots() << LogBytesPerInt; 1340 1341 st->print("PROLOG\n\t"); 1342 if (C->need_stack_bang(framesize)) { 1343 st->print("stack_overflow_check\n\t"); 1344 } 1345 1346 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1347 st->print("save return pc\n\t"); 1348 st->print("push frame %ld\n\t", -framesize); 1349 } 1350 } 1351 #endif 1352 1353 // Macro used instead of the common __ to emulate the pipes of PPC. 1354 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1355 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1356 // still no scheduling of this code is possible, the micro scheduler is aware of the 1357 // code and can update its internal data. The following mechanism is used to achieve this: 1358 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1359 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1360 #if 0 // TODO: PPC port 1361 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1362 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1363 _masm. 1364 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1365 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1366 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1367 C->hb_scheduling()->_pdScheduling->advance_offset 1368 #else 1369 #define ___(op) if (UsePower6SchedulerPPC64) \ 1370 Unimplemented(); \ 1371 _masm. 1372 #define ___stop if (UsePower6SchedulerPPC64) \ 1373 Unimplemented() 1374 #define ___advance if (UsePower6SchedulerPPC64) \ 1375 Unimplemented() 1376 #endif 1377 1378 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1379 Compile* C = ra_->C; 1380 MacroAssembler _masm(&cbuf); 1381 1382 const long framesize = C->frame_size_in_bytes(); 1383 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1384 1385 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1386 1387 const Register return_pc = R20; // Must match return_addr() in frame section. 1388 const Register callers_sp = R21; 1389 const Register push_frame_temp = R22; 1390 const Register toc_temp = R23; 1391 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1392 1393 if (method_is_frameless) { 1394 // Add nop at beginning of all frameless methods to prevent any 1395 // oop instructions from getting overwritten by make_not_entrant 1396 // (patching attempt would fail). 1397 ___(nop) nop(); 1398 } else { 1399 // Get return pc. 1400 ___(mflr) mflr(return_pc); 1401 } 1402 1403 // Calls to C2R adapters often do not accept exceptional returns. 1404 // We require that their callers must bang for them. But be 1405 // careful, because some VM calls (such as call site linkage) can 1406 // use several kilobytes of stack. But the stack safety zone should 1407 // account for that. See bugs 4446381, 4468289, 4497237. 1408 1409 int bangsize = C->bang_size_in_bytes(); 1410 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1411 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1412 // Unfortunately we cannot use the function provided in 1413 // assembler.cpp as we have to emulate the pipes. So I had to 1414 // insert the code of generate_stack_overflow_check(), see 1415 // assembler.cpp for some illuminative comments. 1416 const int page_size = os::vm_page_size(); 1417 int bang_end = JavaThread::stack_shadow_zone_size(); 1418 1419 // This is how far the previous frame's stack banging extended. 1420 const int bang_end_safe = bang_end; 1421 1422 if (bangsize > page_size) { 1423 bang_end += bangsize; 1424 } 1425 1426 int bang_offset = bang_end_safe; 1427 1428 while (bang_offset <= bang_end) { 1429 // Need at least one stack bang at end of shadow zone. 1430 1431 // Again I had to copy code, this time from assembler_ppc.cpp, 1432 // bang_stack_with_offset - see there for comments. 1433 1434 // Stack grows down, caller passes positive offset. 1435 assert(bang_offset > 0, "must bang with positive offset"); 1436 1437 long stdoffset = -bang_offset; 1438 1439 if (Assembler::is_simm(stdoffset, 16)) { 1440 // Signed 16 bit offset, a simple std is ok. 1441 if (UseLoadInstructionsForStackBangingPPC64) { 1442 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1443 } else { 1444 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1445 } 1446 } else if (Assembler::is_simm(stdoffset, 31)) { 1447 // Use largeoffset calculations for addis & ld/std. 1448 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1449 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1450 1451 Register tmp = R11; 1452 ___(addis) addis(tmp, R1_SP, hi); 1453 if (UseLoadInstructionsForStackBangingPPC64) { 1454 ___(ld) ld(R0, lo, tmp); 1455 } else { 1456 ___(std) std(R0, lo, tmp); 1457 } 1458 } else { 1459 ShouldNotReachHere(); 1460 } 1461 1462 bang_offset += page_size; 1463 } 1464 // R11 trashed 1465 } // C->need_stack_bang(framesize) && UseStackBanging 1466 1467 unsigned int bytes = (unsigned int)framesize; 1468 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1469 ciMethod *currMethod = C->method(); 1470 1471 // Optimized version for most common case. 1472 if (UsePower6SchedulerPPC64 && 1473 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1474 !(false /* ConstantsALot TODO: PPC port*/)) { 1475 ___(or) mr(callers_sp, R1_SP); 1476 ___(std) std(return_pc, _abi(lr), R1_SP); 1477 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1478 return; 1479 } 1480 1481 if (!method_is_frameless) { 1482 // Get callers sp. 1483 ___(or) mr(callers_sp, R1_SP); 1484 1485 // Push method's frame, modifies SP. 1486 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1487 // The ABI is already accounted for in 'framesize' via the 1488 // 'out_preserve' area. 1489 Register tmp = push_frame_temp; 1490 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1491 if (Assembler::is_simm(-offset, 16)) { 1492 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1493 } else { 1494 long x = -offset; 1495 // Had to insert load_const(tmp, -offset). 1496 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1497 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1498 ___(rldicr) sldi(tmp, tmp, 32); 1499 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1500 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1501 1502 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1503 } 1504 } 1505 #if 0 // TODO: PPC port 1506 // For testing large constant pools, emit a lot of constants to constant pool. 1507 // "Randomize" const_size. 1508 if (ConstantsALot) { 1509 const int num_consts = const_size(); 1510 for (int i = 0; i < num_consts; i++) { 1511 __ long_constant(0xB0B5B00BBABE); 1512 } 1513 } 1514 #endif 1515 if (!method_is_frameless) { 1516 // Save return pc. 1517 ___(std) std(return_pc, _abi(lr), callers_sp); 1518 } 1519 1520 C->set_frame_complete(cbuf.insts_size()); 1521 } 1522 #undef ___ 1523 #undef ___stop 1524 #undef ___advance 1525 1526 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1527 // Variable size. determine dynamically. 1528 return MachNode::size(ra_); 1529 } 1530 1531 int MachPrologNode::reloc() const { 1532 // Return number of relocatable values contained in this instruction. 1533 return 1; // 1 reloc entry for load_const(toc). 1534 } 1535 1536 //============================================================================= 1537 1538 #ifndef PRODUCT 1539 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1540 Compile* C = ra_->C; 1541 1542 st->print("EPILOG\n\t"); 1543 st->print("restore return pc\n\t"); 1544 st->print("pop frame\n\t"); 1545 1546 if (do_polling() && C->is_method_compilation()) { 1547 st->print("touch polling page\n\t"); 1548 } 1549 } 1550 #endif 1551 1552 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1553 Compile* C = ra_->C; 1554 MacroAssembler _masm(&cbuf); 1555 1556 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1557 assert(framesize >= 0, "negative frame-size?"); 1558 1559 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1560 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1561 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1562 const Register polling_page = R12; 1563 1564 if (!method_is_frameless) { 1565 // Restore return pc relative to callers' sp. 1566 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1567 } 1568 1569 if (method_needs_polling) { 1570 if (SafepointMechanism::uses_thread_local_poll()) { 1571 __ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread); 1572 } else { 1573 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); 1574 } 1575 } 1576 1577 if (!method_is_frameless) { 1578 // Move return pc to LR. 1579 __ mtlr(return_pc); 1580 // Pop frame (fixed frame-size). 1581 __ addi(R1_SP, R1_SP, (int)framesize); 1582 } 1583 1584 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1585 __ reserved_stack_check(return_pc); 1586 } 1587 1588 if (method_needs_polling) { 1589 // We need to mark the code position where the load from the safepoint 1590 // polling page was emitted as relocInfo::poll_return_type here. 1591 __ relocate(relocInfo::poll_return_type); 1592 __ load_from_polling_page(polling_page); 1593 } 1594 } 1595 1596 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1597 // Variable size. Determine dynamically. 1598 return MachNode::size(ra_); 1599 } 1600 1601 int MachEpilogNode::reloc() const { 1602 // Return number of relocatable values contained in this instruction. 1603 return 1; // 1 for load_from_polling_page. 1604 } 1605 1606 const Pipeline * MachEpilogNode::pipeline() const { 1607 return MachNode::pipeline_class(); 1608 } 1609 1610 // This method seems to be obsolete. It is declared in machnode.hpp 1611 // and defined in all *.ad files, but it is never called. Should we 1612 // get rid of it? 1613 int MachEpilogNode::safepoint_offset() const { 1614 assert(do_polling(), "no return for this epilog node"); 1615 return 0; 1616 } 1617 1618 #if 0 // TODO: PPC port 1619 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1620 MacroAssembler _masm(&cbuf); 1621 if (LoadPollAddressFromThread) { 1622 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1623 } else { 1624 _masm.nop(); 1625 } 1626 } 1627 1628 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1629 if (LoadPollAddressFromThread) { 1630 return 4; 1631 } else { 1632 return 4; 1633 } 1634 } 1635 1636 #ifndef PRODUCT 1637 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1638 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1639 } 1640 #endif 1641 1642 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1643 return RSCRATCH1_BITS64_REG_mask(); 1644 } 1645 #endif // PPC port 1646 1647 // ============================================================================= 1648 1649 // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or 1650 // rc_stack. 1651 enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack }; 1652 1653 static enum RC rc_class(OptoReg::Name reg) { 1654 // Return the register class for the given register. The given register 1655 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1656 // enumeration in adGlobals_ppc.hpp. 1657 1658 if (reg == OptoReg::Bad) return rc_bad; 1659 1660 // We have 64 integer register halves, starting at index 0. 1661 if (reg < 64) return rc_int; 1662 1663 // We have 64 floating-point register halves, starting at index 64. 1664 if (reg < 64+64) return rc_float; 1665 1666 // We have 64 vector-scalar registers, starting at index 128. 1667 if (reg < 64+64+64) return rc_vs; 1668 1669 // Between float regs & stack are the flags regs. 1670 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1671 1672 return rc_stack; 1673 } 1674 1675 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1676 bool do_print, Compile* C, outputStream *st) { 1677 1678 assert(opcode == Assembler::LD_OPCODE || 1679 opcode == Assembler::STD_OPCODE || 1680 opcode == Assembler::LWZ_OPCODE || 1681 opcode == Assembler::STW_OPCODE || 1682 opcode == Assembler::LFD_OPCODE || 1683 opcode == Assembler::STFD_OPCODE || 1684 opcode == Assembler::LFS_OPCODE || 1685 opcode == Assembler::STFS_OPCODE, 1686 "opcode not supported"); 1687 1688 if (cbuf) { 1689 int d = 1690 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1691 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1692 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1693 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1694 } 1695 #ifndef PRODUCT 1696 else if (do_print) { 1697 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1698 op_str, 1699 Matcher::regName[reg], 1700 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1701 } 1702 #endif 1703 return 4; // size 1704 } 1705 1706 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1707 Compile* C = ra_->C; 1708 1709 // Get registers to move. 1710 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1711 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1712 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1713 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1714 1715 enum RC src_hi_rc = rc_class(src_hi); 1716 enum RC src_lo_rc = rc_class(src_lo); 1717 enum RC dst_hi_rc = rc_class(dst_hi); 1718 enum RC dst_lo_rc = rc_class(dst_lo); 1719 1720 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1721 if (src_hi != OptoReg::Bad) 1722 assert((src_lo&1)==0 && src_lo+1==src_hi && 1723 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1724 "expected aligned-adjacent pairs"); 1725 // Generate spill code! 1726 int size = 0; 1727 1728 if (src_lo == dst_lo && src_hi == dst_hi) 1729 return size; // Self copy, no move. 1730 1731 if (bottom_type()->isa_vect() != NULL && ideal_reg() == Op_VecX) { 1732 // Memory->Memory Spill. 1733 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1734 int src_offset = ra_->reg2offset(src_lo); 1735 int dst_offset = ra_->reg2offset(dst_lo); 1736 if (cbuf) { 1737 MacroAssembler _masm(cbuf); 1738 __ ld(R0, src_offset, R1_SP); 1739 __ std(R0, dst_offset, R1_SP); 1740 __ ld(R0, src_offset+8, R1_SP); 1741 __ std(R0, dst_offset+8, R1_SP); 1742 } 1743 size += 16; 1744 } 1745 // VectorSRegister->Memory Spill. 1746 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) { 1747 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1748 int dst_offset = ra_->reg2offset(dst_lo); 1749 if (cbuf) { 1750 MacroAssembler _masm(cbuf); 1751 __ addi(R0, R1_SP, dst_offset); 1752 __ stxvd2x(Rsrc, R0); 1753 } 1754 size += 8; 1755 } 1756 // Memory->VectorSRegister Spill. 1757 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) { 1758 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1759 int src_offset = ra_->reg2offset(src_lo); 1760 if (cbuf) { 1761 MacroAssembler _masm(cbuf); 1762 __ addi(R0, R1_SP, src_offset); 1763 __ lxvd2x(Rdst, R0); 1764 } 1765 size += 8; 1766 } 1767 // VectorSRegister->VectorSRegister. 1768 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) { 1769 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1770 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1771 if (cbuf) { 1772 MacroAssembler _masm(cbuf); 1773 __ xxlor(Rdst, Rsrc, Rsrc); 1774 } 1775 size += 4; 1776 } 1777 else { 1778 ShouldNotReachHere(); // No VSR spill. 1779 } 1780 return size; 1781 } 1782 1783 // -------------------------------------- 1784 // Memory->Memory Spill. Use R0 to hold the value. 1785 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1786 int src_offset = ra_->reg2offset(src_lo); 1787 int dst_offset = ra_->reg2offset(dst_lo); 1788 if (src_hi != OptoReg::Bad) { 1789 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1790 "expected same type of move for high parts"); 1791 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1792 if (!cbuf && !do_size) st->print("\n\t"); 1793 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1794 } else { 1795 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1796 if (!cbuf && !do_size) st->print("\n\t"); 1797 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1798 } 1799 return size; 1800 } 1801 1802 // -------------------------------------- 1803 // Check for float->int copy; requires a trip through memory. 1804 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1805 Unimplemented(); 1806 } 1807 1808 // -------------------------------------- 1809 // Check for integer reg-reg copy. 1810 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1811 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1812 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1813 size = (Rsrc != Rdst) ? 4 : 0; 1814 1815 if (cbuf) { 1816 MacroAssembler _masm(cbuf); 1817 if (size) { 1818 __ mr(Rdst, Rsrc); 1819 } 1820 } 1821 #ifndef PRODUCT 1822 else if (!do_size) { 1823 if (size) { 1824 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1825 } else { 1826 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1827 } 1828 } 1829 #endif 1830 return size; 1831 } 1832 1833 // Check for integer store. 1834 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1835 int dst_offset = ra_->reg2offset(dst_lo); 1836 if (src_hi != OptoReg::Bad) { 1837 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1838 "expected same type of move for high parts"); 1839 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1840 } else { 1841 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1842 } 1843 return size; 1844 } 1845 1846 // Check for integer load. 1847 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1848 int src_offset = ra_->reg2offset(src_lo); 1849 if (src_hi != OptoReg::Bad) { 1850 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1851 "expected same type of move for high parts"); 1852 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1853 } else { 1854 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1855 } 1856 return size; 1857 } 1858 1859 // Check for float reg-reg copy. 1860 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1861 if (cbuf) { 1862 MacroAssembler _masm(cbuf); 1863 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1864 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1865 __ fmr(Rdst, Rsrc); 1866 } 1867 #ifndef PRODUCT 1868 else if (!do_size) { 1869 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1870 } 1871 #endif 1872 return 4; 1873 } 1874 1875 // Check for float store. 1876 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1877 int dst_offset = ra_->reg2offset(dst_lo); 1878 if (src_hi != OptoReg::Bad) { 1879 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1880 "expected same type of move for high parts"); 1881 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1882 } else { 1883 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1884 } 1885 return size; 1886 } 1887 1888 // Check for float load. 1889 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1890 int src_offset = ra_->reg2offset(src_lo); 1891 if (src_hi != OptoReg::Bad) { 1892 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1893 "expected same type of move for high parts"); 1894 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1895 } else { 1896 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1897 } 1898 return size; 1899 } 1900 1901 // -------------------------------------------------------------------- 1902 // Check for hi bits still needing moving. Only happens for misaligned 1903 // arguments to native calls. 1904 if (src_hi == dst_hi) 1905 return size; // Self copy; no move. 1906 1907 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1908 ShouldNotReachHere(); // Unimplemented 1909 return 0; 1910 } 1911 1912 #ifndef PRODUCT 1913 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1914 if (!ra_) 1915 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1916 else 1917 implementation(NULL, ra_, false, st); 1918 } 1919 #endif 1920 1921 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1922 implementation(&cbuf, ra_, false, NULL); 1923 } 1924 1925 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1926 return implementation(NULL, ra_, true, NULL); 1927 } 1928 1929 #if 0 // TODO: PPC port 1930 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1931 #ifndef PRODUCT 1932 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1933 #endif 1934 assert(ra_->node_regs_max_index() != 0, ""); 1935 1936 // Get registers to move. 1937 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1938 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1939 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1940 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1941 1942 enum RC src_lo_rc = rc_class(src_lo); 1943 enum RC dst_lo_rc = rc_class(dst_lo); 1944 1945 if (src_lo == dst_lo && src_hi == dst_hi) 1946 return ppc64Opcode_none; // Self copy, no move. 1947 1948 // -------------------------------------- 1949 // Memory->Memory Spill. Use R0 to hold the value. 1950 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1951 return ppc64Opcode_compound; 1952 } 1953 1954 // -------------------------------------- 1955 // Check for float->int copy; requires a trip through memory. 1956 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1957 Unimplemented(); 1958 } 1959 1960 // -------------------------------------- 1961 // Check for integer reg-reg copy. 1962 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1963 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1964 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1965 if (Rsrc == Rdst) { 1966 return ppc64Opcode_none; 1967 } else { 1968 return ppc64Opcode_or; 1969 } 1970 } 1971 1972 // Check for integer store. 1973 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1974 if (src_hi != OptoReg::Bad) { 1975 return ppc64Opcode_std; 1976 } else { 1977 return ppc64Opcode_stw; 1978 } 1979 } 1980 1981 // Check for integer load. 1982 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1983 if (src_hi != OptoReg::Bad) { 1984 return ppc64Opcode_ld; 1985 } else { 1986 return ppc64Opcode_lwz; 1987 } 1988 } 1989 1990 // Check for float reg-reg copy. 1991 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1992 return ppc64Opcode_fmr; 1993 } 1994 1995 // Check for float store. 1996 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1997 if (src_hi != OptoReg::Bad) { 1998 return ppc64Opcode_stfd; 1999 } else { 2000 return ppc64Opcode_stfs; 2001 } 2002 } 2003 2004 // Check for float load. 2005 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 2006 if (src_hi != OptoReg::Bad) { 2007 return ppc64Opcode_lfd; 2008 } else { 2009 return ppc64Opcode_lfs; 2010 } 2011 } 2012 2013 // -------------------------------------------------------------------- 2014 // Check for hi bits still needing moving. Only happens for misaligned 2015 // arguments to native calls. 2016 if (src_hi == dst_hi) { 2017 return ppc64Opcode_none; // Self copy; no move. 2018 } 2019 2020 ShouldNotReachHere(); 2021 return ppc64Opcode_undefined; 2022 } 2023 #endif // PPC port 2024 2025 #ifndef PRODUCT 2026 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2027 st->print("NOP \t// %d nops to pad for loops.", _count); 2028 } 2029 #endif 2030 2031 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 2032 MacroAssembler _masm(&cbuf); 2033 // _count contains the number of nops needed for padding. 2034 for (int i = 0; i < _count; i++) { 2035 __ nop(); 2036 } 2037 } 2038 2039 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 2040 return _count * 4; 2041 } 2042 2043 #ifndef PRODUCT 2044 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2045 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2046 char reg_str[128]; 2047 ra_->dump_register(this, reg_str); 2048 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 2049 } 2050 #endif 2051 2052 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2053 MacroAssembler _masm(&cbuf); 2054 2055 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2056 int reg = ra_->get_encode(this); 2057 2058 if (Assembler::is_simm(offset, 16)) { 2059 __ addi(as_Register(reg), R1, offset); 2060 } else { 2061 ShouldNotReachHere(); 2062 } 2063 } 2064 2065 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2066 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2067 return 4; 2068 } 2069 2070 #ifndef PRODUCT 2071 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2072 st->print_cr("---- MachUEPNode ----"); 2073 st->print_cr("..."); 2074 } 2075 #endif 2076 2077 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2078 // This is the unverified entry point. 2079 MacroAssembler _masm(&cbuf); 2080 2081 // Inline_cache contains a klass. 2082 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 2083 Register receiver_klass = R12_scratch2; // tmp 2084 2085 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 2086 assert(R11_scratch1 == R11, "need prologue scratch register"); 2087 2088 // Check for NULL argument if we don't have implicit null checks. 2089 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 2090 if (TrapBasedNullChecks) { 2091 __ trap_null_check(R3_ARG1); 2092 } else { 2093 Label valid; 2094 __ cmpdi(CCR0, R3_ARG1, 0); 2095 __ bne_predict_taken(CCR0, valid); 2096 // We have a null argument, branch to ic_miss_stub. 2097 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2098 relocInfo::runtime_call_type); 2099 __ bind(valid); 2100 } 2101 } 2102 // Assume argument is not NULL, load klass from receiver. 2103 __ load_klass(receiver_klass, R3_ARG1); 2104 2105 if (TrapBasedICMissChecks) { 2106 __ trap_ic_miss_check(receiver_klass, ic_klass); 2107 } else { 2108 Label valid; 2109 __ cmpd(CCR0, receiver_klass, ic_klass); 2110 __ beq_predict_taken(CCR0, valid); 2111 // We have an unexpected klass, branch to ic_miss_stub. 2112 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2113 relocInfo::runtime_call_type); 2114 __ bind(valid); 2115 } 2116 2117 // Argument is valid and klass is as expected, continue. 2118 } 2119 2120 #if 0 // TODO: PPC port 2121 // Optimize UEP code on z (save a load_const() call in main path). 2122 int MachUEPNode::ep_offset() { 2123 return 0; 2124 } 2125 #endif 2126 2127 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2128 // Variable size. Determine dynamically. 2129 return MachNode::size(ra_); 2130 } 2131 2132 //============================================================================= 2133 2134 %} // interrupt source 2135 2136 source_hpp %{ // Header information of the source block. 2137 2138 class HandlerImpl { 2139 2140 public: 2141 2142 static int emit_exception_handler(CodeBuffer &cbuf); 2143 static int emit_deopt_handler(CodeBuffer& cbuf); 2144 2145 static uint size_exception_handler() { 2146 // The exception_handler is a b64_patchable. 2147 return MacroAssembler::b64_patchable_size; 2148 } 2149 2150 static uint size_deopt_handler() { 2151 // The deopt_handler is a bl64_patchable. 2152 return MacroAssembler::bl64_patchable_size; 2153 } 2154 2155 }; 2156 2157 %} // end source_hpp 2158 2159 source %{ 2160 2161 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2162 MacroAssembler _masm(&cbuf); 2163 2164 address base = __ start_a_stub(size_exception_handler()); 2165 if (base == NULL) return 0; // CodeBuffer::expand failed 2166 2167 int offset = __ offset(); 2168 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2169 relocInfo::runtime_call_type); 2170 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2171 __ end_a_stub(); 2172 2173 return offset; 2174 } 2175 2176 // The deopt_handler is like the exception handler, but it calls to 2177 // the deoptimization blob instead of jumping to the exception blob. 2178 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2179 MacroAssembler _masm(&cbuf); 2180 2181 address base = __ start_a_stub(size_deopt_handler()); 2182 if (base == NULL) return 0; // CodeBuffer::expand failed 2183 2184 int offset = __ offset(); 2185 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2186 relocInfo::runtime_call_type); 2187 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2188 __ end_a_stub(); 2189 2190 return offset; 2191 } 2192 2193 //============================================================================= 2194 2195 // Use a frame slots bias for frameless methods if accessing the stack. 2196 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2197 if (as_Register(reg_enc) == R1_SP) { 2198 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2199 } 2200 return 0; 2201 } 2202 2203 const bool Matcher::match_rule_supported(int opcode) { 2204 if (!has_match_rule(opcode)) 2205 return false; 2206 2207 switch (opcode) { 2208 case Op_SqrtD: 2209 return VM_Version::has_fsqrt(); 2210 case Op_CountLeadingZerosI: 2211 case Op_CountLeadingZerosL: 2212 case Op_CountTrailingZerosI: 2213 case Op_CountTrailingZerosL: 2214 if (!UseCountLeadingZerosInstructionsPPC64) 2215 return false; 2216 break; 2217 2218 case Op_PopCountI: 2219 case Op_PopCountL: 2220 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2221 2222 case Op_StrComp: 2223 return SpecialStringCompareTo; 2224 case Op_StrEquals: 2225 return SpecialStringEquals; 2226 case Op_StrIndexOf: 2227 case Op_StrIndexOfChar: 2228 return SpecialStringIndexOf; 2229 case Op_AddVB: 2230 case Op_AddVS: 2231 case Op_AddVI: 2232 case Op_AddVF: 2233 case Op_AddVD: 2234 case Op_SubVB: 2235 case Op_SubVS: 2236 case Op_SubVI: 2237 case Op_SubVF: 2238 case Op_SubVD: 2239 case Op_MulVS: 2240 case Op_MulVF: 2241 case Op_MulVD: 2242 case Op_DivVF: 2243 case Op_DivVD: 2244 case Op_AbsVF: 2245 case Op_AbsVD: 2246 case Op_NegVF: 2247 case Op_NegVD: 2248 case Op_SqrtVF: 2249 case Op_SqrtVD: 2250 case Op_AddVL: 2251 case Op_SubVL: 2252 case Op_MulVI: 2253 return SuperwordUseVSX; 2254 case Op_PopCountVI: 2255 return (SuperwordUseVSX && UsePopCountInstruction); 2256 } 2257 2258 return true; // Per default match rules are supported. 2259 } 2260 2261 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2262 2263 // TODO 2264 // identify extra cases that we might want to provide match rules for 2265 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2266 bool ret_value = match_rule_supported(opcode); 2267 // Add rules here. 2268 2269 return ret_value; // Per default match rules are supported. 2270 } 2271 2272 const bool Matcher::has_predicated_vectors(void) { 2273 return false; 2274 } 2275 2276 const int Matcher::float_pressure(int default_pressure_threshold) { 2277 return default_pressure_threshold; 2278 } 2279 2280 int Matcher::regnum_to_fpu_offset(int regnum) { 2281 // No user for this method? 2282 Unimplemented(); 2283 return 999; 2284 } 2285 2286 const bool Matcher::convL2FSupported(void) { 2287 // fcfids can do the conversion (>= Power7). 2288 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2289 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2290 } 2291 2292 // Vector width in bytes. 2293 const int Matcher::vector_width_in_bytes(BasicType bt) { 2294 if (SuperwordUseVSX) { 2295 assert(MaxVectorSize == 16, ""); 2296 return 16; 2297 } else { 2298 assert(MaxVectorSize == 8, ""); 2299 return 8; 2300 } 2301 } 2302 2303 // Vector ideal reg. 2304 const uint Matcher::vector_ideal_reg(int size) { 2305 if (SuperwordUseVSX) { 2306 assert(MaxVectorSize == 16 && size == 16, ""); 2307 return Op_VecX; 2308 } else { 2309 assert(MaxVectorSize == 8 && size == 8, ""); 2310 return Op_RegL; 2311 } 2312 } 2313 2314 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2315 fatal("vector shift is not supported"); 2316 return Node::NotAMachineReg; 2317 } 2318 2319 // Limits on vector size (number of elements) loaded into vector. 2320 const int Matcher::max_vector_size(const BasicType bt) { 2321 assert(is_java_primitive(bt), "only primitive type vectors"); 2322 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2323 } 2324 2325 const int Matcher::min_vector_size(const BasicType bt) { 2326 return max_vector_size(bt); // Same as max. 2327 } 2328 2329 // PPC doesn't support misaligned vectors store/load. 2330 const bool Matcher::misaligned_vectors_ok() { 2331 return !AlignVector; // can be changed by flag 2332 } 2333 2334 // PPC AES support not yet implemented 2335 const bool Matcher::pass_original_key_for_aes() { 2336 return false; 2337 } 2338 2339 // RETURNS: whether this branch offset is short enough that a short 2340 // branch can be used. 2341 // 2342 // If the platform does not provide any short branch variants, then 2343 // this method should return `false' for offset 0. 2344 // 2345 // `Compile::Fill_buffer' will decide on basis of this information 2346 // whether to do the pass `Compile::Shorten_branches' at all. 2347 // 2348 // And `Compile::Shorten_branches' will decide on basis of this 2349 // information whether to replace particular branch sites by short 2350 // ones. 2351 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2352 // Is the offset within the range of a ppc64 pc relative branch? 2353 bool b; 2354 2355 const int safety_zone = 3 * BytesPerInstWord; 2356 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2357 29 - 16 + 1 + 2); 2358 return b; 2359 } 2360 2361 const bool Matcher::isSimpleConstant64(jlong value) { 2362 // Probably always true, even if a temp register is required. 2363 return true; 2364 } 2365 /* TODO: PPC port 2366 // Make a new machine dependent decode node (with its operands). 2367 MachTypeNode *Matcher::make_decode_node() { 2368 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2369 "This method is only implemented for unscaled cOops mode so far"); 2370 MachTypeNode *decode = new decodeN_unscaledNode(); 2371 decode->set_opnd_array(0, new iRegPdstOper()); 2372 decode->set_opnd_array(1, new iRegNsrcOper()); 2373 return decode; 2374 } 2375 */ 2376 2377 // false => size gets scaled to BytesPerLong, ok. 2378 const bool Matcher::init_array_count_is_in_bytes = false; 2379 2380 // Use conditional move (CMOVL) on Power7. 2381 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2382 2383 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2384 // fsel doesn't accept a condition register as input, so this would be slightly different. 2385 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2386 2387 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2388 const bool Matcher::require_postalloc_expand = true; 2389 2390 // Do we need to mask the count passed to shift instructions or does 2391 // the cpu only look at the lower 5/6 bits anyway? 2392 // PowerPC requires masked shift counts. 2393 const bool Matcher::need_masked_shift_count = true; 2394 2395 // This affects two different things: 2396 // - how Decode nodes are matched 2397 // - how ImplicitNullCheck opportunities are recognized 2398 // If true, the matcher will try to remove all Decodes and match them 2399 // (as operands) into nodes. NullChecks are not prepared to deal with 2400 // Decodes by final_graph_reshaping(). 2401 // If false, final_graph_reshaping() forces the decode behind the Cmp 2402 // for a NullCheck. The matcher matches the Decode node into a register. 2403 // Implicit_null_check optimization moves the Decode along with the 2404 // memory operation back up before the NullCheck. 2405 bool Matcher::narrow_oop_use_complex_address() { 2406 // TODO: PPC port if (MatchDecodeNodes) return true; 2407 return false; 2408 } 2409 2410 bool Matcher::narrow_klass_use_complex_address() { 2411 NOT_LP64(ShouldNotCallThis()); 2412 assert(UseCompressedClassPointers, "only for compressed klass code"); 2413 // TODO: PPC port if (MatchDecodeNodes) return true; 2414 return false; 2415 } 2416 2417 bool Matcher::const_oop_prefer_decode() { 2418 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2419 return Universe::narrow_oop_base() == NULL; 2420 } 2421 2422 bool Matcher::const_klass_prefer_decode() { 2423 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2424 return Universe::narrow_klass_base() == NULL; 2425 } 2426 2427 // Is it better to copy float constants, or load them directly from memory? 2428 // Intel can load a float constant from a direct address, requiring no 2429 // extra registers. Most RISCs will have to materialize an address into a 2430 // register first, so they would do better to copy the constant from stack. 2431 const bool Matcher::rematerialize_float_constants = false; 2432 2433 // If CPU can load and store mis-aligned doubles directly then no fixup is 2434 // needed. Else we split the double into 2 integer pieces and move it 2435 // piece-by-piece. Only happens when passing doubles into C code as the 2436 // Java calling convention forces doubles to be aligned. 2437 const bool Matcher::misaligned_doubles_ok = true; 2438 2439 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2440 Unimplemented(); 2441 } 2442 2443 // Advertise here if the CPU requires explicit rounding operations 2444 // to implement the UseStrictFP mode. 2445 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2446 2447 // Do floats take an entire double register or just half? 2448 // 2449 // A float occupies a ppc64 double register. For the allocator, a 2450 // ppc64 double register appears as a pair of float registers. 2451 bool Matcher::float_in_double() { return true; } 2452 2453 // Do ints take an entire long register or just half? 2454 // The relevant question is how the int is callee-saved: 2455 // the whole long is written but de-opt'ing will have to extract 2456 // the relevant 32 bits. 2457 const bool Matcher::int_in_long = true; 2458 2459 // Constants for c2c and c calling conventions. 2460 2461 const MachRegisterNumbers iarg_reg[8] = { 2462 R3_num, R4_num, R5_num, R6_num, 2463 R7_num, R8_num, R9_num, R10_num 2464 }; 2465 2466 const MachRegisterNumbers farg_reg[13] = { 2467 F1_num, F2_num, F3_num, F4_num, 2468 F5_num, F6_num, F7_num, F8_num, 2469 F9_num, F10_num, F11_num, F12_num, 2470 F13_num 2471 }; 2472 2473 const MachRegisterNumbers vsarg_reg[64] = { 2474 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2475 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2476 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2477 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2478 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2479 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2480 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2481 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2482 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2483 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2484 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2485 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2486 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2487 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2488 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2489 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2490 }; 2491 2492 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2493 2494 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2495 2496 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2497 2498 // Return whether or not this register is ever used as an argument. This 2499 // function is used on startup to build the trampoline stubs in generateOptoStub. 2500 // Registers not mentioned will be killed by the VM call in the trampoline, and 2501 // arguments in those registers not be available to the callee. 2502 bool Matcher::can_be_java_arg(int reg) { 2503 // We return true for all registers contained in iarg_reg[] and 2504 // farg_reg[] and their virtual halves. 2505 // We must include the virtual halves in order to get STDs and LDs 2506 // instead of STWs and LWs in the trampoline stubs. 2507 2508 if ( reg == R3_num || reg == R3_H_num 2509 || reg == R4_num || reg == R4_H_num 2510 || reg == R5_num || reg == R5_H_num 2511 || reg == R6_num || reg == R6_H_num 2512 || reg == R7_num || reg == R7_H_num 2513 || reg == R8_num || reg == R8_H_num 2514 || reg == R9_num || reg == R9_H_num 2515 || reg == R10_num || reg == R10_H_num) 2516 return true; 2517 2518 if ( reg == F1_num || reg == F1_H_num 2519 || reg == F2_num || reg == F2_H_num 2520 || reg == F3_num || reg == F3_H_num 2521 || reg == F4_num || reg == F4_H_num 2522 || reg == F5_num || reg == F5_H_num 2523 || reg == F6_num || reg == F6_H_num 2524 || reg == F7_num || reg == F7_H_num 2525 || reg == F8_num || reg == F8_H_num 2526 || reg == F9_num || reg == F9_H_num 2527 || reg == F10_num || reg == F10_H_num 2528 || reg == F11_num || reg == F11_H_num 2529 || reg == F12_num || reg == F12_H_num 2530 || reg == F13_num || reg == F13_H_num) 2531 return true; 2532 2533 return false; 2534 } 2535 2536 bool Matcher::is_spillable_arg(int reg) { 2537 return can_be_java_arg(reg); 2538 } 2539 2540 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2541 return false; 2542 } 2543 2544 // Register for DIVI projection of divmodI. 2545 RegMask Matcher::divI_proj_mask() { 2546 ShouldNotReachHere(); 2547 return RegMask(); 2548 } 2549 2550 // Register for MODI projection of divmodI. 2551 RegMask Matcher::modI_proj_mask() { 2552 ShouldNotReachHere(); 2553 return RegMask(); 2554 } 2555 2556 // Register for DIVL projection of divmodL. 2557 RegMask Matcher::divL_proj_mask() { 2558 ShouldNotReachHere(); 2559 return RegMask(); 2560 } 2561 2562 // Register for MODL projection of divmodL. 2563 RegMask Matcher::modL_proj_mask() { 2564 ShouldNotReachHere(); 2565 return RegMask(); 2566 } 2567 2568 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2569 return RegMask(); 2570 } 2571 2572 const bool Matcher::convi2l_type_required = true; 2573 2574 %} 2575 2576 //----------ENCODING BLOCK----------------------------------------------------- 2577 // This block specifies the encoding classes used by the compiler to output 2578 // byte streams. Encoding classes are parameterized macros used by 2579 // Machine Instruction Nodes in order to generate the bit encoding of the 2580 // instruction. Operands specify their base encoding interface with the 2581 // interface keyword. There are currently supported four interfaces, 2582 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2583 // operand to generate a function which returns its register number when 2584 // queried. CONST_INTER causes an operand to generate a function which 2585 // returns the value of the constant when queried. MEMORY_INTER causes an 2586 // operand to generate four functions which return the Base Register, the 2587 // Index Register, the Scale Value, and the Offset Value of the operand when 2588 // queried. COND_INTER causes an operand to generate six functions which 2589 // return the encoding code (ie - encoding bits for the instruction) 2590 // associated with each basic boolean condition for a conditional instruction. 2591 // 2592 // Instructions specify two basic values for encoding. Again, a function 2593 // is available to check if the constant displacement is an oop. They use the 2594 // ins_encode keyword to specify their encoding classes (which must be 2595 // a sequence of enc_class names, and their parameters, specified in 2596 // the encoding block), and they use the 2597 // opcode keyword to specify, in order, their primary, secondary, and 2598 // tertiary opcode. Only the opcode sections which a particular instruction 2599 // needs for encoding need to be specified. 2600 encode %{ 2601 enc_class enc_unimplemented %{ 2602 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2603 MacroAssembler _masm(&cbuf); 2604 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2605 %} 2606 2607 enc_class enc_untested %{ 2608 #ifdef ASSERT 2609 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2610 MacroAssembler _masm(&cbuf); 2611 __ untested("Untested mach node encoding in AD file."); 2612 #else 2613 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2614 #endif 2615 %} 2616 2617 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2618 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2619 MacroAssembler _masm(&cbuf); 2620 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2621 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2622 %} 2623 2624 // Load acquire. 2625 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2626 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2627 MacroAssembler _masm(&cbuf); 2628 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2629 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2630 __ twi_0($dst$$Register); 2631 __ isync(); 2632 %} 2633 2634 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2635 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2636 2637 MacroAssembler _masm(&cbuf); 2638 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2639 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2640 %} 2641 2642 // Load acquire. 2643 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2644 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2645 2646 MacroAssembler _masm(&cbuf); 2647 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2648 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2649 __ twi_0($dst$$Register); 2650 __ isync(); 2651 %} 2652 2653 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2654 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2655 2656 MacroAssembler _masm(&cbuf); 2657 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2658 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2659 %} 2660 2661 // Load acquire. 2662 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2663 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2664 2665 MacroAssembler _masm(&cbuf); 2666 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2667 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2668 __ twi_0($dst$$Register); 2669 __ isync(); 2670 %} 2671 2672 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2673 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2674 MacroAssembler _masm(&cbuf); 2675 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2676 // Operand 'ds' requires 4-alignment. 2677 assert((Idisp & 0x3) == 0, "unaligned offset"); 2678 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2679 %} 2680 2681 // Load acquire. 2682 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2683 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2684 MacroAssembler _masm(&cbuf); 2685 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2686 // Operand 'ds' requires 4-alignment. 2687 assert((Idisp & 0x3) == 0, "unaligned offset"); 2688 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2689 __ twi_0($dst$$Register); 2690 __ isync(); 2691 %} 2692 2693 enc_class enc_lfd(RegF dst, memory mem) %{ 2694 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2695 MacroAssembler _masm(&cbuf); 2696 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2697 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2698 %} 2699 2700 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2701 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2702 2703 MacroAssembler _masm(&cbuf); 2704 int toc_offset = 0; 2705 2706 address const_toc_addr; 2707 // Create a non-oop constant, no relocation needed. 2708 // If it is an IC, it has a virtual_call_Relocation. 2709 const_toc_addr = __ long_constant((jlong)$src$$constant); 2710 if (const_toc_addr == NULL) { 2711 ciEnv::current()->record_out_of_memory_failure(); 2712 return; 2713 } 2714 2715 // Get the constant's TOC offset. 2716 toc_offset = __ offset_to_method_toc(const_toc_addr); 2717 2718 // Keep the current instruction offset in mind. 2719 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2720 2721 __ ld($dst$$Register, toc_offset, $toc$$Register); 2722 %} 2723 2724 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2725 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2726 2727 MacroAssembler _masm(&cbuf); 2728 2729 if (!ra_->C->in_scratch_emit_size()) { 2730 address const_toc_addr; 2731 // Create a non-oop constant, no relocation needed. 2732 // If it is an IC, it has a virtual_call_Relocation. 2733 const_toc_addr = __ long_constant((jlong)$src$$constant); 2734 if (const_toc_addr == NULL) { 2735 ciEnv::current()->record_out_of_memory_failure(); 2736 return; 2737 } 2738 2739 // Get the constant's TOC offset. 2740 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2741 // Store the toc offset of the constant. 2742 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2743 2744 // Also keep the current instruction offset in mind. 2745 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2746 } 2747 2748 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2749 %} 2750 2751 %} // encode 2752 2753 source %{ 2754 2755 typedef struct { 2756 loadConL_hiNode *_large_hi; 2757 loadConL_loNode *_large_lo; 2758 loadConLNode *_small; 2759 MachNode *_last; 2760 } loadConLNodesTuple; 2761 2762 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2763 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2764 loadConLNodesTuple nodes; 2765 2766 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2767 if (large_constant_pool) { 2768 // Create new nodes. 2769 loadConL_hiNode *m1 = new loadConL_hiNode(); 2770 loadConL_loNode *m2 = new loadConL_loNode(); 2771 2772 // inputs for new nodes 2773 m1->add_req(NULL, toc); 2774 m2->add_req(NULL, m1); 2775 2776 // operands for new nodes 2777 m1->_opnds[0] = new iRegLdstOper(); // dst 2778 m1->_opnds[1] = immSrc; // src 2779 m1->_opnds[2] = new iRegPdstOper(); // toc 2780 m2->_opnds[0] = new iRegLdstOper(); // dst 2781 m2->_opnds[1] = immSrc; // src 2782 m2->_opnds[2] = new iRegLdstOper(); // base 2783 2784 // Initialize ins_attrib TOC fields. 2785 m1->_const_toc_offset = -1; 2786 m2->_const_toc_offset_hi_node = m1; 2787 2788 // Initialize ins_attrib instruction offset. 2789 m1->_cbuf_insts_offset = -1; 2790 2791 // register allocation for new nodes 2792 ra_->set_pair(m1->_idx, reg_second, reg_first); 2793 ra_->set_pair(m2->_idx, reg_second, reg_first); 2794 2795 // Create result. 2796 nodes._large_hi = m1; 2797 nodes._large_lo = m2; 2798 nodes._small = NULL; 2799 nodes._last = nodes._large_lo; 2800 assert(m2->bottom_type()->isa_long(), "must be long"); 2801 } else { 2802 loadConLNode *m2 = new loadConLNode(); 2803 2804 // inputs for new nodes 2805 m2->add_req(NULL, toc); 2806 2807 // operands for new nodes 2808 m2->_opnds[0] = new iRegLdstOper(); // dst 2809 m2->_opnds[1] = immSrc; // src 2810 m2->_opnds[2] = new iRegPdstOper(); // toc 2811 2812 // Initialize ins_attrib instruction offset. 2813 m2->_cbuf_insts_offset = -1; 2814 2815 // register allocation for new nodes 2816 ra_->set_pair(m2->_idx, reg_second, reg_first); 2817 2818 // Create result. 2819 nodes._large_hi = NULL; 2820 nodes._large_lo = NULL; 2821 nodes._small = m2; 2822 nodes._last = nodes._small; 2823 assert(m2->bottom_type()->isa_long(), "must be long"); 2824 } 2825 2826 return nodes; 2827 } 2828 2829 typedef struct { 2830 loadConL_hiNode *_large_hi; 2831 loadConL_loNode *_large_lo; 2832 mtvsrdNode *_moved; 2833 xxspltdNode *_replicated; 2834 loadConLNode *_small; 2835 MachNode *_last; 2836 } loadConLReplicatedNodesTuple; 2837 2838 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2839 vecXOper *dst, immI_0Oper *zero, 2840 OptoReg::Name reg_second, OptoReg::Name reg_first, 2841 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2842 loadConLReplicatedNodesTuple nodes; 2843 2844 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2845 if (large_constant_pool) { 2846 // Create new nodes. 2847 loadConL_hiNode *m1 = new loadConL_hiNode(); 2848 loadConL_loNode *m2 = new loadConL_loNode(); 2849 mtvsrdNode *m3 = new mtvsrdNode(); 2850 xxspltdNode *m4 = new xxspltdNode(); 2851 2852 // inputs for new nodes 2853 m1->add_req(NULL, toc); 2854 m2->add_req(NULL, m1); 2855 m3->add_req(NULL, m2); 2856 m4->add_req(NULL, m3); 2857 2858 // operands for new nodes 2859 m1->_opnds[0] = new iRegLdstOper(); // dst 2860 m1->_opnds[1] = immSrc; // src 2861 m1->_opnds[2] = new iRegPdstOper(); // toc 2862 2863 m2->_opnds[0] = new iRegLdstOper(); // dst 2864 m2->_opnds[1] = immSrc; // src 2865 m2->_opnds[2] = new iRegLdstOper(); // base 2866 2867 m3->_opnds[0] = new vecXOper(); // dst 2868 m3->_opnds[1] = new iRegLdstOper(); // src 2869 2870 m4->_opnds[0] = new vecXOper(); // dst 2871 m4->_opnds[1] = new vecXOper(); // src 2872 m4->_opnds[2] = zero; 2873 2874 // Initialize ins_attrib TOC fields. 2875 m1->_const_toc_offset = -1; 2876 m2->_const_toc_offset_hi_node = m1; 2877 2878 // Initialize ins_attrib instruction offset. 2879 m1->_cbuf_insts_offset = -1; 2880 2881 // register allocation for new nodes 2882 ra_->set_pair(m1->_idx, reg_second, reg_first); 2883 ra_->set_pair(m2->_idx, reg_second, reg_first); 2884 ra_->set1(m3->_idx, reg_second); 2885 ra_->set2(m3->_idx, reg_vec_first); 2886 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2887 2888 // Create result. 2889 nodes._large_hi = m1; 2890 nodes._large_lo = m2; 2891 nodes._moved = m3; 2892 nodes._replicated = m4; 2893 nodes._small = NULL; 2894 nodes._last = nodes._replicated; 2895 assert(m2->bottom_type()->isa_long(), "must be long"); 2896 } else { 2897 loadConLNode *m2 = new loadConLNode(); 2898 mtvsrdNode *m3 = new mtvsrdNode(); 2899 xxspltdNode *m4 = new xxspltdNode(); 2900 2901 // inputs for new nodes 2902 m2->add_req(NULL, toc); 2903 2904 // operands for new nodes 2905 m2->_opnds[0] = new iRegLdstOper(); // dst 2906 m2->_opnds[1] = immSrc; // src 2907 m2->_opnds[2] = new iRegPdstOper(); // toc 2908 2909 m3->_opnds[0] = new vecXOper(); // dst 2910 m3->_opnds[1] = new iRegLdstOper(); // src 2911 2912 m4->_opnds[0] = new vecXOper(); // dst 2913 m4->_opnds[1] = new vecXOper(); // src 2914 m4->_opnds[2] = zero; 2915 2916 // Initialize ins_attrib instruction offset. 2917 m2->_cbuf_insts_offset = -1; 2918 ra_->set1(m3->_idx, reg_second); 2919 ra_->set2(m3->_idx, reg_vec_first); 2920 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2921 2922 // register allocation for new nodes 2923 ra_->set_pair(m2->_idx, reg_second, reg_first); 2924 2925 // Create result. 2926 nodes._large_hi = NULL; 2927 nodes._large_lo = NULL; 2928 nodes._small = m2; 2929 nodes._moved = m3; 2930 nodes._replicated = m4; 2931 nodes._last = nodes._replicated; 2932 assert(m2->bottom_type()->isa_long(), "must be long"); 2933 } 2934 2935 return nodes; 2936 } 2937 2938 %} // source 2939 2940 encode %{ 2941 // Postalloc expand emitter for loading a long constant from the method's TOC. 2942 // Enc_class needed as consttanttablebase is not supported by postalloc 2943 // expand. 2944 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2945 // Create new nodes. 2946 loadConLNodesTuple loadConLNodes = 2947 loadConLNodesTuple_create(ra_, n_toc, op_src, 2948 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2949 2950 // Push new nodes. 2951 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2952 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2953 2954 // some asserts 2955 assert(nodes->length() >= 1, "must have created at least 1 node"); 2956 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2957 %} 2958 2959 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2960 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2961 2962 MacroAssembler _masm(&cbuf); 2963 int toc_offset = 0; 2964 2965 intptr_t val = $src$$constant; 2966 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2967 address const_toc_addr; 2968 if (constant_reloc == relocInfo::oop_type) { 2969 // Create an oop constant and a corresponding relocation. 2970 AddressLiteral a = __ allocate_oop_address((jobject)val); 2971 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2972 __ relocate(a.rspec()); 2973 } else if (constant_reloc == relocInfo::metadata_type) { 2974 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2975 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2976 __ relocate(a.rspec()); 2977 } else { 2978 // Create a non-oop constant, no relocation needed. 2979 const_toc_addr = __ long_constant((jlong)$src$$constant); 2980 } 2981 2982 if (const_toc_addr == NULL) { 2983 ciEnv::current()->record_out_of_memory_failure(); 2984 return; 2985 } 2986 // Get the constant's TOC offset. 2987 toc_offset = __ offset_to_method_toc(const_toc_addr); 2988 2989 __ ld($dst$$Register, toc_offset, $toc$$Register); 2990 %} 2991 2992 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2993 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2994 2995 MacroAssembler _masm(&cbuf); 2996 if (!ra_->C->in_scratch_emit_size()) { 2997 intptr_t val = $src$$constant; 2998 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2999 address const_toc_addr; 3000 if (constant_reloc == relocInfo::oop_type) { 3001 // Create an oop constant and a corresponding relocation. 3002 AddressLiteral a = __ allocate_oop_address((jobject)val); 3003 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3004 __ relocate(a.rspec()); 3005 } else if (constant_reloc == relocInfo::metadata_type) { 3006 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 3007 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3008 __ relocate(a.rspec()); 3009 } else { // non-oop pointers, e.g. card mark base, heap top 3010 // Create a non-oop constant, no relocation needed. 3011 const_toc_addr = __ long_constant((jlong)$src$$constant); 3012 } 3013 3014 if (const_toc_addr == NULL) { 3015 ciEnv::current()->record_out_of_memory_failure(); 3016 return; 3017 } 3018 // Get the constant's TOC offset. 3019 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 3020 // Store the toc offset of the constant. 3021 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 3022 } 3023 3024 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 3025 %} 3026 3027 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 3028 // Enc_class needed as consttanttablebase is not supported by postalloc 3029 // expand. 3030 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 3031 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3032 if (large_constant_pool) { 3033 // Create new nodes. 3034 loadConP_hiNode *m1 = new loadConP_hiNode(); 3035 loadConP_loNode *m2 = new loadConP_loNode(); 3036 3037 // inputs for new nodes 3038 m1->add_req(NULL, n_toc); 3039 m2->add_req(NULL, m1); 3040 3041 // operands for new nodes 3042 m1->_opnds[0] = new iRegPdstOper(); // dst 3043 m1->_opnds[1] = op_src; // src 3044 m1->_opnds[2] = new iRegPdstOper(); // toc 3045 m2->_opnds[0] = new iRegPdstOper(); // dst 3046 m2->_opnds[1] = op_src; // src 3047 m2->_opnds[2] = new iRegLdstOper(); // base 3048 3049 // Initialize ins_attrib TOC fields. 3050 m1->_const_toc_offset = -1; 3051 m2->_const_toc_offset_hi_node = m1; 3052 3053 // Register allocation for new nodes. 3054 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3055 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3056 3057 nodes->push(m1); 3058 nodes->push(m2); 3059 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3060 } else { 3061 loadConPNode *m2 = new loadConPNode(); 3062 3063 // inputs for new nodes 3064 m2->add_req(NULL, n_toc); 3065 3066 // operands for new nodes 3067 m2->_opnds[0] = new iRegPdstOper(); // dst 3068 m2->_opnds[1] = op_src; // src 3069 m2->_opnds[2] = new iRegPdstOper(); // toc 3070 3071 // Register allocation for new nodes. 3072 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3073 3074 nodes->push(m2); 3075 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3076 } 3077 %} 3078 3079 // Enc_class needed as consttanttablebase is not supported by postalloc 3080 // expand. 3081 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3082 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3083 3084 MachNode *m2; 3085 if (large_constant_pool) { 3086 m2 = new loadConFCompNode(); 3087 } else { 3088 m2 = new loadConFNode(); 3089 } 3090 // inputs for new nodes 3091 m2->add_req(NULL, n_toc); 3092 3093 // operands for new nodes 3094 m2->_opnds[0] = op_dst; 3095 m2->_opnds[1] = op_src; 3096 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3097 3098 // register allocation for new nodes 3099 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3100 nodes->push(m2); 3101 %} 3102 3103 // Enc_class needed as consttanttablebase is not supported by postalloc 3104 // expand. 3105 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3106 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3107 3108 MachNode *m2; 3109 if (large_constant_pool) { 3110 m2 = new loadConDCompNode(); 3111 } else { 3112 m2 = new loadConDNode(); 3113 } 3114 // inputs for new nodes 3115 m2->add_req(NULL, n_toc); 3116 3117 // operands for new nodes 3118 m2->_opnds[0] = op_dst; 3119 m2->_opnds[1] = op_src; 3120 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3121 3122 // register allocation for new nodes 3123 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3124 nodes->push(m2); 3125 %} 3126 3127 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3128 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3129 MacroAssembler _masm(&cbuf); 3130 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3131 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3132 %} 3133 3134 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3135 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3136 MacroAssembler _masm(&cbuf); 3137 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3138 // Operand 'ds' requires 4-alignment. 3139 assert((Idisp & 0x3) == 0, "unaligned offset"); 3140 __ std($src$$Register, Idisp, $mem$$base$$Register); 3141 %} 3142 3143 enc_class enc_stfs(RegF src, memory mem) %{ 3144 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3145 MacroAssembler _masm(&cbuf); 3146 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3147 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3148 %} 3149 3150 enc_class enc_stfd(RegF src, memory mem) %{ 3151 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3152 MacroAssembler _masm(&cbuf); 3153 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3154 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3155 %} 3156 3157 // Use release_store for card-marking to ensure that previous 3158 // oop-stores are visible before the card-mark change. 3159 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3160 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3161 // FIXME: Implement this as a cmove and use a fixed condition code 3162 // register which is written on every transition to compiled code, 3163 // e.g. in call-stub and when returning from runtime stubs. 3164 // 3165 // Proposed code sequence for the cmove implementation: 3166 // 3167 // Label skip_release; 3168 // __ beq(CCRfixed, skip_release); 3169 // __ release(); 3170 // __ bind(skip_release); 3171 // __ stb(card mark); 3172 3173 MacroAssembler _masm(&cbuf); 3174 Label skip_storestore; 3175 3176 #if 0 // TODO: PPC port 3177 // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the 3178 // StoreStore barrier conditionally. 3179 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3180 __ cmpwi($crx$$CondRegister, R0, 0); 3181 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3182 #endif 3183 __ li(R0, 0); 3184 __ membar(Assembler::StoreStore); 3185 #if 0 // TODO: PPC port 3186 __ bind(skip_storestore); 3187 #endif 3188 3189 // Do the store. 3190 if ($mem$$index == 0) { 3191 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3192 } else { 3193 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3194 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3195 } 3196 %} 3197 3198 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3199 3200 if (VM_Version::has_isel()) { 3201 // use isel instruction with Power 7 3202 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3203 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3204 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3205 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3206 3207 n_compare->add_req(n_region, n_src); 3208 n_compare->_opnds[0] = op_crx; 3209 n_compare->_opnds[1] = op_src; 3210 n_compare->_opnds[2] = new immL16Oper(0); 3211 3212 n_sub_base->add_req(n_region, n_src); 3213 n_sub_base->_opnds[0] = op_dst; 3214 n_sub_base->_opnds[1] = op_src; 3215 n_sub_base->_bottom_type = _bottom_type; 3216 3217 n_shift->add_req(n_region, n_sub_base); 3218 n_shift->_opnds[0] = op_dst; 3219 n_shift->_opnds[1] = op_dst; 3220 n_shift->_bottom_type = _bottom_type; 3221 3222 n_cond_set->add_req(n_region, n_compare, n_shift); 3223 n_cond_set->_opnds[0] = op_dst; 3224 n_cond_set->_opnds[1] = op_crx; 3225 n_cond_set->_opnds[2] = op_dst; 3226 n_cond_set->_bottom_type = _bottom_type; 3227 3228 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3229 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3230 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3231 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3232 3233 nodes->push(n_compare); 3234 nodes->push(n_sub_base); 3235 nodes->push(n_shift); 3236 nodes->push(n_cond_set); 3237 3238 } else { 3239 // before Power 7 3240 moveRegNode *n_move = new moveRegNode(); 3241 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3242 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3243 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3244 3245 n_move->add_req(n_region, n_src); 3246 n_move->_opnds[0] = op_dst; 3247 n_move->_opnds[1] = op_src; 3248 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3249 3250 n_compare->add_req(n_region, n_src); 3251 n_compare->add_prec(n_move); 3252 3253 n_compare->_opnds[0] = op_crx; 3254 n_compare->_opnds[1] = op_src; 3255 n_compare->_opnds[2] = new immL16Oper(0); 3256 3257 n_sub_base->add_req(n_region, n_compare, n_src); 3258 n_sub_base->_opnds[0] = op_dst; 3259 n_sub_base->_opnds[1] = op_crx; 3260 n_sub_base->_opnds[2] = op_src; 3261 n_sub_base->_bottom_type = _bottom_type; 3262 3263 n_shift->add_req(n_region, n_sub_base); 3264 n_shift->_opnds[0] = op_dst; 3265 n_shift->_opnds[1] = op_dst; 3266 n_shift->_bottom_type = _bottom_type; 3267 3268 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3269 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3270 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3271 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3272 3273 nodes->push(n_move); 3274 nodes->push(n_compare); 3275 nodes->push(n_sub_base); 3276 nodes->push(n_shift); 3277 } 3278 3279 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3280 %} 3281 3282 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3283 3284 encodeP_subNode *n1 = new encodeP_subNode(); 3285 n1->add_req(n_region, n_src); 3286 n1->_opnds[0] = op_dst; 3287 n1->_opnds[1] = op_src; 3288 n1->_bottom_type = _bottom_type; 3289 3290 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3291 n2->add_req(n_region, n1); 3292 n2->_opnds[0] = op_dst; 3293 n2->_opnds[1] = op_dst; 3294 n2->_bottom_type = _bottom_type; 3295 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3296 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3297 3298 nodes->push(n1); 3299 nodes->push(n2); 3300 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3301 %} 3302 3303 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3304 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3305 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3306 3307 n_compare->add_req(n_region, n_src); 3308 n_compare->_opnds[0] = op_crx; 3309 n_compare->_opnds[1] = op_src; 3310 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3311 3312 n_shift->add_req(n_region, n_src); 3313 n_shift->_opnds[0] = op_dst; 3314 n_shift->_opnds[1] = op_src; 3315 n_shift->_bottom_type = _bottom_type; 3316 3317 if (VM_Version::has_isel()) { 3318 // use isel instruction with Power 7 3319 3320 decodeN_addNode *n_add_base = new decodeN_addNode(); 3321 n_add_base->add_req(n_region, n_shift); 3322 n_add_base->_opnds[0] = op_dst; 3323 n_add_base->_opnds[1] = op_dst; 3324 n_add_base->_bottom_type = _bottom_type; 3325 3326 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3327 n_cond_set->add_req(n_region, n_compare, n_add_base); 3328 n_cond_set->_opnds[0] = op_dst; 3329 n_cond_set->_opnds[1] = op_crx; 3330 n_cond_set->_opnds[2] = op_dst; 3331 n_cond_set->_bottom_type = _bottom_type; 3332 3333 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3334 ra_->set_oop(n_cond_set, true); 3335 3336 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3337 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3338 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3339 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3340 3341 nodes->push(n_compare); 3342 nodes->push(n_shift); 3343 nodes->push(n_add_base); 3344 nodes->push(n_cond_set); 3345 3346 } else { 3347 // before Power 7 3348 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3349 3350 n_add_base->add_req(n_region, n_compare, n_shift); 3351 n_add_base->_opnds[0] = op_dst; 3352 n_add_base->_opnds[1] = op_crx; 3353 n_add_base->_opnds[2] = op_dst; 3354 n_add_base->_bottom_type = _bottom_type; 3355 3356 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3357 ra_->set_oop(n_add_base, true); 3358 3359 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3360 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3361 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3362 3363 nodes->push(n_compare); 3364 nodes->push(n_shift); 3365 nodes->push(n_add_base); 3366 } 3367 %} 3368 3369 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3370 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3371 n1->add_req(n_region, n_src); 3372 n1->_opnds[0] = op_dst; 3373 n1->_opnds[1] = op_src; 3374 n1->_bottom_type = _bottom_type; 3375 3376 decodeN_addNode *n2 = new decodeN_addNode(); 3377 n2->add_req(n_region, n1); 3378 n2->_opnds[0] = op_dst; 3379 n2->_opnds[1] = op_dst; 3380 n2->_bottom_type = _bottom_type; 3381 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3382 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3383 3384 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3385 ra_->set_oop(n2, true); 3386 3387 nodes->push(n1); 3388 nodes->push(n2); 3389 %} 3390 3391 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3392 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3393 3394 MacroAssembler _masm(&cbuf); 3395 int cc = $cmp$$cmpcode; 3396 int flags_reg = $crx$$reg; 3397 Label done; 3398 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3399 // Branch if not (cmp crx). 3400 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3401 __ mr($dst$$Register, $src$$Register); 3402 // TODO PPC port __ endgroup_if_needed(_size == 12); 3403 __ bind(done); 3404 %} 3405 3406 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3407 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3408 3409 MacroAssembler _masm(&cbuf); 3410 Label done; 3411 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3412 // Branch if not (cmp crx). 3413 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3414 __ li($dst$$Register, $src$$constant); 3415 // TODO PPC port __ endgroup_if_needed(_size == 12); 3416 __ bind(done); 3417 %} 3418 3419 // This enc_class is needed so that scheduler gets proper 3420 // input mapping for latency computation. 3421 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3422 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3423 MacroAssembler _masm(&cbuf); 3424 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3425 %} 3426 3427 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3428 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3429 3430 MacroAssembler _masm(&cbuf); 3431 3432 Label done; 3433 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3434 __ li($dst$$Register, $zero$$constant); 3435 __ beq($crx$$CondRegister, done); 3436 __ li($dst$$Register, $notzero$$constant); 3437 __ bind(done); 3438 %} 3439 3440 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3441 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3442 3443 MacroAssembler _masm(&cbuf); 3444 3445 Label done; 3446 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3447 __ li($dst$$Register, $zero$$constant); 3448 __ beq($crx$$CondRegister, done); 3449 __ li($dst$$Register, $notzero$$constant); 3450 __ bind(done); 3451 %} 3452 3453 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3454 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3455 3456 MacroAssembler _masm(&cbuf); 3457 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3458 Label done; 3459 __ bso($crx$$CondRegister, done); 3460 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3461 // TODO PPC port __ endgroup_if_needed(_size == 12); 3462 __ bind(done); 3463 %} 3464 3465 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3466 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3467 3468 MacroAssembler _masm(&cbuf); 3469 Label done; 3470 __ bso($crx$$CondRegister, done); 3471 __ mffprd($dst$$Register, $src$$FloatRegister); 3472 // TODO PPC port __ endgroup_if_needed(_size == 12); 3473 __ bind(done); 3474 %} 3475 3476 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3477 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3478 3479 MacroAssembler _masm(&cbuf); 3480 Label d; // dummy 3481 __ bind(d); 3482 Label* p = ($lbl$$label); 3483 // `p' is `NULL' when this encoding class is used only to 3484 // determine the size of the encoded instruction. 3485 Label& l = (NULL == p)? d : *(p); 3486 int cc = $cmp$$cmpcode; 3487 int flags_reg = $crx$$reg; 3488 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3489 int bhint = Assembler::bhintNoHint; 3490 3491 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3492 if (_prob <= PROB_NEVER) { 3493 bhint = Assembler::bhintIsNotTaken; 3494 } else if (_prob >= PROB_ALWAYS) { 3495 bhint = Assembler::bhintIsTaken; 3496 } 3497 } 3498 3499 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3500 cc_to_biint(cc, flags_reg), 3501 l); 3502 %} 3503 3504 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3505 // The scheduler doesn't know about branch shortening, so we set the opcode 3506 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3507 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3508 3509 MacroAssembler _masm(&cbuf); 3510 Label d; // dummy 3511 __ bind(d); 3512 Label* p = ($lbl$$label); 3513 // `p' is `NULL' when this encoding class is used only to 3514 // determine the size of the encoded instruction. 3515 Label& l = (NULL == p)? d : *(p); 3516 int cc = $cmp$$cmpcode; 3517 int flags_reg = $crx$$reg; 3518 int bhint = Assembler::bhintNoHint; 3519 3520 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3521 if (_prob <= PROB_NEVER) { 3522 bhint = Assembler::bhintIsNotTaken; 3523 } else if (_prob >= PROB_ALWAYS) { 3524 bhint = Assembler::bhintIsTaken; 3525 } 3526 } 3527 3528 // Tell the conditional far branch to optimize itself when being relocated. 3529 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3530 cc_to_biint(cc, flags_reg), 3531 l, 3532 MacroAssembler::bc_far_optimize_on_relocate); 3533 %} 3534 3535 // Branch used with Power6 scheduling (can be shortened without changing the node). 3536 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3537 // The scheduler doesn't know about branch shortening, so we set the opcode 3538 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3539 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3540 3541 MacroAssembler _masm(&cbuf); 3542 Label d; // dummy 3543 __ bind(d); 3544 Label* p = ($lbl$$label); 3545 // `p' is `NULL' when this encoding class is used only to 3546 // determine the size of the encoded instruction. 3547 Label& l = (NULL == p)? d : *(p); 3548 int cc = $cmp$$cmpcode; 3549 int flags_reg = $crx$$reg; 3550 int bhint = Assembler::bhintNoHint; 3551 3552 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3553 if (_prob <= PROB_NEVER) { 3554 bhint = Assembler::bhintIsNotTaken; 3555 } else if (_prob >= PROB_ALWAYS) { 3556 bhint = Assembler::bhintIsTaken; 3557 } 3558 } 3559 3560 #if 0 // TODO: PPC port 3561 if (_size == 8) { 3562 // Tell the conditional far branch to optimize itself when being relocated. 3563 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3564 cc_to_biint(cc, flags_reg), 3565 l, 3566 MacroAssembler::bc_far_optimize_on_relocate); 3567 } else { 3568 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3569 cc_to_biint(cc, flags_reg), 3570 l); 3571 } 3572 #endif 3573 Unimplemented(); 3574 %} 3575 3576 // Postalloc expand emitter for loading a replicatef float constant from 3577 // the method's TOC. 3578 // Enc_class needed as consttanttablebase is not supported by postalloc 3579 // expand. 3580 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3581 // Create new nodes. 3582 3583 // Make an operand with the bit pattern to load as float. 3584 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3585 3586 loadConLNodesTuple loadConLNodes = 3587 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3588 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3589 3590 // Push new nodes. 3591 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3592 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3593 3594 assert(nodes->length() >= 1, "must have created at least 1 node"); 3595 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3596 %} 3597 3598 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3599 // Create new nodes. 3600 3601 // Make an operand with the bit pattern to load as float. 3602 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3603 immI_0Oper *op_zero = new immI_0Oper(0); 3604 3605 loadConLReplicatedNodesTuple loadConLNodes = 3606 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3607 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3608 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3609 3610 // Push new nodes. 3611 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3612 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3613 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3614 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3615 3616 assert(nodes->length() >= 1, "must have created at least 1 node"); 3617 %} 3618 3619 // This enc_class is needed so that scheduler gets proper 3620 // input mapping for latency computation. 3621 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3622 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3623 // Fake operand dst needed for PPC scheduler. 3624 assert($dst$$constant == 0x0, "dst must be 0x0"); 3625 3626 MacroAssembler _masm(&cbuf); 3627 // Mark the code position where the load from the safepoint 3628 // polling page was emitted as relocInfo::poll_type. 3629 __ relocate(relocInfo::poll_type); 3630 __ load_from_polling_page($poll$$Register); 3631 %} 3632 3633 // A Java static call or a runtime call. 3634 // 3635 // Branch-and-link relative to a trampoline. 3636 // The trampoline loads the target address and does a long branch to there. 3637 // In case we call java, the trampoline branches to a interpreter_stub 3638 // which loads the inline cache and the real call target from the constant pool. 3639 // 3640 // This basically looks like this: 3641 // 3642 // >>>> consts -+ -+ 3643 // | |- offset1 3644 // [call target1] | <-+ 3645 // [IC cache] |- offset2 3646 // [call target2] <--+ 3647 // 3648 // <<<< consts 3649 // >>>> insts 3650 // 3651 // bl offset16 -+ -+ ??? // How many bits available? 3652 // | | 3653 // <<<< insts | | 3654 // >>>> stubs | | 3655 // | |- trampoline_stub_Reloc 3656 // trampoline stub: | <-+ 3657 // r2 = toc | 3658 // r2 = [r2 + offset1] | // Load call target1 from const section 3659 // mtctr r2 | 3660 // bctr |- static_stub_Reloc 3661 // comp_to_interp_stub: <---+ 3662 // r1 = toc 3663 // ICreg = [r1 + IC_offset] // Load IC from const section 3664 // r1 = [r1 + offset2] // Load call target2 from const section 3665 // mtctr r1 3666 // bctr 3667 // 3668 // <<<< stubs 3669 // 3670 // The call instruction in the code either 3671 // - Branches directly to a compiled method if the offset is encodable in instruction. 3672 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3673 // - Branches to the compiled_to_interp stub if the target is interpreted. 3674 // 3675 // Further there are three relocations from the loads to the constants in 3676 // the constant section. 3677 // 3678 // Usage of r1 and r2 in the stubs allows to distinguish them. 3679 enc_class enc_java_static_call(method meth) %{ 3680 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3681 3682 MacroAssembler _masm(&cbuf); 3683 address entry_point = (address)$meth$$method; 3684 3685 if (!_method) { 3686 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3687 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3688 } else { 3689 // Remember the offset not the address. 3690 const int start_offset = __ offset(); 3691 3692 // The trampoline stub. 3693 // No entry point given, use the current pc. 3694 // Make sure branch fits into 3695 if (entry_point == 0) entry_point = __ pc(); 3696 3697 // Put the entry point as a constant into the constant pool. 3698 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3699 if (entry_point_toc_addr == NULL) { 3700 ciEnv::current()->record_out_of_memory_failure(); 3701 return; 3702 } 3703 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3704 3705 // Emit the trampoline stub which will be related to the branch-and-link below. 3706 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3707 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3708 int method_index = resolved_method_index(cbuf); 3709 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3710 : static_call_Relocation::spec(method_index)); 3711 3712 // The real call. 3713 // Note: At this point we do not have the address of the trampoline 3714 // stub, and the entry point might be too far away for bl, so __ pc() 3715 // serves as dummy and the bl will be patched later. 3716 cbuf.set_insts_mark(); 3717 __ bl(__ pc()); // Emits a relocation. 3718 3719 // The stub for call to interpreter. 3720 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3721 if (stub == NULL) { 3722 ciEnv::current()->record_failure("CodeCache is full"); 3723 return; 3724 } 3725 } 3726 %} 3727 3728 // Second node of expanded dynamic call - the call. 3729 enc_class enc_java_dynamic_call_sched(method meth) %{ 3730 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3731 3732 MacroAssembler _masm(&cbuf); 3733 3734 if (!ra_->C->in_scratch_emit_size()) { 3735 // Create a call trampoline stub for the given method. 3736 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3737 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3738 if (entry_point_const == NULL) { 3739 ciEnv::current()->record_out_of_memory_failure(); 3740 return; 3741 } 3742 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3743 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3744 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3745 3746 // Build relocation at call site with ic position as data. 3747 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3748 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3749 "must have one, but can't have both"); 3750 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3751 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3752 "must contain instruction offset"); 3753 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3754 ? _load_ic_hi_node->_cbuf_insts_offset 3755 : _load_ic_node->_cbuf_insts_offset; 3756 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3757 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3758 "should be load from TOC"); 3759 int method_index = resolved_method_index(cbuf); 3760 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3761 } 3762 3763 // At this point I do not have the address of the trampoline stub, 3764 // and the entry point might be too far away for bl. Pc() serves 3765 // as dummy and bl will be patched later. 3766 __ bl((address) __ pc()); 3767 %} 3768 3769 // postalloc expand emitter for virtual calls. 3770 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3771 3772 // Create the nodes for loading the IC from the TOC. 3773 loadConLNodesTuple loadConLNodes_IC = 3774 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3775 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3776 3777 // Create the call node. 3778 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3779 call->_method_handle_invoke = _method_handle_invoke; 3780 call->_vtable_index = _vtable_index; 3781 call->_method = _method; 3782 call->_bci = _bci; 3783 call->_optimized_virtual = _optimized_virtual; 3784 call->_tf = _tf; 3785 call->_entry_point = _entry_point; 3786 call->_cnt = _cnt; 3787 call->_argsize = _argsize; 3788 call->_oop_map = _oop_map; 3789 call->_jvms = _jvms; 3790 call->_jvmadj = _jvmadj; 3791 call->_in_rms = _in_rms; 3792 call->_nesting = _nesting; 3793 call->_override_symbolic_info = _override_symbolic_info; 3794 3795 // New call needs all inputs of old call. 3796 // Req... 3797 for (uint i = 0; i < req(); ++i) { 3798 // The expanded node does not need toc any more. 3799 // Add the inline cache constant here instead. This expresses the 3800 // register of the inline cache must be live at the call. 3801 // Else we would have to adapt JVMState by -1. 3802 if (i == mach_constant_base_node_input()) { 3803 call->add_req(loadConLNodes_IC._last); 3804 } else { 3805 call->add_req(in(i)); 3806 } 3807 } 3808 // ...as well as prec 3809 for (uint i = req(); i < len(); ++i) { 3810 call->add_prec(in(i)); 3811 } 3812 3813 // Remember nodes loading the inline cache into r19. 3814 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3815 call->_load_ic_node = loadConLNodes_IC._small; 3816 3817 // Operands for new nodes. 3818 call->_opnds[0] = _opnds[0]; 3819 call->_opnds[1] = _opnds[1]; 3820 3821 // Only the inline cache is associated with a register. 3822 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3823 3824 // Push new nodes. 3825 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3826 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3827 nodes->push(call); 3828 %} 3829 3830 // Compound version of call dynamic 3831 // Toc is only passed so that it can be used in ins_encode statement. 3832 // In the code we have to use $constanttablebase. 3833 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3834 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3835 MacroAssembler _masm(&cbuf); 3836 int start_offset = __ offset(); 3837 3838 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3839 #if 0 3840 int vtable_index = this->_vtable_index; 3841 if (_vtable_index < 0) { 3842 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3843 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3844 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3845 3846 // Virtual call relocation will point to ic load. 3847 address virtual_call_meta_addr = __ pc(); 3848 // Load a clear inline cache. 3849 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3850 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3851 if (!success) { 3852 ciEnv::current()->record_out_of_memory_failure(); 3853 return; 3854 } 3855 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3856 // to determine who we intended to call. 3857 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3858 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3859 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3860 "Fix constant in ret_addr_offset()"); 3861 } else { 3862 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3863 // Go thru the vtable. Get receiver klass. Receiver already 3864 // checked for non-null. If we'll go thru a C2I adapter, the 3865 // interpreter expects method in R19_method. 3866 3867 __ load_klass(R11_scratch1, R3); 3868 3869 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3870 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3871 __ li(R19_method, v_off); 3872 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3873 // NOTE: for vtable dispatches, the vtable entry will never be 3874 // null. However it may very well end up in handle_wrong_method 3875 // if the method is abstract for the particular class. 3876 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3877 // Call target. Either compiled code or C2I adapter. 3878 __ mtctr(R11_scratch1); 3879 __ bctrl(); 3880 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3881 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3882 } 3883 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3884 "Fix constant in ret_addr_offset()"); 3885 } 3886 #endif 3887 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3888 %} 3889 3890 // a runtime call 3891 enc_class enc_java_to_runtime_call (method meth) %{ 3892 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3893 3894 MacroAssembler _masm(&cbuf); 3895 const address start_pc = __ pc(); 3896 3897 #if defined(ABI_ELFv2) 3898 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3899 __ call_c(entry, relocInfo::runtime_call_type); 3900 #else 3901 // The function we're going to call. 3902 FunctionDescriptor fdtemp; 3903 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3904 3905 Register Rtoc = R12_scratch2; 3906 // Calculate the method's TOC. 3907 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3908 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3909 // pool entries; call_c_using_toc will optimize the call. 3910 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3911 if (!success) { 3912 ciEnv::current()->record_out_of_memory_failure(); 3913 return; 3914 } 3915 #endif 3916 3917 // Check the ret_addr_offset. 3918 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3919 "Fix constant in ret_addr_offset()"); 3920 %} 3921 3922 // Move to ctr for leaf call. 3923 // This enc_class is needed so that scheduler gets proper 3924 // input mapping for latency computation. 3925 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3926 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3927 MacroAssembler _masm(&cbuf); 3928 __ mtctr($src$$Register); 3929 %} 3930 3931 // Postalloc expand emitter for runtime leaf calls. 3932 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3933 loadConLNodesTuple loadConLNodes_Entry; 3934 #if defined(ABI_ELFv2) 3935 jlong entry_address = (jlong) this->entry_point(); 3936 assert(entry_address, "need address here"); 3937 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3938 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3939 #else 3940 // Get the struct that describes the function we are about to call. 3941 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3942 assert(fd, "need fd here"); 3943 jlong entry_address = (jlong) fd->entry(); 3944 // new nodes 3945 loadConLNodesTuple loadConLNodes_Env; 3946 loadConLNodesTuple loadConLNodes_Toc; 3947 3948 // Create nodes and operands for loading the entry point. 3949 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3950 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3951 3952 3953 // Create nodes and operands for loading the env pointer. 3954 if (fd->env() != NULL) { 3955 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3956 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3957 } else { 3958 loadConLNodes_Env._large_hi = NULL; 3959 loadConLNodes_Env._large_lo = NULL; 3960 loadConLNodes_Env._small = NULL; 3961 loadConLNodes_Env._last = new loadConL16Node(); 3962 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3963 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3964 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3965 } 3966 3967 // Create nodes and operands for loading the Toc point. 3968 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3969 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3970 #endif // ABI_ELFv2 3971 // mtctr node 3972 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3973 3974 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3975 mtctr->add_req(0, loadConLNodes_Entry._last); 3976 3977 mtctr->_opnds[0] = new iRegLdstOper(); 3978 mtctr->_opnds[1] = new iRegLdstOper(); 3979 3980 // call node 3981 MachCallLeafNode *call = new CallLeafDirectNode(); 3982 3983 call->_opnds[0] = _opnds[0]; 3984 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3985 3986 // Make the new call node look like the old one. 3987 call->_name = _name; 3988 call->_tf = _tf; 3989 call->_entry_point = _entry_point; 3990 call->_cnt = _cnt; 3991 call->_argsize = _argsize; 3992 call->_oop_map = _oop_map; 3993 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3994 call->_jvms = NULL; 3995 call->_jvmadj = _jvmadj; 3996 call->_in_rms = _in_rms; 3997 call->_nesting = _nesting; 3998 3999 4000 // New call needs all inputs of old call. 4001 // Req... 4002 for (uint i = 0; i < req(); ++i) { 4003 if (i != mach_constant_base_node_input()) { 4004 call->add_req(in(i)); 4005 } 4006 } 4007 4008 // These must be reqired edges, as the registers are live up to 4009 // the call. Else the constants are handled as kills. 4010 call->add_req(mtctr); 4011 #if !defined(ABI_ELFv2) 4012 call->add_req(loadConLNodes_Env._last); 4013 call->add_req(loadConLNodes_Toc._last); 4014 #endif 4015 4016 // ...as well as prec 4017 for (uint i = req(); i < len(); ++i) { 4018 call->add_prec(in(i)); 4019 } 4020 4021 // registers 4022 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 4023 4024 // Insert the new nodes. 4025 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 4026 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 4027 #if !defined(ABI_ELFv2) 4028 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 4029 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 4030 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 4031 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 4032 #endif 4033 nodes->push(mtctr); 4034 nodes->push(call); 4035 %} 4036 %} 4037 4038 //----------FRAME-------------------------------------------------------------- 4039 // Definition of frame structure and management information. 4040 4041 frame %{ 4042 // What direction does stack grow in (assumed to be same for native & Java). 4043 stack_direction(TOWARDS_LOW); 4044 4045 // These two registers define part of the calling convention between 4046 // compiled code and the interpreter. 4047 4048 // Inline Cache Register or method for I2C. 4049 inline_cache_reg(R19); // R19_method 4050 4051 // Method Oop Register when calling interpreter. 4052 interpreter_method_oop_reg(R19); // R19_method 4053 4054 // Optional: name the operand used by cisc-spilling to access 4055 // [stack_pointer + offset]. 4056 cisc_spilling_operand_name(indOffset); 4057 4058 // Number of stack slots consumed by a Monitor enter. 4059 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 4060 4061 // Compiled code's Frame Pointer. 4062 frame_pointer(R1); // R1_SP 4063 4064 // Interpreter stores its frame pointer in a register which is 4065 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 4066 // interpreted java to compiled java. 4067 // 4068 // R14_state holds pointer to caller's cInterpreter. 4069 interpreter_frame_pointer(R14); // R14_state 4070 4071 stack_alignment(frame::alignment_in_bytes); 4072 4073 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4074 4075 // Number of outgoing stack slots killed above the 4076 // out_preserve_stack_slots for calls to C. Supports the var-args 4077 // backing area for register parms. 4078 // 4079 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4080 4081 // The after-PROLOG location of the return address. Location of 4082 // return address specifies a type (REG or STACK) and a number 4083 // representing the register number (i.e. - use a register name) or 4084 // stack slot. 4085 // 4086 // A: Link register is stored in stack slot ... 4087 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4088 // J: Therefore, we make sure that the link register is also in R11_scratch1 4089 // at the end of the prolog. 4090 // B: We use R20, now. 4091 //return_addr(REG R20); 4092 4093 // G: After reading the comments made by all the luminaries on their 4094 // failure to tell the compiler where the return address really is, 4095 // I hardly dare to try myself. However, I'm convinced it's in slot 4096 // 4 what apparently works and saves us some spills. 4097 return_addr(STACK 4); 4098 4099 // This is the body of the function 4100 // 4101 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4102 // uint length, // length of array 4103 // bool is_outgoing) 4104 // 4105 // The `sig' array is to be updated. sig[j] represents the location 4106 // of the j-th argument, either a register or a stack slot. 4107 4108 // Comment taken from i486.ad: 4109 // Body of function which returns an integer array locating 4110 // arguments either in registers or in stack slots. Passed an array 4111 // of ideal registers called "sig" and a "length" count. Stack-slot 4112 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4113 // arguments for a CALLEE. Incoming stack arguments are 4114 // automatically biased by the preserve_stack_slots field above. 4115 calling_convention %{ 4116 // No difference between ingoing/outgoing. Just pass false. 4117 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4118 %} 4119 4120 // Comment taken from i486.ad: 4121 // Body of function which returns an integer array locating 4122 // arguments either in registers or in stack slots. Passed an array 4123 // of ideal registers called "sig" and a "length" count. Stack-slot 4124 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4125 // arguments for a CALLEE. Incoming stack arguments are 4126 // automatically biased by the preserve_stack_slots field above. 4127 c_calling_convention %{ 4128 // This is obviously always outgoing. 4129 // C argument in register AND stack slot. 4130 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4131 %} 4132 4133 // Location of native (C/C++) and interpreter return values. This 4134 // is specified to be the same as Java. In the 32-bit VM, long 4135 // values are actually returned from native calls in O0:O1 and 4136 // returned to the interpreter in I0:I1. The copying to and from 4137 // the register pairs is done by the appropriate call and epilog 4138 // opcodes. This simplifies the register allocator. 4139 c_return_value %{ 4140 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4141 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4142 "only return normal values"); 4143 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4144 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4145 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4146 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4147 %} 4148 4149 // Location of compiled Java return values. Same as C 4150 return_value %{ 4151 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4152 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4153 "only return normal values"); 4154 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4155 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4156 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4157 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4158 %} 4159 %} 4160 4161 4162 //----------ATTRIBUTES--------------------------------------------------------- 4163 4164 //----------Operand Attributes------------------------------------------------- 4165 op_attrib op_cost(1); // Required cost attribute. 4166 4167 //----------Instruction Attributes--------------------------------------------- 4168 4169 // Cost attribute. required. 4170 ins_attrib ins_cost(DEFAULT_COST); 4171 4172 // Is this instruction a non-matching short branch variant of some 4173 // long branch? Not required. 4174 ins_attrib ins_short_branch(0); 4175 4176 ins_attrib ins_is_TrapBasedCheckNode(true); 4177 4178 // Number of constants. 4179 // This instruction uses the given number of constants 4180 // (optional attribute). 4181 // This is needed to determine in time whether the constant pool will 4182 // exceed 4000 entries. Before postalloc_expand the overall number of constants 4183 // is determined. It's also used to compute the constant pool size 4184 // in Output(). 4185 ins_attrib ins_num_consts(0); 4186 4187 // Required alignment attribute (must be a power of 2) specifies the 4188 // alignment that some part of the instruction (not necessarily the 4189 // start) requires. If > 1, a compute_padding() function must be 4190 // provided for the instruction. 4191 ins_attrib ins_alignment(1); 4192 4193 // Enforce/prohibit rematerializations. 4194 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4195 // then rematerialization of that instruction is prohibited and the 4196 // instruction's value will be spilled if necessary. 4197 // Causes that MachNode::rematerialize() returns false. 4198 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 4199 // then rematerialization should be enforced and a copy of the instruction 4200 // should be inserted if possible; rematerialization is not guaranteed. 4201 // Note: this may result in rematerializations in front of every use. 4202 // Causes that MachNode::rematerialize() can return true. 4203 // (optional attribute) 4204 ins_attrib ins_cannot_rematerialize(false); 4205 ins_attrib ins_should_rematerialize(false); 4206 4207 // Instruction has variable size depending on alignment. 4208 ins_attrib ins_variable_size_depending_on_alignment(false); 4209 4210 // Instruction is a nop. 4211 ins_attrib ins_is_nop(false); 4212 4213 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4214 ins_attrib ins_use_mach_if_fast_lock_node(false); 4215 4216 // Field for the toc offset of a constant. 4217 // 4218 // This is needed if the toc offset is not encodable as an immediate in 4219 // the PPC load instruction. If so, the upper (hi) bits of the offset are 4220 // added to the toc, and from this a load with immediate is performed. 4221 // With postalloc expand, we get two nodes that require the same offset 4222 // but which don't know about each other. The offset is only known 4223 // when the constant is added to the constant pool during emitting. 4224 // It is generated in the 'hi'-node adding the upper bits, and saved 4225 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 4226 // the offset from there when it gets encoded. 4227 ins_attrib ins_field_const_toc_offset(0); 4228 ins_attrib ins_field_const_toc_offset_hi_node(0); 4229 4230 // A field that can hold the instructions offset in the code buffer. 4231 // Set in the nodes emitter. 4232 ins_attrib ins_field_cbuf_insts_offset(-1); 4233 4234 // Fields for referencing a call's load-IC-node. 4235 // If the toc offset can not be encoded as an immediate in a load, we 4236 // use two nodes. 4237 ins_attrib ins_field_load_ic_hi_node(0); 4238 ins_attrib ins_field_load_ic_node(0); 4239 4240 //----------OPERANDS----------------------------------------------------------- 4241 // Operand definitions must precede instruction definitions for correct 4242 // parsing in the ADLC because operands constitute user defined types 4243 // which are used in instruction definitions. 4244 // 4245 // Formats are generated automatically for constants and base registers. 4246 4247 operand vecX() %{ 4248 constraint(ALLOC_IN_RC(vs_reg)); 4249 match(VecX); 4250 4251 format %{ %} 4252 interface(REG_INTER); 4253 %} 4254 4255 //----------Simple Operands---------------------------------------------------- 4256 // Immediate Operands 4257 4258 // Integer Immediate: 32-bit 4259 operand immI() %{ 4260 match(ConI); 4261 op_cost(40); 4262 format %{ %} 4263 interface(CONST_INTER); 4264 %} 4265 4266 operand immI8() %{ 4267 predicate(Assembler::is_simm(n->get_int(), 8)); 4268 op_cost(0); 4269 match(ConI); 4270 format %{ %} 4271 interface(CONST_INTER); 4272 %} 4273 4274 // Integer Immediate: 16-bit 4275 operand immI16() %{ 4276 predicate(Assembler::is_simm(n->get_int(), 16)); 4277 op_cost(0); 4278 match(ConI); 4279 format %{ %} 4280 interface(CONST_INTER); 4281 %} 4282 4283 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4284 operand immIhi16() %{ 4285 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4286 match(ConI); 4287 op_cost(0); 4288 format %{ %} 4289 interface(CONST_INTER); 4290 %} 4291 4292 operand immInegpow2() %{ 4293 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 4294 match(ConI); 4295 op_cost(0); 4296 format %{ %} 4297 interface(CONST_INTER); 4298 %} 4299 4300 operand immIpow2minus1() %{ 4301 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 4302 match(ConI); 4303 op_cost(0); 4304 format %{ %} 4305 interface(CONST_INTER); 4306 %} 4307 4308 operand immIpowerOf2() %{ 4309 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 4310 match(ConI); 4311 op_cost(0); 4312 format %{ %} 4313 interface(CONST_INTER); 4314 %} 4315 4316 // Unsigned Integer Immediate: the values 0-31 4317 operand uimmI5() %{ 4318 predicate(Assembler::is_uimm(n->get_int(), 5)); 4319 match(ConI); 4320 op_cost(0); 4321 format %{ %} 4322 interface(CONST_INTER); 4323 %} 4324 4325 // Unsigned Integer Immediate: 6-bit 4326 operand uimmI6() %{ 4327 predicate(Assembler::is_uimm(n->get_int(), 6)); 4328 match(ConI); 4329 op_cost(0); 4330 format %{ %} 4331 interface(CONST_INTER); 4332 %} 4333 4334 // Unsigned Integer Immediate: 6-bit int, greater than 32 4335 operand uimmI6_ge32() %{ 4336 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4337 match(ConI); 4338 op_cost(0); 4339 format %{ %} 4340 interface(CONST_INTER); 4341 %} 4342 4343 // Unsigned Integer Immediate: 15-bit 4344 operand uimmI15() %{ 4345 predicate(Assembler::is_uimm(n->get_int(), 15)); 4346 match(ConI); 4347 op_cost(0); 4348 format %{ %} 4349 interface(CONST_INTER); 4350 %} 4351 4352 // Unsigned Integer Immediate: 16-bit 4353 operand uimmI16() %{ 4354 predicate(Assembler::is_uimm(n->get_int(), 16)); 4355 match(ConI); 4356 op_cost(0); 4357 format %{ %} 4358 interface(CONST_INTER); 4359 %} 4360 4361 // constant 'int 0'. 4362 operand immI_0() %{ 4363 predicate(n->get_int() == 0); 4364 match(ConI); 4365 op_cost(0); 4366 format %{ %} 4367 interface(CONST_INTER); 4368 %} 4369 4370 // constant 'int 1'. 4371 operand immI_1() %{ 4372 predicate(n->get_int() == 1); 4373 match(ConI); 4374 op_cost(0); 4375 format %{ %} 4376 interface(CONST_INTER); 4377 %} 4378 4379 // constant 'int -1'. 4380 operand immI_minus1() %{ 4381 predicate(n->get_int() == -1); 4382 match(ConI); 4383 op_cost(0); 4384 format %{ %} 4385 interface(CONST_INTER); 4386 %} 4387 4388 // int value 16. 4389 operand immI_16() %{ 4390 predicate(n->get_int() == 16); 4391 match(ConI); 4392 op_cost(0); 4393 format %{ %} 4394 interface(CONST_INTER); 4395 %} 4396 4397 // int value 24. 4398 operand immI_24() %{ 4399 predicate(n->get_int() == 24); 4400 match(ConI); 4401 op_cost(0); 4402 format %{ %} 4403 interface(CONST_INTER); 4404 %} 4405 4406 // Compressed oops constants 4407 // Pointer Immediate 4408 operand immN() %{ 4409 match(ConN); 4410 4411 op_cost(10); 4412 format %{ %} 4413 interface(CONST_INTER); 4414 %} 4415 4416 // NULL Pointer Immediate 4417 operand immN_0() %{ 4418 predicate(n->get_narrowcon() == 0); 4419 match(ConN); 4420 4421 op_cost(0); 4422 format %{ %} 4423 interface(CONST_INTER); 4424 %} 4425 4426 // Compressed klass constants 4427 operand immNKlass() %{ 4428 match(ConNKlass); 4429 4430 op_cost(0); 4431 format %{ %} 4432 interface(CONST_INTER); 4433 %} 4434 4435 // This operand can be used to avoid matching of an instruct 4436 // with chain rule. 4437 operand immNKlass_NM() %{ 4438 match(ConNKlass); 4439 predicate(false); 4440 op_cost(0); 4441 format %{ %} 4442 interface(CONST_INTER); 4443 %} 4444 4445 // Pointer Immediate: 64-bit 4446 operand immP() %{ 4447 match(ConP); 4448 op_cost(0); 4449 format %{ %} 4450 interface(CONST_INTER); 4451 %} 4452 4453 // Operand to avoid match of loadConP. 4454 // This operand can be used to avoid matching of an instruct 4455 // with chain rule. 4456 operand immP_NM() %{ 4457 match(ConP); 4458 predicate(false); 4459 op_cost(0); 4460 format %{ %} 4461 interface(CONST_INTER); 4462 %} 4463 4464 // costant 'pointer 0'. 4465 operand immP_0() %{ 4466 predicate(n->get_ptr() == 0); 4467 match(ConP); 4468 op_cost(0); 4469 format %{ %} 4470 interface(CONST_INTER); 4471 %} 4472 4473 // pointer 0x0 or 0x1 4474 operand immP_0or1() %{ 4475 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4476 match(ConP); 4477 op_cost(0); 4478 format %{ %} 4479 interface(CONST_INTER); 4480 %} 4481 4482 operand immL() %{ 4483 match(ConL); 4484 op_cost(40); 4485 format %{ %} 4486 interface(CONST_INTER); 4487 %} 4488 4489 operand immLmax30() %{ 4490 predicate((n->get_long() <= 30)); 4491 match(ConL); 4492 op_cost(0); 4493 format %{ %} 4494 interface(CONST_INTER); 4495 %} 4496 4497 // Long Immediate: 16-bit 4498 operand immL16() %{ 4499 predicate(Assembler::is_simm(n->get_long(), 16)); 4500 match(ConL); 4501 op_cost(0); 4502 format %{ %} 4503 interface(CONST_INTER); 4504 %} 4505 4506 // Long Immediate: 16-bit, 4-aligned 4507 operand immL16Alg4() %{ 4508 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4509 match(ConL); 4510 op_cost(0); 4511 format %{ %} 4512 interface(CONST_INTER); 4513 %} 4514 4515 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4516 operand immL32hi16() %{ 4517 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4518 match(ConL); 4519 op_cost(0); 4520 format %{ %} 4521 interface(CONST_INTER); 4522 %} 4523 4524 // Long Immediate: 32-bit 4525 operand immL32() %{ 4526 predicate(Assembler::is_simm(n->get_long(), 32)); 4527 match(ConL); 4528 op_cost(0); 4529 format %{ %} 4530 interface(CONST_INTER); 4531 %} 4532 4533 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4534 operand immLhighest16() %{ 4535 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4536 match(ConL); 4537 op_cost(0); 4538 format %{ %} 4539 interface(CONST_INTER); 4540 %} 4541 4542 operand immLnegpow2() %{ 4543 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4544 match(ConL); 4545 op_cost(0); 4546 format %{ %} 4547 interface(CONST_INTER); 4548 %} 4549 4550 operand immLpow2minus1() %{ 4551 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4552 (n->get_long() != (jlong)0xffffffffffffffffL)); 4553 match(ConL); 4554 op_cost(0); 4555 format %{ %} 4556 interface(CONST_INTER); 4557 %} 4558 4559 // constant 'long 0'. 4560 operand immL_0() %{ 4561 predicate(n->get_long() == 0L); 4562 match(ConL); 4563 op_cost(0); 4564 format %{ %} 4565 interface(CONST_INTER); 4566 %} 4567 4568 // constat ' long -1'. 4569 operand immL_minus1() %{ 4570 predicate(n->get_long() == -1L); 4571 match(ConL); 4572 op_cost(0); 4573 format %{ %} 4574 interface(CONST_INTER); 4575 %} 4576 4577 // Long Immediate: low 32-bit mask 4578 operand immL_32bits() %{ 4579 predicate(n->get_long() == 0xFFFFFFFFL); 4580 match(ConL); 4581 op_cost(0); 4582 format %{ %} 4583 interface(CONST_INTER); 4584 %} 4585 4586 // Unsigned Long Immediate: 16-bit 4587 operand uimmL16() %{ 4588 predicate(Assembler::is_uimm(n->get_long(), 16)); 4589 match(ConL); 4590 op_cost(0); 4591 format %{ %} 4592 interface(CONST_INTER); 4593 %} 4594 4595 // Float Immediate 4596 operand immF() %{ 4597 match(ConF); 4598 op_cost(40); 4599 format %{ %} 4600 interface(CONST_INTER); 4601 %} 4602 4603 // Float Immediate: +0.0f. 4604 operand immF_0() %{ 4605 predicate(jint_cast(n->getf()) == 0); 4606 match(ConF); 4607 4608 op_cost(0); 4609 format %{ %} 4610 interface(CONST_INTER); 4611 %} 4612 4613 // Double Immediate 4614 operand immD() %{ 4615 match(ConD); 4616 op_cost(40); 4617 format %{ %} 4618 interface(CONST_INTER); 4619 %} 4620 4621 // Integer Register Operands 4622 // Integer Destination Register 4623 // See definition of reg_class bits32_reg_rw. 4624 operand iRegIdst() %{ 4625 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4626 match(RegI); 4627 match(rscratch1RegI); 4628 match(rscratch2RegI); 4629 match(rarg1RegI); 4630 match(rarg2RegI); 4631 match(rarg3RegI); 4632 match(rarg4RegI); 4633 format %{ %} 4634 interface(REG_INTER); 4635 %} 4636 4637 // Integer Source Register 4638 // See definition of reg_class bits32_reg_ro. 4639 operand iRegIsrc() %{ 4640 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4641 match(RegI); 4642 match(rscratch1RegI); 4643 match(rscratch2RegI); 4644 match(rarg1RegI); 4645 match(rarg2RegI); 4646 match(rarg3RegI); 4647 match(rarg4RegI); 4648 format %{ %} 4649 interface(REG_INTER); 4650 %} 4651 4652 operand rscratch1RegI() %{ 4653 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4654 match(iRegIdst); 4655 format %{ %} 4656 interface(REG_INTER); 4657 %} 4658 4659 operand rscratch2RegI() %{ 4660 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4661 match(iRegIdst); 4662 format %{ %} 4663 interface(REG_INTER); 4664 %} 4665 4666 operand rarg1RegI() %{ 4667 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4668 match(iRegIdst); 4669 format %{ %} 4670 interface(REG_INTER); 4671 %} 4672 4673 operand rarg2RegI() %{ 4674 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4675 match(iRegIdst); 4676 format %{ %} 4677 interface(REG_INTER); 4678 %} 4679 4680 operand rarg3RegI() %{ 4681 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4682 match(iRegIdst); 4683 format %{ %} 4684 interface(REG_INTER); 4685 %} 4686 4687 operand rarg4RegI() %{ 4688 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4689 match(iRegIdst); 4690 format %{ %} 4691 interface(REG_INTER); 4692 %} 4693 4694 operand rarg1RegL() %{ 4695 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4696 match(iRegLdst); 4697 format %{ %} 4698 interface(REG_INTER); 4699 %} 4700 4701 operand rarg2RegL() %{ 4702 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4703 match(iRegLdst); 4704 format %{ %} 4705 interface(REG_INTER); 4706 %} 4707 4708 operand rarg3RegL() %{ 4709 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4710 match(iRegLdst); 4711 format %{ %} 4712 interface(REG_INTER); 4713 %} 4714 4715 operand rarg4RegL() %{ 4716 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4717 match(iRegLdst); 4718 format %{ %} 4719 interface(REG_INTER); 4720 %} 4721 4722 // Pointer Destination Register 4723 // See definition of reg_class bits64_reg_rw. 4724 operand iRegPdst() %{ 4725 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4726 match(RegP); 4727 match(rscratch1RegP); 4728 match(rscratch2RegP); 4729 match(rarg1RegP); 4730 match(rarg2RegP); 4731 match(rarg3RegP); 4732 match(rarg4RegP); 4733 format %{ %} 4734 interface(REG_INTER); 4735 %} 4736 4737 // Pointer Destination Register 4738 // Operand not using r11 and r12 (killed in epilog). 4739 operand iRegPdstNoScratch() %{ 4740 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4741 match(RegP); 4742 match(rarg1RegP); 4743 match(rarg2RegP); 4744 match(rarg3RegP); 4745 match(rarg4RegP); 4746 format %{ %} 4747 interface(REG_INTER); 4748 %} 4749 4750 // Pointer Source Register 4751 // See definition of reg_class bits64_reg_ro. 4752 operand iRegPsrc() %{ 4753 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4754 match(RegP); 4755 match(iRegPdst); 4756 match(rscratch1RegP); 4757 match(rscratch2RegP); 4758 match(rarg1RegP); 4759 match(rarg2RegP); 4760 match(rarg3RegP); 4761 match(rarg4RegP); 4762 match(threadRegP); 4763 format %{ %} 4764 interface(REG_INTER); 4765 %} 4766 4767 // Thread operand. 4768 operand threadRegP() %{ 4769 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4770 match(iRegPdst); 4771 format %{ "R16" %} 4772 interface(REG_INTER); 4773 %} 4774 4775 operand rscratch1RegP() %{ 4776 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4777 match(iRegPdst); 4778 format %{ "R11" %} 4779 interface(REG_INTER); 4780 %} 4781 4782 operand rscratch2RegP() %{ 4783 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4784 match(iRegPdst); 4785 format %{ %} 4786 interface(REG_INTER); 4787 %} 4788 4789 operand rarg1RegP() %{ 4790 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4791 match(iRegPdst); 4792 format %{ %} 4793 interface(REG_INTER); 4794 %} 4795 4796 operand rarg2RegP() %{ 4797 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4798 match(iRegPdst); 4799 format %{ %} 4800 interface(REG_INTER); 4801 %} 4802 4803 operand rarg3RegP() %{ 4804 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4805 match(iRegPdst); 4806 format %{ %} 4807 interface(REG_INTER); 4808 %} 4809 4810 operand rarg4RegP() %{ 4811 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4812 match(iRegPdst); 4813 format %{ %} 4814 interface(REG_INTER); 4815 %} 4816 4817 operand iRegNsrc() %{ 4818 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4819 match(RegN); 4820 match(iRegNdst); 4821 4822 format %{ %} 4823 interface(REG_INTER); 4824 %} 4825 4826 operand iRegNdst() %{ 4827 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4828 match(RegN); 4829 4830 format %{ %} 4831 interface(REG_INTER); 4832 %} 4833 4834 // Long Destination Register 4835 // See definition of reg_class bits64_reg_rw. 4836 operand iRegLdst() %{ 4837 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4838 match(RegL); 4839 match(rscratch1RegL); 4840 match(rscratch2RegL); 4841 format %{ %} 4842 interface(REG_INTER); 4843 %} 4844 4845 // Long Source Register 4846 // See definition of reg_class bits64_reg_ro. 4847 operand iRegLsrc() %{ 4848 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4849 match(RegL); 4850 match(iRegLdst); 4851 match(rscratch1RegL); 4852 match(rscratch2RegL); 4853 format %{ %} 4854 interface(REG_INTER); 4855 %} 4856 4857 // Special operand for ConvL2I. 4858 operand iRegL2Isrc(iRegLsrc reg) %{ 4859 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4860 match(ConvL2I reg); 4861 format %{ "ConvL2I($reg)" %} 4862 interface(REG_INTER) 4863 %} 4864 4865 operand rscratch1RegL() %{ 4866 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4867 match(RegL); 4868 format %{ %} 4869 interface(REG_INTER); 4870 %} 4871 4872 operand rscratch2RegL() %{ 4873 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4874 match(RegL); 4875 format %{ %} 4876 interface(REG_INTER); 4877 %} 4878 4879 // Condition Code Flag Registers 4880 operand flagsReg() %{ 4881 constraint(ALLOC_IN_RC(int_flags)); 4882 match(RegFlags); 4883 format %{ %} 4884 interface(REG_INTER); 4885 %} 4886 4887 operand flagsRegSrc() %{ 4888 constraint(ALLOC_IN_RC(int_flags_ro)); 4889 match(RegFlags); 4890 match(flagsReg); 4891 match(flagsRegCR0); 4892 format %{ %} 4893 interface(REG_INTER); 4894 %} 4895 4896 // Condition Code Flag Register CR0 4897 operand flagsRegCR0() %{ 4898 constraint(ALLOC_IN_RC(int_flags_CR0)); 4899 match(RegFlags); 4900 format %{ "CR0" %} 4901 interface(REG_INTER); 4902 %} 4903 4904 operand flagsRegCR1() %{ 4905 constraint(ALLOC_IN_RC(int_flags_CR1)); 4906 match(RegFlags); 4907 format %{ "CR1" %} 4908 interface(REG_INTER); 4909 %} 4910 4911 operand flagsRegCR6() %{ 4912 constraint(ALLOC_IN_RC(int_flags_CR6)); 4913 match(RegFlags); 4914 format %{ "CR6" %} 4915 interface(REG_INTER); 4916 %} 4917 4918 operand regCTR() %{ 4919 constraint(ALLOC_IN_RC(ctr_reg)); 4920 // RegFlags should work. Introducing a RegSpecial type would cause a 4921 // lot of changes. 4922 match(RegFlags); 4923 format %{"SR_CTR" %} 4924 interface(REG_INTER); 4925 %} 4926 4927 operand regD() %{ 4928 constraint(ALLOC_IN_RC(dbl_reg)); 4929 match(RegD); 4930 format %{ %} 4931 interface(REG_INTER); 4932 %} 4933 4934 operand regF() %{ 4935 constraint(ALLOC_IN_RC(flt_reg)); 4936 match(RegF); 4937 format %{ %} 4938 interface(REG_INTER); 4939 %} 4940 4941 // Special Registers 4942 4943 // Method Register 4944 operand inline_cache_regP(iRegPdst reg) %{ 4945 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4946 match(reg); 4947 format %{ %} 4948 interface(REG_INTER); 4949 %} 4950 4951 operand compiler_method_oop_regP(iRegPdst reg) %{ 4952 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4953 match(reg); 4954 format %{ %} 4955 interface(REG_INTER); 4956 %} 4957 4958 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4959 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4960 match(reg); 4961 format %{ %} 4962 interface(REG_INTER); 4963 %} 4964 4965 // Operands to remove register moves in unscaled mode. 4966 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4967 operand iRegP2N(iRegPsrc reg) %{ 4968 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4969 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4970 match(EncodeP reg); 4971 format %{ "$reg" %} 4972 interface(REG_INTER) 4973 %} 4974 4975 operand iRegN2P(iRegNsrc reg) %{ 4976 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4977 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4978 match(DecodeN reg); 4979 format %{ "$reg" %} 4980 interface(REG_INTER) 4981 %} 4982 4983 operand iRegN2P_klass(iRegNsrc reg) %{ 4984 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4985 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4986 match(DecodeNKlass reg); 4987 format %{ "$reg" %} 4988 interface(REG_INTER) 4989 %} 4990 4991 //----------Complex Operands--------------------------------------------------- 4992 // Indirect Memory Reference 4993 operand indirect(iRegPsrc reg) %{ 4994 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4995 match(reg); 4996 op_cost(100); 4997 format %{ "[$reg]" %} 4998 interface(MEMORY_INTER) %{ 4999 base($reg); 5000 index(0x0); 5001 scale(0x0); 5002 disp(0x0); 5003 %} 5004 %} 5005 5006 // Indirect with Offset 5007 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 5008 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5009 match(AddP reg offset); 5010 op_cost(100); 5011 format %{ "[$reg + $offset]" %} 5012 interface(MEMORY_INTER) %{ 5013 base($reg); 5014 index(0x0); 5015 scale(0x0); 5016 disp($offset); 5017 %} 5018 %} 5019 5020 // Indirect with 4-aligned Offset 5021 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 5022 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5023 match(AddP reg offset); 5024 op_cost(100); 5025 format %{ "[$reg + $offset]" %} 5026 interface(MEMORY_INTER) %{ 5027 base($reg); 5028 index(0x0); 5029 scale(0x0); 5030 disp($offset); 5031 %} 5032 %} 5033 5034 //----------Complex Operands for Compressed OOPs------------------------------- 5035 // Compressed OOPs with narrow_oop_shift == 0. 5036 5037 // Indirect Memory Reference, compressed OOP 5038 operand indirectNarrow(iRegNsrc reg) %{ 5039 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5040 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5041 match(DecodeN reg); 5042 op_cost(100); 5043 format %{ "[$reg]" %} 5044 interface(MEMORY_INTER) %{ 5045 base($reg); 5046 index(0x0); 5047 scale(0x0); 5048 disp(0x0); 5049 %} 5050 %} 5051 5052 operand indirectNarrow_klass(iRegNsrc reg) %{ 5053 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5054 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5055 match(DecodeNKlass reg); 5056 op_cost(100); 5057 format %{ "[$reg]" %} 5058 interface(MEMORY_INTER) %{ 5059 base($reg); 5060 index(0x0); 5061 scale(0x0); 5062 disp(0x0); 5063 %} 5064 %} 5065 5066 // Indirect with Offset, compressed OOP 5067 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 5068 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5069 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5070 match(AddP (DecodeN reg) offset); 5071 op_cost(100); 5072 format %{ "[$reg + $offset]" %} 5073 interface(MEMORY_INTER) %{ 5074 base($reg); 5075 index(0x0); 5076 scale(0x0); 5077 disp($offset); 5078 %} 5079 %} 5080 5081 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5082 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5083 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5084 match(AddP (DecodeNKlass reg) offset); 5085 op_cost(100); 5086 format %{ "[$reg + $offset]" %} 5087 interface(MEMORY_INTER) %{ 5088 base($reg); 5089 index(0x0); 5090 scale(0x0); 5091 disp($offset); 5092 %} 5093 %} 5094 5095 // Indirect with 4-aligned Offset, compressed OOP 5096 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 5097 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5098 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5099 match(AddP (DecodeN reg) offset); 5100 op_cost(100); 5101 format %{ "[$reg + $offset]" %} 5102 interface(MEMORY_INTER) %{ 5103 base($reg); 5104 index(0x0); 5105 scale(0x0); 5106 disp($offset); 5107 %} 5108 %} 5109 5110 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5111 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5112 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5113 match(AddP (DecodeNKlass reg) offset); 5114 op_cost(100); 5115 format %{ "[$reg + $offset]" %} 5116 interface(MEMORY_INTER) %{ 5117 base($reg); 5118 index(0x0); 5119 scale(0x0); 5120 disp($offset); 5121 %} 5122 %} 5123 5124 //----------Special Memory Operands-------------------------------------------- 5125 // Stack Slot Operand 5126 // 5127 // This operand is used for loading and storing temporary values on 5128 // the stack where a match requires a value to flow through memory. 5129 operand stackSlotI(sRegI reg) %{ 5130 constraint(ALLOC_IN_RC(stack_slots)); 5131 op_cost(100); 5132 //match(RegI); 5133 format %{ "[sp+$reg]" %} 5134 interface(MEMORY_INTER) %{ 5135 base(0x1); // R1_SP 5136 index(0x0); 5137 scale(0x0); 5138 disp($reg); // Stack Offset 5139 %} 5140 %} 5141 5142 operand stackSlotL(sRegL reg) %{ 5143 constraint(ALLOC_IN_RC(stack_slots)); 5144 op_cost(100); 5145 //match(RegL); 5146 format %{ "[sp+$reg]" %} 5147 interface(MEMORY_INTER) %{ 5148 base(0x1); // R1_SP 5149 index(0x0); 5150 scale(0x0); 5151 disp($reg); // Stack Offset 5152 %} 5153 %} 5154 5155 operand stackSlotP(sRegP reg) %{ 5156 constraint(ALLOC_IN_RC(stack_slots)); 5157 op_cost(100); 5158 //match(RegP); 5159 format %{ "[sp+$reg]" %} 5160 interface(MEMORY_INTER) %{ 5161 base(0x1); // R1_SP 5162 index(0x0); 5163 scale(0x0); 5164 disp($reg); // Stack Offset 5165 %} 5166 %} 5167 5168 operand stackSlotF(sRegF reg) %{ 5169 constraint(ALLOC_IN_RC(stack_slots)); 5170 op_cost(100); 5171 //match(RegF); 5172 format %{ "[sp+$reg]" %} 5173 interface(MEMORY_INTER) %{ 5174 base(0x1); // R1_SP 5175 index(0x0); 5176 scale(0x0); 5177 disp($reg); // Stack Offset 5178 %} 5179 %} 5180 5181 operand stackSlotD(sRegD reg) %{ 5182 constraint(ALLOC_IN_RC(stack_slots)); 5183 op_cost(100); 5184 //match(RegD); 5185 format %{ "[sp+$reg]" %} 5186 interface(MEMORY_INTER) %{ 5187 base(0x1); // R1_SP 5188 index(0x0); 5189 scale(0x0); 5190 disp($reg); // Stack Offset 5191 %} 5192 %} 5193 5194 // Operands for expressing Control Flow 5195 // NOTE: Label is a predefined operand which should not be redefined in 5196 // the AD file. It is generically handled within the ADLC. 5197 5198 //----------Conditional Branch Operands---------------------------------------- 5199 // Comparison Op 5200 // 5201 // This is the operation of the comparison, and is limited to the 5202 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5203 // (!=). 5204 // 5205 // Other attributes of the comparison, such as unsignedness, are specified 5206 // by the comparison instruction that sets a condition code flags register. 5207 // That result is represented by a flags operand whose subtype is appropriate 5208 // to the unsignedness (etc.) of the comparison. 5209 // 5210 // Later, the instruction which matches both the Comparison Op (a Bool) and 5211 // the flags (produced by the Cmp) specifies the coding of the comparison op 5212 // by matching a specific subtype of Bool operand below. 5213 5214 // When used for floating point comparisons: unordered same as less. 5215 operand cmpOp() %{ 5216 match(Bool); 5217 format %{ "" %} 5218 interface(COND_INTER) %{ 5219 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5220 // BO & BI 5221 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5222 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5223 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5224 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5225 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5226 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5227 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5228 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5229 %} 5230 %} 5231 5232 //----------OPERAND CLASSES---------------------------------------------------- 5233 // Operand Classes are groups of operands that are used to simplify 5234 // instruction definitions by not requiring the AD writer to specify 5235 // seperate instructions for every form of operand when the 5236 // instruction accepts multiple operand types with the same basic 5237 // encoding and format. The classic case of this is memory operands. 5238 // Indirect is not included since its use is limited to Compare & Swap. 5239 5240 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5241 // Memory operand where offsets are 4-aligned. Required for ld, std. 5242 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5243 opclass indirectMemory(indirect, indirectNarrow); 5244 5245 // Special opclass for I and ConvL2I. 5246 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5247 5248 // Operand classes to match encode and decode. iRegN_P2N is only used 5249 // for storeN. I have never seen an encode node elsewhere. 5250 opclass iRegN_P2N(iRegNsrc, iRegP2N); 5251 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5252 5253 //----------PIPELINE----------------------------------------------------------- 5254 5255 pipeline %{ 5256 5257 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5258 // J. Res. & Dev., No. 1, Jan. 2002. 5259 5260 //----------ATTRIBUTES--------------------------------------------------------- 5261 attributes %{ 5262 5263 // Power4 instructions are of fixed length. 5264 fixed_size_instructions; 5265 5266 // TODO: if `bundle' means number of instructions fetched 5267 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5268 // max instructions issued per cycle, this is 5. 5269 max_instructions_per_bundle = 8; 5270 5271 // A Power4 instruction is 4 bytes long. 5272 instruction_unit_size = 4; 5273 5274 // The Power4 processor fetches 64 bytes... 5275 instruction_fetch_unit_size = 64; 5276 5277 // ...in one line 5278 instruction_fetch_units = 1 5279 5280 // Unused, list one so that array generated by adlc is not empty. 5281 // Aix compiler chokes if _nop_count = 0. 5282 nops(fxNop); 5283 %} 5284 5285 //----------RESOURCES---------------------------------------------------------- 5286 // Resources are the functional units available to the machine 5287 resources( 5288 PPC_BR, // branch unit 5289 PPC_CR, // condition unit 5290 PPC_FX1, // integer arithmetic unit 1 5291 PPC_FX2, // integer arithmetic unit 2 5292 PPC_LDST1, // load/store unit 1 5293 PPC_LDST2, // load/store unit 2 5294 PPC_FP1, // float arithmetic unit 1 5295 PPC_FP2, // float arithmetic unit 2 5296 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5297 PPC_FX = PPC_FX1 | PPC_FX2, 5298 PPC_FP = PPC_FP1 | PPC_FP2 5299 ); 5300 5301 //----------PIPELINE DESCRIPTION----------------------------------------------- 5302 // Pipeline Description specifies the stages in the machine's pipeline 5303 pipe_desc( 5304 // Power4 longest pipeline path 5305 PPC_IF, // instruction fetch 5306 PPC_IC, 5307 //PPC_BP, // branch prediction 5308 PPC_D0, // decode 5309 PPC_D1, // decode 5310 PPC_D2, // decode 5311 PPC_D3, // decode 5312 PPC_Xfer1, 5313 PPC_GD, // group definition 5314 PPC_MP, // map 5315 PPC_ISS, // issue 5316 PPC_RF, // resource fetch 5317 PPC_EX1, // execute (all units) 5318 PPC_EX2, // execute (FP, LDST) 5319 PPC_EX3, // execute (FP, LDST) 5320 PPC_EX4, // execute (FP) 5321 PPC_EX5, // execute (FP) 5322 PPC_EX6, // execute (FP) 5323 PPC_WB, // write back 5324 PPC_Xfer2, 5325 PPC_CP 5326 ); 5327 5328 //----------PIPELINE CLASSES--------------------------------------------------- 5329 // Pipeline Classes describe the stages in which input and output are 5330 // referenced by the hardware pipeline. 5331 5332 // Simple pipeline classes. 5333 5334 // Default pipeline class. 5335 pipe_class pipe_class_default() %{ 5336 single_instruction; 5337 fixed_latency(2); 5338 %} 5339 5340 // Pipeline class for empty instructions. 5341 pipe_class pipe_class_empty() %{ 5342 single_instruction; 5343 fixed_latency(0); 5344 %} 5345 5346 // Pipeline class for compares. 5347 pipe_class pipe_class_compare() %{ 5348 single_instruction; 5349 fixed_latency(16); 5350 %} 5351 5352 // Pipeline class for traps. 5353 pipe_class pipe_class_trap() %{ 5354 single_instruction; 5355 fixed_latency(100); 5356 %} 5357 5358 // Pipeline class for memory operations. 5359 pipe_class pipe_class_memory() %{ 5360 single_instruction; 5361 fixed_latency(16); 5362 %} 5363 5364 // Pipeline class for call. 5365 pipe_class pipe_class_call() %{ 5366 single_instruction; 5367 fixed_latency(100); 5368 %} 5369 5370 // Define the class for the Nop node. 5371 define %{ 5372 MachNop = pipe_class_default; 5373 %} 5374 5375 %} 5376 5377 //----------INSTRUCTIONS------------------------------------------------------- 5378 5379 // Naming of instructions: 5380 // opA_operB / opA_operB_operC: 5381 // Operation 'op' with one or two source operands 'oper'. Result 5382 // type is A, source operand types are B and C. 5383 // Iff A == B == C, B and C are left out. 5384 // 5385 // The instructions are ordered according to the following scheme: 5386 // - loads 5387 // - load constants 5388 // - prefetch 5389 // - store 5390 // - encode/decode 5391 // - membar 5392 // - conditional moves 5393 // - compare & swap 5394 // - arithmetic and logic operations 5395 // * int: Add, Sub, Mul, Div, Mod 5396 // * int: lShift, arShift, urShift, rot 5397 // * float: Add, Sub, Mul, Div 5398 // * and, or, xor ... 5399 // - register moves: float <-> int, reg <-> stack, repl 5400 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5401 // - conv (low level type cast requiring bit changes (sign extend etc) 5402 // - compares, range & zero checks. 5403 // - branches 5404 // - complex operations, intrinsics, min, max, replicate 5405 // - lock 5406 // - Calls 5407 // 5408 // If there are similar instructions with different types they are sorted: 5409 // int before float 5410 // small before big 5411 // signed before unsigned 5412 // e.g., loadS before loadUS before loadI before loadF. 5413 5414 5415 //----------Load/Store Instructions-------------------------------------------- 5416 5417 //----------Load Instructions-------------------------------------------------- 5418 5419 // Converts byte to int. 5420 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5421 // reuses the 'amount' operand, but adlc expects that operand specification 5422 // and operands in match rule are equivalent. 5423 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5424 effect(DEF dst, USE src); 5425 format %{ "EXTSB $dst, $src \t// byte->int" %} 5426 size(4); 5427 ins_encode %{ 5428 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5429 __ extsb($dst$$Register, $src$$Register); 5430 %} 5431 ins_pipe(pipe_class_default); 5432 %} 5433 5434 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5435 // match-rule, false predicate 5436 match(Set dst (LoadB mem)); 5437 predicate(false); 5438 5439 format %{ "LBZ $dst, $mem" %} 5440 size(4); 5441 ins_encode( enc_lbz(dst, mem) ); 5442 ins_pipe(pipe_class_memory); 5443 %} 5444 5445 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5446 // match-rule, false predicate 5447 match(Set dst (LoadB mem)); 5448 predicate(false); 5449 5450 format %{ "LBZ $dst, $mem\n\t" 5451 "TWI $dst\n\t" 5452 "ISYNC" %} 5453 size(12); 5454 ins_encode( enc_lbz_ac(dst, mem) ); 5455 ins_pipe(pipe_class_memory); 5456 %} 5457 5458 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5459 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5460 match(Set dst (LoadB mem)); 5461 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5462 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5463 expand %{ 5464 iRegIdst tmp; 5465 loadUB_indirect(tmp, mem); 5466 convB2I_reg_2(dst, tmp); 5467 %} 5468 %} 5469 5470 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5471 match(Set dst (LoadB mem)); 5472 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5473 expand %{ 5474 iRegIdst tmp; 5475 loadUB_indirect_ac(tmp, mem); 5476 convB2I_reg_2(dst, tmp); 5477 %} 5478 %} 5479 5480 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5481 // match-rule, false predicate 5482 match(Set dst (LoadB mem)); 5483 predicate(false); 5484 5485 format %{ "LBZ $dst, $mem" %} 5486 size(4); 5487 ins_encode( enc_lbz(dst, mem) ); 5488 ins_pipe(pipe_class_memory); 5489 %} 5490 5491 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5492 // match-rule, false predicate 5493 match(Set dst (LoadB mem)); 5494 predicate(false); 5495 5496 format %{ "LBZ $dst, $mem\n\t" 5497 "TWI $dst\n\t" 5498 "ISYNC" %} 5499 size(12); 5500 ins_encode( enc_lbz_ac(dst, mem) ); 5501 ins_pipe(pipe_class_memory); 5502 %} 5503 5504 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5505 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5506 match(Set dst (LoadB mem)); 5507 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5508 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5509 5510 expand %{ 5511 iRegIdst tmp; 5512 loadUB_indOffset16(tmp, mem); 5513 convB2I_reg_2(dst, tmp); 5514 %} 5515 %} 5516 5517 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5518 match(Set dst (LoadB mem)); 5519 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5520 5521 expand %{ 5522 iRegIdst tmp; 5523 loadUB_indOffset16_ac(tmp, mem); 5524 convB2I_reg_2(dst, tmp); 5525 %} 5526 %} 5527 5528 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5529 instruct loadUB(iRegIdst dst, memory mem) %{ 5530 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5531 match(Set dst (LoadUB mem)); 5532 ins_cost(MEMORY_REF_COST); 5533 5534 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5535 size(4); 5536 ins_encode( enc_lbz(dst, mem) ); 5537 ins_pipe(pipe_class_memory); 5538 %} 5539 5540 // Load Unsigned Byte (8bit UNsigned) acquire. 5541 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5542 match(Set dst (LoadUB mem)); 5543 ins_cost(3*MEMORY_REF_COST); 5544 5545 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5546 "TWI $dst\n\t" 5547 "ISYNC" %} 5548 size(12); 5549 ins_encode( enc_lbz_ac(dst, mem) ); 5550 ins_pipe(pipe_class_memory); 5551 %} 5552 5553 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5554 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5555 match(Set dst (ConvI2L (LoadUB mem))); 5556 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5557 ins_cost(MEMORY_REF_COST); 5558 5559 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5560 size(4); 5561 ins_encode( enc_lbz(dst, mem) ); 5562 ins_pipe(pipe_class_memory); 5563 %} 5564 5565 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5566 match(Set dst (ConvI2L (LoadUB mem))); 5567 ins_cost(3*MEMORY_REF_COST); 5568 5569 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5570 "TWI $dst\n\t" 5571 "ISYNC" %} 5572 size(12); 5573 ins_encode( enc_lbz_ac(dst, mem) ); 5574 ins_pipe(pipe_class_memory); 5575 %} 5576 5577 // Load Short (16bit signed) 5578 instruct loadS(iRegIdst dst, memory mem) %{ 5579 match(Set dst (LoadS mem)); 5580 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5581 ins_cost(MEMORY_REF_COST); 5582 5583 format %{ "LHA $dst, $mem" %} 5584 size(4); 5585 ins_encode %{ 5586 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5587 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5588 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5589 %} 5590 ins_pipe(pipe_class_memory); 5591 %} 5592 5593 // Load Short (16bit signed) acquire. 5594 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5595 match(Set dst (LoadS mem)); 5596 ins_cost(3*MEMORY_REF_COST); 5597 5598 format %{ "LHA $dst, $mem\t acquire\n\t" 5599 "TWI $dst\n\t" 5600 "ISYNC" %} 5601 size(12); 5602 ins_encode %{ 5603 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5604 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5605 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5606 __ twi_0($dst$$Register); 5607 __ isync(); 5608 %} 5609 ins_pipe(pipe_class_memory); 5610 %} 5611 5612 // Load Char (16bit unsigned) 5613 instruct loadUS(iRegIdst dst, memory mem) %{ 5614 match(Set dst (LoadUS mem)); 5615 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5616 ins_cost(MEMORY_REF_COST); 5617 5618 format %{ "LHZ $dst, $mem" %} 5619 size(4); 5620 ins_encode( enc_lhz(dst, mem) ); 5621 ins_pipe(pipe_class_memory); 5622 %} 5623 5624 // Load Char (16bit unsigned) acquire. 5625 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5626 match(Set dst (LoadUS mem)); 5627 ins_cost(3*MEMORY_REF_COST); 5628 5629 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5630 "TWI $dst\n\t" 5631 "ISYNC" %} 5632 size(12); 5633 ins_encode( enc_lhz_ac(dst, mem) ); 5634 ins_pipe(pipe_class_memory); 5635 %} 5636 5637 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5638 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5639 match(Set dst (ConvI2L (LoadUS mem))); 5640 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5641 ins_cost(MEMORY_REF_COST); 5642 5643 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5644 size(4); 5645 ins_encode( enc_lhz(dst, mem) ); 5646 ins_pipe(pipe_class_memory); 5647 %} 5648 5649 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5650 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5651 match(Set dst (ConvI2L (LoadUS mem))); 5652 ins_cost(3*MEMORY_REF_COST); 5653 5654 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5655 "TWI $dst\n\t" 5656 "ISYNC" %} 5657 size(12); 5658 ins_encode( enc_lhz_ac(dst, mem) ); 5659 ins_pipe(pipe_class_memory); 5660 %} 5661 5662 // Load Integer. 5663 instruct loadI(iRegIdst dst, memory mem) %{ 5664 match(Set dst (LoadI mem)); 5665 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5666 ins_cost(MEMORY_REF_COST); 5667 5668 format %{ "LWZ $dst, $mem" %} 5669 size(4); 5670 ins_encode( enc_lwz(dst, mem) ); 5671 ins_pipe(pipe_class_memory); 5672 %} 5673 5674 // Load Integer acquire. 5675 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5676 match(Set dst (LoadI mem)); 5677 ins_cost(3*MEMORY_REF_COST); 5678 5679 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5680 "TWI $dst\n\t" 5681 "ISYNC" %} 5682 size(12); 5683 ins_encode( enc_lwz_ac(dst, mem) ); 5684 ins_pipe(pipe_class_memory); 5685 %} 5686 5687 // Match loading integer and casting it to unsigned int in 5688 // long register. 5689 // LoadI + ConvI2L + AndL 0xffffffff. 5690 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5691 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5692 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5693 ins_cost(MEMORY_REF_COST); 5694 5695 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5696 size(4); 5697 ins_encode( enc_lwz(dst, mem) ); 5698 ins_pipe(pipe_class_memory); 5699 %} 5700 5701 // Match loading integer and casting it to long. 5702 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5703 match(Set dst (ConvI2L (LoadI mem))); 5704 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5705 ins_cost(MEMORY_REF_COST); 5706 5707 format %{ "LWA $dst, $mem \t// loadI2L" %} 5708 size(4); 5709 ins_encode %{ 5710 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5711 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5712 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5713 %} 5714 ins_pipe(pipe_class_memory); 5715 %} 5716 5717 // Match loading integer and casting it to long - acquire. 5718 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5719 match(Set dst (ConvI2L (LoadI mem))); 5720 ins_cost(3*MEMORY_REF_COST); 5721 5722 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5723 "TWI $dst\n\t" 5724 "ISYNC" %} 5725 size(12); 5726 ins_encode %{ 5727 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5728 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5729 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5730 __ twi_0($dst$$Register); 5731 __ isync(); 5732 %} 5733 ins_pipe(pipe_class_memory); 5734 %} 5735 5736 // Load Long - aligned 5737 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5738 match(Set dst (LoadL mem)); 5739 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5740 ins_cost(MEMORY_REF_COST); 5741 5742 format %{ "LD $dst, $mem \t// long" %} 5743 size(4); 5744 ins_encode( enc_ld(dst, mem) ); 5745 ins_pipe(pipe_class_memory); 5746 %} 5747 5748 // Load Long - aligned acquire. 5749 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5750 match(Set dst (LoadL mem)); 5751 ins_cost(3*MEMORY_REF_COST); 5752 5753 format %{ "LD $dst, $mem \t// long acquire\n\t" 5754 "TWI $dst\n\t" 5755 "ISYNC" %} 5756 size(12); 5757 ins_encode( enc_ld_ac(dst, mem) ); 5758 ins_pipe(pipe_class_memory); 5759 %} 5760 5761 // Load Long - UNaligned 5762 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5763 match(Set dst (LoadL_unaligned mem)); 5764 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5765 ins_cost(MEMORY_REF_COST); 5766 5767 format %{ "LD $dst, $mem \t// unaligned long" %} 5768 size(4); 5769 ins_encode( enc_ld(dst, mem) ); 5770 ins_pipe(pipe_class_memory); 5771 %} 5772 5773 // Load nodes for superwords 5774 5775 // Load Aligned Packed Byte 5776 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5777 predicate(n->as_LoadVector()->memory_size() == 8); 5778 match(Set dst (LoadVector mem)); 5779 ins_cost(MEMORY_REF_COST); 5780 5781 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5782 size(4); 5783 ins_encode( enc_ld(dst, mem) ); 5784 ins_pipe(pipe_class_memory); 5785 %} 5786 5787 // Load Aligned Packed Byte 5788 instruct loadV16(vecX dst, indirect mem) %{ 5789 predicate(n->as_LoadVector()->memory_size() == 16); 5790 match(Set dst (LoadVector mem)); 5791 ins_cost(MEMORY_REF_COST); 5792 5793 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5794 size(4); 5795 ins_encode %{ 5796 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5797 %} 5798 ins_pipe(pipe_class_default); 5799 %} 5800 5801 // Load Range, range = array length (=jint) 5802 instruct loadRange(iRegIdst dst, memory mem) %{ 5803 match(Set dst (LoadRange mem)); 5804 ins_cost(MEMORY_REF_COST); 5805 5806 format %{ "LWZ $dst, $mem \t// range" %} 5807 size(4); 5808 ins_encode( enc_lwz(dst, mem) ); 5809 ins_pipe(pipe_class_memory); 5810 %} 5811 5812 // Load Compressed Pointer 5813 instruct loadN(iRegNdst dst, memory mem) %{ 5814 match(Set dst (LoadN mem)); 5815 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5816 ins_cost(MEMORY_REF_COST); 5817 5818 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5819 size(4); 5820 ins_encode( enc_lwz(dst, mem) ); 5821 ins_pipe(pipe_class_memory); 5822 %} 5823 5824 // Load Compressed Pointer acquire. 5825 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5826 match(Set dst (LoadN mem)); 5827 ins_cost(3*MEMORY_REF_COST); 5828 5829 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5830 "TWI $dst\n\t" 5831 "ISYNC" %} 5832 size(12); 5833 ins_encode( enc_lwz_ac(dst, mem) ); 5834 ins_pipe(pipe_class_memory); 5835 %} 5836 5837 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5838 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5839 match(Set dst (DecodeN (LoadN mem))); 5840 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5841 ins_cost(MEMORY_REF_COST); 5842 5843 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5844 size(4); 5845 ins_encode( enc_lwz(dst, mem) ); 5846 ins_pipe(pipe_class_memory); 5847 %} 5848 5849 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5850 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5851 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5852 _kids[0]->_leaf->as_Load()->is_unordered()); 5853 ins_cost(MEMORY_REF_COST); 5854 5855 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5856 size(4); 5857 ins_encode( enc_lwz(dst, mem) ); 5858 ins_pipe(pipe_class_memory); 5859 %} 5860 5861 // Load Pointer 5862 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5863 match(Set dst (LoadP mem)); 5864 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5865 ins_cost(MEMORY_REF_COST); 5866 5867 format %{ "LD $dst, $mem \t// ptr" %} 5868 size(4); 5869 ins_encode( enc_ld(dst, mem) ); 5870 ins_pipe(pipe_class_memory); 5871 %} 5872 5873 // Load Pointer acquire. 5874 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5875 match(Set dst (LoadP mem)); 5876 ins_cost(3*MEMORY_REF_COST); 5877 5878 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5879 "TWI $dst\n\t" 5880 "ISYNC" %} 5881 size(12); 5882 ins_encode( enc_ld_ac(dst, mem) ); 5883 ins_pipe(pipe_class_memory); 5884 %} 5885 5886 // LoadP + CastP2L 5887 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5888 match(Set dst (CastP2X (LoadP mem))); 5889 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5890 ins_cost(MEMORY_REF_COST); 5891 5892 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5893 size(4); 5894 ins_encode( enc_ld(dst, mem) ); 5895 ins_pipe(pipe_class_memory); 5896 %} 5897 5898 // Load compressed klass pointer. 5899 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5900 match(Set dst (LoadNKlass mem)); 5901 ins_cost(MEMORY_REF_COST); 5902 5903 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5904 size(4); 5905 ins_encode( enc_lwz(dst, mem) ); 5906 ins_pipe(pipe_class_memory); 5907 %} 5908 5909 // Load Klass Pointer 5910 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5911 match(Set dst (LoadKlass mem)); 5912 ins_cost(MEMORY_REF_COST); 5913 5914 format %{ "LD $dst, $mem \t// klass ptr" %} 5915 size(4); 5916 ins_encode( enc_ld(dst, mem) ); 5917 ins_pipe(pipe_class_memory); 5918 %} 5919 5920 // Load Float 5921 instruct loadF(regF dst, memory mem) %{ 5922 match(Set dst (LoadF mem)); 5923 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5924 ins_cost(MEMORY_REF_COST); 5925 5926 format %{ "LFS $dst, $mem" %} 5927 size(4); 5928 ins_encode %{ 5929 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5930 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5931 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5932 %} 5933 ins_pipe(pipe_class_memory); 5934 %} 5935 5936 // Load Float acquire. 5937 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5938 match(Set dst (LoadF mem)); 5939 effect(TEMP cr0); 5940 ins_cost(3*MEMORY_REF_COST); 5941 5942 format %{ "LFS $dst, $mem \t// acquire\n\t" 5943 "FCMPU cr0, $dst, $dst\n\t" 5944 "BNE cr0, next\n" 5945 "next:\n\t" 5946 "ISYNC" %} 5947 size(16); 5948 ins_encode %{ 5949 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5950 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5951 Label next; 5952 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5953 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5954 __ bne(CCR0, next); 5955 __ bind(next); 5956 __ isync(); 5957 %} 5958 ins_pipe(pipe_class_memory); 5959 %} 5960 5961 // Load Double - aligned 5962 instruct loadD(regD dst, memory mem) %{ 5963 match(Set dst (LoadD mem)); 5964 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5965 ins_cost(MEMORY_REF_COST); 5966 5967 format %{ "LFD $dst, $mem" %} 5968 size(4); 5969 ins_encode( enc_lfd(dst, mem) ); 5970 ins_pipe(pipe_class_memory); 5971 %} 5972 5973 // Load Double - aligned acquire. 5974 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5975 match(Set dst (LoadD mem)); 5976 effect(TEMP cr0); 5977 ins_cost(3*MEMORY_REF_COST); 5978 5979 format %{ "LFD $dst, $mem \t// acquire\n\t" 5980 "FCMPU cr0, $dst, $dst\n\t" 5981 "BNE cr0, next\n" 5982 "next:\n\t" 5983 "ISYNC" %} 5984 size(16); 5985 ins_encode %{ 5986 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5987 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5988 Label next; 5989 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5990 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5991 __ bne(CCR0, next); 5992 __ bind(next); 5993 __ isync(); 5994 %} 5995 ins_pipe(pipe_class_memory); 5996 %} 5997 5998 // Load Double - UNaligned 5999 instruct loadD_unaligned(regD dst, memory mem) %{ 6000 match(Set dst (LoadD_unaligned mem)); 6001 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 6002 ins_cost(MEMORY_REF_COST); 6003 6004 format %{ "LFD $dst, $mem" %} 6005 size(4); 6006 ins_encode( enc_lfd(dst, mem) ); 6007 ins_pipe(pipe_class_memory); 6008 %} 6009 6010 //----------Constants-------------------------------------------------------- 6011 6012 // Load MachConstantTableBase: add hi offset to global toc. 6013 // TODO: Handle hidden register r29 in bundler! 6014 instruct loadToc_hi(iRegLdst dst) %{ 6015 effect(DEF dst); 6016 ins_cost(DEFAULT_COST); 6017 6018 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 6019 size(4); 6020 ins_encode %{ 6021 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6022 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 6023 %} 6024 ins_pipe(pipe_class_default); 6025 %} 6026 6027 // Load MachConstantTableBase: add lo offset to global toc. 6028 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 6029 effect(DEF dst, USE src); 6030 ins_cost(DEFAULT_COST); 6031 6032 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 6033 size(4); 6034 ins_encode %{ 6035 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6036 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 6037 %} 6038 ins_pipe(pipe_class_default); 6039 %} 6040 6041 // Load 16-bit integer constant 0xssss???? 6042 instruct loadConI16(iRegIdst dst, immI16 src) %{ 6043 match(Set dst src); 6044 6045 format %{ "LI $dst, $src" %} 6046 size(4); 6047 ins_encode %{ 6048 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6049 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6050 %} 6051 ins_pipe(pipe_class_default); 6052 %} 6053 6054 // Load integer constant 0x????0000 6055 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 6056 match(Set dst src); 6057 ins_cost(DEFAULT_COST); 6058 6059 format %{ "LIS $dst, $src.hi" %} 6060 size(4); 6061 ins_encode %{ 6062 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6063 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 6064 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6065 %} 6066 ins_pipe(pipe_class_default); 6067 %} 6068 6069 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 6070 // and sign extended), this adds the low 16 bits. 6071 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6072 // no match-rule, false predicate 6073 effect(DEF dst, USE src1, USE src2); 6074 predicate(false); 6075 6076 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6077 size(4); 6078 ins_encode %{ 6079 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6080 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6081 %} 6082 ins_pipe(pipe_class_default); 6083 %} 6084 6085 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6086 match(Set dst src); 6087 ins_cost(DEFAULT_COST*2); 6088 6089 expand %{ 6090 // Would like to use $src$$constant. 6091 immI16 srcLo %{ _opnds[1]->constant() %} 6092 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6093 immIhi16 srcHi %{ _opnds[1]->constant() %} 6094 iRegIdst tmpI; 6095 loadConIhi16(tmpI, srcHi); 6096 loadConI32_lo16(dst, tmpI, srcLo); 6097 %} 6098 %} 6099 6100 // No constant pool entries required. 6101 instruct loadConL16(iRegLdst dst, immL16 src) %{ 6102 match(Set dst src); 6103 6104 format %{ "LI $dst, $src \t// long" %} 6105 size(4); 6106 ins_encode %{ 6107 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6108 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6109 %} 6110 ins_pipe(pipe_class_default); 6111 %} 6112 6113 // Load long constant 0xssssssss????0000 6114 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6115 match(Set dst src); 6116 ins_cost(DEFAULT_COST); 6117 6118 format %{ "LIS $dst, $src.hi \t// long" %} 6119 size(4); 6120 ins_encode %{ 6121 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6122 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6123 %} 6124 ins_pipe(pipe_class_default); 6125 %} 6126 6127 // To load a 32 bit constant: merge lower 16 bits into already loaded 6128 // high 16 bits. 6129 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6130 // no match-rule, false predicate 6131 effect(DEF dst, USE src1, USE src2); 6132 predicate(false); 6133 6134 format %{ "ORI $dst, $src1, $src2.lo" %} 6135 size(4); 6136 ins_encode %{ 6137 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6138 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6139 %} 6140 ins_pipe(pipe_class_default); 6141 %} 6142 6143 // Load 32-bit long constant 6144 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6145 match(Set dst src); 6146 ins_cost(DEFAULT_COST*2); 6147 6148 expand %{ 6149 // Would like to use $src$$constant. 6150 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6151 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6152 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6153 iRegLdst tmpL; 6154 loadConL32hi16(tmpL, srcHi); 6155 loadConL32_lo16(dst, tmpL, srcLo); 6156 %} 6157 %} 6158 6159 // Load long constant 0x????000000000000. 6160 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6161 match(Set dst src); 6162 ins_cost(DEFAULT_COST); 6163 6164 expand %{ 6165 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6166 immI shift32 %{ 32 %} 6167 iRegLdst tmpL; 6168 loadConL32hi16(tmpL, srcHi); 6169 lshiftL_regL_immI(dst, tmpL, shift32); 6170 %} 6171 %} 6172 6173 // Expand node for constant pool load: small offset. 6174 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6175 effect(DEF dst, USE src, USE toc); 6176 ins_cost(MEMORY_REF_COST); 6177 6178 ins_num_consts(1); 6179 // Needed so that CallDynamicJavaDirect can compute the address of this 6180 // instruction for relocation. 6181 ins_field_cbuf_insts_offset(int); 6182 6183 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6184 size(4); 6185 ins_encode( enc_load_long_constL(dst, src, toc) ); 6186 ins_pipe(pipe_class_memory); 6187 %} 6188 6189 // Expand node for constant pool load: large offset. 6190 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6191 effect(DEF dst, USE src, USE toc); 6192 predicate(false); 6193 6194 ins_num_consts(1); 6195 ins_field_const_toc_offset(int); 6196 // Needed so that CallDynamicJavaDirect can compute the address of this 6197 // instruction for relocation. 6198 ins_field_cbuf_insts_offset(int); 6199 6200 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6201 size(4); 6202 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6203 ins_pipe(pipe_class_default); 6204 %} 6205 6206 // Expand node for constant pool load: large offset. 6207 // No constant pool entries required. 6208 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6209 effect(DEF dst, USE src, USE base); 6210 predicate(false); 6211 6212 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6213 6214 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6215 size(4); 6216 ins_encode %{ 6217 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6218 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6219 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6220 %} 6221 ins_pipe(pipe_class_memory); 6222 %} 6223 6224 // Load long constant from constant table. Expand in case of 6225 // offset > 16 bit is needed. 6226 // Adlc adds toc node MachConstantTableBase. 6227 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6228 match(Set dst src); 6229 ins_cost(MEMORY_REF_COST); 6230 6231 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6232 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6233 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6234 %} 6235 6236 // Load NULL as compressed oop. 6237 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6238 match(Set dst src); 6239 ins_cost(DEFAULT_COST); 6240 6241 format %{ "LI $dst, $src \t// compressed ptr" %} 6242 size(4); 6243 ins_encode %{ 6244 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6245 __ li($dst$$Register, 0); 6246 %} 6247 ins_pipe(pipe_class_default); 6248 %} 6249 6250 // Load hi part of compressed oop constant. 6251 instruct loadConN_hi(iRegNdst dst, immN src) %{ 6252 effect(DEF dst, USE src); 6253 ins_cost(DEFAULT_COST); 6254 6255 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6256 size(4); 6257 ins_encode %{ 6258 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6259 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6260 %} 6261 ins_pipe(pipe_class_default); 6262 %} 6263 6264 // Add lo part of compressed oop constant to already loaded hi part. 6265 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6266 effect(DEF dst, USE src1, USE src2); 6267 ins_cost(DEFAULT_COST); 6268 6269 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6270 size(4); 6271 ins_encode %{ 6272 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6273 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6274 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6275 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6276 __ relocate(rspec, 1); 6277 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6278 %} 6279 ins_pipe(pipe_class_default); 6280 %} 6281 6282 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6283 effect(DEF dst, USE src, USE shift, USE mask_begin); 6284 6285 size(4); 6286 ins_encode %{ 6287 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6288 %} 6289 ins_pipe(pipe_class_default); 6290 %} 6291 6292 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6293 // leaving the upper 32 bits with sign-extension bits. 6294 // This clears these bits: dst = src & 0xFFFFFFFF. 6295 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6296 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6297 effect(DEF dst, USE src); 6298 predicate(false); 6299 6300 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6301 size(4); 6302 ins_encode %{ 6303 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6304 __ clrldi($dst$$Register, $src$$Register, 0x20); 6305 %} 6306 ins_pipe(pipe_class_default); 6307 %} 6308 6309 // Optimize DecodeN for disjoint base. 6310 // Load base of compressed oops into a register 6311 instruct loadBase(iRegLdst dst) %{ 6312 effect(DEF dst); 6313 6314 format %{ "LoadConst $dst, heapbase" %} 6315 ins_encode %{ 6316 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6317 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 6318 %} 6319 ins_pipe(pipe_class_default); 6320 %} 6321 6322 // Loading ConN must be postalloc expanded so that edges between 6323 // the nodes are safe. They may not interfere with a safepoint. 6324 // GL TODO: This needs three instructions: better put this into the constant pool. 6325 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6326 match(Set dst src); 6327 ins_cost(DEFAULT_COST*2); 6328 6329 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6330 postalloc_expand %{ 6331 MachNode *m1 = new loadConN_hiNode(); 6332 MachNode *m2 = new loadConN_loNode(); 6333 MachNode *m3 = new clearMs32bNode(); 6334 m1->add_req(NULL); 6335 m2->add_req(NULL, m1); 6336 m3->add_req(NULL, m2); 6337 m1->_opnds[0] = op_dst; 6338 m1->_opnds[1] = op_src; 6339 m2->_opnds[0] = op_dst; 6340 m2->_opnds[1] = op_dst; 6341 m2->_opnds[2] = op_src; 6342 m3->_opnds[0] = op_dst; 6343 m3->_opnds[1] = op_dst; 6344 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6345 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6346 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6347 nodes->push(m1); 6348 nodes->push(m2); 6349 nodes->push(m3); 6350 %} 6351 %} 6352 6353 // We have seen a safepoint between the hi and lo parts, and this node was handled 6354 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6355 // not a narrow oop. 6356 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6357 match(Set dst src); 6358 effect(DEF dst, USE src); 6359 ins_cost(DEFAULT_COST); 6360 6361 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6362 size(4); 6363 ins_encode %{ 6364 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6365 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 6366 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6367 %} 6368 ins_pipe(pipe_class_default); 6369 %} 6370 6371 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6372 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6373 match(Set dst src1); 6374 effect(TEMP src2); 6375 ins_cost(DEFAULT_COST); 6376 6377 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6378 size(4); 6379 ins_encode %{ 6380 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6381 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6382 %} 6383 ins_pipe(pipe_class_default); 6384 %} 6385 6386 // This needs a match rule so that build_oop_map knows this is 6387 // not a narrow oop. 6388 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6389 match(Set dst src1); 6390 effect(TEMP src2); 6391 ins_cost(DEFAULT_COST); 6392 6393 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6394 size(4); 6395 ins_encode %{ 6396 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6397 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 6398 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6399 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6400 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6401 6402 __ relocate(rspec, 1); 6403 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6404 %} 6405 ins_pipe(pipe_class_default); 6406 %} 6407 6408 // Loading ConNKlass must be postalloc expanded so that edges between 6409 // the nodes are safe. They may not interfere with a safepoint. 6410 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6411 match(Set dst src); 6412 ins_cost(DEFAULT_COST*2); 6413 6414 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6415 postalloc_expand %{ 6416 // Load high bits into register. Sign extended. 6417 MachNode *m1 = new loadConNKlass_hiNode(); 6418 m1->add_req(NULL); 6419 m1->_opnds[0] = op_dst; 6420 m1->_opnds[1] = op_src; 6421 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6422 nodes->push(m1); 6423 6424 MachNode *m2 = m1; 6425 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 6426 // Value might be 1-extended. Mask out these bits. 6427 m2 = new loadConNKlass_maskNode(); 6428 m2->add_req(NULL, m1); 6429 m2->_opnds[0] = op_dst; 6430 m2->_opnds[1] = op_src; 6431 m2->_opnds[2] = op_dst; 6432 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6433 nodes->push(m2); 6434 } 6435 6436 MachNode *m3 = new loadConNKlass_loNode(); 6437 m3->add_req(NULL, m2); 6438 m3->_opnds[0] = op_dst; 6439 m3->_opnds[1] = op_src; 6440 m3->_opnds[2] = op_dst; 6441 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6442 nodes->push(m3); 6443 %} 6444 %} 6445 6446 // 0x1 is used in object initialization (initial object header). 6447 // No constant pool entries required. 6448 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6449 match(Set dst src); 6450 6451 format %{ "LI $dst, $src \t// ptr" %} 6452 size(4); 6453 ins_encode %{ 6454 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6455 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6456 %} 6457 ins_pipe(pipe_class_default); 6458 %} 6459 6460 // Expand node for constant pool load: small offset. 6461 // The match rule is needed to generate the correct bottom_type(), 6462 // however this node should never match. The use of predicate is not 6463 // possible since ADLC forbids predicates for chain rules. The higher 6464 // costs do not prevent matching in this case. For that reason the 6465 // operand immP_NM with predicate(false) is used. 6466 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6467 match(Set dst src); 6468 effect(TEMP toc); 6469 6470 ins_num_consts(1); 6471 6472 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6473 size(4); 6474 ins_encode( enc_load_long_constP(dst, src, toc) ); 6475 ins_pipe(pipe_class_memory); 6476 %} 6477 6478 // Expand node for constant pool load: large offset. 6479 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6480 effect(DEF dst, USE src, USE toc); 6481 predicate(false); 6482 6483 ins_num_consts(1); 6484 ins_field_const_toc_offset(int); 6485 6486 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6487 size(4); 6488 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6489 ins_pipe(pipe_class_default); 6490 %} 6491 6492 // Expand node for constant pool load: large offset. 6493 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6494 match(Set dst src); 6495 effect(TEMP base); 6496 6497 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6498 6499 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6500 size(4); 6501 ins_encode %{ 6502 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6503 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6504 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6505 %} 6506 ins_pipe(pipe_class_memory); 6507 %} 6508 6509 // Load pointer constant from constant table. Expand in case an 6510 // offset > 16 bit is needed. 6511 // Adlc adds toc node MachConstantTableBase. 6512 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6513 match(Set dst src); 6514 ins_cost(MEMORY_REF_COST); 6515 6516 // This rule does not use "expand" because then 6517 // the result type is not known to be an Oop. An ADLC 6518 // enhancement will be needed to make that work - not worth it! 6519 6520 // If this instruction rematerializes, it prolongs the live range 6521 // of the toc node, causing illegal graphs. 6522 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6523 ins_cannot_rematerialize(true); 6524 6525 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6526 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6527 %} 6528 6529 // Expand node for constant pool load: small offset. 6530 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6531 effect(DEF dst, USE src, USE toc); 6532 ins_cost(MEMORY_REF_COST); 6533 6534 ins_num_consts(1); 6535 6536 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6537 size(4); 6538 ins_encode %{ 6539 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6540 address float_address = __ float_constant($src$$constant); 6541 if (float_address == NULL) { 6542 ciEnv::current()->record_out_of_memory_failure(); 6543 return; 6544 } 6545 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6546 %} 6547 ins_pipe(pipe_class_memory); 6548 %} 6549 6550 // Expand node for constant pool load: large offset. 6551 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6552 effect(DEF dst, USE src, USE toc); 6553 ins_cost(MEMORY_REF_COST); 6554 6555 ins_num_consts(1); 6556 6557 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6558 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6559 "ADDIS $toc, $toc, -offset_hi"%} 6560 size(12); 6561 ins_encode %{ 6562 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6563 FloatRegister Rdst = $dst$$FloatRegister; 6564 Register Rtoc = $toc$$Register; 6565 address float_address = __ float_constant($src$$constant); 6566 if (float_address == NULL) { 6567 ciEnv::current()->record_out_of_memory_failure(); 6568 return; 6569 } 6570 int offset = __ offset_to_method_toc(float_address); 6571 int hi = (offset + (1<<15))>>16; 6572 int lo = offset - hi * (1<<16); 6573 6574 __ addis(Rtoc, Rtoc, hi); 6575 __ lfs(Rdst, lo, Rtoc); 6576 __ addis(Rtoc, Rtoc, -hi); 6577 %} 6578 ins_pipe(pipe_class_memory); 6579 %} 6580 6581 // Adlc adds toc node MachConstantTableBase. 6582 instruct loadConF_Ex(regF dst, immF src) %{ 6583 match(Set dst src); 6584 ins_cost(MEMORY_REF_COST); 6585 6586 // See loadConP. 6587 ins_cannot_rematerialize(true); 6588 6589 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6590 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6591 %} 6592 6593 // Expand node for constant pool load: small offset. 6594 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6595 effect(DEF dst, USE src, USE toc); 6596 ins_cost(MEMORY_REF_COST); 6597 6598 ins_num_consts(1); 6599 6600 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6601 size(4); 6602 ins_encode %{ 6603 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6604 address float_address = __ double_constant($src$$constant); 6605 if (float_address == NULL) { 6606 ciEnv::current()->record_out_of_memory_failure(); 6607 return; 6608 } 6609 int offset = __ offset_to_method_toc(float_address); 6610 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6611 %} 6612 ins_pipe(pipe_class_memory); 6613 %} 6614 6615 // Expand node for constant pool load: large offset. 6616 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6617 effect(DEF dst, USE src, USE toc); 6618 ins_cost(MEMORY_REF_COST); 6619 6620 ins_num_consts(1); 6621 6622 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6623 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6624 "ADDIS $toc, $toc, -offset_hi" %} 6625 size(12); 6626 ins_encode %{ 6627 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6628 FloatRegister Rdst = $dst$$FloatRegister; 6629 Register Rtoc = $toc$$Register; 6630 address float_address = __ double_constant($src$$constant); 6631 if (float_address == NULL) { 6632 ciEnv::current()->record_out_of_memory_failure(); 6633 return; 6634 } 6635 int offset = __ offset_to_method_toc(float_address); 6636 int hi = (offset + (1<<15))>>16; 6637 int lo = offset - hi * (1<<16); 6638 6639 __ addis(Rtoc, Rtoc, hi); 6640 __ lfd(Rdst, lo, Rtoc); 6641 __ addis(Rtoc, Rtoc, -hi); 6642 %} 6643 ins_pipe(pipe_class_memory); 6644 %} 6645 6646 // Adlc adds toc node MachConstantTableBase. 6647 instruct loadConD_Ex(regD dst, immD src) %{ 6648 match(Set dst src); 6649 ins_cost(MEMORY_REF_COST); 6650 6651 // See loadConP. 6652 ins_cannot_rematerialize(true); 6653 6654 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6655 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6656 %} 6657 6658 // Prefetch instructions. 6659 // Must be safe to execute with invalid address (cannot fault). 6660 6661 // Special prefetch versions which use the dcbz instruction. 6662 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6663 match(PrefetchAllocation (AddP mem src)); 6664 predicate(AllocatePrefetchStyle == 3); 6665 ins_cost(MEMORY_REF_COST); 6666 6667 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6668 size(4); 6669 ins_encode %{ 6670 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6671 __ dcbz($src$$Register, $mem$$base$$Register); 6672 %} 6673 ins_pipe(pipe_class_memory); 6674 %} 6675 6676 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6677 match(PrefetchAllocation mem); 6678 predicate(AllocatePrefetchStyle == 3); 6679 ins_cost(MEMORY_REF_COST); 6680 6681 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6682 size(4); 6683 ins_encode %{ 6684 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6685 __ dcbz($mem$$base$$Register); 6686 %} 6687 ins_pipe(pipe_class_memory); 6688 %} 6689 6690 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6691 match(PrefetchAllocation (AddP mem src)); 6692 predicate(AllocatePrefetchStyle != 3); 6693 ins_cost(MEMORY_REF_COST); 6694 6695 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6696 size(4); 6697 ins_encode %{ 6698 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6699 __ dcbtst($src$$Register, $mem$$base$$Register); 6700 %} 6701 ins_pipe(pipe_class_memory); 6702 %} 6703 6704 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6705 match(PrefetchAllocation mem); 6706 predicate(AllocatePrefetchStyle != 3); 6707 ins_cost(MEMORY_REF_COST); 6708 6709 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6710 size(4); 6711 ins_encode %{ 6712 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6713 __ dcbtst($mem$$base$$Register); 6714 %} 6715 ins_pipe(pipe_class_memory); 6716 %} 6717 6718 //----------Store Instructions------------------------------------------------- 6719 6720 // Store Byte 6721 instruct storeB(memory mem, iRegIsrc src) %{ 6722 match(Set mem (StoreB mem src)); 6723 ins_cost(MEMORY_REF_COST); 6724 6725 format %{ "STB $src, $mem \t// byte" %} 6726 size(4); 6727 ins_encode %{ 6728 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6729 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6730 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6731 %} 6732 ins_pipe(pipe_class_memory); 6733 %} 6734 6735 // Store Char/Short 6736 instruct storeC(memory mem, iRegIsrc src) %{ 6737 match(Set mem (StoreC mem src)); 6738 ins_cost(MEMORY_REF_COST); 6739 6740 format %{ "STH $src, $mem \t// short" %} 6741 size(4); 6742 ins_encode %{ 6743 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6744 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6745 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6746 %} 6747 ins_pipe(pipe_class_memory); 6748 %} 6749 6750 // Store Integer 6751 instruct storeI(memory mem, iRegIsrc src) %{ 6752 match(Set mem (StoreI mem src)); 6753 ins_cost(MEMORY_REF_COST); 6754 6755 format %{ "STW $src, $mem" %} 6756 size(4); 6757 ins_encode( enc_stw(src, mem) ); 6758 ins_pipe(pipe_class_memory); 6759 %} 6760 6761 // ConvL2I + StoreI. 6762 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6763 match(Set mem (StoreI mem (ConvL2I src))); 6764 ins_cost(MEMORY_REF_COST); 6765 6766 format %{ "STW l2i($src), $mem" %} 6767 size(4); 6768 ins_encode( enc_stw(src, mem) ); 6769 ins_pipe(pipe_class_memory); 6770 %} 6771 6772 // Store Long 6773 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6774 match(Set mem (StoreL mem src)); 6775 ins_cost(MEMORY_REF_COST); 6776 6777 format %{ "STD $src, $mem \t// long" %} 6778 size(4); 6779 ins_encode( enc_std(src, mem) ); 6780 ins_pipe(pipe_class_memory); 6781 %} 6782 6783 // Store super word nodes. 6784 6785 // Store Aligned Packed Byte long register to memory 6786 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6787 predicate(n->as_StoreVector()->memory_size() == 8); 6788 match(Set mem (StoreVector mem src)); 6789 ins_cost(MEMORY_REF_COST); 6790 6791 format %{ "STD $mem, $src \t// packed8B" %} 6792 size(4); 6793 ins_encode( enc_std(src, mem) ); 6794 ins_pipe(pipe_class_memory); 6795 %} 6796 6797 // Store Packed Byte long register to memory 6798 instruct storeV16(indirect mem, vecX src) %{ 6799 predicate(n->as_StoreVector()->memory_size() == 16); 6800 match(Set mem (StoreVector mem src)); 6801 ins_cost(MEMORY_REF_COST); 6802 6803 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6804 size(4); 6805 ins_encode %{ 6806 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6807 %} 6808 ins_pipe(pipe_class_default); 6809 %} 6810 6811 // Store Compressed Oop 6812 instruct storeN(memory dst, iRegN_P2N src) %{ 6813 match(Set dst (StoreN dst src)); 6814 ins_cost(MEMORY_REF_COST); 6815 6816 format %{ "STW $src, $dst \t// compressed oop" %} 6817 size(4); 6818 ins_encode( enc_stw(src, dst) ); 6819 ins_pipe(pipe_class_memory); 6820 %} 6821 6822 // Store Compressed KLass 6823 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6824 match(Set dst (StoreNKlass dst src)); 6825 ins_cost(MEMORY_REF_COST); 6826 6827 format %{ "STW $src, $dst \t// compressed klass" %} 6828 size(4); 6829 ins_encode( enc_stw(src, dst) ); 6830 ins_pipe(pipe_class_memory); 6831 %} 6832 6833 // Store Pointer 6834 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6835 match(Set dst (StoreP dst src)); 6836 ins_cost(MEMORY_REF_COST); 6837 6838 format %{ "STD $src, $dst \t// ptr" %} 6839 size(4); 6840 ins_encode( enc_std(src, dst) ); 6841 ins_pipe(pipe_class_memory); 6842 %} 6843 6844 // Store Float 6845 instruct storeF(memory mem, regF src) %{ 6846 match(Set mem (StoreF mem src)); 6847 ins_cost(MEMORY_REF_COST); 6848 6849 format %{ "STFS $src, $mem" %} 6850 size(4); 6851 ins_encode( enc_stfs(src, mem) ); 6852 ins_pipe(pipe_class_memory); 6853 %} 6854 6855 // Store Double 6856 instruct storeD(memory mem, regD src) %{ 6857 match(Set mem (StoreD mem src)); 6858 ins_cost(MEMORY_REF_COST); 6859 6860 format %{ "STFD $src, $mem" %} 6861 size(4); 6862 ins_encode( enc_stfd(src, mem) ); 6863 ins_pipe(pipe_class_memory); 6864 %} 6865 6866 //----------Store Instructions With Zeros-------------------------------------- 6867 6868 // Card-mark for CMS garbage collection. 6869 // This cardmark does an optimization so that it must not always 6870 // do a releasing store. For this, it gets the address of 6871 // CMSCollectorCardTableBarrierSetBSExt::_requires_release as input. 6872 // (Using releaseFieldAddr in the match rule is a hack.) 6873 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6874 match(Set mem (StoreCM mem releaseFieldAddr)); 6875 effect(TEMP crx); 6876 predicate(false); 6877 ins_cost(MEMORY_REF_COST); 6878 6879 // See loadConP. 6880 ins_cannot_rematerialize(true); 6881 6882 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6883 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6884 ins_pipe(pipe_class_memory); 6885 %} 6886 6887 // Card-mark for CMS garbage collection. 6888 // This cardmark does an optimization so that it must not always 6889 // do a releasing store. For this, it needs the constant address of 6890 // CMSCollectorCardTableBarrierSetBSExt::_requires_release. 6891 // This constant address is split off here by expand so we can use 6892 // adlc / matcher functionality to load it from the constant section. 6893 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6894 match(Set mem (StoreCM mem zero)); 6895 predicate(UseConcMarkSweepGC); 6896 6897 expand %{ 6898 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableBarrierSetBSExt::requires_release_address() */ %} 6899 iRegLdst releaseFieldAddress; 6900 flagsReg crx; 6901 loadConL_Ex(releaseFieldAddress, baseImm); 6902 storeCM_CMS(mem, releaseFieldAddress, crx); 6903 %} 6904 %} 6905 6906 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6907 match(Set mem (StoreCM mem zero)); 6908 predicate(UseG1GC); 6909 ins_cost(MEMORY_REF_COST); 6910 6911 ins_cannot_rematerialize(true); 6912 6913 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6914 size(8); 6915 ins_encode %{ 6916 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6917 __ li(R0, 0); 6918 //__ release(); // G1: oops are allowed to get visible after dirty marking 6919 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6920 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6921 %} 6922 ins_pipe(pipe_class_memory); 6923 %} 6924 6925 // Convert oop pointer into compressed form. 6926 6927 // Nodes for postalloc expand. 6928 6929 // Shift node for expand. 6930 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6931 // The match rule is needed to make it a 'MachTypeNode'! 6932 match(Set dst (EncodeP src)); 6933 predicate(false); 6934 6935 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6936 size(4); 6937 ins_encode %{ 6938 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6939 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6940 %} 6941 ins_pipe(pipe_class_default); 6942 %} 6943 6944 // Add node for expand. 6945 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6946 // The match rule is needed to make it a 'MachTypeNode'! 6947 match(Set dst (EncodeP src)); 6948 predicate(false); 6949 6950 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6951 ins_encode %{ 6952 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6953 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6954 %} 6955 ins_pipe(pipe_class_default); 6956 %} 6957 6958 // Conditional sub base. 6959 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6960 // The match rule is needed to make it a 'MachTypeNode'! 6961 match(Set dst (EncodeP (Binary crx src1))); 6962 predicate(false); 6963 6964 format %{ "BEQ $crx, done\n\t" 6965 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6966 "done:" %} 6967 ins_encode %{ 6968 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6969 Label done; 6970 __ beq($crx$$CondRegister, done); 6971 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6972 __ bind(done); 6973 %} 6974 ins_pipe(pipe_class_default); 6975 %} 6976 6977 // Power 7 can use isel instruction 6978 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6979 // The match rule is needed to make it a 'MachTypeNode'! 6980 match(Set dst (EncodeP (Binary crx src1))); 6981 predicate(false); 6982 6983 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6984 size(4); 6985 ins_encode %{ 6986 // This is a Power7 instruction for which no machine description exists. 6987 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6988 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6989 %} 6990 ins_pipe(pipe_class_default); 6991 %} 6992 6993 // Disjoint narrow oop base. 6994 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6995 match(Set dst (EncodeP src)); 6996 predicate(Universe::narrow_oop_base_disjoint()); 6997 6998 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6999 size(4); 7000 ins_encode %{ 7001 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7002 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 7003 %} 7004 ins_pipe(pipe_class_default); 7005 %} 7006 7007 // shift != 0, base != 0 7008 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 7009 match(Set dst (EncodeP src)); 7010 effect(TEMP crx); 7011 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 7012 Universe::narrow_oop_shift() != 0 && 7013 Universe::narrow_oop_base_overlaps()); 7014 7015 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 7016 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 7017 %} 7018 7019 // shift != 0, base != 0 7020 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 7021 match(Set dst (EncodeP src)); 7022 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 7023 Universe::narrow_oop_shift() != 0 && 7024 Universe::narrow_oop_base_overlaps()); 7025 7026 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 7027 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 7028 %} 7029 7030 // shift != 0, base == 0 7031 // TODO: This is the same as encodeP_shift. Merge! 7032 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 7033 match(Set dst (EncodeP src)); 7034 predicate(Universe::narrow_oop_shift() != 0 && 7035 Universe::narrow_oop_base() ==0); 7036 7037 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 7038 size(4); 7039 ins_encode %{ 7040 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7041 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 7042 %} 7043 ins_pipe(pipe_class_default); 7044 %} 7045 7046 // Compressed OOPs with narrow_oop_shift == 0. 7047 // shift == 0, base == 0 7048 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 7049 match(Set dst (EncodeP src)); 7050 predicate(Universe::narrow_oop_shift() == 0); 7051 7052 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 7053 // variable size, 0 or 4. 7054 ins_encode %{ 7055 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7056 __ mr_if_needed($dst$$Register, $src$$Register); 7057 %} 7058 ins_pipe(pipe_class_default); 7059 %} 7060 7061 // Decode nodes. 7062 7063 // Shift node for expand. 7064 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 7065 // The match rule is needed to make it a 'MachTypeNode'! 7066 match(Set dst (DecodeN src)); 7067 predicate(false); 7068 7069 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 7070 size(4); 7071 ins_encode %{ 7072 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7073 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7074 %} 7075 ins_pipe(pipe_class_default); 7076 %} 7077 7078 // Add node for expand. 7079 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7080 // The match rule is needed to make it a 'MachTypeNode'! 7081 match(Set dst (DecodeN src)); 7082 predicate(false); 7083 7084 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7085 ins_encode %{ 7086 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7087 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7088 %} 7089 ins_pipe(pipe_class_default); 7090 %} 7091 7092 // conditianal add base for expand 7093 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7094 // The match rule is needed to make it a 'MachTypeNode'! 7095 // NOTICE that the rule is nonsense - we just have to make sure that: 7096 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7097 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7098 match(Set dst (DecodeN (Binary crx src))); 7099 predicate(false); 7100 7101 format %{ "BEQ $crx, done\n\t" 7102 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7103 "done:" %} 7104 ins_encode %{ 7105 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7106 Label done; 7107 __ beq($crx$$CondRegister, done); 7108 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7109 __ bind(done); 7110 %} 7111 ins_pipe(pipe_class_default); 7112 %} 7113 7114 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7115 // The match rule is needed to make it a 'MachTypeNode'! 7116 // NOTICE that the rule is nonsense - we just have to make sure that: 7117 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7118 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7119 match(Set dst (DecodeN (Binary crx src1))); 7120 predicate(false); 7121 7122 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7123 size(4); 7124 ins_encode %{ 7125 // This is a Power7 instruction for which no machine description exists. 7126 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7127 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7128 %} 7129 ins_pipe(pipe_class_default); 7130 %} 7131 7132 // shift != 0, base != 0 7133 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7134 match(Set dst (DecodeN src)); 7135 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7136 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7137 Universe::narrow_oop_shift() != 0 && 7138 Universe::narrow_oop_base() != 0); 7139 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7140 effect(TEMP crx); 7141 7142 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7143 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7144 %} 7145 7146 // shift != 0, base == 0 7147 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7148 match(Set dst (DecodeN src)); 7149 predicate(Universe::narrow_oop_shift() != 0 && 7150 Universe::narrow_oop_base() == 0); 7151 7152 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7153 size(4); 7154 ins_encode %{ 7155 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7156 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7157 %} 7158 ins_pipe(pipe_class_default); 7159 %} 7160 7161 // Optimize DecodeN for disjoint base. 7162 // Shift narrow oop and or it into register that already contains the heap base. 7163 // Base == dst must hold, and is assured by construction in postaloc_expand. 7164 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7165 match(Set dst (DecodeN src)); 7166 effect(TEMP base); 7167 predicate(false); 7168 7169 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7170 size(4); 7171 ins_encode %{ 7172 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7173 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 7174 %} 7175 ins_pipe(pipe_class_default); 7176 %} 7177 7178 // Optimize DecodeN for disjoint base. 7179 // This node requires only one cycle on the critical path. 7180 // We must postalloc_expand as we can not express use_def effects where 7181 // the used register is L and the def'ed register P. 7182 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7183 match(Set dst (DecodeN src)); 7184 effect(TEMP_DEF dst); 7185 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7186 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7187 Universe::narrow_oop_base_disjoint()); 7188 ins_cost(DEFAULT_COST); 7189 7190 format %{ "MOV $dst, heapbase \t\n" 7191 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7192 postalloc_expand %{ 7193 loadBaseNode *n1 = new loadBaseNode(); 7194 n1->add_req(NULL); 7195 n1->_opnds[0] = op_dst; 7196 7197 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7198 n2->add_req(n_region, n_src, n1); 7199 n2->_opnds[0] = op_dst; 7200 n2->_opnds[1] = op_src; 7201 n2->_opnds[2] = op_dst; 7202 n2->_bottom_type = _bottom_type; 7203 7204 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7205 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7206 7207 nodes->push(n1); 7208 nodes->push(n2); 7209 %} 7210 %} 7211 7212 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7213 match(Set dst (DecodeN src)); 7214 effect(TEMP_DEF dst, TEMP crx); 7215 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7216 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7217 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 7218 ins_cost(3 * DEFAULT_COST); 7219 7220 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7221 postalloc_expand %{ 7222 loadBaseNode *n1 = new loadBaseNode(); 7223 n1->add_req(NULL); 7224 n1->_opnds[0] = op_dst; 7225 7226 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7227 n_compare->add_req(n_region, n_src); 7228 n_compare->_opnds[0] = op_crx; 7229 n_compare->_opnds[1] = op_src; 7230 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7231 7232 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7233 n2->add_req(n_region, n_src, n1); 7234 n2->_opnds[0] = op_dst; 7235 n2->_opnds[1] = op_src; 7236 n2->_opnds[2] = op_dst; 7237 n2->_bottom_type = _bottom_type; 7238 7239 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7240 n_cond_set->add_req(n_region, n_compare, n2); 7241 n_cond_set->_opnds[0] = op_dst; 7242 n_cond_set->_opnds[1] = op_crx; 7243 n_cond_set->_opnds[2] = op_dst; 7244 n_cond_set->_bottom_type = _bottom_type; 7245 7246 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7247 ra_->set_oop(n_cond_set, true); 7248 7249 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7250 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7251 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7252 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7253 7254 nodes->push(n1); 7255 nodes->push(n_compare); 7256 nodes->push(n2); 7257 nodes->push(n_cond_set); 7258 %} 7259 %} 7260 7261 // src != 0, shift != 0, base != 0 7262 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7263 match(Set dst (DecodeN src)); 7264 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7265 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7266 Universe::narrow_oop_shift() != 0 && 7267 Universe::narrow_oop_base() != 0); 7268 ins_cost(2 * DEFAULT_COST); 7269 7270 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7271 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7272 %} 7273 7274 // Compressed OOPs with narrow_oop_shift == 0. 7275 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7276 match(Set dst (DecodeN src)); 7277 predicate(Universe::narrow_oop_shift() == 0); 7278 ins_cost(DEFAULT_COST); 7279 7280 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7281 // variable size, 0 or 4. 7282 ins_encode %{ 7283 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7284 __ mr_if_needed($dst$$Register, $src$$Register); 7285 %} 7286 ins_pipe(pipe_class_default); 7287 %} 7288 7289 // Convert compressed oop into int for vectors alignment masking. 7290 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7291 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7292 predicate(Universe::narrow_oop_shift() == 0); 7293 ins_cost(DEFAULT_COST); 7294 7295 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7296 // variable size, 0 or 4. 7297 ins_encode %{ 7298 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7299 __ mr_if_needed($dst$$Register, $src$$Register); 7300 %} 7301 ins_pipe(pipe_class_default); 7302 %} 7303 7304 // Convert klass pointer into compressed form. 7305 7306 // Nodes for postalloc expand. 7307 7308 // Shift node for expand. 7309 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7310 // The match rule is needed to make it a 'MachTypeNode'! 7311 match(Set dst (EncodePKlass src)); 7312 predicate(false); 7313 7314 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7315 size(4); 7316 ins_encode %{ 7317 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7318 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7319 %} 7320 ins_pipe(pipe_class_default); 7321 %} 7322 7323 // Add node for expand. 7324 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7325 // The match rule is needed to make it a 'MachTypeNode'! 7326 match(Set dst (EncodePKlass (Binary base src))); 7327 predicate(false); 7328 7329 format %{ "SUB $dst, $base, $src \t// encode" %} 7330 size(4); 7331 ins_encode %{ 7332 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7333 __ subf($dst$$Register, $base$$Register, $src$$Register); 7334 %} 7335 ins_pipe(pipe_class_default); 7336 %} 7337 7338 // Disjoint narrow oop base. 7339 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7340 match(Set dst (EncodePKlass src)); 7341 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 7342 7343 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7344 size(4); 7345 ins_encode %{ 7346 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7347 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 7348 %} 7349 ins_pipe(pipe_class_default); 7350 %} 7351 7352 // shift != 0, base != 0 7353 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7354 match(Set dst (EncodePKlass (Binary base src))); 7355 predicate(false); 7356 7357 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7358 postalloc_expand %{ 7359 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7360 n1->add_req(n_region, n_base, n_src); 7361 n1->_opnds[0] = op_dst; 7362 n1->_opnds[1] = op_base; 7363 n1->_opnds[2] = op_src; 7364 n1->_bottom_type = _bottom_type; 7365 7366 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7367 n2->add_req(n_region, n1); 7368 n2->_opnds[0] = op_dst; 7369 n2->_opnds[1] = op_dst; 7370 n2->_bottom_type = _bottom_type; 7371 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7372 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7373 7374 nodes->push(n1); 7375 nodes->push(n2); 7376 %} 7377 %} 7378 7379 // shift != 0, base != 0 7380 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7381 match(Set dst (EncodePKlass src)); 7382 //predicate(Universe::narrow_klass_shift() != 0 && 7383 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 7384 7385 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7386 ins_cost(DEFAULT_COST*2); // Don't count constant. 7387 expand %{ 7388 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 7389 iRegLdst base; 7390 loadConL_Ex(base, baseImm); 7391 encodePKlass_not_null_Ex(dst, base, src); 7392 %} 7393 %} 7394 7395 // Decode nodes. 7396 7397 // Shift node for expand. 7398 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7399 // The match rule is needed to make it a 'MachTypeNode'! 7400 match(Set dst (DecodeNKlass src)); 7401 predicate(false); 7402 7403 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7404 size(4); 7405 ins_encode %{ 7406 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7407 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7408 %} 7409 ins_pipe(pipe_class_default); 7410 %} 7411 7412 // Add node for expand. 7413 7414 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7415 // The match rule is needed to make it a 'MachTypeNode'! 7416 match(Set dst (DecodeNKlass (Binary base src))); 7417 predicate(false); 7418 7419 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7420 size(4); 7421 ins_encode %{ 7422 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7423 __ add($dst$$Register, $base$$Register, $src$$Register); 7424 %} 7425 ins_pipe(pipe_class_default); 7426 %} 7427 7428 // src != 0, shift != 0, base != 0 7429 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7430 match(Set dst (DecodeNKlass (Binary base src))); 7431 //effect(kill src); // We need a register for the immediate result after shifting. 7432 predicate(false); 7433 7434 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7435 postalloc_expand %{ 7436 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7437 n1->add_req(n_region, n_base, n_src); 7438 n1->_opnds[0] = op_dst; 7439 n1->_opnds[1] = op_base; 7440 n1->_opnds[2] = op_src; 7441 n1->_bottom_type = _bottom_type; 7442 7443 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7444 n2->add_req(n_region, n1); 7445 n2->_opnds[0] = op_dst; 7446 n2->_opnds[1] = op_dst; 7447 n2->_bottom_type = _bottom_type; 7448 7449 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7450 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7451 7452 nodes->push(n1); 7453 nodes->push(n2); 7454 %} 7455 %} 7456 7457 // src != 0, shift != 0, base != 0 7458 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7459 match(Set dst (DecodeNKlass src)); 7460 // predicate(Universe::narrow_klass_shift() != 0 && 7461 // Universe::narrow_klass_base() != 0); 7462 7463 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7464 7465 ins_cost(DEFAULT_COST*2); // Don't count constant. 7466 expand %{ 7467 // We add first, then we shift. Like this, we can get along with one register less. 7468 // But we have to load the base pre-shifted. 7469 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7470 iRegLdst base; 7471 loadConL_Ex(base, baseImm); 7472 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7473 %} 7474 %} 7475 7476 //----------MemBar Instructions----------------------------------------------- 7477 // Memory barrier flavors 7478 7479 instruct membar_acquire() %{ 7480 match(LoadFence); 7481 ins_cost(4*MEMORY_REF_COST); 7482 7483 format %{ "MEMBAR-acquire" %} 7484 size(4); 7485 ins_encode %{ 7486 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7487 __ acquire(); 7488 %} 7489 ins_pipe(pipe_class_default); 7490 %} 7491 7492 instruct unnecessary_membar_acquire() %{ 7493 match(MemBarAcquire); 7494 ins_cost(0); 7495 7496 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7497 size(0); 7498 ins_encode( /*empty*/ ); 7499 ins_pipe(pipe_class_default); 7500 %} 7501 7502 instruct membar_acquire_lock() %{ 7503 match(MemBarAcquireLock); 7504 ins_cost(0); 7505 7506 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7507 size(0); 7508 ins_encode( /*empty*/ ); 7509 ins_pipe(pipe_class_default); 7510 %} 7511 7512 instruct membar_release() %{ 7513 match(MemBarRelease); 7514 match(StoreFence); 7515 ins_cost(4*MEMORY_REF_COST); 7516 7517 format %{ "MEMBAR-release" %} 7518 size(4); 7519 ins_encode %{ 7520 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7521 __ release(); 7522 %} 7523 ins_pipe(pipe_class_default); 7524 %} 7525 7526 instruct membar_storestore() %{ 7527 match(MemBarStoreStore); 7528 ins_cost(4*MEMORY_REF_COST); 7529 7530 format %{ "MEMBAR-store-store" %} 7531 size(4); 7532 ins_encode %{ 7533 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7534 __ membar(Assembler::StoreStore); 7535 %} 7536 ins_pipe(pipe_class_default); 7537 %} 7538 7539 instruct membar_release_lock() %{ 7540 match(MemBarReleaseLock); 7541 ins_cost(0); 7542 7543 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7544 size(0); 7545 ins_encode( /*empty*/ ); 7546 ins_pipe(pipe_class_default); 7547 %} 7548 7549 instruct membar_volatile() %{ 7550 match(MemBarVolatile); 7551 ins_cost(4*MEMORY_REF_COST); 7552 7553 format %{ "MEMBAR-volatile" %} 7554 size(4); 7555 ins_encode %{ 7556 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7557 __ fence(); 7558 %} 7559 ins_pipe(pipe_class_default); 7560 %} 7561 7562 // This optimization is wrong on PPC. The following pattern is not supported: 7563 // MemBarVolatile 7564 // ^ ^ 7565 // | | 7566 // CtrlProj MemProj 7567 // ^ ^ 7568 // | | 7569 // | Load 7570 // | 7571 // MemBarVolatile 7572 // 7573 // The first MemBarVolatile could get optimized out! According to 7574 // Vladimir, this pattern can not occur on Oracle platforms. 7575 // However, it does occur on PPC64 (because of membars in 7576 // inline_unsafe_load_store). 7577 // 7578 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7579 // Don't forget to look at the implementation of post_store_load_barrier again, 7580 // we did other fixes in that method. 7581 //instruct unnecessary_membar_volatile() %{ 7582 // match(MemBarVolatile); 7583 // predicate(Matcher::post_store_load_barrier(n)); 7584 // ins_cost(0); 7585 // 7586 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7587 // size(0); 7588 // ins_encode( /*empty*/ ); 7589 // ins_pipe(pipe_class_default); 7590 //%} 7591 7592 instruct membar_CPUOrder() %{ 7593 match(MemBarCPUOrder); 7594 ins_cost(0); 7595 7596 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7597 size(0); 7598 ins_encode( /*empty*/ ); 7599 ins_pipe(pipe_class_default); 7600 %} 7601 7602 //----------Conditional Move--------------------------------------------------- 7603 7604 // Cmove using isel. 7605 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7606 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7607 predicate(VM_Version::has_isel()); 7608 ins_cost(DEFAULT_COST); 7609 7610 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7611 size(4); 7612 ins_encode %{ 7613 // This is a Power7 instruction for which no machine description 7614 // exists. Anyways, the scheduler should be off on Power7. 7615 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7616 int cc = $cmp$$cmpcode; 7617 __ isel($dst$$Register, $crx$$CondRegister, 7618 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7619 %} 7620 ins_pipe(pipe_class_default); 7621 %} 7622 7623 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7624 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7625 predicate(!VM_Version::has_isel()); 7626 ins_cost(DEFAULT_COST+BRANCH_COST); 7627 7628 ins_variable_size_depending_on_alignment(true); 7629 7630 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7631 // Worst case is branch + move + stop, no stop without scheduler 7632 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7633 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7634 ins_pipe(pipe_class_default); 7635 %} 7636 7637 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7638 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7639 ins_cost(DEFAULT_COST+BRANCH_COST); 7640 7641 ins_variable_size_depending_on_alignment(true); 7642 7643 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7644 // Worst case is branch + move + stop, no stop without scheduler 7645 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7646 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7647 ins_pipe(pipe_class_default); 7648 %} 7649 7650 // Cmove using isel. 7651 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7652 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7653 predicate(VM_Version::has_isel()); 7654 ins_cost(DEFAULT_COST); 7655 7656 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7657 size(4); 7658 ins_encode %{ 7659 // This is a Power7 instruction for which no machine description 7660 // exists. Anyways, the scheduler should be off on Power7. 7661 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7662 int cc = $cmp$$cmpcode; 7663 __ isel($dst$$Register, $crx$$CondRegister, 7664 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7665 %} 7666 ins_pipe(pipe_class_default); 7667 %} 7668 7669 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7670 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7671 predicate(!VM_Version::has_isel()); 7672 ins_cost(DEFAULT_COST+BRANCH_COST); 7673 7674 ins_variable_size_depending_on_alignment(true); 7675 7676 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7677 // Worst case is branch + move + stop, no stop without scheduler. 7678 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7679 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7680 ins_pipe(pipe_class_default); 7681 %} 7682 7683 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7684 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7685 ins_cost(DEFAULT_COST+BRANCH_COST); 7686 7687 ins_variable_size_depending_on_alignment(true); 7688 7689 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7690 // Worst case is branch + move + stop, no stop without scheduler. 7691 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7692 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7693 ins_pipe(pipe_class_default); 7694 %} 7695 7696 // Cmove using isel. 7697 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7698 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7699 predicate(VM_Version::has_isel()); 7700 ins_cost(DEFAULT_COST); 7701 7702 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7703 size(4); 7704 ins_encode %{ 7705 // This is a Power7 instruction for which no machine description 7706 // exists. Anyways, the scheduler should be off on Power7. 7707 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7708 int cc = $cmp$$cmpcode; 7709 __ isel($dst$$Register, $crx$$CondRegister, 7710 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7711 %} 7712 ins_pipe(pipe_class_default); 7713 %} 7714 7715 // Conditional move for RegN. Only cmov(reg, reg). 7716 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7717 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7718 predicate(!VM_Version::has_isel()); 7719 ins_cost(DEFAULT_COST+BRANCH_COST); 7720 7721 ins_variable_size_depending_on_alignment(true); 7722 7723 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7724 // Worst case is branch + move + stop, no stop without scheduler. 7725 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7726 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7727 ins_pipe(pipe_class_default); 7728 %} 7729 7730 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7731 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7732 ins_cost(DEFAULT_COST+BRANCH_COST); 7733 7734 ins_variable_size_depending_on_alignment(true); 7735 7736 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7737 // Worst case is branch + move + stop, no stop without scheduler. 7738 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7739 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7740 ins_pipe(pipe_class_default); 7741 %} 7742 7743 // Cmove using isel. 7744 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7745 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7746 predicate(VM_Version::has_isel()); 7747 ins_cost(DEFAULT_COST); 7748 7749 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7750 size(4); 7751 ins_encode %{ 7752 // This is a Power7 instruction for which no machine description 7753 // exists. Anyways, the scheduler should be off on Power7. 7754 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7755 int cc = $cmp$$cmpcode; 7756 __ isel($dst$$Register, $crx$$CondRegister, 7757 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7758 %} 7759 ins_pipe(pipe_class_default); 7760 %} 7761 7762 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7763 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7764 predicate(!VM_Version::has_isel()); 7765 ins_cost(DEFAULT_COST+BRANCH_COST); 7766 7767 ins_variable_size_depending_on_alignment(true); 7768 7769 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7770 // Worst case is branch + move + stop, no stop without scheduler. 7771 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7772 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7773 ins_pipe(pipe_class_default); 7774 %} 7775 7776 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7777 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7778 ins_cost(DEFAULT_COST+BRANCH_COST); 7779 7780 ins_variable_size_depending_on_alignment(true); 7781 7782 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7783 // Worst case is branch + move + stop, no stop without scheduler. 7784 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7785 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7786 ins_pipe(pipe_class_default); 7787 %} 7788 7789 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7790 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7791 ins_cost(DEFAULT_COST+BRANCH_COST); 7792 7793 ins_variable_size_depending_on_alignment(true); 7794 7795 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7796 // Worst case is branch + move + stop, no stop without scheduler. 7797 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7798 ins_encode %{ 7799 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7800 Label done; 7801 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7802 // Branch if not (cmp crx). 7803 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7804 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7805 // TODO PPC port __ endgroup_if_needed(_size == 12); 7806 __ bind(done); 7807 %} 7808 ins_pipe(pipe_class_default); 7809 %} 7810 7811 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7812 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7813 ins_cost(DEFAULT_COST+BRANCH_COST); 7814 7815 ins_variable_size_depending_on_alignment(true); 7816 7817 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7818 // Worst case is branch + move + stop, no stop without scheduler. 7819 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7820 ins_encode %{ 7821 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7822 Label done; 7823 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7824 // Branch if not (cmp crx). 7825 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7826 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7827 // TODO PPC port __ endgroup_if_needed(_size == 12); 7828 __ bind(done); 7829 %} 7830 ins_pipe(pipe_class_default); 7831 %} 7832 7833 //----------Conditional_store-------------------------------------------------- 7834 // Conditional-store of the updated heap-top. 7835 // Used during allocation of the shared heap. 7836 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7837 7838 // As compareAndSwapL, but return flag register instead of boolean value in 7839 // int register. 7840 // Used by sun/misc/AtomicLongCSImpl.java. 7841 // Mem_ptr must be a memory operand, else this node does not get 7842 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7843 // can be rematerialized which leads to errors. 7844 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7845 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7846 effect(TEMP cr0); 7847 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7848 ins_encode %{ 7849 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7850 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7851 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7852 noreg, NULL, true); 7853 %} 7854 ins_pipe(pipe_class_default); 7855 %} 7856 7857 // As compareAndSwapP, but return flag register instead of boolean value in 7858 // int register. 7859 // This instruction is matched if UseTLAB is off. 7860 // Mem_ptr must be a memory operand, else this node does not get 7861 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7862 // can be rematerialized which leads to errors. 7863 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7864 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7865 ins_cost(2*MEMORY_REF_COST); 7866 7867 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7868 ins_encode %{ 7869 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7870 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7871 %} 7872 ins_pipe(pipe_class_memory); 7873 %} 7874 7875 // Implement LoadPLocked. Must be ordered against changes of the memory location 7876 // by storePConditional. 7877 // Don't know whether this is ever used. 7878 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7879 match(Set dst (LoadPLocked mem)); 7880 ins_cost(2*MEMORY_REF_COST); 7881 7882 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7883 size(4); 7884 ins_encode %{ 7885 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7886 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7887 %} 7888 ins_pipe(pipe_class_memory); 7889 %} 7890 7891 //----------Compare-And-Swap--------------------------------------------------- 7892 7893 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7894 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7895 // matched. 7896 7897 // Strong versions: 7898 7899 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7900 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7901 predicate(VM_Version::has_lqarx()); 7902 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7903 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7904 ins_encode %{ 7905 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7906 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7907 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7908 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7909 $res$$Register, true); 7910 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7911 __ isync(); 7912 } else { 7913 __ sync(); 7914 } 7915 %} 7916 ins_pipe(pipe_class_default); 7917 %} 7918 7919 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7920 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7921 predicate(!VM_Version::has_lqarx()); 7922 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7923 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7924 ins_encode %{ 7925 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7926 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7927 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7928 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7929 $res$$Register, true); 7930 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7931 __ isync(); 7932 } else { 7933 __ sync(); 7934 } 7935 %} 7936 ins_pipe(pipe_class_default); 7937 %} 7938 7939 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7940 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7941 predicate(VM_Version::has_lqarx()); 7942 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7943 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7944 ins_encode %{ 7945 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7946 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7947 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7948 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7949 $res$$Register, true); 7950 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7951 __ isync(); 7952 } else { 7953 __ sync(); 7954 } 7955 %} 7956 ins_pipe(pipe_class_default); 7957 %} 7958 7959 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7960 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7961 predicate(!VM_Version::has_lqarx()); 7962 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7963 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7964 ins_encode %{ 7965 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7966 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7967 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7968 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7969 $res$$Register, true); 7970 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7971 __ isync(); 7972 } else { 7973 __ sync(); 7974 } 7975 %} 7976 ins_pipe(pipe_class_default); 7977 %} 7978 7979 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7980 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7981 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7982 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7983 ins_encode %{ 7984 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7985 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7986 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7987 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7988 $res$$Register, true); 7989 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7990 __ isync(); 7991 } else { 7992 __ sync(); 7993 } 7994 %} 7995 ins_pipe(pipe_class_default); 7996 %} 7997 7998 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7999 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 8000 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8001 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8002 ins_encode %{ 8003 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8004 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8005 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8006 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8007 $res$$Register, true); 8008 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8009 __ isync(); 8010 } else { 8011 __ sync(); 8012 } 8013 %} 8014 ins_pipe(pipe_class_default); 8015 %} 8016 8017 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8018 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 8019 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8020 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8021 ins_encode %{ 8022 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8023 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8024 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8025 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8026 $res$$Register, NULL, true); 8027 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8028 __ isync(); 8029 } else { 8030 __ sync(); 8031 } 8032 %} 8033 ins_pipe(pipe_class_default); 8034 %} 8035 8036 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8037 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 8038 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8039 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8040 ins_encode %{ 8041 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8042 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8043 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8044 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8045 $res$$Register, NULL, true); 8046 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8047 __ isync(); 8048 } else { 8049 __ sync(); 8050 } 8051 %} 8052 ins_pipe(pipe_class_default); 8053 %} 8054 8055 // Weak versions: 8056 8057 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8058 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8059 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8060 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8061 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8062 ins_encode %{ 8063 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8064 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8065 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8066 MacroAssembler::MemBarNone, 8067 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8068 %} 8069 ins_pipe(pipe_class_default); 8070 %} 8071 8072 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8073 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8074 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8075 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8076 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8077 ins_encode %{ 8078 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8079 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8080 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8081 MacroAssembler::MemBarNone, 8082 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8083 %} 8084 ins_pipe(pipe_class_default); 8085 %} 8086 8087 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8088 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8089 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8090 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8091 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8092 ins_encode %{ 8093 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8094 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8095 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8096 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8097 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8098 %} 8099 ins_pipe(pipe_class_default); 8100 %} 8101 8102 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8103 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8104 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8105 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8106 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8107 ins_encode %{ 8108 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8109 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8110 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8111 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8112 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8113 %} 8114 ins_pipe(pipe_class_default); 8115 %} 8116 8117 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8118 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8119 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8120 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8121 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8122 ins_encode %{ 8123 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8124 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8125 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8126 MacroAssembler::MemBarNone, 8127 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8128 %} 8129 ins_pipe(pipe_class_default); 8130 %} 8131 8132 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8133 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8134 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8135 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8136 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8137 ins_encode %{ 8138 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8139 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8140 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8141 MacroAssembler::MemBarNone, 8142 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8143 %} 8144 ins_pipe(pipe_class_default); 8145 %} 8146 8147 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8148 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8149 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8150 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8151 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8152 ins_encode %{ 8153 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8154 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8155 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8156 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8157 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8158 %} 8159 ins_pipe(pipe_class_default); 8160 %} 8161 8162 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8163 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8164 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8165 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8166 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8167 ins_encode %{ 8168 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8169 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8170 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8171 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8172 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8173 %} 8174 ins_pipe(pipe_class_default); 8175 %} 8176 8177 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8178 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8179 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8180 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8181 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8182 ins_encode %{ 8183 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8184 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8185 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8186 MacroAssembler::MemBarNone, 8187 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8188 %} 8189 ins_pipe(pipe_class_default); 8190 %} 8191 8192 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8193 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8194 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8195 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8196 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8197 ins_encode %{ 8198 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8199 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8200 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8201 // value is never passed to caller. 8202 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8203 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8204 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8205 %} 8206 ins_pipe(pipe_class_default); 8207 %} 8208 8209 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8210 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8211 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8212 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8213 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8214 ins_encode %{ 8215 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8216 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8217 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8218 MacroAssembler::MemBarNone, 8219 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8220 %} 8221 ins_pipe(pipe_class_default); 8222 %} 8223 8224 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8225 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8226 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8227 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8228 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8229 ins_encode %{ 8230 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8231 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8232 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8233 // value is never passed to caller. 8234 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8235 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8236 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8237 %} 8238 ins_pipe(pipe_class_default); 8239 %} 8240 8241 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8242 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8243 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8244 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8245 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8246 ins_encode %{ 8247 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8248 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8249 // value is never passed to caller. 8250 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8251 MacroAssembler::MemBarNone, 8252 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8253 %} 8254 ins_pipe(pipe_class_default); 8255 %} 8256 8257 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8258 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8259 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8260 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8261 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 8262 ins_encode %{ 8263 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8264 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8265 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8266 // value is never passed to caller. 8267 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8268 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8269 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8270 %} 8271 ins_pipe(pipe_class_default); 8272 %} 8273 8274 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8275 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8276 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8277 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8278 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8279 ins_encode %{ 8280 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8281 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8282 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8283 MacroAssembler::MemBarNone, 8284 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8285 %} 8286 ins_pipe(pipe_class_default); 8287 %} 8288 8289 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8290 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8291 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8292 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8293 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8294 ins_encode %{ 8295 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8296 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8297 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8298 // value is never passed to caller. 8299 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8300 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8301 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8302 %} 8303 ins_pipe(pipe_class_default); 8304 %} 8305 8306 // CompareAndExchange 8307 8308 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8309 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8310 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8311 effect(TEMP_DEF res, TEMP cr0); 8312 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8313 ins_encode %{ 8314 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8315 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8316 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8317 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8318 noreg, true); 8319 %} 8320 ins_pipe(pipe_class_default); 8321 %} 8322 8323 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8324 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8325 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8326 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8327 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8328 ins_encode %{ 8329 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8330 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8331 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8332 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8333 noreg, true); 8334 %} 8335 ins_pipe(pipe_class_default); 8336 %} 8337 8338 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8339 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8340 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8341 effect(TEMP_DEF res, TEMP cr0); 8342 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8343 ins_encode %{ 8344 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8345 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8346 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8347 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8348 noreg, true); 8349 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8350 __ isync(); 8351 } else { 8352 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8353 __ sync(); 8354 } 8355 %} 8356 ins_pipe(pipe_class_default); 8357 %} 8358 8359 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8360 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8361 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8362 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8363 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8364 ins_encode %{ 8365 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8366 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8367 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8368 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8369 noreg, true); 8370 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8371 __ isync(); 8372 } else { 8373 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8374 __ sync(); 8375 } 8376 %} 8377 ins_pipe(pipe_class_default); 8378 %} 8379 8380 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8381 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8382 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8383 effect(TEMP_DEF res, TEMP cr0); 8384 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8385 ins_encode %{ 8386 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8387 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8388 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8389 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8390 noreg, true); 8391 %} 8392 ins_pipe(pipe_class_default); 8393 %} 8394 8395 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8396 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8397 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8398 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8399 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8400 ins_encode %{ 8401 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8402 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8403 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8404 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8405 noreg, true); 8406 %} 8407 ins_pipe(pipe_class_default); 8408 %} 8409 8410 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8411 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8412 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8413 effect(TEMP_DEF res, TEMP cr0); 8414 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8415 ins_encode %{ 8416 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8417 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8418 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8419 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8420 noreg, true); 8421 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8422 __ isync(); 8423 } else { 8424 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8425 __ sync(); 8426 } 8427 %} 8428 ins_pipe(pipe_class_default); 8429 %} 8430 8431 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8432 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8433 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8434 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8435 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8436 ins_encode %{ 8437 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8438 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8439 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8440 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8441 noreg, true); 8442 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8443 __ isync(); 8444 } else { 8445 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8446 __ sync(); 8447 } 8448 %} 8449 ins_pipe(pipe_class_default); 8450 %} 8451 8452 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8453 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8454 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8455 effect(TEMP_DEF res, TEMP cr0); 8456 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8457 ins_encode %{ 8458 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8459 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8460 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8461 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8462 noreg, true); 8463 %} 8464 ins_pipe(pipe_class_default); 8465 %} 8466 8467 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8468 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8469 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8470 effect(TEMP_DEF res, TEMP cr0); 8471 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8472 ins_encode %{ 8473 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8474 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8475 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8476 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8477 noreg, true); 8478 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8479 __ isync(); 8480 } else { 8481 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8482 __ sync(); 8483 } 8484 %} 8485 ins_pipe(pipe_class_default); 8486 %} 8487 8488 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8489 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8490 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8491 effect(TEMP_DEF res, TEMP cr0); 8492 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8493 ins_encode %{ 8494 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8495 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8496 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8497 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8498 noreg, true); 8499 %} 8500 ins_pipe(pipe_class_default); 8501 %} 8502 8503 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8504 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8505 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8506 effect(TEMP_DEF res, TEMP cr0); 8507 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8508 ins_encode %{ 8509 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8510 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8511 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8512 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8513 noreg, true); 8514 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8515 __ isync(); 8516 } else { 8517 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8518 __ sync(); 8519 } 8520 %} 8521 ins_pipe(pipe_class_default); 8522 %} 8523 8524 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8525 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8526 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8527 effect(TEMP_DEF res, TEMP cr0); 8528 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8529 ins_encode %{ 8530 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8531 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8532 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8533 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8534 noreg, NULL, true); 8535 %} 8536 ins_pipe(pipe_class_default); 8537 %} 8538 8539 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8540 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8541 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8542 effect(TEMP_DEF res, TEMP cr0); 8543 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8544 ins_encode %{ 8545 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8546 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8547 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8548 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8549 noreg, NULL, true); 8550 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8551 __ isync(); 8552 } else { 8553 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8554 __ sync(); 8555 } 8556 %} 8557 ins_pipe(pipe_class_default); 8558 %} 8559 8560 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8561 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8562 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8563 effect(TEMP_DEF res, TEMP cr0); 8564 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8565 ins_encode %{ 8566 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8567 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8568 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8569 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8570 noreg, NULL, true); 8571 %} 8572 ins_pipe(pipe_class_default); 8573 %} 8574 8575 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8576 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8577 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8578 effect(TEMP_DEF res, TEMP cr0); 8579 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8580 ins_encode %{ 8581 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8582 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8583 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8584 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8585 noreg, NULL, true); 8586 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8587 __ isync(); 8588 } else { 8589 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8590 __ sync(); 8591 } 8592 %} 8593 ins_pipe(pipe_class_default); 8594 %} 8595 8596 // Special RMW 8597 8598 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8599 match(Set res (GetAndAddB mem_ptr src)); 8600 predicate(VM_Version::has_lqarx()); 8601 effect(TEMP_DEF res, TEMP cr0); 8602 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8603 ins_encode %{ 8604 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8605 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8606 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8607 __ isync(); 8608 } else { 8609 __ sync(); 8610 } 8611 %} 8612 ins_pipe(pipe_class_default); 8613 %} 8614 8615 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8616 match(Set res (GetAndAddB mem_ptr src)); 8617 predicate(!VM_Version::has_lqarx()); 8618 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8619 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8620 ins_encode %{ 8621 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8622 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8623 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8624 __ isync(); 8625 } else { 8626 __ sync(); 8627 } 8628 %} 8629 ins_pipe(pipe_class_default); 8630 %} 8631 8632 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8633 match(Set res (GetAndAddS mem_ptr src)); 8634 predicate(VM_Version::has_lqarx()); 8635 effect(TEMP_DEF res, TEMP cr0); 8636 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8637 ins_encode %{ 8638 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8639 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8640 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8641 __ isync(); 8642 } else { 8643 __ sync(); 8644 } 8645 %} 8646 ins_pipe(pipe_class_default); 8647 %} 8648 8649 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8650 match(Set res (GetAndAddS mem_ptr src)); 8651 predicate(!VM_Version::has_lqarx()); 8652 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8653 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8654 ins_encode %{ 8655 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8656 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8657 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8658 __ isync(); 8659 } else { 8660 __ sync(); 8661 } 8662 %} 8663 ins_pipe(pipe_class_default); 8664 %} 8665 8666 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8667 match(Set res (GetAndAddI mem_ptr src)); 8668 effect(TEMP_DEF res, TEMP cr0); 8669 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8670 ins_encode %{ 8671 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8672 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8673 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8674 __ isync(); 8675 } else { 8676 __ sync(); 8677 } 8678 %} 8679 ins_pipe(pipe_class_default); 8680 %} 8681 8682 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8683 match(Set res (GetAndAddL mem_ptr src)); 8684 effect(TEMP_DEF res, TEMP cr0); 8685 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8686 ins_encode %{ 8687 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8688 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8689 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8690 __ isync(); 8691 } else { 8692 __ sync(); 8693 } 8694 %} 8695 ins_pipe(pipe_class_default); 8696 %} 8697 8698 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8699 match(Set res (GetAndSetB mem_ptr src)); 8700 predicate(VM_Version::has_lqarx()); 8701 effect(TEMP_DEF res, TEMP cr0); 8702 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8703 ins_encode %{ 8704 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8705 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8706 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8707 __ isync(); 8708 } else { 8709 __ sync(); 8710 } 8711 %} 8712 ins_pipe(pipe_class_default); 8713 %} 8714 8715 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8716 match(Set res (GetAndSetB mem_ptr src)); 8717 predicate(!VM_Version::has_lqarx()); 8718 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8719 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8720 ins_encode %{ 8721 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8722 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8723 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8724 __ isync(); 8725 } else { 8726 __ sync(); 8727 } 8728 %} 8729 ins_pipe(pipe_class_default); 8730 %} 8731 8732 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8733 match(Set res (GetAndSetS mem_ptr src)); 8734 predicate(VM_Version::has_lqarx()); 8735 effect(TEMP_DEF res, TEMP cr0); 8736 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8737 ins_encode %{ 8738 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8739 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8740 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8741 __ isync(); 8742 } else { 8743 __ sync(); 8744 } 8745 %} 8746 ins_pipe(pipe_class_default); 8747 %} 8748 8749 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8750 match(Set res (GetAndSetS mem_ptr src)); 8751 predicate(!VM_Version::has_lqarx()); 8752 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8753 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8754 ins_encode %{ 8755 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8756 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8757 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8758 __ isync(); 8759 } else { 8760 __ sync(); 8761 } 8762 %} 8763 ins_pipe(pipe_class_default); 8764 %} 8765 8766 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8767 match(Set res (GetAndSetI mem_ptr src)); 8768 effect(TEMP_DEF res, TEMP cr0); 8769 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8770 ins_encode %{ 8771 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8772 MacroAssembler::cmpxchgx_hint_atomic_update()); 8773 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8774 __ isync(); 8775 } else { 8776 __ sync(); 8777 } 8778 %} 8779 ins_pipe(pipe_class_default); 8780 %} 8781 8782 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8783 match(Set res (GetAndSetL mem_ptr src)); 8784 effect(TEMP_DEF res, TEMP cr0); 8785 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8786 ins_encode %{ 8787 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8788 MacroAssembler::cmpxchgx_hint_atomic_update()); 8789 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8790 __ isync(); 8791 } else { 8792 __ sync(); 8793 } 8794 %} 8795 ins_pipe(pipe_class_default); 8796 %} 8797 8798 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8799 match(Set res (GetAndSetP mem_ptr src)); 8800 effect(TEMP_DEF res, TEMP cr0); 8801 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8802 ins_encode %{ 8803 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8804 MacroAssembler::cmpxchgx_hint_atomic_update()); 8805 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8806 __ isync(); 8807 } else { 8808 __ sync(); 8809 } 8810 %} 8811 ins_pipe(pipe_class_default); 8812 %} 8813 8814 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8815 match(Set res (GetAndSetN mem_ptr src)); 8816 effect(TEMP_DEF res, TEMP cr0); 8817 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8818 ins_encode %{ 8819 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8820 MacroAssembler::cmpxchgx_hint_atomic_update()); 8821 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8822 __ isync(); 8823 } else { 8824 __ sync(); 8825 } 8826 %} 8827 ins_pipe(pipe_class_default); 8828 %} 8829 8830 //----------Arithmetic Instructions-------------------------------------------- 8831 // Addition Instructions 8832 8833 // Register Addition 8834 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8835 match(Set dst (AddI src1 src2)); 8836 format %{ "ADD $dst, $src1, $src2" %} 8837 size(4); 8838 ins_encode %{ 8839 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8840 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8841 %} 8842 ins_pipe(pipe_class_default); 8843 %} 8844 8845 // Expand does not work with above instruct. (??) 8846 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8847 // no match-rule 8848 effect(DEF dst, USE src1, USE src2); 8849 format %{ "ADD $dst, $src1, $src2" %} 8850 size(4); 8851 ins_encode %{ 8852 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8853 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8854 %} 8855 ins_pipe(pipe_class_default); 8856 %} 8857 8858 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8859 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8860 ins_cost(DEFAULT_COST*3); 8861 8862 expand %{ 8863 // FIXME: we should do this in the ideal world. 8864 iRegIdst tmp1; 8865 iRegIdst tmp2; 8866 addI_reg_reg(tmp1, src1, src2); 8867 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8868 addI_reg_reg(dst, tmp1, tmp2); 8869 %} 8870 %} 8871 8872 // Immediate Addition 8873 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8874 match(Set dst (AddI src1 src2)); 8875 format %{ "ADDI $dst, $src1, $src2" %} 8876 size(4); 8877 ins_encode %{ 8878 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8879 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8880 %} 8881 ins_pipe(pipe_class_default); 8882 %} 8883 8884 // Immediate Addition with 16-bit shifted operand 8885 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8886 match(Set dst (AddI src1 src2)); 8887 format %{ "ADDIS $dst, $src1, $src2" %} 8888 size(4); 8889 ins_encode %{ 8890 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8891 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8892 %} 8893 ins_pipe(pipe_class_default); 8894 %} 8895 8896 // Long Addition 8897 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8898 match(Set dst (AddL src1 src2)); 8899 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8900 size(4); 8901 ins_encode %{ 8902 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8903 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8904 %} 8905 ins_pipe(pipe_class_default); 8906 %} 8907 8908 // Expand does not work with above instruct. (??) 8909 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8910 // no match-rule 8911 effect(DEF dst, USE src1, USE src2); 8912 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8913 size(4); 8914 ins_encode %{ 8915 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8916 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8917 %} 8918 ins_pipe(pipe_class_default); 8919 %} 8920 8921 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8922 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8923 ins_cost(DEFAULT_COST*3); 8924 8925 expand %{ 8926 // FIXME: we should do this in the ideal world. 8927 iRegLdst tmp1; 8928 iRegLdst tmp2; 8929 addL_reg_reg(tmp1, src1, src2); 8930 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8931 addL_reg_reg(dst, tmp1, tmp2); 8932 %} 8933 %} 8934 8935 // AddL + ConvL2I. 8936 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8937 match(Set dst (ConvL2I (AddL src1 src2))); 8938 8939 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8940 size(4); 8941 ins_encode %{ 8942 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8943 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8944 %} 8945 ins_pipe(pipe_class_default); 8946 %} 8947 8948 // No constant pool entries required. 8949 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8950 match(Set dst (AddL src1 src2)); 8951 8952 format %{ "ADDI $dst, $src1, $src2" %} 8953 size(4); 8954 ins_encode %{ 8955 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8956 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8957 %} 8958 ins_pipe(pipe_class_default); 8959 %} 8960 8961 // Long Immediate Addition with 16-bit shifted operand. 8962 // No constant pool entries required. 8963 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8964 match(Set dst (AddL src1 src2)); 8965 8966 format %{ "ADDIS $dst, $src1, $src2" %} 8967 size(4); 8968 ins_encode %{ 8969 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8970 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8971 %} 8972 ins_pipe(pipe_class_default); 8973 %} 8974 8975 // Pointer Register Addition 8976 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8977 match(Set dst (AddP src1 src2)); 8978 format %{ "ADD $dst, $src1, $src2" %} 8979 size(4); 8980 ins_encode %{ 8981 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8982 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8983 %} 8984 ins_pipe(pipe_class_default); 8985 %} 8986 8987 // Pointer Immediate Addition 8988 // No constant pool entries required. 8989 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8990 match(Set dst (AddP src1 src2)); 8991 8992 format %{ "ADDI $dst, $src1, $src2" %} 8993 size(4); 8994 ins_encode %{ 8995 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8996 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8997 %} 8998 ins_pipe(pipe_class_default); 8999 %} 9000 9001 // Pointer Immediate Addition with 16-bit shifted operand. 9002 // No constant pool entries required. 9003 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 9004 match(Set dst (AddP src1 src2)); 9005 9006 format %{ "ADDIS $dst, $src1, $src2" %} 9007 size(4); 9008 ins_encode %{ 9009 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 9010 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 9011 %} 9012 ins_pipe(pipe_class_default); 9013 %} 9014 9015 //--------------------- 9016 // Subtraction Instructions 9017 9018 // Register Subtraction 9019 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9020 match(Set dst (SubI src1 src2)); 9021 format %{ "SUBF $dst, $src2, $src1" %} 9022 size(4); 9023 ins_encode %{ 9024 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9025 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9026 %} 9027 ins_pipe(pipe_class_default); 9028 %} 9029 9030 // Immediate Subtraction 9031 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 9032 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 9033 9034 // SubI from constant (using subfic). 9035 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 9036 match(Set dst (SubI src1 src2)); 9037 format %{ "SUBI $dst, $src1, $src2" %} 9038 9039 size(4); 9040 ins_encode %{ 9041 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 9042 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 9043 %} 9044 ins_pipe(pipe_class_default); 9045 %} 9046 9047 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 9048 // positive integers and 0xF...F for negative ones. 9049 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 9050 // no match-rule, false predicate 9051 effect(DEF dst, USE src); 9052 predicate(false); 9053 9054 format %{ "SRAWI $dst, $src, #31" %} 9055 size(4); 9056 ins_encode %{ 9057 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9058 __ srawi($dst$$Register, $src$$Register, 0x1f); 9059 %} 9060 ins_pipe(pipe_class_default); 9061 %} 9062 9063 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 9064 match(Set dst (AbsI src)); 9065 ins_cost(DEFAULT_COST*3); 9066 9067 expand %{ 9068 iRegIdst tmp1; 9069 iRegIdst tmp2; 9070 signmask32I_regI(tmp1, src); 9071 xorI_reg_reg(tmp2, tmp1, src); 9072 subI_reg_reg(dst, tmp2, tmp1); 9073 %} 9074 %} 9075 9076 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9077 match(Set dst (SubI zero src2)); 9078 format %{ "NEG $dst, $src2" %} 9079 size(4); 9080 ins_encode %{ 9081 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9082 __ neg($dst$$Register, $src2$$Register); 9083 %} 9084 ins_pipe(pipe_class_default); 9085 %} 9086 9087 // Long subtraction 9088 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9089 match(Set dst (SubL src1 src2)); 9090 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9091 size(4); 9092 ins_encode %{ 9093 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9094 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9095 %} 9096 ins_pipe(pipe_class_default); 9097 %} 9098 9099 // SubL + convL2I. 9100 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9101 match(Set dst (ConvL2I (SubL src1 src2))); 9102 9103 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9104 size(4); 9105 ins_encode %{ 9106 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9107 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9108 %} 9109 ins_pipe(pipe_class_default); 9110 %} 9111 9112 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9113 // positive longs and 0xF...F for negative ones. 9114 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9115 // no match-rule, false predicate 9116 effect(DEF dst, USE src); 9117 predicate(false); 9118 9119 format %{ "SRADI $dst, $src, #63" %} 9120 size(4); 9121 ins_encode %{ 9122 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9123 __ sradi($dst$$Register, $src$$Register, 0x3f); 9124 %} 9125 ins_pipe(pipe_class_default); 9126 %} 9127 9128 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9129 // positive longs and 0xF...F for negative ones. 9130 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9131 // no match-rule, false predicate 9132 effect(DEF dst, USE src); 9133 predicate(false); 9134 9135 format %{ "SRADI $dst, $src, #63" %} 9136 size(4); 9137 ins_encode %{ 9138 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9139 __ sradi($dst$$Register, $src$$Register, 0x3f); 9140 %} 9141 ins_pipe(pipe_class_default); 9142 %} 9143 9144 // Long negation 9145 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9146 match(Set dst (SubL zero src2)); 9147 format %{ "NEG $dst, $src2 \t// long" %} 9148 size(4); 9149 ins_encode %{ 9150 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9151 __ neg($dst$$Register, $src2$$Register); 9152 %} 9153 ins_pipe(pipe_class_default); 9154 %} 9155 9156 // NegL + ConvL2I. 9157 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9158 match(Set dst (ConvL2I (SubL zero src2))); 9159 9160 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9161 size(4); 9162 ins_encode %{ 9163 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9164 __ neg($dst$$Register, $src2$$Register); 9165 %} 9166 ins_pipe(pipe_class_default); 9167 %} 9168 9169 // Multiplication Instructions 9170 // Integer Multiplication 9171 9172 // Register Multiplication 9173 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9174 match(Set dst (MulI src1 src2)); 9175 ins_cost(DEFAULT_COST); 9176 9177 format %{ "MULLW $dst, $src1, $src2" %} 9178 size(4); 9179 ins_encode %{ 9180 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9181 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9182 %} 9183 ins_pipe(pipe_class_default); 9184 %} 9185 9186 // Immediate Multiplication 9187 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9188 match(Set dst (MulI src1 src2)); 9189 ins_cost(DEFAULT_COST); 9190 9191 format %{ "MULLI $dst, $src1, $src2" %} 9192 size(4); 9193 ins_encode %{ 9194 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9195 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9196 %} 9197 ins_pipe(pipe_class_default); 9198 %} 9199 9200 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9201 match(Set dst (MulL src1 src2)); 9202 ins_cost(DEFAULT_COST); 9203 9204 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9205 size(4); 9206 ins_encode %{ 9207 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9208 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9209 %} 9210 ins_pipe(pipe_class_default); 9211 %} 9212 9213 // Multiply high for optimized long division by constant. 9214 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9215 match(Set dst (MulHiL src1 src2)); 9216 ins_cost(DEFAULT_COST); 9217 9218 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9219 size(4); 9220 ins_encode %{ 9221 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9222 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9223 %} 9224 ins_pipe(pipe_class_default); 9225 %} 9226 9227 // Immediate Multiplication 9228 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9229 match(Set dst (MulL src1 src2)); 9230 ins_cost(DEFAULT_COST); 9231 9232 format %{ "MULLI $dst, $src1, $src2" %} 9233 size(4); 9234 ins_encode %{ 9235 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9236 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9237 %} 9238 ins_pipe(pipe_class_default); 9239 %} 9240 9241 // Integer Division with Immediate -1: Negate. 9242 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9243 match(Set dst (DivI src1 src2)); 9244 ins_cost(DEFAULT_COST); 9245 9246 format %{ "NEG $dst, $src1 \t// /-1" %} 9247 size(4); 9248 ins_encode %{ 9249 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9250 __ neg($dst$$Register, $src1$$Register); 9251 %} 9252 ins_pipe(pipe_class_default); 9253 %} 9254 9255 // Integer Division with constant, but not -1. 9256 // We should be able to improve this by checking the type of src2. 9257 // It might well be that src2 is known to be positive. 9258 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9259 match(Set dst (DivI src1 src2)); 9260 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9261 ins_cost(2*DEFAULT_COST); 9262 9263 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9264 size(4); 9265 ins_encode %{ 9266 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9267 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9268 %} 9269 ins_pipe(pipe_class_default); 9270 %} 9271 9272 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9273 effect(USE_DEF dst, USE src1, USE crx); 9274 predicate(false); 9275 9276 ins_variable_size_depending_on_alignment(true); 9277 9278 format %{ "CMOVE $dst, neg($src1), $crx" %} 9279 // Worst case is branch + move + stop, no stop without scheduler. 9280 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 9281 ins_encode %{ 9282 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9283 Label done; 9284 __ bne($crx$$CondRegister, done); 9285 __ neg($dst$$Register, $src1$$Register); 9286 // TODO PPC port __ endgroup_if_needed(_size == 12); 9287 __ bind(done); 9288 %} 9289 ins_pipe(pipe_class_default); 9290 %} 9291 9292 // Integer Division with Registers not containing constants. 9293 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9294 match(Set dst (DivI src1 src2)); 9295 ins_cost(10*DEFAULT_COST); 9296 9297 expand %{ 9298 immI16 imm %{ (int)-1 %} 9299 flagsReg tmp1; 9300 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9301 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9302 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9303 %} 9304 %} 9305 9306 // Long Division with Immediate -1: Negate. 9307 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9308 match(Set dst (DivL src1 src2)); 9309 ins_cost(DEFAULT_COST); 9310 9311 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9312 size(4); 9313 ins_encode %{ 9314 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9315 __ neg($dst$$Register, $src1$$Register); 9316 %} 9317 ins_pipe(pipe_class_default); 9318 %} 9319 9320 // Long Division with constant, but not -1. 9321 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9322 match(Set dst (DivL src1 src2)); 9323 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9324 ins_cost(2*DEFAULT_COST); 9325 9326 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9327 size(4); 9328 ins_encode %{ 9329 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9330 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9331 %} 9332 ins_pipe(pipe_class_default); 9333 %} 9334 9335 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9336 effect(USE_DEF dst, USE src1, USE crx); 9337 predicate(false); 9338 9339 ins_variable_size_depending_on_alignment(true); 9340 9341 format %{ "CMOVE $dst, neg($src1), $crx" %} 9342 // Worst case is branch + move + stop, no stop without scheduler. 9343 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 9344 ins_encode %{ 9345 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9346 Label done; 9347 __ bne($crx$$CondRegister, done); 9348 __ neg($dst$$Register, $src1$$Register); 9349 // TODO PPC port __ endgroup_if_needed(_size == 12); 9350 __ bind(done); 9351 %} 9352 ins_pipe(pipe_class_default); 9353 %} 9354 9355 // Long Division with Registers not containing constants. 9356 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9357 match(Set dst (DivL src1 src2)); 9358 ins_cost(10*DEFAULT_COST); 9359 9360 expand %{ 9361 immL16 imm %{ (int)-1 %} 9362 flagsReg tmp1; 9363 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9364 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9365 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9366 %} 9367 %} 9368 9369 // Integer Remainder with registers. 9370 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9371 match(Set dst (ModI src1 src2)); 9372 ins_cost(10*DEFAULT_COST); 9373 9374 expand %{ 9375 immI16 imm %{ (int)-1 %} 9376 flagsReg tmp1; 9377 iRegIdst tmp2; 9378 iRegIdst tmp3; 9379 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9380 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9381 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9382 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9383 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9384 %} 9385 %} 9386 9387 // Long Remainder with registers 9388 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9389 match(Set dst (ModL src1 src2)); 9390 ins_cost(10*DEFAULT_COST); 9391 9392 expand %{ 9393 immL16 imm %{ (int)-1 %} 9394 flagsReg tmp1; 9395 iRegLdst tmp2; 9396 iRegLdst tmp3; 9397 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9398 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9399 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9400 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9401 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9402 %} 9403 %} 9404 9405 // Integer Shift Instructions 9406 9407 // Register Shift Left 9408 9409 // Clear all but the lowest #mask bits. 9410 // Used to normalize shift amounts in registers. 9411 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9412 // no match-rule, false predicate 9413 effect(DEF dst, USE src, USE mask); 9414 predicate(false); 9415 9416 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9417 size(4); 9418 ins_encode %{ 9419 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9420 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9421 %} 9422 ins_pipe(pipe_class_default); 9423 %} 9424 9425 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9426 // no match-rule, false predicate 9427 effect(DEF dst, USE src1, USE src2); 9428 predicate(false); 9429 9430 format %{ "SLW $dst, $src1, $src2" %} 9431 size(4); 9432 ins_encode %{ 9433 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9434 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9435 %} 9436 ins_pipe(pipe_class_default); 9437 %} 9438 9439 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9440 match(Set dst (LShiftI src1 src2)); 9441 ins_cost(DEFAULT_COST*2); 9442 expand %{ 9443 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9444 iRegIdst tmpI; 9445 maskI_reg_imm(tmpI, src2, mask); 9446 lShiftI_reg_reg(dst, src1, tmpI); 9447 %} 9448 %} 9449 9450 // Register Shift Left Immediate 9451 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9452 match(Set dst (LShiftI src1 src2)); 9453 9454 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9455 size(4); 9456 ins_encode %{ 9457 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9458 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9459 %} 9460 ins_pipe(pipe_class_default); 9461 %} 9462 9463 // AndI with negpow2-constant + LShiftI 9464 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9465 match(Set dst (LShiftI (AndI src1 src2) src3)); 9466 predicate(UseRotateAndMaskInstructionsPPC64); 9467 9468 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9469 size(4); 9470 ins_encode %{ 9471 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9472 long src2 = $src2$$constant; 9473 long src3 = $src3$$constant; 9474 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9475 if (maskbits >= 32) { 9476 __ li($dst$$Register, 0); // addi 9477 } else { 9478 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9479 } 9480 %} 9481 ins_pipe(pipe_class_default); 9482 %} 9483 9484 // RShiftI + AndI with negpow2-constant + LShiftI 9485 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9486 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9487 predicate(UseRotateAndMaskInstructionsPPC64); 9488 9489 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9490 size(4); 9491 ins_encode %{ 9492 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9493 long src2 = $src2$$constant; 9494 long src3 = $src3$$constant; 9495 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9496 if (maskbits >= 32) { 9497 __ li($dst$$Register, 0); // addi 9498 } else { 9499 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9500 } 9501 %} 9502 ins_pipe(pipe_class_default); 9503 %} 9504 9505 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9506 // no match-rule, false predicate 9507 effect(DEF dst, USE src1, USE src2); 9508 predicate(false); 9509 9510 format %{ "SLD $dst, $src1, $src2" %} 9511 size(4); 9512 ins_encode %{ 9513 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9514 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9515 %} 9516 ins_pipe(pipe_class_default); 9517 %} 9518 9519 // Register Shift Left 9520 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9521 match(Set dst (LShiftL src1 src2)); 9522 ins_cost(DEFAULT_COST*2); 9523 expand %{ 9524 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9525 iRegIdst tmpI; 9526 maskI_reg_imm(tmpI, src2, mask); 9527 lShiftL_regL_regI(dst, src1, tmpI); 9528 %} 9529 %} 9530 9531 // Register Shift Left Immediate 9532 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9533 match(Set dst (LShiftL src1 src2)); 9534 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9535 size(4); 9536 ins_encode %{ 9537 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9538 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9539 %} 9540 ins_pipe(pipe_class_default); 9541 %} 9542 9543 // If we shift more than 32 bits, we need not convert I2L. 9544 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9545 match(Set dst (LShiftL (ConvI2L src1) src2)); 9546 ins_cost(DEFAULT_COST); 9547 9548 size(4); 9549 format %{ "SLDI $dst, i2l($src1), $src2" %} 9550 ins_encode %{ 9551 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9552 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9553 %} 9554 ins_pipe(pipe_class_default); 9555 %} 9556 9557 // Shift a postivie int to the left. 9558 // Clrlsldi clears the upper 32 bits and shifts. 9559 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9560 match(Set dst (LShiftL (ConvI2L src1) src2)); 9561 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9562 9563 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9564 size(4); 9565 ins_encode %{ 9566 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9567 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9568 %} 9569 ins_pipe(pipe_class_default); 9570 %} 9571 9572 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9573 // no match-rule, false predicate 9574 effect(DEF dst, USE src1, USE src2); 9575 predicate(false); 9576 9577 format %{ "SRAW $dst, $src1, $src2" %} 9578 size(4); 9579 ins_encode %{ 9580 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9581 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9582 %} 9583 ins_pipe(pipe_class_default); 9584 %} 9585 9586 // Register Arithmetic Shift Right 9587 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9588 match(Set dst (RShiftI src1 src2)); 9589 ins_cost(DEFAULT_COST*2); 9590 expand %{ 9591 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9592 iRegIdst tmpI; 9593 maskI_reg_imm(tmpI, src2, mask); 9594 arShiftI_reg_reg(dst, src1, tmpI); 9595 %} 9596 %} 9597 9598 // Register Arithmetic Shift Right Immediate 9599 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9600 match(Set dst (RShiftI src1 src2)); 9601 9602 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9603 size(4); 9604 ins_encode %{ 9605 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9606 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9607 %} 9608 ins_pipe(pipe_class_default); 9609 %} 9610 9611 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9612 // no match-rule, false predicate 9613 effect(DEF dst, USE src1, USE src2); 9614 predicate(false); 9615 9616 format %{ "SRAD $dst, $src1, $src2" %} 9617 size(4); 9618 ins_encode %{ 9619 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9620 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9621 %} 9622 ins_pipe(pipe_class_default); 9623 %} 9624 9625 // Register Shift Right Arithmetic Long 9626 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9627 match(Set dst (RShiftL src1 src2)); 9628 ins_cost(DEFAULT_COST*2); 9629 9630 expand %{ 9631 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9632 iRegIdst tmpI; 9633 maskI_reg_imm(tmpI, src2, mask); 9634 arShiftL_regL_regI(dst, src1, tmpI); 9635 %} 9636 %} 9637 9638 // Register Shift Right Immediate 9639 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9640 match(Set dst (RShiftL src1 src2)); 9641 9642 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9643 size(4); 9644 ins_encode %{ 9645 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9646 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9647 %} 9648 ins_pipe(pipe_class_default); 9649 %} 9650 9651 // RShiftL + ConvL2I 9652 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9653 match(Set dst (ConvL2I (RShiftL src1 src2))); 9654 9655 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9656 size(4); 9657 ins_encode %{ 9658 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9659 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9660 %} 9661 ins_pipe(pipe_class_default); 9662 %} 9663 9664 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9665 // no match-rule, false predicate 9666 effect(DEF dst, USE src1, USE src2); 9667 predicate(false); 9668 9669 format %{ "SRW $dst, $src1, $src2" %} 9670 size(4); 9671 ins_encode %{ 9672 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9673 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9674 %} 9675 ins_pipe(pipe_class_default); 9676 %} 9677 9678 // Register Shift Right 9679 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9680 match(Set dst (URShiftI src1 src2)); 9681 ins_cost(DEFAULT_COST*2); 9682 9683 expand %{ 9684 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9685 iRegIdst tmpI; 9686 maskI_reg_imm(tmpI, src2, mask); 9687 urShiftI_reg_reg(dst, src1, tmpI); 9688 %} 9689 %} 9690 9691 // Register Shift Right Immediate 9692 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9693 match(Set dst (URShiftI src1 src2)); 9694 9695 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9696 size(4); 9697 ins_encode %{ 9698 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9699 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9700 %} 9701 ins_pipe(pipe_class_default); 9702 %} 9703 9704 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9705 // no match-rule, false predicate 9706 effect(DEF dst, USE src1, USE src2); 9707 predicate(false); 9708 9709 format %{ "SRD $dst, $src1, $src2" %} 9710 size(4); 9711 ins_encode %{ 9712 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9713 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9714 %} 9715 ins_pipe(pipe_class_default); 9716 %} 9717 9718 // Register Shift Right 9719 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9720 match(Set dst (URShiftL src1 src2)); 9721 ins_cost(DEFAULT_COST*2); 9722 9723 expand %{ 9724 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9725 iRegIdst tmpI; 9726 maskI_reg_imm(tmpI, src2, mask); 9727 urShiftL_regL_regI(dst, src1, tmpI); 9728 %} 9729 %} 9730 9731 // Register Shift Right Immediate 9732 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9733 match(Set dst (URShiftL src1 src2)); 9734 9735 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9736 size(4); 9737 ins_encode %{ 9738 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9739 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9740 %} 9741 ins_pipe(pipe_class_default); 9742 %} 9743 9744 // URShiftL + ConvL2I. 9745 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9746 match(Set dst (ConvL2I (URShiftL src1 src2))); 9747 9748 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9749 size(4); 9750 ins_encode %{ 9751 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9752 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9753 %} 9754 ins_pipe(pipe_class_default); 9755 %} 9756 9757 // Register Shift Right Immediate with a CastP2X 9758 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9759 match(Set dst (URShiftL (CastP2X src1) src2)); 9760 9761 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9762 size(4); 9763 ins_encode %{ 9764 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9765 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9766 %} 9767 ins_pipe(pipe_class_default); 9768 %} 9769 9770 // Bitfield Extract: URShiftI + AndI 9771 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9772 match(Set dst (AndI (URShiftI src1 src2) src3)); 9773 9774 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9775 size(4); 9776 ins_encode %{ 9777 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9778 int rshift = ($src2$$constant) & 0x1f; 9779 int length = log2_long(((jlong) $src3$$constant) + 1); 9780 if (rshift + length > 32) { 9781 // if necessary, adjust mask to omit rotated bits. 9782 length = 32 - rshift; 9783 } 9784 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9785 %} 9786 ins_pipe(pipe_class_default); 9787 %} 9788 9789 // Bitfield Extract: URShiftL + AndL 9790 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9791 match(Set dst (AndL (URShiftL src1 src2) src3)); 9792 9793 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9794 size(4); 9795 ins_encode %{ 9796 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9797 int rshift = ($src2$$constant) & 0x3f; 9798 int length = log2_long(((jlong) $src3$$constant) + 1); 9799 if (rshift + length > 64) { 9800 // if necessary, adjust mask to omit rotated bits. 9801 length = 64 - rshift; 9802 } 9803 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9804 %} 9805 ins_pipe(pipe_class_default); 9806 %} 9807 9808 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9809 match(Set dst (ConvL2I (ConvI2L src))); 9810 9811 format %{ "EXTSW $dst, $src \t// int->int" %} 9812 size(4); 9813 ins_encode %{ 9814 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9815 __ extsw($dst$$Register, $src$$Register); 9816 %} 9817 ins_pipe(pipe_class_default); 9818 %} 9819 9820 //----------Rotate Instructions------------------------------------------------ 9821 9822 // Rotate Left by 8-bit immediate 9823 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9824 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9825 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9826 9827 format %{ "ROTLWI $dst, $src, $lshift" %} 9828 size(4); 9829 ins_encode %{ 9830 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9831 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9832 %} 9833 ins_pipe(pipe_class_default); 9834 %} 9835 9836 // Rotate Right by 8-bit immediate 9837 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9838 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9839 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9840 9841 format %{ "ROTRWI $dst, $rshift" %} 9842 size(4); 9843 ins_encode %{ 9844 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9845 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9846 %} 9847 ins_pipe(pipe_class_default); 9848 %} 9849 9850 //----------Floating Point Arithmetic Instructions----------------------------- 9851 9852 // Add float single precision 9853 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9854 match(Set dst (AddF src1 src2)); 9855 9856 format %{ "FADDS $dst, $src1, $src2" %} 9857 size(4); 9858 ins_encode %{ 9859 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9860 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9861 %} 9862 ins_pipe(pipe_class_default); 9863 %} 9864 9865 // Add float double precision 9866 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9867 match(Set dst (AddD src1 src2)); 9868 9869 format %{ "FADD $dst, $src1, $src2" %} 9870 size(4); 9871 ins_encode %{ 9872 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9873 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9874 %} 9875 ins_pipe(pipe_class_default); 9876 %} 9877 9878 // Sub float single precision 9879 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9880 match(Set dst (SubF src1 src2)); 9881 9882 format %{ "FSUBS $dst, $src1, $src2" %} 9883 size(4); 9884 ins_encode %{ 9885 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9886 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9887 %} 9888 ins_pipe(pipe_class_default); 9889 %} 9890 9891 // Sub float double precision 9892 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9893 match(Set dst (SubD src1 src2)); 9894 format %{ "FSUB $dst, $src1, $src2" %} 9895 size(4); 9896 ins_encode %{ 9897 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9898 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9899 %} 9900 ins_pipe(pipe_class_default); 9901 %} 9902 9903 // Mul float single precision 9904 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9905 match(Set dst (MulF src1 src2)); 9906 format %{ "FMULS $dst, $src1, $src2" %} 9907 size(4); 9908 ins_encode %{ 9909 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9910 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9911 %} 9912 ins_pipe(pipe_class_default); 9913 %} 9914 9915 // Mul float double precision 9916 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9917 match(Set dst (MulD src1 src2)); 9918 format %{ "FMUL $dst, $src1, $src2" %} 9919 size(4); 9920 ins_encode %{ 9921 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9922 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9923 %} 9924 ins_pipe(pipe_class_default); 9925 %} 9926 9927 // Div float single precision 9928 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9929 match(Set dst (DivF src1 src2)); 9930 format %{ "FDIVS $dst, $src1, $src2" %} 9931 size(4); 9932 ins_encode %{ 9933 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9934 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9935 %} 9936 ins_pipe(pipe_class_default); 9937 %} 9938 9939 // Div float double precision 9940 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9941 match(Set dst (DivD src1 src2)); 9942 format %{ "FDIV $dst, $src1, $src2" %} 9943 size(4); 9944 ins_encode %{ 9945 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9946 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9947 %} 9948 ins_pipe(pipe_class_default); 9949 %} 9950 9951 // Absolute float single precision 9952 instruct absF_reg(regF dst, regF src) %{ 9953 match(Set dst (AbsF src)); 9954 format %{ "FABS $dst, $src \t// float" %} 9955 size(4); 9956 ins_encode %{ 9957 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9958 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9959 %} 9960 ins_pipe(pipe_class_default); 9961 %} 9962 9963 // Absolute float double precision 9964 instruct absD_reg(regD dst, regD src) %{ 9965 match(Set dst (AbsD src)); 9966 format %{ "FABS $dst, $src \t// double" %} 9967 size(4); 9968 ins_encode %{ 9969 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9970 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9971 %} 9972 ins_pipe(pipe_class_default); 9973 %} 9974 9975 instruct negF_reg(regF dst, regF src) %{ 9976 match(Set dst (NegF src)); 9977 format %{ "FNEG $dst, $src \t// float" %} 9978 size(4); 9979 ins_encode %{ 9980 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9981 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9982 %} 9983 ins_pipe(pipe_class_default); 9984 %} 9985 9986 instruct negD_reg(regD dst, regD src) %{ 9987 match(Set dst (NegD src)); 9988 format %{ "FNEG $dst, $src \t// double" %} 9989 size(4); 9990 ins_encode %{ 9991 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9992 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9993 %} 9994 ins_pipe(pipe_class_default); 9995 %} 9996 9997 // AbsF + NegF. 9998 instruct negF_absF_reg(regF dst, regF src) %{ 9999 match(Set dst (NegF (AbsF src))); 10000 format %{ "FNABS $dst, $src \t// float" %} 10001 size(4); 10002 ins_encode %{ 10003 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10004 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10005 %} 10006 ins_pipe(pipe_class_default); 10007 %} 10008 10009 // AbsD + NegD. 10010 instruct negD_absD_reg(regD dst, regD src) %{ 10011 match(Set dst (NegD (AbsD src))); 10012 format %{ "FNABS $dst, $src \t// double" %} 10013 size(4); 10014 ins_encode %{ 10015 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10016 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10017 %} 10018 ins_pipe(pipe_class_default); 10019 %} 10020 10021 // VM_Version::has_fsqrt() decides if this node will be used. 10022 // Sqrt float double precision 10023 instruct sqrtD_reg(regD dst, regD src) %{ 10024 match(Set dst (SqrtD src)); 10025 format %{ "FSQRT $dst, $src" %} 10026 size(4); 10027 ins_encode %{ 10028 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 10029 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 10030 %} 10031 ins_pipe(pipe_class_default); 10032 %} 10033 10034 // Single-precision sqrt. 10035 instruct sqrtF_reg(regF dst, regF src) %{ 10036 match(Set dst (SqrtF src)); 10037 predicate(VM_Version::has_fsqrts()); 10038 ins_cost(DEFAULT_COST); 10039 10040 format %{ "FSQRTS $dst, $src" %} 10041 size(4); 10042 ins_encode %{ 10043 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 10044 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 10045 %} 10046 ins_pipe(pipe_class_default); 10047 %} 10048 10049 instruct roundDouble_nop(regD dst) %{ 10050 match(Set dst (RoundDouble dst)); 10051 ins_cost(0); 10052 10053 format %{ " -- \t// RoundDouble not needed - empty" %} 10054 size(0); 10055 // PPC results are already "rounded" (i.e., normal-format IEEE). 10056 ins_encode( /*empty*/ ); 10057 ins_pipe(pipe_class_default); 10058 %} 10059 10060 instruct roundFloat_nop(regF dst) %{ 10061 match(Set dst (RoundFloat dst)); 10062 ins_cost(0); 10063 10064 format %{ " -- \t// RoundFloat not needed - empty" %} 10065 size(0); 10066 // PPC results are already "rounded" (i.e., normal-format IEEE). 10067 ins_encode( /*empty*/ ); 10068 ins_pipe(pipe_class_default); 10069 %} 10070 10071 10072 // Multiply-Accumulate 10073 // src1 * src2 + src3 10074 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10075 match(Set dst (FmaF src3 (Binary src1 src2))); 10076 10077 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10078 size(4); 10079 ins_encode %{ 10080 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10081 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10082 %} 10083 ins_pipe(pipe_class_default); 10084 %} 10085 10086 // src1 * src2 + src3 10087 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10088 match(Set dst (FmaD src3 (Binary src1 src2))); 10089 10090 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10091 size(4); 10092 ins_encode %{ 10093 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10094 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10095 %} 10096 ins_pipe(pipe_class_default); 10097 %} 10098 10099 // -src1 * src2 + src3 = -(src1*src2-src3) 10100 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10101 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10102 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10103 10104 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10105 size(4); 10106 ins_encode %{ 10107 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10108 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10109 %} 10110 ins_pipe(pipe_class_default); 10111 %} 10112 10113 // -src1 * src2 + src3 = -(src1*src2-src3) 10114 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10115 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10116 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10117 10118 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10119 size(4); 10120 ins_encode %{ 10121 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10122 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10123 %} 10124 ins_pipe(pipe_class_default); 10125 %} 10126 10127 // -src1 * src2 - src3 = -(src1*src2+src3) 10128 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10129 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10130 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10131 10132 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10133 size(4); 10134 ins_encode %{ 10135 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10136 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10137 %} 10138 ins_pipe(pipe_class_default); 10139 %} 10140 10141 // -src1 * src2 - src3 = -(src1*src2+src3) 10142 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10143 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10144 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10145 10146 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10147 size(4); 10148 ins_encode %{ 10149 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10150 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10151 %} 10152 ins_pipe(pipe_class_default); 10153 %} 10154 10155 // src1 * src2 - src3 10156 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10157 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10158 10159 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10160 size(4); 10161 ins_encode %{ 10162 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10163 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10164 %} 10165 ins_pipe(pipe_class_default); 10166 %} 10167 10168 // src1 * src2 - src3 10169 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10170 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10171 10172 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10173 size(4); 10174 ins_encode %{ 10175 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10176 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10177 %} 10178 ins_pipe(pipe_class_default); 10179 %} 10180 10181 10182 //----------Logical Instructions----------------------------------------------- 10183 10184 // And Instructions 10185 10186 // Register And 10187 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10188 match(Set dst (AndI src1 src2)); 10189 format %{ "AND $dst, $src1, $src2" %} 10190 size(4); 10191 ins_encode %{ 10192 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10193 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10194 %} 10195 ins_pipe(pipe_class_default); 10196 %} 10197 10198 // Left shifted Immediate And 10199 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10200 match(Set dst (AndI src1 src2)); 10201 effect(KILL cr0); 10202 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10203 size(4); 10204 ins_encode %{ 10205 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10206 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10207 %} 10208 ins_pipe(pipe_class_default); 10209 %} 10210 10211 // Immediate And 10212 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10213 match(Set dst (AndI src1 src2)); 10214 effect(KILL cr0); 10215 10216 format %{ "ANDI $dst, $src1, $src2" %} 10217 size(4); 10218 ins_encode %{ 10219 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10220 // FIXME: avoid andi_ ? 10221 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10222 %} 10223 ins_pipe(pipe_class_default); 10224 %} 10225 10226 // Immediate And where the immediate is a negative power of 2. 10227 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10228 match(Set dst (AndI src1 src2)); 10229 format %{ "ANDWI $dst, $src1, $src2" %} 10230 size(4); 10231 ins_encode %{ 10232 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10233 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10234 %} 10235 ins_pipe(pipe_class_default); 10236 %} 10237 10238 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10239 match(Set dst (AndI src1 src2)); 10240 format %{ "ANDWI $dst, $src1, $src2" %} 10241 size(4); 10242 ins_encode %{ 10243 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10244 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10245 %} 10246 ins_pipe(pipe_class_default); 10247 %} 10248 10249 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10250 match(Set dst (AndI src1 src2)); 10251 predicate(UseRotateAndMaskInstructionsPPC64); 10252 format %{ "ANDWI $dst, $src1, $src2" %} 10253 size(4); 10254 ins_encode %{ 10255 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10256 __ rlwinm($dst$$Register, $src1$$Register, 0, 10257 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10258 %} 10259 ins_pipe(pipe_class_default); 10260 %} 10261 10262 // Register And Long 10263 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10264 match(Set dst (AndL src1 src2)); 10265 ins_cost(DEFAULT_COST); 10266 10267 format %{ "AND $dst, $src1, $src2 \t// long" %} 10268 size(4); 10269 ins_encode %{ 10270 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10271 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10272 %} 10273 ins_pipe(pipe_class_default); 10274 %} 10275 10276 // Immediate And long 10277 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10278 match(Set dst (AndL src1 src2)); 10279 effect(KILL cr0); 10280 10281 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10282 size(4); 10283 ins_encode %{ 10284 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10285 // FIXME: avoid andi_ ? 10286 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10287 %} 10288 ins_pipe(pipe_class_default); 10289 %} 10290 10291 // Immediate And Long where the immediate is a negative power of 2. 10292 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10293 match(Set dst (AndL src1 src2)); 10294 format %{ "ANDDI $dst, $src1, $src2" %} 10295 size(4); 10296 ins_encode %{ 10297 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10298 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10299 %} 10300 ins_pipe(pipe_class_default); 10301 %} 10302 10303 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10304 match(Set dst (AndL src1 src2)); 10305 format %{ "ANDDI $dst, $src1, $src2" %} 10306 size(4); 10307 ins_encode %{ 10308 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10309 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10310 %} 10311 ins_pipe(pipe_class_default); 10312 %} 10313 10314 // AndL + ConvL2I. 10315 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10316 match(Set dst (ConvL2I (AndL src1 src2))); 10317 ins_cost(DEFAULT_COST); 10318 10319 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10320 size(4); 10321 ins_encode %{ 10322 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10323 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10324 %} 10325 ins_pipe(pipe_class_default); 10326 %} 10327 10328 // Or Instructions 10329 10330 // Register Or 10331 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10332 match(Set dst (OrI src1 src2)); 10333 format %{ "OR $dst, $src1, $src2" %} 10334 size(4); 10335 ins_encode %{ 10336 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10337 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10338 %} 10339 ins_pipe(pipe_class_default); 10340 %} 10341 10342 // Expand does not work with above instruct. (??) 10343 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10344 // no match-rule 10345 effect(DEF dst, USE src1, USE src2); 10346 format %{ "OR $dst, $src1, $src2" %} 10347 size(4); 10348 ins_encode %{ 10349 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10350 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10351 %} 10352 ins_pipe(pipe_class_default); 10353 %} 10354 10355 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10356 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10357 ins_cost(DEFAULT_COST*3); 10358 10359 expand %{ 10360 // FIXME: we should do this in the ideal world. 10361 iRegIdst tmp1; 10362 iRegIdst tmp2; 10363 orI_reg_reg(tmp1, src1, src2); 10364 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10365 orI_reg_reg(dst, tmp1, tmp2); 10366 %} 10367 %} 10368 10369 // Immediate Or 10370 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10371 match(Set dst (OrI src1 src2)); 10372 format %{ "ORI $dst, $src1, $src2" %} 10373 size(4); 10374 ins_encode %{ 10375 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10376 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10377 %} 10378 ins_pipe(pipe_class_default); 10379 %} 10380 10381 // Register Or Long 10382 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10383 match(Set dst (OrL src1 src2)); 10384 ins_cost(DEFAULT_COST); 10385 10386 size(4); 10387 format %{ "OR $dst, $src1, $src2 \t// long" %} 10388 ins_encode %{ 10389 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10390 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10391 %} 10392 ins_pipe(pipe_class_default); 10393 %} 10394 10395 // OrL + ConvL2I. 10396 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10397 match(Set dst (ConvL2I (OrL src1 src2))); 10398 ins_cost(DEFAULT_COST); 10399 10400 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10401 size(4); 10402 ins_encode %{ 10403 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10404 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10405 %} 10406 ins_pipe(pipe_class_default); 10407 %} 10408 10409 // Immediate Or long 10410 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10411 match(Set dst (OrL src1 con)); 10412 ins_cost(DEFAULT_COST); 10413 10414 format %{ "ORI $dst, $src1, $con \t// long" %} 10415 size(4); 10416 ins_encode %{ 10417 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10418 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10419 %} 10420 ins_pipe(pipe_class_default); 10421 %} 10422 10423 // Xor Instructions 10424 10425 // Register Xor 10426 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10427 match(Set dst (XorI src1 src2)); 10428 format %{ "XOR $dst, $src1, $src2" %} 10429 size(4); 10430 ins_encode %{ 10431 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10432 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10433 %} 10434 ins_pipe(pipe_class_default); 10435 %} 10436 10437 // Expand does not work with above instruct. (??) 10438 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10439 // no match-rule 10440 effect(DEF dst, USE src1, USE src2); 10441 format %{ "XOR $dst, $src1, $src2" %} 10442 size(4); 10443 ins_encode %{ 10444 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10445 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10446 %} 10447 ins_pipe(pipe_class_default); 10448 %} 10449 10450 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10451 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10452 ins_cost(DEFAULT_COST*3); 10453 10454 expand %{ 10455 // FIXME: we should do this in the ideal world. 10456 iRegIdst tmp1; 10457 iRegIdst tmp2; 10458 xorI_reg_reg(tmp1, src1, src2); 10459 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10460 xorI_reg_reg(dst, tmp1, tmp2); 10461 %} 10462 %} 10463 10464 // Immediate Xor 10465 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10466 match(Set dst (XorI src1 src2)); 10467 format %{ "XORI $dst, $src1, $src2" %} 10468 size(4); 10469 ins_encode %{ 10470 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10471 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10472 %} 10473 ins_pipe(pipe_class_default); 10474 %} 10475 10476 // Register Xor Long 10477 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10478 match(Set dst (XorL src1 src2)); 10479 ins_cost(DEFAULT_COST); 10480 10481 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10482 size(4); 10483 ins_encode %{ 10484 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10485 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10486 %} 10487 ins_pipe(pipe_class_default); 10488 %} 10489 10490 // XorL + ConvL2I. 10491 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10492 match(Set dst (ConvL2I (XorL src1 src2))); 10493 ins_cost(DEFAULT_COST); 10494 10495 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10496 size(4); 10497 ins_encode %{ 10498 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10499 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10500 %} 10501 ins_pipe(pipe_class_default); 10502 %} 10503 10504 // Immediate Xor Long 10505 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10506 match(Set dst (XorL src1 src2)); 10507 ins_cost(DEFAULT_COST); 10508 10509 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10510 size(4); 10511 ins_encode %{ 10512 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10513 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10514 %} 10515 ins_pipe(pipe_class_default); 10516 %} 10517 10518 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10519 match(Set dst (XorI src1 src2)); 10520 ins_cost(DEFAULT_COST); 10521 10522 format %{ "NOT $dst, $src1 ($src2)" %} 10523 size(4); 10524 ins_encode %{ 10525 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10526 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10527 %} 10528 ins_pipe(pipe_class_default); 10529 %} 10530 10531 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10532 match(Set dst (XorL src1 src2)); 10533 ins_cost(DEFAULT_COST); 10534 10535 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10536 size(4); 10537 ins_encode %{ 10538 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10539 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10540 %} 10541 ins_pipe(pipe_class_default); 10542 %} 10543 10544 // And-complement 10545 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10546 match(Set dst (AndI (XorI src1 src2) src3)); 10547 ins_cost(DEFAULT_COST); 10548 10549 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10550 size(4); 10551 ins_encode( enc_andc(dst, src3, src1) ); 10552 ins_pipe(pipe_class_default); 10553 %} 10554 10555 // And-complement 10556 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10557 // no match-rule, false predicate 10558 effect(DEF dst, USE src1, USE src2); 10559 predicate(false); 10560 10561 format %{ "ANDC $dst, $src1, $src2" %} 10562 size(4); 10563 ins_encode %{ 10564 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10565 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10566 %} 10567 ins_pipe(pipe_class_default); 10568 %} 10569 10570 //----------Moves between int/long and float/double---------------------------- 10571 // 10572 // The following rules move values from int/long registers/stack-locations 10573 // to float/double registers/stack-locations and vice versa, without doing any 10574 // conversions. These rules are used to implement the bit-conversion methods 10575 // of java.lang.Float etc., e.g. 10576 // int floatToIntBits(float value) 10577 // float intBitsToFloat(int bits) 10578 // 10579 // Notes on the implementation on ppc64: 10580 // For Power7 and earlier, the rules are limited to those which move between a 10581 // register and a stack-location, because we always have to go through memory 10582 // when moving between a float register and an integer register. 10583 // This restriction is removed in Power8 with the introduction of the mtfprd 10584 // and mffprd instructions. 10585 10586 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10587 match(Set dst (MoveL2D src)); 10588 predicate(VM_Version::has_mtfprd()); 10589 10590 format %{ "MTFPRD $dst, $src" %} 10591 size(4); 10592 ins_encode %{ 10593 __ mtfprd($dst$$FloatRegister, $src$$Register); 10594 %} 10595 ins_pipe(pipe_class_default); 10596 %} 10597 10598 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10599 // no match-rule, false predicate 10600 effect(DEF dst, USE src); 10601 predicate(false); 10602 10603 format %{ "MTFPRWA $dst, $src" %} 10604 size(4); 10605 ins_encode %{ 10606 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10607 %} 10608 ins_pipe(pipe_class_default); 10609 %} 10610 10611 //---------- Chain stack slots between similar types -------- 10612 10613 // These are needed so that the rules below can match. 10614 10615 // Load integer from stack slot 10616 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10617 match(Set dst src); 10618 ins_cost(MEMORY_REF_COST); 10619 10620 format %{ "LWZ $dst, $src" %} 10621 size(4); 10622 ins_encode( enc_lwz(dst, src) ); 10623 ins_pipe(pipe_class_memory); 10624 %} 10625 10626 // Store integer to stack slot 10627 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10628 match(Set dst src); 10629 ins_cost(MEMORY_REF_COST); 10630 10631 format %{ "STW $src, $dst \t// stk" %} 10632 size(4); 10633 ins_encode( enc_stw(src, dst) ); // rs=rt 10634 ins_pipe(pipe_class_memory); 10635 %} 10636 10637 // Load long from stack slot 10638 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10639 match(Set dst src); 10640 ins_cost(MEMORY_REF_COST); 10641 10642 format %{ "LD $dst, $src \t// long" %} 10643 size(4); 10644 ins_encode( enc_ld(dst, src) ); 10645 ins_pipe(pipe_class_memory); 10646 %} 10647 10648 // Store long to stack slot 10649 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10650 match(Set dst src); 10651 ins_cost(MEMORY_REF_COST); 10652 10653 format %{ "STD $src, $dst \t// long" %} 10654 size(4); 10655 ins_encode( enc_std(src, dst) ); // rs=rt 10656 ins_pipe(pipe_class_memory); 10657 %} 10658 10659 //----------Moves between int and float 10660 10661 // Move float value from float stack-location to integer register. 10662 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10663 match(Set dst (MoveF2I src)); 10664 ins_cost(MEMORY_REF_COST); 10665 10666 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10667 size(4); 10668 ins_encode( enc_lwz(dst, src) ); 10669 ins_pipe(pipe_class_memory); 10670 %} 10671 10672 // Move float value from float register to integer stack-location. 10673 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10674 match(Set dst (MoveF2I src)); 10675 ins_cost(MEMORY_REF_COST); 10676 10677 format %{ "STFS $src, $dst \t// MoveF2I" %} 10678 size(4); 10679 ins_encode( enc_stfs(src, dst) ); 10680 ins_pipe(pipe_class_memory); 10681 %} 10682 10683 // Move integer value from integer stack-location to float register. 10684 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10685 match(Set dst (MoveI2F src)); 10686 ins_cost(MEMORY_REF_COST); 10687 10688 format %{ "LFS $dst, $src \t// MoveI2F" %} 10689 size(4); 10690 ins_encode %{ 10691 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10692 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10693 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10694 %} 10695 ins_pipe(pipe_class_memory); 10696 %} 10697 10698 // Move integer value from integer register to float stack-location. 10699 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10700 match(Set dst (MoveI2F src)); 10701 ins_cost(MEMORY_REF_COST); 10702 10703 format %{ "STW $src, $dst \t// MoveI2F" %} 10704 size(4); 10705 ins_encode( enc_stw(src, dst) ); 10706 ins_pipe(pipe_class_memory); 10707 %} 10708 10709 //----------Moves between long and float 10710 10711 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10712 // no match-rule, false predicate 10713 effect(DEF dst, USE src); 10714 predicate(false); 10715 10716 format %{ "storeD $src, $dst \t// STACK" %} 10717 size(4); 10718 ins_encode( enc_stfd(src, dst) ); 10719 ins_pipe(pipe_class_default); 10720 %} 10721 10722 //----------Moves between long and double 10723 10724 // Move double value from double stack-location to long register. 10725 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10726 match(Set dst (MoveD2L src)); 10727 ins_cost(MEMORY_REF_COST); 10728 size(4); 10729 format %{ "LD $dst, $src \t// MoveD2L" %} 10730 ins_encode( enc_ld(dst, src) ); 10731 ins_pipe(pipe_class_memory); 10732 %} 10733 10734 // Move double value from double register to long stack-location. 10735 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10736 match(Set dst (MoveD2L src)); 10737 effect(DEF dst, USE src); 10738 ins_cost(MEMORY_REF_COST); 10739 10740 format %{ "STFD $src, $dst \t// MoveD2L" %} 10741 size(4); 10742 ins_encode( enc_stfd(src, dst) ); 10743 ins_pipe(pipe_class_memory); 10744 %} 10745 10746 // Move long value from long stack-location to double register. 10747 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10748 match(Set dst (MoveL2D src)); 10749 ins_cost(MEMORY_REF_COST); 10750 10751 format %{ "LFD $dst, $src \t// MoveL2D" %} 10752 size(4); 10753 ins_encode( enc_lfd(dst, src) ); 10754 ins_pipe(pipe_class_memory); 10755 %} 10756 10757 // Move long value from long register to double stack-location. 10758 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10759 match(Set dst (MoveL2D src)); 10760 ins_cost(MEMORY_REF_COST); 10761 10762 format %{ "STD $src, $dst \t// MoveL2D" %} 10763 size(4); 10764 ins_encode( enc_std(src, dst) ); 10765 ins_pipe(pipe_class_memory); 10766 %} 10767 10768 //----------Register Move Instructions----------------------------------------- 10769 10770 // Replicate for Superword 10771 10772 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10773 predicate(false); 10774 effect(DEF dst, USE src); 10775 10776 format %{ "MR $dst, $src \t// replicate " %} 10777 // variable size, 0 or 4. 10778 ins_encode %{ 10779 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10780 __ mr_if_needed($dst$$Register, $src$$Register); 10781 %} 10782 ins_pipe(pipe_class_default); 10783 %} 10784 10785 //----------Cast instructions (Java-level type cast)--------------------------- 10786 10787 // Cast Long to Pointer for unsafe natives. 10788 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10789 match(Set dst (CastX2P src)); 10790 10791 format %{ "MR $dst, $src \t// Long->Ptr" %} 10792 // variable size, 0 or 4. 10793 ins_encode %{ 10794 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10795 __ mr_if_needed($dst$$Register, $src$$Register); 10796 %} 10797 ins_pipe(pipe_class_default); 10798 %} 10799 10800 // Cast Pointer to Long for unsafe natives. 10801 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10802 match(Set dst (CastP2X src)); 10803 10804 format %{ "MR $dst, $src \t// Ptr->Long" %} 10805 // variable size, 0 or 4. 10806 ins_encode %{ 10807 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10808 __ mr_if_needed($dst$$Register, $src$$Register); 10809 %} 10810 ins_pipe(pipe_class_default); 10811 %} 10812 10813 instruct castPP(iRegPdst dst) %{ 10814 match(Set dst (CastPP dst)); 10815 format %{ " -- \t// castPP of $dst" %} 10816 size(0); 10817 ins_encode( /*empty*/ ); 10818 ins_pipe(pipe_class_default); 10819 %} 10820 10821 instruct castII(iRegIdst dst) %{ 10822 match(Set dst (CastII dst)); 10823 format %{ " -- \t// castII of $dst" %} 10824 size(0); 10825 ins_encode( /*empty*/ ); 10826 ins_pipe(pipe_class_default); 10827 %} 10828 10829 instruct checkCastPP(iRegPdst dst) %{ 10830 match(Set dst (CheckCastPP dst)); 10831 format %{ " -- \t// checkcastPP of $dst" %} 10832 size(0); 10833 ins_encode( /*empty*/ ); 10834 ins_pipe(pipe_class_default); 10835 %} 10836 10837 //----------Convert instructions----------------------------------------------- 10838 10839 // Convert to boolean. 10840 10841 // int_to_bool(src) : { 1 if src != 0 10842 // { 0 else 10843 // 10844 // strategy: 10845 // 1) Count leading zeros of 32 bit-value src, 10846 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10847 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10848 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10849 10850 // convI2Bool 10851 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10852 match(Set dst (Conv2B src)); 10853 predicate(UseCountLeadingZerosInstructionsPPC64); 10854 ins_cost(DEFAULT_COST); 10855 10856 expand %{ 10857 immI shiftAmount %{ 0x5 %} 10858 uimmI16 mask %{ 0x1 %} 10859 iRegIdst tmp1; 10860 iRegIdst tmp2; 10861 countLeadingZerosI(tmp1, src); 10862 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10863 xorI_reg_uimm16(dst, tmp2, mask); 10864 %} 10865 %} 10866 10867 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10868 match(Set dst (Conv2B src)); 10869 effect(TEMP crx); 10870 predicate(!UseCountLeadingZerosInstructionsPPC64); 10871 ins_cost(DEFAULT_COST); 10872 10873 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10874 "LI $dst, #0\n\t" 10875 "BEQ $crx, done\n\t" 10876 "LI $dst, #1\n" 10877 "done:" %} 10878 size(16); 10879 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10880 ins_pipe(pipe_class_compare); 10881 %} 10882 10883 // ConvI2B + XorI 10884 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10885 match(Set dst (XorI (Conv2B src) mask)); 10886 predicate(UseCountLeadingZerosInstructionsPPC64); 10887 ins_cost(DEFAULT_COST); 10888 10889 expand %{ 10890 immI shiftAmount %{ 0x5 %} 10891 iRegIdst tmp1; 10892 countLeadingZerosI(tmp1, src); 10893 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10894 %} 10895 %} 10896 10897 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10898 match(Set dst (XorI (Conv2B src) mask)); 10899 effect(TEMP crx); 10900 predicate(!UseCountLeadingZerosInstructionsPPC64); 10901 ins_cost(DEFAULT_COST); 10902 10903 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10904 "LI $dst, #1\n\t" 10905 "BEQ $crx, done\n\t" 10906 "LI $dst, #0\n" 10907 "done:" %} 10908 size(16); 10909 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10910 ins_pipe(pipe_class_compare); 10911 %} 10912 10913 // AndI 0b0..010..0 + ConvI2B 10914 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10915 match(Set dst (Conv2B (AndI src mask))); 10916 predicate(UseRotateAndMaskInstructionsPPC64); 10917 ins_cost(DEFAULT_COST); 10918 10919 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10920 size(4); 10921 ins_encode %{ 10922 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10923 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10924 %} 10925 ins_pipe(pipe_class_default); 10926 %} 10927 10928 // Convert pointer to boolean. 10929 // 10930 // ptr_to_bool(src) : { 1 if src != 0 10931 // { 0 else 10932 // 10933 // strategy: 10934 // 1) Count leading zeros of 64 bit-value src, 10935 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10936 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10937 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10938 10939 // ConvP2B 10940 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10941 match(Set dst (Conv2B src)); 10942 predicate(UseCountLeadingZerosInstructionsPPC64); 10943 ins_cost(DEFAULT_COST); 10944 10945 expand %{ 10946 immI shiftAmount %{ 0x6 %} 10947 uimmI16 mask %{ 0x1 %} 10948 iRegIdst tmp1; 10949 iRegIdst tmp2; 10950 countLeadingZerosP(tmp1, src); 10951 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10952 xorI_reg_uimm16(dst, tmp2, mask); 10953 %} 10954 %} 10955 10956 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10957 match(Set dst (Conv2B src)); 10958 effect(TEMP crx); 10959 predicate(!UseCountLeadingZerosInstructionsPPC64); 10960 ins_cost(DEFAULT_COST); 10961 10962 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10963 "LI $dst, #0\n\t" 10964 "BEQ $crx, done\n\t" 10965 "LI $dst, #1\n" 10966 "done:" %} 10967 size(16); 10968 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10969 ins_pipe(pipe_class_compare); 10970 %} 10971 10972 // ConvP2B + XorI 10973 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10974 match(Set dst (XorI (Conv2B src) mask)); 10975 predicate(UseCountLeadingZerosInstructionsPPC64); 10976 ins_cost(DEFAULT_COST); 10977 10978 expand %{ 10979 immI shiftAmount %{ 0x6 %} 10980 iRegIdst tmp1; 10981 countLeadingZerosP(tmp1, src); 10982 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10983 %} 10984 %} 10985 10986 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10987 match(Set dst (XorI (Conv2B src) mask)); 10988 effect(TEMP crx); 10989 predicate(!UseCountLeadingZerosInstructionsPPC64); 10990 ins_cost(DEFAULT_COST); 10991 10992 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10993 "LI $dst, #1\n\t" 10994 "BEQ $crx, done\n\t" 10995 "LI $dst, #0\n" 10996 "done:" %} 10997 size(16); 10998 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10999 ins_pipe(pipe_class_compare); 11000 %} 11001 11002 // if src1 < src2, return -1 else return 0 11003 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 11004 match(Set dst (CmpLTMask src1 src2)); 11005 ins_cost(DEFAULT_COST*4); 11006 11007 expand %{ 11008 iRegLdst src1s; 11009 iRegLdst src2s; 11010 iRegLdst diff; 11011 convI2L_reg(src1s, src1); // Ensure proper sign extension. 11012 convI2L_reg(src2s, src2); // Ensure proper sign extension. 11013 subL_reg_reg(diff, src1s, src2s); 11014 // Need to consider >=33 bit result, therefore we need signmaskL. 11015 signmask64I_regL(dst, diff); 11016 %} 11017 %} 11018 11019 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 11020 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 11021 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 11022 size(4); 11023 ins_encode %{ 11024 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 11025 __ srawi($dst$$Register, $src1$$Register, 0x1f); 11026 %} 11027 ins_pipe(pipe_class_default); 11028 %} 11029 11030 //----------Arithmetic Conversion Instructions--------------------------------- 11031 11032 // Convert to Byte -- nop 11033 // Convert to Short -- nop 11034 11035 // Convert to Int 11036 11037 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 11038 match(Set dst (RShiftI (LShiftI src amount) amount)); 11039 format %{ "EXTSB $dst, $src \t// byte->int" %} 11040 size(4); 11041 ins_encode %{ 11042 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 11043 __ extsb($dst$$Register, $src$$Register); 11044 %} 11045 ins_pipe(pipe_class_default); 11046 %} 11047 11048 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 11049 effect(DEF dst, USE src); 11050 11051 size(4); 11052 ins_encode %{ 11053 __ extsh($dst$$Register, $src$$Register); 11054 %} 11055 ins_pipe(pipe_class_default); 11056 %} 11057 11058 // LShiftI 16 + RShiftI 16 converts short to int. 11059 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 11060 match(Set dst (RShiftI (LShiftI src amount) amount)); 11061 format %{ "EXTSH $dst, $src \t// short->int" %} 11062 size(4); 11063 ins_encode %{ 11064 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 11065 __ extsh($dst$$Register, $src$$Register); 11066 %} 11067 ins_pipe(pipe_class_default); 11068 %} 11069 11070 // ConvL2I + ConvI2L: Sign extend int in long register. 11071 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11072 match(Set dst (ConvI2L (ConvL2I src))); 11073 11074 format %{ "EXTSW $dst, $src \t// long->long" %} 11075 size(4); 11076 ins_encode %{ 11077 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11078 __ extsw($dst$$Register, $src$$Register); 11079 %} 11080 ins_pipe(pipe_class_default); 11081 %} 11082 11083 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11084 match(Set dst (ConvL2I src)); 11085 format %{ "MR $dst, $src \t// long->int" %} 11086 // variable size, 0 or 4 11087 ins_encode %{ 11088 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11089 __ mr_if_needed($dst$$Register, $src$$Register); 11090 %} 11091 ins_pipe(pipe_class_default); 11092 %} 11093 11094 instruct convD2IRaw_regD(regD dst, regD src) %{ 11095 // no match-rule, false predicate 11096 effect(DEF dst, USE src); 11097 predicate(false); 11098 11099 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11100 size(4); 11101 ins_encode %{ 11102 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11103 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11104 %} 11105 ins_pipe(pipe_class_default); 11106 %} 11107 11108 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 11109 // no match-rule, false predicate 11110 effect(DEF dst, USE crx, USE src); 11111 predicate(false); 11112 11113 ins_variable_size_depending_on_alignment(true); 11114 11115 format %{ "cmovI $crx, $dst, $src" %} 11116 // Worst case is branch + move + stop, no stop without scheduler. 11117 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 11118 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11119 ins_pipe(pipe_class_default); 11120 %} 11121 11122 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11123 // no match-rule, false predicate 11124 effect(DEF dst, USE crx, USE src); 11125 predicate(false); 11126 11127 ins_variable_size_depending_on_alignment(true); 11128 11129 format %{ "cmovI $crx, $dst, $src" %} 11130 // Worst case is branch + move + stop, no stop without scheduler. 11131 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 11132 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11133 ins_pipe(pipe_class_default); 11134 %} 11135 11136 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11137 // no match-rule, false predicate 11138 effect(DEF dst, USE crx, USE mem); 11139 predicate(false); 11140 11141 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11142 postalloc_expand %{ 11143 // 11144 // replaces 11145 // 11146 // region dst crx mem 11147 // \ | | / 11148 // dst=cmovI_bso_stackSlotL_conLvalue0 11149 // 11150 // with 11151 // 11152 // region dst 11153 // \ / 11154 // dst=loadConI16(0) 11155 // | 11156 // ^ region dst crx mem 11157 // | \ | | / 11158 // dst=cmovI_bso_stackSlotL 11159 // 11160 11161 // Create new nodes. 11162 MachNode *m1 = new loadConI16Node(); 11163 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11164 11165 // inputs for new nodes 11166 m1->add_req(n_region); 11167 m2->add_req(n_region, n_crx, n_mem); 11168 11169 // precedences for new nodes 11170 m2->add_prec(m1); 11171 11172 // operands for new nodes 11173 m1->_opnds[0] = op_dst; 11174 m1->_opnds[1] = new immI16Oper(0); 11175 11176 m2->_opnds[0] = op_dst; 11177 m2->_opnds[1] = op_crx; 11178 m2->_opnds[2] = op_mem; 11179 11180 // registers for new nodes 11181 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11182 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11183 11184 // Insert new nodes. 11185 nodes->push(m1); 11186 nodes->push(m2); 11187 %} 11188 %} 11189 11190 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11191 // no match-rule, false predicate 11192 effect(DEF dst, USE crx, USE src); 11193 predicate(false); 11194 11195 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11196 postalloc_expand %{ 11197 // 11198 // replaces 11199 // 11200 // region dst crx src 11201 // \ | | / 11202 // dst=cmovI_bso_reg_conLvalue0 11203 // 11204 // with 11205 // 11206 // region dst 11207 // \ / 11208 // dst=loadConI16(0) 11209 // | 11210 // ^ region dst crx src 11211 // | \ | | / 11212 // dst=cmovI_bso_reg 11213 // 11214 11215 // Create new nodes. 11216 MachNode *m1 = new loadConI16Node(); 11217 MachNode *m2 = new cmovI_bso_regNode(); 11218 11219 // inputs for new nodes 11220 m1->add_req(n_region); 11221 m2->add_req(n_region, n_crx, n_src); 11222 11223 // precedences for new nodes 11224 m2->add_prec(m1); 11225 11226 // operands for new nodes 11227 m1->_opnds[0] = op_dst; 11228 m1->_opnds[1] = new immI16Oper(0); 11229 11230 m2->_opnds[0] = op_dst; 11231 m2->_opnds[1] = op_crx; 11232 m2->_opnds[2] = op_src; 11233 11234 // registers for new nodes 11235 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11236 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11237 11238 // Insert new nodes. 11239 nodes->push(m1); 11240 nodes->push(m2); 11241 %} 11242 %} 11243 11244 // Double to Int conversion, NaN is mapped to 0. 11245 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11246 match(Set dst (ConvD2I src)); 11247 predicate(!VM_Version::has_mtfprd()); 11248 ins_cost(DEFAULT_COST); 11249 11250 expand %{ 11251 regD tmpD; 11252 stackSlotL tmpS; 11253 flagsReg crx; 11254 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11255 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11256 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11257 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11258 %} 11259 %} 11260 11261 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11262 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11263 match(Set dst (ConvD2I src)); 11264 predicate(VM_Version::has_mtfprd()); 11265 ins_cost(DEFAULT_COST); 11266 11267 expand %{ 11268 regD tmpD; 11269 flagsReg crx; 11270 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11271 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11272 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11273 %} 11274 %} 11275 11276 instruct convF2IRaw_regF(regF dst, regF src) %{ 11277 // no match-rule, false predicate 11278 effect(DEF dst, USE src); 11279 predicate(false); 11280 11281 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11282 size(4); 11283 ins_encode %{ 11284 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11285 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11286 %} 11287 ins_pipe(pipe_class_default); 11288 %} 11289 11290 // Float to Int conversion, NaN is mapped to 0. 11291 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11292 match(Set dst (ConvF2I src)); 11293 predicate(!VM_Version::has_mtfprd()); 11294 ins_cost(DEFAULT_COST); 11295 11296 expand %{ 11297 regF tmpF; 11298 stackSlotL tmpS; 11299 flagsReg crx; 11300 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11301 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11302 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11303 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11304 %} 11305 %} 11306 11307 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11308 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11309 match(Set dst (ConvF2I src)); 11310 predicate(VM_Version::has_mtfprd()); 11311 ins_cost(DEFAULT_COST); 11312 11313 expand %{ 11314 regF tmpF; 11315 flagsReg crx; 11316 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11317 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11318 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11319 %} 11320 %} 11321 11322 // Convert to Long 11323 11324 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11325 match(Set dst (ConvI2L src)); 11326 format %{ "EXTSW $dst, $src \t// int->long" %} 11327 size(4); 11328 ins_encode %{ 11329 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11330 __ extsw($dst$$Register, $src$$Register); 11331 %} 11332 ins_pipe(pipe_class_default); 11333 %} 11334 11335 // Zero-extend: convert unsigned int to long (convUI2L). 11336 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11337 match(Set dst (AndL (ConvI2L src) mask)); 11338 ins_cost(DEFAULT_COST); 11339 11340 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11341 size(4); 11342 ins_encode %{ 11343 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11344 __ clrldi($dst$$Register, $src$$Register, 32); 11345 %} 11346 ins_pipe(pipe_class_default); 11347 %} 11348 11349 // Zero-extend: convert unsigned int to long in long register. 11350 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11351 match(Set dst (AndL src mask)); 11352 ins_cost(DEFAULT_COST); 11353 11354 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11355 size(4); 11356 ins_encode %{ 11357 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11358 __ clrldi($dst$$Register, $src$$Register, 32); 11359 %} 11360 ins_pipe(pipe_class_default); 11361 %} 11362 11363 instruct convF2LRaw_regF(regF dst, regF src) %{ 11364 // no match-rule, false predicate 11365 effect(DEF dst, USE src); 11366 predicate(false); 11367 11368 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11369 size(4); 11370 ins_encode %{ 11371 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11372 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11373 %} 11374 ins_pipe(pipe_class_default); 11375 %} 11376 11377 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 11378 // no match-rule, false predicate 11379 effect(DEF dst, USE crx, USE src); 11380 predicate(false); 11381 11382 ins_variable_size_depending_on_alignment(true); 11383 11384 format %{ "cmovL $crx, $dst, $src" %} 11385 // Worst case is branch + move + stop, no stop without scheduler. 11386 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 11387 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11388 ins_pipe(pipe_class_default); 11389 %} 11390 11391 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11392 // no match-rule, false predicate 11393 effect(DEF dst, USE crx, USE src); 11394 predicate(false); 11395 11396 ins_variable_size_depending_on_alignment(true); 11397 11398 format %{ "cmovL $crx, $dst, $src" %} 11399 // Worst case is branch + move + stop, no stop without scheduler. 11400 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 11401 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11402 ins_pipe(pipe_class_default); 11403 %} 11404 11405 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11406 // no match-rule, false predicate 11407 effect(DEF dst, USE crx, USE mem); 11408 predicate(false); 11409 11410 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11411 postalloc_expand %{ 11412 // 11413 // replaces 11414 // 11415 // region dst crx mem 11416 // \ | | / 11417 // dst=cmovL_bso_stackSlotL_conLvalue0 11418 // 11419 // with 11420 // 11421 // region dst 11422 // \ / 11423 // dst=loadConL16(0) 11424 // | 11425 // ^ region dst crx mem 11426 // | \ | | / 11427 // dst=cmovL_bso_stackSlotL 11428 // 11429 11430 // Create new nodes. 11431 MachNode *m1 = new loadConL16Node(); 11432 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11433 11434 // inputs for new nodes 11435 m1->add_req(n_region); 11436 m2->add_req(n_region, n_crx, n_mem); 11437 m2->add_prec(m1); 11438 11439 // operands for new nodes 11440 m1->_opnds[0] = op_dst; 11441 m1->_opnds[1] = new immL16Oper(0); 11442 m2->_opnds[0] = op_dst; 11443 m2->_opnds[1] = op_crx; 11444 m2->_opnds[2] = op_mem; 11445 11446 // registers for new nodes 11447 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11448 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11449 11450 // Insert new nodes. 11451 nodes->push(m1); 11452 nodes->push(m2); 11453 %} 11454 %} 11455 11456 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11457 // no match-rule, false predicate 11458 effect(DEF dst, USE crx, USE src); 11459 predicate(false); 11460 11461 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11462 postalloc_expand %{ 11463 // 11464 // replaces 11465 // 11466 // region dst crx src 11467 // \ | | / 11468 // dst=cmovL_bso_reg_conLvalue0 11469 // 11470 // with 11471 // 11472 // region dst 11473 // \ / 11474 // dst=loadConL16(0) 11475 // | 11476 // ^ region dst crx src 11477 // | \ | | / 11478 // dst=cmovL_bso_reg 11479 // 11480 11481 // Create new nodes. 11482 MachNode *m1 = new loadConL16Node(); 11483 MachNode *m2 = new cmovL_bso_regNode(); 11484 11485 // inputs for new nodes 11486 m1->add_req(n_region); 11487 m2->add_req(n_region, n_crx, n_src); 11488 m2->add_prec(m1); 11489 11490 // operands for new nodes 11491 m1->_opnds[0] = op_dst; 11492 m1->_opnds[1] = new immL16Oper(0); 11493 m2->_opnds[0] = op_dst; 11494 m2->_opnds[1] = op_crx; 11495 m2->_opnds[2] = op_src; 11496 11497 // registers for new nodes 11498 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11499 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11500 11501 // Insert new nodes. 11502 nodes->push(m1); 11503 nodes->push(m2); 11504 %} 11505 %} 11506 11507 // Float to Long conversion, NaN is mapped to 0. 11508 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11509 match(Set dst (ConvF2L src)); 11510 predicate(!VM_Version::has_mtfprd()); 11511 ins_cost(DEFAULT_COST); 11512 11513 expand %{ 11514 regF tmpF; 11515 stackSlotL tmpS; 11516 flagsReg crx; 11517 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11518 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11519 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11520 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11521 %} 11522 %} 11523 11524 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11525 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11526 match(Set dst (ConvF2L src)); 11527 predicate(VM_Version::has_mtfprd()); 11528 ins_cost(DEFAULT_COST); 11529 11530 expand %{ 11531 regF tmpF; 11532 flagsReg crx; 11533 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11534 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11535 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11536 %} 11537 %} 11538 11539 instruct convD2LRaw_regD(regD dst, regD src) %{ 11540 // no match-rule, false predicate 11541 effect(DEF dst, USE src); 11542 predicate(false); 11543 11544 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11545 size(4); 11546 ins_encode %{ 11547 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11548 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11549 %} 11550 ins_pipe(pipe_class_default); 11551 %} 11552 11553 // Double to Long conversion, NaN is mapped to 0. 11554 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11555 match(Set dst (ConvD2L src)); 11556 predicate(!VM_Version::has_mtfprd()); 11557 ins_cost(DEFAULT_COST); 11558 11559 expand %{ 11560 regD tmpD; 11561 stackSlotL tmpS; 11562 flagsReg crx; 11563 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11564 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11565 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11566 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11567 %} 11568 %} 11569 11570 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11571 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11572 match(Set dst (ConvD2L src)); 11573 predicate(VM_Version::has_mtfprd()); 11574 ins_cost(DEFAULT_COST); 11575 11576 expand %{ 11577 regD tmpD; 11578 flagsReg crx; 11579 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11580 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11581 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11582 %} 11583 %} 11584 11585 // Convert to Float 11586 11587 // Placed here as needed in expand. 11588 instruct convL2DRaw_regD(regD dst, regD src) %{ 11589 // no match-rule, false predicate 11590 effect(DEF dst, USE src); 11591 predicate(false); 11592 11593 format %{ "FCFID $dst, $src \t// convL2D" %} 11594 size(4); 11595 ins_encode %{ 11596 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11597 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11598 %} 11599 ins_pipe(pipe_class_default); 11600 %} 11601 11602 // Placed here as needed in expand. 11603 instruct convD2F_reg(regF dst, regD src) %{ 11604 match(Set dst (ConvD2F src)); 11605 format %{ "FRSP $dst, $src \t// convD2F" %} 11606 size(4); 11607 ins_encode %{ 11608 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11609 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11610 %} 11611 ins_pipe(pipe_class_default); 11612 %} 11613 11614 // Integer to Float conversion. 11615 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11616 match(Set dst (ConvI2F src)); 11617 predicate(!VM_Version::has_fcfids()); 11618 ins_cost(DEFAULT_COST); 11619 11620 expand %{ 11621 iRegLdst tmpL; 11622 stackSlotL tmpS; 11623 regD tmpD; 11624 regD tmpD2; 11625 convI2L_reg(tmpL, src); // Sign-extension int to long. 11626 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11627 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11628 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11629 convD2F_reg(dst, tmpD2); // Convert double to float. 11630 %} 11631 %} 11632 11633 instruct convL2FRaw_regF(regF dst, regD src) %{ 11634 // no match-rule, false predicate 11635 effect(DEF dst, USE src); 11636 predicate(false); 11637 11638 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11639 size(4); 11640 ins_encode %{ 11641 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11642 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11643 %} 11644 ins_pipe(pipe_class_default); 11645 %} 11646 11647 // Integer to Float conversion. Special version for Power7. 11648 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11649 match(Set dst (ConvI2F src)); 11650 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11651 ins_cost(DEFAULT_COST); 11652 11653 expand %{ 11654 iRegLdst tmpL; 11655 stackSlotL tmpS; 11656 regD tmpD; 11657 convI2L_reg(tmpL, src); // Sign-extension int to long. 11658 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11659 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11660 convL2FRaw_regF(dst, tmpD); // Convert to float. 11661 %} 11662 %} 11663 11664 // Integer to Float conversion. Special version for Power8. 11665 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11666 match(Set dst (ConvI2F src)); 11667 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11668 ins_cost(DEFAULT_COST); 11669 11670 expand %{ 11671 regD tmpD; 11672 moveI2D_reg(tmpD, src); 11673 convL2FRaw_regF(dst, tmpD); // Convert to float. 11674 %} 11675 %} 11676 11677 // L2F to avoid runtime call. 11678 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11679 match(Set dst (ConvL2F src)); 11680 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11681 ins_cost(DEFAULT_COST); 11682 11683 expand %{ 11684 stackSlotL tmpS; 11685 regD tmpD; 11686 regL_to_stkL(tmpS, src); // Store long to stack. 11687 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11688 convL2FRaw_regF(dst, tmpD); // Convert to float. 11689 %} 11690 %} 11691 11692 // L2F to avoid runtime call. Special version for Power8. 11693 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11694 match(Set dst (ConvL2F src)); 11695 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11696 ins_cost(DEFAULT_COST); 11697 11698 expand %{ 11699 regD tmpD; 11700 moveL2D_reg(tmpD, src); 11701 convL2FRaw_regF(dst, tmpD); // Convert to float. 11702 %} 11703 %} 11704 11705 // Moved up as used in expand. 11706 //instruct convD2F_reg(regF dst, regD src) %{%} 11707 11708 // Convert to Double 11709 11710 // Integer to Double conversion. 11711 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11712 match(Set dst (ConvI2D src)); 11713 predicate(!VM_Version::has_mtfprd()); 11714 ins_cost(DEFAULT_COST); 11715 11716 expand %{ 11717 iRegLdst tmpL; 11718 stackSlotL tmpS; 11719 regD tmpD; 11720 convI2L_reg(tmpL, src); // Sign-extension int to long. 11721 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11722 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11723 convL2DRaw_regD(dst, tmpD); // Convert to double. 11724 %} 11725 %} 11726 11727 // Integer to Double conversion. Special version for Power8. 11728 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11729 match(Set dst (ConvI2D src)); 11730 predicate(VM_Version::has_mtfprd()); 11731 ins_cost(DEFAULT_COST); 11732 11733 expand %{ 11734 regD tmpD; 11735 moveI2D_reg(tmpD, src); 11736 convL2DRaw_regD(dst, tmpD); // Convert to double. 11737 %} 11738 %} 11739 11740 // Long to Double conversion 11741 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11742 match(Set dst (ConvL2D src)); 11743 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11744 11745 expand %{ 11746 regD tmpD; 11747 moveL2D_stack_reg(tmpD, src); 11748 convL2DRaw_regD(dst, tmpD); 11749 %} 11750 %} 11751 11752 // Long to Double conversion. Special version for Power8. 11753 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11754 match(Set dst (ConvL2D src)); 11755 predicate(VM_Version::has_mtfprd()); 11756 ins_cost(DEFAULT_COST); 11757 11758 expand %{ 11759 regD tmpD; 11760 moveL2D_reg(tmpD, src); 11761 convL2DRaw_regD(dst, tmpD); // Convert to double. 11762 %} 11763 %} 11764 11765 instruct convF2D_reg(regD dst, regF src) %{ 11766 match(Set dst (ConvF2D src)); 11767 format %{ "FMR $dst, $src \t// float->double" %} 11768 // variable size, 0 or 4 11769 ins_encode %{ 11770 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11771 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11772 %} 11773 ins_pipe(pipe_class_default); 11774 %} 11775 11776 //----------Control Flow Instructions------------------------------------------ 11777 // Compare Instructions 11778 11779 // Compare Integers 11780 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11781 match(Set crx (CmpI src1 src2)); 11782 size(4); 11783 format %{ "CMPW $crx, $src1, $src2" %} 11784 ins_encode %{ 11785 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11786 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11787 %} 11788 ins_pipe(pipe_class_compare); 11789 %} 11790 11791 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11792 match(Set crx (CmpI src1 src2)); 11793 format %{ "CMPWI $crx, $src1, $src2" %} 11794 size(4); 11795 ins_encode %{ 11796 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11797 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11798 %} 11799 ins_pipe(pipe_class_compare); 11800 %} 11801 11802 // (src1 & src2) == 0? 11803 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11804 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11805 // r0 is killed 11806 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11807 size(4); 11808 ins_encode %{ 11809 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11810 __ andi_(R0, $src1$$Register, $src2$$constant); 11811 %} 11812 ins_pipe(pipe_class_compare); 11813 %} 11814 11815 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11816 match(Set crx (CmpL src1 src2)); 11817 format %{ "CMPD $crx, $src1, $src2" %} 11818 size(4); 11819 ins_encode %{ 11820 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11821 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11822 %} 11823 ins_pipe(pipe_class_compare); 11824 %} 11825 11826 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11827 match(Set crx (CmpL src1 src2)); 11828 format %{ "CMPDI $crx, $src1, $src2" %} 11829 size(4); 11830 ins_encode %{ 11831 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11832 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11833 %} 11834 ins_pipe(pipe_class_compare); 11835 %} 11836 11837 // Added CmpUL for LoopPredicate. 11838 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11839 match(Set crx (CmpUL src1 src2)); 11840 format %{ "CMPLD $crx, $src1, $src2" %} 11841 size(4); 11842 ins_encode %{ 11843 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11844 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11845 %} 11846 ins_pipe(pipe_class_compare); 11847 %} 11848 11849 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11850 match(Set crx (CmpUL src1 src2)); 11851 format %{ "CMPLDI $crx, $src1, $src2" %} 11852 size(4); 11853 ins_encode %{ 11854 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11855 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11856 %} 11857 ins_pipe(pipe_class_compare); 11858 %} 11859 11860 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11861 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11862 // r0 is killed 11863 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11864 size(4); 11865 ins_encode %{ 11866 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11867 __ and_(R0, $src1$$Register, $src2$$Register); 11868 %} 11869 ins_pipe(pipe_class_compare); 11870 %} 11871 11872 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11873 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11874 // r0 is killed 11875 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11876 size(4); 11877 ins_encode %{ 11878 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11879 __ andi_(R0, $src1$$Register, $src2$$constant); 11880 %} 11881 ins_pipe(pipe_class_compare); 11882 %} 11883 11884 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11885 // no match-rule, false predicate 11886 effect(DEF dst, USE crx); 11887 predicate(false); 11888 11889 ins_variable_size_depending_on_alignment(true); 11890 11891 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11892 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11893 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16); 11894 ins_encode %{ 11895 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11896 Label done; 11897 // li(Rdst, 0); // equal -> 0 11898 __ beq($crx$$CondRegister, done); 11899 __ li($dst$$Register, 1); // greater -> +1 11900 __ bgt($crx$$CondRegister, done); 11901 __ li($dst$$Register, -1); // unordered or less -> -1 11902 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11903 __ bind(done); 11904 %} 11905 ins_pipe(pipe_class_compare); 11906 %} 11907 11908 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11909 // no match-rule, false predicate 11910 effect(DEF dst, USE crx); 11911 predicate(false); 11912 11913 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11914 postalloc_expand %{ 11915 // 11916 // replaces 11917 // 11918 // region crx 11919 // \ | 11920 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11921 // 11922 // with 11923 // 11924 // region 11925 // \ 11926 // dst=loadConI16(0) 11927 // | 11928 // ^ region crx 11929 // | \ | 11930 // dst=cmovI_conIvalueMinus1_conIvalue1 11931 // 11932 11933 // Create new nodes. 11934 MachNode *m1 = new loadConI16Node(); 11935 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11936 11937 // inputs for new nodes 11938 m1->add_req(n_region); 11939 m2->add_req(n_region, n_crx); 11940 m2->add_prec(m1); 11941 11942 // operands for new nodes 11943 m1->_opnds[0] = op_dst; 11944 m1->_opnds[1] = new immI16Oper(0); 11945 m2->_opnds[0] = op_dst; 11946 m2->_opnds[1] = op_crx; 11947 11948 // registers for new nodes 11949 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11950 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11951 11952 // Insert new nodes. 11953 nodes->push(m1); 11954 nodes->push(m2); 11955 %} 11956 %} 11957 11958 // Manifest a CmpL3 result in an integer register. Very painful. 11959 // This is the test to avoid. 11960 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11961 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11962 match(Set dst (CmpL3 src1 src2)); 11963 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11964 11965 expand %{ 11966 flagsReg tmp1; 11967 cmpL_reg_reg(tmp1, src1, src2); 11968 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11969 %} 11970 %} 11971 11972 // Implicit range checks. 11973 // A range check in the ideal world has one of the following shapes: 11974 // - (If le (CmpU length index)), (IfTrue throw exception) 11975 // - (If lt (CmpU index length)), (IfFalse throw exception) 11976 // 11977 // Match range check 'If le (CmpU length index)'. 11978 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11979 match(If cmp (CmpU src_length index)); 11980 effect(USE labl); 11981 predicate(TrapBasedRangeChecks && 11982 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11983 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11984 (Matcher::branches_to_uncommon_trap(_leaf))); 11985 11986 ins_is_TrapBasedCheckNode(true); 11987 11988 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11989 size(4); 11990 ins_encode %{ 11991 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11992 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11993 __ trap_range_check_le($src_length$$Register, $index$$constant); 11994 } else { 11995 // Both successors are uncommon traps, probability is 0. 11996 // Node got flipped during fixup flow. 11997 assert($cmp$$cmpcode == 0x9, "must be greater"); 11998 __ trap_range_check_g($src_length$$Register, $index$$constant); 11999 } 12000 %} 12001 ins_pipe(pipe_class_trap); 12002 %} 12003 12004 // Match range check 'If lt (CmpU index length)'. 12005 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 12006 match(If cmp (CmpU src_index src_length)); 12007 effect(USE labl); 12008 predicate(TrapBasedRangeChecks && 12009 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12010 _leaf->as_If()->_prob >= PROB_ALWAYS && 12011 (Matcher::branches_to_uncommon_trap(_leaf))); 12012 12013 ins_is_TrapBasedCheckNode(true); 12014 12015 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 12016 size(4); 12017 ins_encode %{ 12018 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 12019 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12020 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 12021 } else { 12022 // Both successors are uncommon traps, probability is 0. 12023 // Node got flipped during fixup flow. 12024 assert($cmp$$cmpcode == 0x8, "must be less"); 12025 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 12026 } 12027 %} 12028 ins_pipe(pipe_class_trap); 12029 %} 12030 12031 // Match range check 'If lt (CmpU index length)'. 12032 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 12033 match(If cmp (CmpU src_index length)); 12034 effect(USE labl); 12035 predicate(TrapBasedRangeChecks && 12036 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12037 _leaf->as_If()->_prob >= PROB_ALWAYS && 12038 (Matcher::branches_to_uncommon_trap(_leaf))); 12039 12040 ins_is_TrapBasedCheckNode(true); 12041 12042 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 12043 size(4); 12044 ins_encode %{ 12045 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12046 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12047 __ trap_range_check_ge($src_index$$Register, $length$$constant); 12048 } else { 12049 // Both successors are uncommon traps, probability is 0. 12050 // Node got flipped during fixup flow. 12051 assert($cmp$$cmpcode == 0x8, "must be less"); 12052 __ trap_range_check_l($src_index$$Register, $length$$constant); 12053 } 12054 %} 12055 ins_pipe(pipe_class_trap); 12056 %} 12057 12058 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 12059 match(Set crx (CmpU src1 src2)); 12060 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 12061 size(4); 12062 ins_encode %{ 12063 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12064 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12065 %} 12066 ins_pipe(pipe_class_compare); 12067 %} 12068 12069 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 12070 match(Set crx (CmpU src1 src2)); 12071 size(4); 12072 format %{ "CMPLWI $crx, $src1, $src2" %} 12073 ins_encode %{ 12074 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12075 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12076 %} 12077 ins_pipe(pipe_class_compare); 12078 %} 12079 12080 // Implicit zero checks (more implicit null checks). 12081 // No constant pool entries required. 12082 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12083 match(If cmp (CmpN value zero)); 12084 effect(USE labl); 12085 predicate(TrapBasedNullChecks && 12086 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12087 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12088 Matcher::branches_to_uncommon_trap(_leaf)); 12089 ins_cost(1); 12090 12091 ins_is_TrapBasedCheckNode(true); 12092 12093 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12094 size(4); 12095 ins_encode %{ 12096 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12097 if ($cmp$$cmpcode == 0xA) { 12098 __ trap_null_check($value$$Register); 12099 } else { 12100 // Both successors are uncommon traps, probability is 0. 12101 // Node got flipped during fixup flow. 12102 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12103 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12104 } 12105 %} 12106 ins_pipe(pipe_class_trap); 12107 %} 12108 12109 // Compare narrow oops. 12110 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12111 match(Set crx (CmpN src1 src2)); 12112 12113 size(4); 12114 ins_cost(2); 12115 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12116 ins_encode %{ 12117 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12118 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12119 %} 12120 ins_pipe(pipe_class_compare); 12121 %} 12122 12123 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12124 match(Set crx (CmpN src1 src2)); 12125 // Make this more expensive than zeroCheckN_iReg_imm0. 12126 ins_cost(2); 12127 12128 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12129 size(4); 12130 ins_encode %{ 12131 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12132 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12133 %} 12134 ins_pipe(pipe_class_compare); 12135 %} 12136 12137 // Implicit zero checks (more implicit null checks). 12138 // No constant pool entries required. 12139 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12140 match(If cmp (CmpP value zero)); 12141 effect(USE labl); 12142 predicate(TrapBasedNullChecks && 12143 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12144 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12145 Matcher::branches_to_uncommon_trap(_leaf)); 12146 ins_cost(1); // Should not be cheaper than zeroCheckN. 12147 12148 ins_is_TrapBasedCheckNode(true); 12149 12150 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12151 size(4); 12152 ins_encode %{ 12153 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12154 if ($cmp$$cmpcode == 0xA) { 12155 __ trap_null_check($value$$Register); 12156 } else { 12157 // Both successors are uncommon traps, probability is 0. 12158 // Node got flipped during fixup flow. 12159 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12160 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12161 } 12162 %} 12163 ins_pipe(pipe_class_trap); 12164 %} 12165 12166 // Compare Pointers 12167 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12168 match(Set crx (CmpP src1 src2)); 12169 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12170 size(4); 12171 ins_encode %{ 12172 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12173 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12174 %} 12175 ins_pipe(pipe_class_compare); 12176 %} 12177 12178 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12179 match(Set crx (CmpP src1 src2)); 12180 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12181 size(4); 12182 ins_encode %{ 12183 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12184 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12185 %} 12186 ins_pipe(pipe_class_compare); 12187 %} 12188 12189 // Used in postalloc expand. 12190 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12191 // This match rule prevents reordering of node before a safepoint. 12192 // This only makes sense if this instructions is used exclusively 12193 // for the expansion of EncodeP! 12194 match(Set crx (CmpP src1 src2)); 12195 predicate(false); 12196 12197 format %{ "CMPDI $crx, $src1, $src2" %} 12198 size(4); 12199 ins_encode %{ 12200 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12201 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12202 %} 12203 ins_pipe(pipe_class_compare); 12204 %} 12205 12206 //----------Float Compares---------------------------------------------------- 12207 12208 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12209 // Needs matchrule, see cmpDUnordered. 12210 match(Set crx (CmpF src1 src2)); 12211 // no match-rule, false predicate 12212 predicate(false); 12213 12214 format %{ "cmpFUrd $crx, $src1, $src2" %} 12215 size(4); 12216 ins_encode %{ 12217 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12218 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12219 %} 12220 ins_pipe(pipe_class_default); 12221 %} 12222 12223 instruct cmov_bns_less(flagsReg crx) %{ 12224 // no match-rule, false predicate 12225 effect(DEF crx); 12226 predicate(false); 12227 12228 ins_variable_size_depending_on_alignment(true); 12229 12230 format %{ "cmov $crx" %} 12231 // Worst case is branch + move + stop, no stop without scheduler. 12232 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12); 12233 ins_encode %{ 12234 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12235 Label done; 12236 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12237 __ li(R0, 0); 12238 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12239 // TODO PPC port __ endgroup_if_needed(_size == 16); 12240 __ bind(done); 12241 %} 12242 ins_pipe(pipe_class_default); 12243 %} 12244 12245 // Compare floating, generate condition code. 12246 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12247 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12248 // 12249 // The following code sequence occurs a lot in mpegaudio: 12250 // 12251 // block BXX: 12252 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12253 // cmpFUrd CCR6, F11, F9 12254 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12255 // cmov CCR6 12256 // 8: instruct branchConSched: 12257 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12258 match(Set crx (CmpF src1 src2)); 12259 ins_cost(DEFAULT_COST+BRANCH_COST); 12260 12261 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12262 postalloc_expand %{ 12263 // 12264 // replaces 12265 // 12266 // region src1 src2 12267 // \ | | 12268 // crx=cmpF_reg_reg 12269 // 12270 // with 12271 // 12272 // region src1 src2 12273 // \ | | 12274 // crx=cmpFUnordered_reg_reg 12275 // | 12276 // ^ region 12277 // | \ 12278 // crx=cmov_bns_less 12279 // 12280 12281 // Create new nodes. 12282 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12283 MachNode *m2 = new cmov_bns_lessNode(); 12284 12285 // inputs for new nodes 12286 m1->add_req(n_region, n_src1, n_src2); 12287 m2->add_req(n_region); 12288 m2->add_prec(m1); 12289 12290 // operands for new nodes 12291 m1->_opnds[0] = op_crx; 12292 m1->_opnds[1] = op_src1; 12293 m1->_opnds[2] = op_src2; 12294 m2->_opnds[0] = op_crx; 12295 12296 // registers for new nodes 12297 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12298 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12299 12300 // Insert new nodes. 12301 nodes->push(m1); 12302 nodes->push(m2); 12303 %} 12304 %} 12305 12306 // Compare float, generate -1,0,1 12307 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12308 match(Set dst (CmpF3 src1 src2)); 12309 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12310 12311 expand %{ 12312 flagsReg tmp1; 12313 cmpFUnordered_reg_reg(tmp1, src1, src2); 12314 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12315 %} 12316 %} 12317 12318 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12319 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12320 // node right before the conditional move using it. 12321 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12322 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12323 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12324 // conditional move was supposed to be spilled. 12325 match(Set crx (CmpD src1 src2)); 12326 // False predicate, shall not be matched. 12327 predicate(false); 12328 12329 format %{ "cmpFUrd $crx, $src1, $src2" %} 12330 size(4); 12331 ins_encode %{ 12332 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12333 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12334 %} 12335 ins_pipe(pipe_class_default); 12336 %} 12337 12338 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12339 match(Set crx (CmpD src1 src2)); 12340 ins_cost(DEFAULT_COST+BRANCH_COST); 12341 12342 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12343 postalloc_expand %{ 12344 // 12345 // replaces 12346 // 12347 // region src1 src2 12348 // \ | | 12349 // crx=cmpD_reg_reg 12350 // 12351 // with 12352 // 12353 // region src1 src2 12354 // \ | | 12355 // crx=cmpDUnordered_reg_reg 12356 // | 12357 // ^ region 12358 // | \ 12359 // crx=cmov_bns_less 12360 // 12361 12362 // create new nodes 12363 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12364 MachNode *m2 = new cmov_bns_lessNode(); 12365 12366 // inputs for new nodes 12367 m1->add_req(n_region, n_src1, n_src2); 12368 m2->add_req(n_region); 12369 m2->add_prec(m1); 12370 12371 // operands for new nodes 12372 m1->_opnds[0] = op_crx; 12373 m1->_opnds[1] = op_src1; 12374 m1->_opnds[2] = op_src2; 12375 m2->_opnds[0] = op_crx; 12376 12377 // registers for new nodes 12378 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12379 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12380 12381 // Insert new nodes. 12382 nodes->push(m1); 12383 nodes->push(m2); 12384 %} 12385 %} 12386 12387 // Compare double, generate -1,0,1 12388 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12389 match(Set dst (CmpD3 src1 src2)); 12390 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12391 12392 expand %{ 12393 flagsReg tmp1; 12394 cmpDUnordered_reg_reg(tmp1, src1, src2); 12395 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12396 %} 12397 %} 12398 12399 //----------Branches--------------------------------------------------------- 12400 // Jump 12401 12402 // Direct Branch. 12403 instruct branch(label labl) %{ 12404 match(Goto); 12405 effect(USE labl); 12406 ins_cost(BRANCH_COST); 12407 12408 format %{ "B $labl" %} 12409 size(4); 12410 ins_encode %{ 12411 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12412 Label d; // dummy 12413 __ bind(d); 12414 Label* p = $labl$$label; 12415 // `p' is `NULL' when this encoding class is used only to 12416 // determine the size of the encoded instruction. 12417 Label& l = (NULL == p)? d : *(p); 12418 __ b(l); 12419 %} 12420 ins_pipe(pipe_class_default); 12421 %} 12422 12423 // Conditional Near Branch 12424 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12425 // Same match rule as `branchConFar'. 12426 match(If cmp crx); 12427 effect(USE lbl); 12428 ins_cost(BRANCH_COST); 12429 12430 // If set to 1 this indicates that the current instruction is a 12431 // short variant of a long branch. This avoids using this 12432 // instruction in first-pass matching. It will then only be used in 12433 // the `Shorten_branches' pass. 12434 ins_short_branch(1); 12435 12436 format %{ "B$cmp $crx, $lbl" %} 12437 size(4); 12438 ins_encode( enc_bc(crx, cmp, lbl) ); 12439 ins_pipe(pipe_class_default); 12440 %} 12441 12442 // This is for cases when the ppc64 `bc' instruction does not 12443 // reach far enough. So we emit a far branch here, which is more 12444 // expensive. 12445 // 12446 // Conditional Far Branch 12447 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12448 // Same match rule as `branchCon'. 12449 match(If cmp crx); 12450 effect(USE crx, USE lbl); 12451 predicate(!false /* TODO: PPC port HB_Schedule*/); 12452 // Higher cost than `branchCon'. 12453 ins_cost(5*BRANCH_COST); 12454 12455 // This is not a short variant of a branch, but the long variant. 12456 ins_short_branch(0); 12457 12458 format %{ "B_FAR$cmp $crx, $lbl" %} 12459 size(8); 12460 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12461 ins_pipe(pipe_class_default); 12462 %} 12463 12464 // Conditional Branch used with Power6 scheduler (can be far or short). 12465 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12466 // Same match rule as `branchCon'. 12467 match(If cmp crx); 12468 effect(USE crx, USE lbl); 12469 predicate(false /* TODO: PPC port HB_Schedule*/); 12470 // Higher cost than `branchCon'. 12471 ins_cost(5*BRANCH_COST); 12472 12473 // Actually size doesn't depend on alignment but on shortening. 12474 ins_variable_size_depending_on_alignment(true); 12475 // long variant. 12476 ins_short_branch(0); 12477 12478 format %{ "B_FAR$cmp $crx, $lbl" %} 12479 size(8); // worst case 12480 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12481 ins_pipe(pipe_class_default); 12482 %} 12483 12484 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12485 match(CountedLoopEnd cmp crx); 12486 effect(USE labl); 12487 ins_cost(BRANCH_COST); 12488 12489 // short variant. 12490 ins_short_branch(1); 12491 12492 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12493 size(4); 12494 ins_encode( enc_bc(crx, cmp, labl) ); 12495 ins_pipe(pipe_class_default); 12496 %} 12497 12498 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12499 match(CountedLoopEnd cmp crx); 12500 effect(USE labl); 12501 predicate(!false /* TODO: PPC port HB_Schedule */); 12502 ins_cost(BRANCH_COST); 12503 12504 // Long variant. 12505 ins_short_branch(0); 12506 12507 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12508 size(8); 12509 ins_encode( enc_bc_far(crx, cmp, labl) ); 12510 ins_pipe(pipe_class_default); 12511 %} 12512 12513 // Conditional Branch used with Power6 scheduler (can be far or short). 12514 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12515 match(CountedLoopEnd cmp crx); 12516 effect(USE labl); 12517 predicate(false /* TODO: PPC port HB_Schedule */); 12518 // Higher cost than `branchCon'. 12519 ins_cost(5*BRANCH_COST); 12520 12521 // Actually size doesn't depend on alignment but on shortening. 12522 ins_variable_size_depending_on_alignment(true); 12523 // Long variant. 12524 ins_short_branch(0); 12525 12526 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12527 size(8); // worst case 12528 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12529 ins_pipe(pipe_class_default); 12530 %} 12531 12532 // ============================================================================ 12533 // Java runtime operations, intrinsics and other complex operations. 12534 12535 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12536 // array for an instance of the superklass. Set a hidden internal cache on a 12537 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12538 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12539 // 12540 // GL TODO: Improve this. 12541 // - result should not be a TEMP 12542 // - Add match rule as on sparc avoiding additional Cmp. 12543 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12544 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12545 match(Set result (PartialSubtypeCheck subklass superklass)); 12546 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12547 ins_cost(DEFAULT_COST*10); 12548 12549 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12550 ins_encode %{ 12551 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12552 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12553 $tmp_klass$$Register, NULL, $result$$Register); 12554 %} 12555 ins_pipe(pipe_class_default); 12556 %} 12557 12558 // inlined locking and unlocking 12559 12560 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12561 match(Set crx (FastLock oop box)); 12562 effect(TEMP tmp1, TEMP tmp2); 12563 predicate(!Compile::current()->use_rtm()); 12564 12565 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12566 ins_encode %{ 12567 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12568 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12569 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12570 UseBiasedLocking && !UseOptoBiasInlining); 12571 // If locking was successfull, crx should indicate 'EQ'. 12572 // The compiler generates a branch to the runtime call to 12573 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12574 %} 12575 ins_pipe(pipe_class_compare); 12576 %} 12577 12578 // Separate version for TM. Use bound register for box to enable USE_KILL. 12579 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12580 match(Set crx (FastLock oop box)); 12581 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12582 predicate(Compile::current()->use_rtm()); 12583 12584 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12585 ins_encode %{ 12586 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12587 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12588 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12589 /*Biased Locking*/ false, 12590 _rtm_counters, _stack_rtm_counters, 12591 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12592 /*TM*/ true, ra_->C->profile_rtm()); 12593 // If locking was successfull, crx should indicate 'EQ'. 12594 // The compiler generates a branch to the runtime call to 12595 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12596 %} 12597 ins_pipe(pipe_class_compare); 12598 %} 12599 12600 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12601 match(Set crx (FastUnlock oop box)); 12602 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12603 predicate(!Compile::current()->use_rtm()); 12604 12605 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12606 ins_encode %{ 12607 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12608 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12609 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12610 UseBiasedLocking && !UseOptoBiasInlining, 12611 false); 12612 // If unlocking was successfull, crx should indicate 'EQ'. 12613 // The compiler generates a branch to the runtime call to 12614 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12615 %} 12616 ins_pipe(pipe_class_compare); 12617 %} 12618 12619 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12620 match(Set crx (FastUnlock oop box)); 12621 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12622 predicate(Compile::current()->use_rtm()); 12623 12624 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12625 ins_encode %{ 12626 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12627 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12628 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12629 /*Biased Locking*/ false, /*TM*/ true); 12630 // If unlocking was successfull, crx should indicate 'EQ'. 12631 // The compiler generates a branch to the runtime call to 12632 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12633 %} 12634 ins_pipe(pipe_class_compare); 12635 %} 12636 12637 // Align address. 12638 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12639 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12640 12641 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12642 size(4); 12643 ins_encode %{ 12644 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12645 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12646 %} 12647 ins_pipe(pipe_class_default); 12648 %} 12649 12650 // Array size computation. 12651 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12652 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12653 12654 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12655 size(4); 12656 ins_encode %{ 12657 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12658 __ subf($dst$$Register, $start$$Register, $end$$Register); 12659 %} 12660 ins_pipe(pipe_class_default); 12661 %} 12662 12663 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12664 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12665 match(Set dummy (ClearArray cnt base)); 12666 effect(USE_KILL base, KILL ctr); 12667 ins_cost(2 * MEMORY_REF_COST); 12668 12669 format %{ "ClearArray $cnt, $base" %} 12670 ins_encode %{ 12671 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12672 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12673 %} 12674 ins_pipe(pipe_class_default); 12675 %} 12676 12677 // Clear-array with constant large array length. 12678 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12679 match(Set dummy (ClearArray cnt base)); 12680 effect(USE_KILL base, TEMP tmp, KILL ctr); 12681 ins_cost(3 * MEMORY_REF_COST); 12682 12683 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12684 ins_encode %{ 12685 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12686 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12687 %} 12688 ins_pipe(pipe_class_default); 12689 %} 12690 12691 // Clear-array with dynamic array length. 12692 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12693 match(Set dummy (ClearArray cnt base)); 12694 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12695 ins_cost(4 * MEMORY_REF_COST); 12696 12697 format %{ "ClearArray $cnt, $base" %} 12698 ins_encode %{ 12699 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12700 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12701 %} 12702 ins_pipe(pipe_class_default); 12703 %} 12704 12705 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12706 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12707 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12708 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12709 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12710 ins_cost(300); 12711 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12712 ins_encode %{ 12713 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12714 __ string_compare($str1$$Register, $str2$$Register, 12715 $cnt1$$Register, $cnt2$$Register, 12716 $tmp$$Register, 12717 $result$$Register, StrIntrinsicNode::LL); 12718 %} 12719 ins_pipe(pipe_class_default); 12720 %} 12721 12722 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12723 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12724 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12725 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12726 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12727 ins_cost(300); 12728 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12729 ins_encode %{ 12730 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12731 __ string_compare($str1$$Register, $str2$$Register, 12732 $cnt1$$Register, $cnt2$$Register, 12733 $tmp$$Register, 12734 $result$$Register, StrIntrinsicNode::UU); 12735 %} 12736 ins_pipe(pipe_class_default); 12737 %} 12738 12739 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12740 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12741 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12742 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12743 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12744 ins_cost(300); 12745 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12746 ins_encode %{ 12747 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12748 __ string_compare($str1$$Register, $str2$$Register, 12749 $cnt1$$Register, $cnt2$$Register, 12750 $tmp$$Register, 12751 $result$$Register, StrIntrinsicNode::LU); 12752 %} 12753 ins_pipe(pipe_class_default); 12754 %} 12755 12756 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12757 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12758 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12759 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12760 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12761 ins_cost(300); 12762 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12763 ins_encode %{ 12764 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12765 __ string_compare($str2$$Register, $str1$$Register, 12766 $cnt2$$Register, $cnt1$$Register, 12767 $tmp$$Register, 12768 $result$$Register, StrIntrinsicNode::UL); 12769 %} 12770 ins_pipe(pipe_class_default); 12771 %} 12772 12773 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12774 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12775 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12776 match(Set result (StrEquals (Binary str1 str2) cnt)); 12777 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12778 ins_cost(300); 12779 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12780 ins_encode %{ 12781 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12782 __ array_equals(false, $str1$$Register, $str2$$Register, 12783 $cnt$$Register, $tmp$$Register, 12784 $result$$Register, true /* byte */); 12785 %} 12786 ins_pipe(pipe_class_default); 12787 %} 12788 12789 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12790 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12791 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12792 match(Set result (StrEquals (Binary str1 str2) cnt)); 12793 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12794 ins_cost(300); 12795 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12796 ins_encode %{ 12797 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12798 __ array_equals(false, $str1$$Register, $str2$$Register, 12799 $cnt$$Register, $tmp$$Register, 12800 $result$$Register, false /* byte */); 12801 %} 12802 ins_pipe(pipe_class_default); 12803 %} 12804 12805 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12806 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12807 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12808 match(Set result (AryEq ary1 ary2)); 12809 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12810 ins_cost(300); 12811 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12812 ins_encode %{ 12813 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12814 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12815 $tmp1$$Register, $tmp2$$Register, 12816 $result$$Register, true /* byte */); 12817 %} 12818 ins_pipe(pipe_class_default); 12819 %} 12820 12821 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12822 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12823 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12824 match(Set result (AryEq ary1 ary2)); 12825 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12826 ins_cost(300); 12827 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12828 ins_encode %{ 12829 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12830 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12831 $tmp1$$Register, $tmp2$$Register, 12832 $result$$Register, false /* byte */); 12833 %} 12834 ins_pipe(pipe_class_default); 12835 %} 12836 12837 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12838 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12839 iRegIdst tmp1, iRegIdst tmp2, 12840 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12841 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12842 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12843 // Required for EA: check if it is still a type_array. 12844 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12845 ins_cost(150); 12846 12847 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12848 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12849 12850 ins_encode %{ 12851 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12852 immPOper *needleOper = (immPOper *)$needleImm; 12853 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12854 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12855 jchar chr; 12856 #ifdef VM_LITTLE_ENDIAN 12857 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12858 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12859 #else 12860 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12861 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12862 #endif 12863 __ string_indexof_char($result$$Register, 12864 $haystack$$Register, $haycnt$$Register, 12865 R0, chr, 12866 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12867 %} 12868 ins_pipe(pipe_class_compare); 12869 %} 12870 12871 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12872 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12873 iRegIdst tmp1, iRegIdst tmp2, 12874 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12875 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12876 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12877 // Required for EA: check if it is still a type_array. 12878 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12879 ins_cost(150); 12880 12881 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12882 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12883 12884 ins_encode %{ 12885 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12886 immPOper *needleOper = (immPOper *)$needleImm; 12887 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12888 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12889 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12890 __ string_indexof_char($result$$Register, 12891 $haystack$$Register, $haycnt$$Register, 12892 R0, chr, 12893 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12894 %} 12895 ins_pipe(pipe_class_compare); 12896 %} 12897 12898 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12899 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12900 iRegIdst tmp1, iRegIdst tmp2, 12901 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12902 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12903 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12904 // Required for EA: check if it is still a type_array. 12905 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12906 ins_cost(150); 12907 12908 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12909 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12910 12911 ins_encode %{ 12912 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12913 immPOper *needleOper = (immPOper *)$needleImm; 12914 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12915 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12916 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12917 __ string_indexof_char($result$$Register, 12918 $haystack$$Register, $haycnt$$Register, 12919 R0, chr, 12920 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12921 %} 12922 ins_pipe(pipe_class_compare); 12923 %} 12924 12925 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12926 rscratch2RegP needle, immI_1 needlecntImm, 12927 iRegIdst tmp1, iRegIdst tmp2, 12928 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12929 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12930 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12931 // Required for EA: check if it is still a type_array. 12932 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12933 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12934 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12935 ins_cost(180); 12936 12937 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12938 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12939 ins_encode %{ 12940 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12941 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12942 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12943 guarantee(needle_values, "sanity"); 12944 jchar chr; 12945 #ifdef VM_LITTLE_ENDIAN 12946 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12947 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12948 #else 12949 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12950 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12951 #endif 12952 __ string_indexof_char($result$$Register, 12953 $haystack$$Register, $haycnt$$Register, 12954 R0, chr, 12955 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12956 %} 12957 ins_pipe(pipe_class_compare); 12958 %} 12959 12960 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12961 rscratch2RegP needle, immI_1 needlecntImm, 12962 iRegIdst tmp1, iRegIdst tmp2, 12963 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12964 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12965 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12966 // Required for EA: check if it is still a type_array. 12967 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12968 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12969 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12970 ins_cost(180); 12971 12972 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12973 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12974 ins_encode %{ 12975 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12976 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12977 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12978 guarantee(needle_values, "sanity"); 12979 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12980 __ string_indexof_char($result$$Register, 12981 $haystack$$Register, $haycnt$$Register, 12982 R0, chr, 12983 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12984 %} 12985 ins_pipe(pipe_class_compare); 12986 %} 12987 12988 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12989 rscratch2RegP needle, immI_1 needlecntImm, 12990 iRegIdst tmp1, iRegIdst tmp2, 12991 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12992 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12993 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12994 // Required for EA: check if it is still a type_array. 12995 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12996 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12997 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12998 ins_cost(180); 12999 13000 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13001 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13002 ins_encode %{ 13003 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13004 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13005 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13006 guarantee(needle_values, "sanity"); 13007 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13008 __ string_indexof_char($result$$Register, 13009 $haystack$$Register, $haycnt$$Register, 13010 R0, chr, 13011 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13012 %} 13013 ins_pipe(pipe_class_compare); 13014 %} 13015 13016 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13017 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 13018 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13019 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 13020 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13021 ins_cost(180); 13022 13023 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 13024 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13025 ins_encode %{ 13026 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13027 __ string_indexof_char($result$$Register, 13028 $haystack$$Register, $haycnt$$Register, 13029 $ch$$Register, 0 /* this is not used if the character is already in a register */, 13030 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13031 %} 13032 ins_pipe(pipe_class_compare); 13033 %} 13034 13035 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13036 iRegPsrc needle, uimmI15 needlecntImm, 13037 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13038 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13039 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13040 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13041 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13042 // Required for EA: check if it is still a type_array. 13043 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13044 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13045 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13046 ins_cost(250); 13047 13048 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13049 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13050 ins_encode %{ 13051 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13052 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13053 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13054 13055 __ string_indexof($result$$Register, 13056 $haystack$$Register, $haycnt$$Register, 13057 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13058 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13059 %} 13060 ins_pipe(pipe_class_compare); 13061 %} 13062 13063 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13064 iRegPsrc needle, uimmI15 needlecntImm, 13065 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13066 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13067 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13068 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13069 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13070 // Required for EA: check if it is still a type_array. 13071 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13072 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13073 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13074 ins_cost(250); 13075 13076 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13077 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13078 ins_encode %{ 13079 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13080 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13081 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13082 13083 __ string_indexof($result$$Register, 13084 $haystack$$Register, $haycnt$$Register, 13085 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13086 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13087 %} 13088 ins_pipe(pipe_class_compare); 13089 %} 13090 13091 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13092 iRegPsrc needle, uimmI15 needlecntImm, 13093 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13094 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13095 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13096 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13097 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13098 // Required for EA: check if it is still a type_array. 13099 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13100 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13101 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13102 ins_cost(250); 13103 13104 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13105 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13106 ins_encode %{ 13107 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13108 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13109 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13110 13111 __ string_indexof($result$$Register, 13112 $haystack$$Register, $haycnt$$Register, 13113 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13114 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13115 %} 13116 ins_pipe(pipe_class_compare); 13117 %} 13118 13119 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13120 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13121 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13122 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13123 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13124 TEMP_DEF result, 13125 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13126 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13127 ins_cost(300); 13128 13129 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13130 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13131 ins_encode %{ 13132 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13133 __ string_indexof($result$$Register, 13134 $haystack$$Register, $haycnt$$Register, 13135 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13136 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13137 %} 13138 ins_pipe(pipe_class_compare); 13139 %} 13140 13141 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13142 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13143 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13144 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13145 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13146 TEMP_DEF result, 13147 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13148 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13149 ins_cost(300); 13150 13151 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13152 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13153 ins_encode %{ 13154 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13155 __ string_indexof($result$$Register, 13156 $haystack$$Register, $haycnt$$Register, 13157 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13158 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13159 %} 13160 ins_pipe(pipe_class_compare); 13161 %} 13162 13163 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13164 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13165 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13166 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13167 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13168 TEMP_DEF result, 13169 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13170 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13171 ins_cost(300); 13172 13173 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13174 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13175 ins_encode %{ 13176 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13177 __ string_indexof($result$$Register, 13178 $haystack$$Register, $haycnt$$Register, 13179 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13180 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13181 %} 13182 ins_pipe(pipe_class_compare); 13183 %} 13184 13185 // char[] to byte[] compression 13186 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13187 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13188 match(Set result (StrCompressedCopy src (Binary dst len))); 13189 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13190 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13191 ins_cost(300); 13192 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13193 ins_encode %{ 13194 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13195 Label Lskip, Ldone; 13196 __ li($result$$Register, 0); 13197 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13198 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13199 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13200 __ beq(CCR0, Lskip); 13201 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13202 __ bind(Lskip); 13203 __ mr($result$$Register, $len$$Register); 13204 __ bind(Ldone); 13205 %} 13206 ins_pipe(pipe_class_default); 13207 %} 13208 13209 // byte[] to char[] inflation 13210 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13211 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13212 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13213 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13214 ins_cost(300); 13215 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13216 ins_encode %{ 13217 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13218 Label Ldone; 13219 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13220 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13221 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13222 __ beq(CCR0, Ldone); 13223 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13224 __ bind(Ldone); 13225 %} 13226 ins_pipe(pipe_class_default); 13227 %} 13228 13229 // StringCoding.java intrinsics 13230 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13231 regCTR ctr, flagsRegCR0 cr0) 13232 %{ 13233 match(Set result (HasNegatives ary1 len)); 13234 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13235 ins_cost(300); 13236 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13237 ins_encode %{ 13238 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13239 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13240 $tmp1$$Register, $tmp2$$Register); 13241 %} 13242 ins_pipe(pipe_class_default); 13243 %} 13244 13245 // encode char[] to byte[] in ISO_8859_1 13246 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13247 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13248 match(Set result (EncodeISOArray src (Binary dst len))); 13249 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13250 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13251 ins_cost(300); 13252 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13253 ins_encode %{ 13254 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13255 Label Lslow, Lfailure1, Lfailure2, Ldone; 13256 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13257 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13258 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13259 __ beq(CCR0, Ldone); 13260 __ bind(Lslow); 13261 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13262 __ li($result$$Register, 0); 13263 __ b(Ldone); 13264 13265 __ bind(Lfailure1); 13266 __ mr($result$$Register, $len$$Register); 13267 __ mfctr($tmp1$$Register); 13268 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13269 __ beq(CCR0, Ldone); 13270 __ b(Lslow); 13271 13272 __ bind(Lfailure2); 13273 __ mfctr($result$$Register); // Remaining characters. 13274 13275 __ bind(Ldone); 13276 __ subf($result$$Register, $result$$Register, $len$$Register); 13277 %} 13278 ins_pipe(pipe_class_default); 13279 %} 13280 13281 13282 //---------- Min/Max Instructions --------------------------------------------- 13283 13284 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13285 match(Set dst (MinI src1 src2)); 13286 ins_cost(DEFAULT_COST*6); 13287 13288 expand %{ 13289 iRegLdst src1s; 13290 iRegLdst src2s; 13291 iRegLdst diff; 13292 iRegLdst sm; 13293 iRegLdst doz; // difference or zero 13294 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13295 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13296 subL_reg_reg(diff, src2s, src1s); 13297 // Need to consider >=33 bit result, therefore we need signmaskL. 13298 signmask64L_regL(sm, diff); 13299 andL_reg_reg(doz, diff, sm); // <=0 13300 addI_regL_regL(dst, doz, src1s); 13301 %} 13302 %} 13303 13304 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13305 match(Set dst (MinI src1 src2)); 13306 effect(KILL cr0); 13307 predicate(VM_Version::has_isel()); 13308 ins_cost(DEFAULT_COST*2); 13309 13310 ins_encode %{ 13311 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13312 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13313 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13314 %} 13315 ins_pipe(pipe_class_default); 13316 %} 13317 13318 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13319 match(Set dst (MaxI src1 src2)); 13320 ins_cost(DEFAULT_COST*6); 13321 13322 expand %{ 13323 iRegLdst src1s; 13324 iRegLdst src2s; 13325 iRegLdst diff; 13326 iRegLdst sm; 13327 iRegLdst doz; // difference or zero 13328 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13329 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13330 subL_reg_reg(diff, src2s, src1s); 13331 // Need to consider >=33 bit result, therefore we need signmaskL. 13332 signmask64L_regL(sm, diff); 13333 andcL_reg_reg(doz, diff, sm); // >=0 13334 addI_regL_regL(dst, doz, src1s); 13335 %} 13336 %} 13337 13338 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13339 match(Set dst (MaxI src1 src2)); 13340 effect(KILL cr0); 13341 predicate(VM_Version::has_isel()); 13342 ins_cost(DEFAULT_COST*2); 13343 13344 ins_encode %{ 13345 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13346 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13347 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13348 %} 13349 ins_pipe(pipe_class_default); 13350 %} 13351 13352 //---------- Population Count Instructions ------------------------------------ 13353 13354 // Popcnt for Power7. 13355 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13356 match(Set dst (PopCountI src)); 13357 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13358 ins_cost(DEFAULT_COST); 13359 13360 format %{ "POPCNTW $dst, $src" %} 13361 size(4); 13362 ins_encode %{ 13363 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13364 __ popcntw($dst$$Register, $src$$Register); 13365 %} 13366 ins_pipe(pipe_class_default); 13367 %} 13368 13369 // Popcnt for Power7. 13370 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13371 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13372 match(Set dst (PopCountL src)); 13373 ins_cost(DEFAULT_COST); 13374 13375 format %{ "POPCNTD $dst, $src" %} 13376 size(4); 13377 ins_encode %{ 13378 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13379 __ popcntd($dst$$Register, $src$$Register); 13380 %} 13381 ins_pipe(pipe_class_default); 13382 %} 13383 13384 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13385 match(Set dst (CountLeadingZerosI src)); 13386 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13387 ins_cost(DEFAULT_COST); 13388 13389 format %{ "CNTLZW $dst, $src" %} 13390 size(4); 13391 ins_encode %{ 13392 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13393 __ cntlzw($dst$$Register, $src$$Register); 13394 %} 13395 ins_pipe(pipe_class_default); 13396 %} 13397 13398 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13399 match(Set dst (CountLeadingZerosL src)); 13400 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13401 ins_cost(DEFAULT_COST); 13402 13403 format %{ "CNTLZD $dst, $src" %} 13404 size(4); 13405 ins_encode %{ 13406 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13407 __ cntlzd($dst$$Register, $src$$Register); 13408 %} 13409 ins_pipe(pipe_class_default); 13410 %} 13411 13412 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13413 // no match-rule, false predicate 13414 effect(DEF dst, USE src); 13415 predicate(false); 13416 13417 format %{ "CNTLZD $dst, $src" %} 13418 size(4); 13419 ins_encode %{ 13420 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13421 __ cntlzd($dst$$Register, $src$$Register); 13422 %} 13423 ins_pipe(pipe_class_default); 13424 %} 13425 13426 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13427 match(Set dst (CountTrailingZerosI src)); 13428 predicate(UseCountLeadingZerosInstructionsPPC64); 13429 ins_cost(DEFAULT_COST); 13430 13431 expand %{ 13432 immI16 imm1 %{ (int)-1 %} 13433 immI16 imm2 %{ (int)32 %} 13434 immI_minus1 m1 %{ -1 %} 13435 iRegIdst tmpI1; 13436 iRegIdst tmpI2; 13437 iRegIdst tmpI3; 13438 addI_reg_imm16(tmpI1, src, imm1); 13439 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13440 countLeadingZerosI(tmpI3, tmpI2); 13441 subI_imm16_reg(dst, imm2, tmpI3); 13442 %} 13443 %} 13444 13445 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13446 match(Set dst (CountTrailingZerosL src)); 13447 predicate(UseCountLeadingZerosInstructionsPPC64); 13448 ins_cost(DEFAULT_COST); 13449 13450 expand %{ 13451 immL16 imm1 %{ (long)-1 %} 13452 immI16 imm2 %{ (int)64 %} 13453 iRegLdst tmpL1; 13454 iRegLdst tmpL2; 13455 iRegIdst tmpL3; 13456 addL_reg_imm16(tmpL1, src, imm1); 13457 andcL_reg_reg(tmpL2, tmpL1, src); 13458 countLeadingZerosL(tmpL3, tmpL2); 13459 subI_imm16_reg(dst, imm2, tmpL3); 13460 %} 13461 %} 13462 13463 // Expand nodes for byte_reverse_int. 13464 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13465 effect(DEF dst, USE src, USE pos, USE shift); 13466 predicate(false); 13467 13468 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13469 size(4); 13470 ins_encode %{ 13471 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13472 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13473 %} 13474 ins_pipe(pipe_class_default); 13475 %} 13476 13477 // As insrwi_a, but with USE_DEF. 13478 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13479 effect(USE_DEF dst, USE src, USE pos, USE shift); 13480 predicate(false); 13481 13482 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13483 size(4); 13484 ins_encode %{ 13485 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13486 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13487 %} 13488 ins_pipe(pipe_class_default); 13489 %} 13490 13491 // Just slightly faster than java implementation. 13492 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13493 match(Set dst (ReverseBytesI src)); 13494 ins_cost(7*DEFAULT_COST); 13495 13496 expand %{ 13497 immI16 imm24 %{ (int) 24 %} 13498 immI16 imm16 %{ (int) 16 %} 13499 immI16 imm8 %{ (int) 8 %} 13500 immI16 imm4 %{ (int) 4 %} 13501 immI16 imm0 %{ (int) 0 %} 13502 iRegLdst tmpI1; 13503 iRegLdst tmpI2; 13504 iRegLdst tmpI3; 13505 13506 urShiftI_reg_imm(tmpI1, src, imm24); 13507 insrwi_a(dst, tmpI1, imm24, imm8); 13508 urShiftI_reg_imm(tmpI2, src, imm16); 13509 insrwi(dst, tmpI2, imm8, imm16); 13510 urShiftI_reg_imm(tmpI3, src, imm8); 13511 insrwi(dst, tmpI3, imm8, imm8); 13512 insrwi(dst, src, imm0, imm8); 13513 %} 13514 %} 13515 13516 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13517 match(Set dst (ReverseBytesL src)); 13518 ins_cost(15*DEFAULT_COST); 13519 13520 expand %{ 13521 immI16 imm56 %{ (int) 56 %} 13522 immI16 imm48 %{ (int) 48 %} 13523 immI16 imm40 %{ (int) 40 %} 13524 immI16 imm32 %{ (int) 32 %} 13525 immI16 imm24 %{ (int) 24 %} 13526 immI16 imm16 %{ (int) 16 %} 13527 immI16 imm8 %{ (int) 8 %} 13528 immI16 imm0 %{ (int) 0 %} 13529 iRegLdst tmpL1; 13530 iRegLdst tmpL2; 13531 iRegLdst tmpL3; 13532 iRegLdst tmpL4; 13533 iRegLdst tmpL5; 13534 iRegLdst tmpL6; 13535 13536 // src : |a|b|c|d|e|f|g|h| 13537 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13538 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13539 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13540 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13541 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13542 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13543 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13544 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13545 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13546 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13547 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13548 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13549 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13550 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13551 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13552 %} 13553 %} 13554 13555 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13556 match(Set dst (ReverseBytesUS src)); 13557 ins_cost(2*DEFAULT_COST); 13558 13559 expand %{ 13560 immI16 imm16 %{ (int) 16 %} 13561 immI16 imm8 %{ (int) 8 %} 13562 13563 urShiftI_reg_imm(dst, src, imm8); 13564 insrwi(dst, src, imm16, imm8); 13565 %} 13566 %} 13567 13568 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13569 match(Set dst (ReverseBytesS src)); 13570 ins_cost(3*DEFAULT_COST); 13571 13572 expand %{ 13573 immI16 imm16 %{ (int) 16 %} 13574 immI16 imm8 %{ (int) 8 %} 13575 iRegLdst tmpI1; 13576 13577 urShiftI_reg_imm(tmpI1, src, imm8); 13578 insrwi(tmpI1, src, imm16, imm8); 13579 extsh(dst, tmpI1); 13580 %} 13581 %} 13582 13583 // Load Integer reversed byte order 13584 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13585 match(Set dst (ReverseBytesI (LoadI mem))); 13586 ins_cost(MEMORY_REF_COST); 13587 13588 size(4); 13589 ins_encode %{ 13590 __ lwbrx($dst$$Register, $mem$$Register); 13591 %} 13592 ins_pipe(pipe_class_default); 13593 %} 13594 13595 // Load Long - aligned and reversed 13596 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13597 match(Set dst (ReverseBytesL (LoadL mem))); 13598 predicate(VM_Version::has_ldbrx()); 13599 ins_cost(MEMORY_REF_COST); 13600 13601 size(4); 13602 ins_encode %{ 13603 __ ldbrx($dst$$Register, $mem$$Register); 13604 %} 13605 ins_pipe(pipe_class_default); 13606 %} 13607 13608 // Load unsigned short / char reversed byte order 13609 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13610 match(Set dst (ReverseBytesUS (LoadUS mem))); 13611 ins_cost(MEMORY_REF_COST); 13612 13613 size(4); 13614 ins_encode %{ 13615 __ lhbrx($dst$$Register, $mem$$Register); 13616 %} 13617 ins_pipe(pipe_class_default); 13618 %} 13619 13620 // Load short reversed byte order 13621 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13622 match(Set dst (ReverseBytesS (LoadS mem))); 13623 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13624 13625 size(8); 13626 ins_encode %{ 13627 __ lhbrx($dst$$Register, $mem$$Register); 13628 __ extsh($dst$$Register, $dst$$Register); 13629 %} 13630 ins_pipe(pipe_class_default); 13631 %} 13632 13633 // Store Integer reversed byte order 13634 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13635 match(Set mem (StoreI mem (ReverseBytesI src))); 13636 ins_cost(MEMORY_REF_COST); 13637 13638 size(4); 13639 ins_encode %{ 13640 __ stwbrx($src$$Register, $mem$$Register); 13641 %} 13642 ins_pipe(pipe_class_default); 13643 %} 13644 13645 // Store Long reversed byte order 13646 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13647 match(Set mem (StoreL mem (ReverseBytesL src))); 13648 predicate(VM_Version::has_stdbrx()); 13649 ins_cost(MEMORY_REF_COST); 13650 13651 size(4); 13652 ins_encode %{ 13653 __ stdbrx($src$$Register, $mem$$Register); 13654 %} 13655 ins_pipe(pipe_class_default); 13656 %} 13657 13658 // Store unsigned short / char reversed byte order 13659 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13660 match(Set mem (StoreC mem (ReverseBytesUS src))); 13661 ins_cost(MEMORY_REF_COST); 13662 13663 size(4); 13664 ins_encode %{ 13665 __ sthbrx($src$$Register, $mem$$Register); 13666 %} 13667 ins_pipe(pipe_class_default); 13668 %} 13669 13670 // Store short reversed byte order 13671 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13672 match(Set mem (StoreC mem (ReverseBytesS src))); 13673 ins_cost(MEMORY_REF_COST); 13674 13675 size(4); 13676 ins_encode %{ 13677 __ sthbrx($src$$Register, $mem$$Register); 13678 %} 13679 ins_pipe(pipe_class_default); 13680 %} 13681 13682 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13683 effect(DEF temp1, USE src); 13684 13685 size(4); 13686 ins_encode %{ 13687 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13688 %} 13689 ins_pipe(pipe_class_default); 13690 %} 13691 13692 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13693 effect(DEF dst, USE src, USE imm1); 13694 13695 size(4); 13696 ins_encode %{ 13697 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13698 %} 13699 ins_pipe(pipe_class_default); 13700 %} 13701 13702 instruct xscvdpspn_regF(vecX dst, regF src) %{ 13703 effect(DEF dst, USE src); 13704 13705 size(4); 13706 ins_encode %{ 13707 __ xscvdpspn($dst$$VectorSRegister, $src$$FloatRegister->to_vsr()); 13708 %} 13709 ins_pipe(pipe_class_default); 13710 %} 13711 13712 //---------- Replicate Vector Instructions ------------------------------------ 13713 13714 // Insrdi does replicate if src == dst. 13715 instruct repl32(iRegLdst dst) %{ 13716 predicate(false); 13717 effect(USE_DEF dst); 13718 13719 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13720 size(4); 13721 ins_encode %{ 13722 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13723 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13724 %} 13725 ins_pipe(pipe_class_default); 13726 %} 13727 13728 // Insrdi does replicate if src == dst. 13729 instruct repl48(iRegLdst dst) %{ 13730 predicate(false); 13731 effect(USE_DEF dst); 13732 13733 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13734 size(4); 13735 ins_encode %{ 13736 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13737 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13738 %} 13739 ins_pipe(pipe_class_default); 13740 %} 13741 13742 // Insrdi does replicate if src == dst. 13743 instruct repl56(iRegLdst dst) %{ 13744 predicate(false); 13745 effect(USE_DEF dst); 13746 13747 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13748 size(4); 13749 ins_encode %{ 13750 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13751 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 13752 %} 13753 ins_pipe(pipe_class_default); 13754 %} 13755 13756 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13757 match(Set dst (ReplicateB src)); 13758 predicate(n->as_Vector()->length() == 8); 13759 expand %{ 13760 moveReg(dst, src); 13761 repl56(dst); 13762 repl48(dst); 13763 repl32(dst); 13764 %} 13765 %} 13766 13767 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 13768 match(Set dst (ReplicateB zero)); 13769 predicate(n->as_Vector()->length() == 8); 13770 format %{ "LI $dst, #0 \t// replicate8B" %} 13771 size(4); 13772 ins_encode %{ 13773 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13774 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13775 %} 13776 ins_pipe(pipe_class_default); 13777 %} 13778 13779 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13780 match(Set dst (ReplicateB src)); 13781 predicate(n->as_Vector()->length() == 8); 13782 format %{ "LI $dst, #-1 \t// replicate8B" %} 13783 size(4); 13784 ins_encode %{ 13785 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13786 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13787 %} 13788 ins_pipe(pipe_class_default); 13789 %} 13790 13791 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 13792 match(Set dst (ReplicateB src)); 13793 predicate(n->as_Vector()->length() == 16); 13794 13795 expand %{ 13796 iRegLdst tmpL; 13797 vecX tmpV; 13798 immI8 imm1 %{ (int) 1 %} 13799 moveReg(tmpL, src); 13800 repl56(tmpL); 13801 repl48(tmpL); 13802 mtvsrwz(tmpV, tmpL); 13803 xxspltw(dst, tmpV, imm1); 13804 %} 13805 %} 13806 13807 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 13808 match(Set dst (ReplicateB zero)); 13809 predicate(n->as_Vector()->length() == 16); 13810 13811 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 13812 size(4); 13813 ins_encode %{ 13814 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13815 %} 13816 ins_pipe(pipe_class_default); 13817 %} 13818 13819 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 13820 match(Set dst (ReplicateB src)); 13821 predicate(n->as_Vector()->length() == 16); 13822 13823 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13824 size(4); 13825 ins_encode %{ 13826 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13827 %} 13828 ins_pipe(pipe_class_default); 13829 %} 13830 13831 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13832 match(Set dst (ReplicateS src)); 13833 predicate(n->as_Vector()->length() == 4); 13834 expand %{ 13835 moveReg(dst, src); 13836 repl48(dst); 13837 repl32(dst); 13838 %} 13839 %} 13840 13841 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 13842 match(Set dst (ReplicateS zero)); 13843 predicate(n->as_Vector()->length() == 4); 13844 format %{ "LI $dst, #0 \t// replicate4C" %} 13845 size(4); 13846 ins_encode %{ 13847 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13848 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13849 %} 13850 ins_pipe(pipe_class_default); 13851 %} 13852 13853 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13854 match(Set dst (ReplicateS src)); 13855 predicate(n->as_Vector()->length() == 4); 13856 format %{ "LI $dst, -1 \t// replicate4C" %} 13857 size(4); 13858 ins_encode %{ 13859 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13860 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13861 %} 13862 ins_pipe(pipe_class_default); 13863 %} 13864 13865 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 13866 match(Set dst (ReplicateS src)); 13867 predicate(n->as_Vector()->length() == 8); 13868 13869 expand %{ 13870 iRegLdst tmpL; 13871 vecX tmpV; 13872 immI8 zero %{ (int) 0 %} 13873 moveReg(tmpL, src); 13874 repl48(tmpL); 13875 repl32(tmpL); 13876 mtvsrd(tmpV, tmpL); 13877 xxpermdi(dst, tmpV, tmpV, zero); 13878 %} 13879 %} 13880 13881 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 13882 match(Set dst (ReplicateS zero)); 13883 predicate(n->as_Vector()->length() == 8); 13884 13885 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 13886 size(4); 13887 ins_encode %{ 13888 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13889 %} 13890 ins_pipe(pipe_class_default); 13891 %} 13892 13893 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 13894 match(Set dst (ReplicateS src)); 13895 predicate(n->as_Vector()->length() == 8); 13896 13897 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13898 size(4); 13899 ins_encode %{ 13900 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13901 %} 13902 ins_pipe(pipe_class_default); 13903 %} 13904 13905 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13906 match(Set dst (ReplicateI src)); 13907 predicate(n->as_Vector()->length() == 2); 13908 ins_cost(2 * DEFAULT_COST); 13909 expand %{ 13910 moveReg(dst, src); 13911 repl32(dst); 13912 %} 13913 %} 13914 13915 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 13916 match(Set dst (ReplicateI zero)); 13917 predicate(n->as_Vector()->length() == 2); 13918 format %{ "LI $dst, #0 \t// replicate4C" %} 13919 size(4); 13920 ins_encode %{ 13921 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13922 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13923 %} 13924 ins_pipe(pipe_class_default); 13925 %} 13926 13927 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13928 match(Set dst (ReplicateI src)); 13929 predicate(n->as_Vector()->length() == 2); 13930 format %{ "LI $dst, -1 \t// replicate4C" %} 13931 size(4); 13932 ins_encode %{ 13933 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13934 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13935 %} 13936 ins_pipe(pipe_class_default); 13937 %} 13938 13939 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 13940 match(Set dst (ReplicateI src)); 13941 predicate(n->as_Vector()->length() == 4); 13942 ins_cost(2 * DEFAULT_COST); 13943 13944 expand %{ 13945 iRegLdst tmpL; 13946 vecX tmpV; 13947 immI8 zero %{ (int) 0 %} 13948 moveReg(tmpL, src); 13949 repl32(tmpL); 13950 mtvsrd(tmpV, tmpL); 13951 xxpermdi(dst, tmpV, tmpV, zero); 13952 %} 13953 %} 13954 13955 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 13956 match(Set dst (ReplicateI zero)); 13957 predicate(n->as_Vector()->length() == 4); 13958 13959 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 13960 size(4); 13961 ins_encode %{ 13962 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13963 %} 13964 ins_pipe(pipe_class_default); 13965 %} 13966 13967 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 13968 match(Set dst (ReplicateI src)); 13969 predicate(n->as_Vector()->length() == 4); 13970 13971 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 13972 size(4); 13973 ins_encode %{ 13974 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13975 %} 13976 ins_pipe(pipe_class_default); 13977 %} 13978 13979 // Move float to int register via stack, replicate. 13980 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 13981 match(Set dst (ReplicateF src)); 13982 predicate(n->as_Vector()->length() == 2); 13983 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13984 expand %{ 13985 stackSlotL tmpS; 13986 iRegIdst tmpI; 13987 moveF2I_reg_stack(tmpS, src); // Move float to stack. 13988 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 13989 moveReg(dst, tmpI); // Move int to long reg. 13990 repl32(dst); // Replicate bitpattern. 13991 %} 13992 %} 13993 13994 // Replicate scalar constant to packed float values in Double register 13995 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 13996 match(Set dst (ReplicateF src)); 13997 predicate(n->as_Vector()->length() == 2); 13998 ins_cost(5 * DEFAULT_COST); 13999 14000 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 14001 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 14002 %} 14003 14004 // Replicate scalar zero constant to packed float values in Double register 14005 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 14006 match(Set dst (ReplicateF zero)); 14007 predicate(n->as_Vector()->length() == 2); 14008 14009 format %{ "LI $dst, #0 \t// replicate2F" %} 14010 ins_encode %{ 14011 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14012 __ li($dst$$Register, 0x0); 14013 %} 14014 ins_pipe(pipe_class_default); 14015 %} 14016 14017 14018 //----------Vector Arithmetic Instructions-------------------------------------- 14019 14020 // Vector Addition Instructions 14021 14022 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{ 14023 match(Set dst (AddVB src1 src2)); 14024 predicate(n->as_Vector()->length() == 16); 14025 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %} 14026 size(4); 14027 ins_encode %{ 14028 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14029 %} 14030 ins_pipe(pipe_class_default); 14031 %} 14032 14033 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{ 14034 match(Set dst (AddVS src1 src2)); 14035 predicate(n->as_Vector()->length() == 8); 14036 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %} 14037 size(4); 14038 ins_encode %{ 14039 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14040 %} 14041 ins_pipe(pipe_class_default); 14042 %} 14043 14044 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{ 14045 match(Set dst (AddVI src1 src2)); 14046 predicate(n->as_Vector()->length() == 4); 14047 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %} 14048 size(4); 14049 ins_encode %{ 14050 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14051 %} 14052 ins_pipe(pipe_class_default); 14053 %} 14054 14055 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{ 14056 match(Set dst (AddVF src1 src2)); 14057 predicate(n->as_Vector()->length() == 4); 14058 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %} 14059 size(4); 14060 ins_encode %{ 14061 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14062 %} 14063 ins_pipe(pipe_class_default); 14064 %} 14065 14066 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{ 14067 match(Set dst (AddVL src1 src2)); 14068 predicate(n->as_Vector()->length() == 2); 14069 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %} 14070 size(4); 14071 ins_encode %{ 14072 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14073 %} 14074 ins_pipe(pipe_class_default); 14075 %} 14076 14077 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{ 14078 match(Set dst (AddVD src1 src2)); 14079 predicate(n->as_Vector()->length() == 2); 14080 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %} 14081 size(4); 14082 ins_encode %{ 14083 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14084 %} 14085 ins_pipe(pipe_class_default); 14086 %} 14087 14088 // Vector Subtraction Instructions 14089 14090 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{ 14091 match(Set dst (SubVB src1 src2)); 14092 predicate(n->as_Vector()->length() == 16); 14093 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %} 14094 size(4); 14095 ins_encode %{ 14096 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14097 %} 14098 ins_pipe(pipe_class_default); 14099 %} 14100 14101 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{ 14102 match(Set dst (SubVS src1 src2)); 14103 predicate(n->as_Vector()->length() == 8); 14104 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %} 14105 size(4); 14106 ins_encode %{ 14107 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14108 %} 14109 ins_pipe(pipe_class_default); 14110 %} 14111 14112 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{ 14113 match(Set dst (SubVI src1 src2)); 14114 predicate(n->as_Vector()->length() == 4); 14115 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %} 14116 size(4); 14117 ins_encode %{ 14118 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14119 %} 14120 ins_pipe(pipe_class_default); 14121 %} 14122 14123 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{ 14124 match(Set dst (SubVF src1 src2)); 14125 predicate(n->as_Vector()->length() == 4); 14126 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %} 14127 size(4); 14128 ins_encode %{ 14129 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14130 %} 14131 ins_pipe(pipe_class_default); 14132 %} 14133 14134 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{ 14135 match(Set dst (SubVL src1 src2)); 14136 predicate(n->as_Vector()->length() == 2); 14137 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %} 14138 size(4); 14139 ins_encode %{ 14140 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14141 %} 14142 ins_pipe(pipe_class_default); 14143 %} 14144 14145 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{ 14146 match(Set dst (SubVD src1 src2)); 14147 predicate(n->as_Vector()->length() == 2); 14148 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %} 14149 size(4); 14150 ins_encode %{ 14151 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14152 %} 14153 ins_pipe(pipe_class_default); 14154 %} 14155 14156 // Vector Multiplication Instructions 14157 14158 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 14159 match(Set dst (MulVS src1 src2)); 14160 predicate(n->as_Vector()->length() == 8); 14161 effect(TEMP tmp); 14162 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %} 14163 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %} 14164 size(8); 14165 ins_encode %{ 14166 __ vspltish($tmp$$VectorSRegister->to_vr(), 0); 14167 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr()); 14168 %} 14169 ins_pipe(pipe_class_default); 14170 %} 14171 14172 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{ 14173 match(Set dst (MulVI src1 src2)); 14174 predicate(n->as_Vector()->length() == 4); 14175 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %} 14176 size(4); 14177 ins_encode %{ 14178 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14179 %} 14180 ins_pipe(pipe_class_default); 14181 %} 14182 14183 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{ 14184 match(Set dst (MulVF src1 src2)); 14185 predicate(n->as_Vector()->length() == 4); 14186 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %} 14187 size(4); 14188 ins_encode %{ 14189 __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14190 %} 14191 ins_pipe(pipe_class_default); 14192 %} 14193 14194 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{ 14195 match(Set dst (MulVD src1 src2)); 14196 predicate(n->as_Vector()->length() == 2); 14197 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %} 14198 size(4); 14199 ins_encode %{ 14200 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14201 %} 14202 ins_pipe(pipe_class_default); 14203 %} 14204 14205 // Vector Division Instructions 14206 14207 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{ 14208 match(Set dst (DivVF src1 src2)); 14209 predicate(n->as_Vector()->length() == 4); 14210 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %} 14211 size(4); 14212 ins_encode %{ 14213 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14214 %} 14215 ins_pipe(pipe_class_default); 14216 %} 14217 14218 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ 14219 match(Set dst (DivVD src1 src2)); 14220 predicate(n->as_Vector()->length() == 2); 14221 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %} 14222 size(4); 14223 ins_encode %{ 14224 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14225 %} 14226 ins_pipe(pipe_class_default); 14227 %} 14228 14229 // Vector Absolute Instructions 14230 14231 instruct vabs4F_reg(vecX dst, vecX src) %{ 14232 match(Set dst (AbsVF src)); 14233 predicate(n->as_Vector()->length() == 4); 14234 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %} 14235 size(4); 14236 ins_encode %{ 14237 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister); 14238 %} 14239 ins_pipe(pipe_class_default); 14240 %} 14241 14242 instruct vabs2D_reg(vecX dst, vecX src) %{ 14243 match(Set dst (AbsVD src)); 14244 predicate(n->as_Vector()->length() == 2); 14245 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %} 14246 size(4); 14247 ins_encode %{ 14248 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister); 14249 %} 14250 ins_pipe(pipe_class_default); 14251 %} 14252 14253 // Vector Negate Instructions 14254 14255 instruct vneg4F_reg(vecX dst, vecX src) %{ 14256 match(Set dst (NegVF src)); 14257 predicate(n->as_Vector()->length() == 4); 14258 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %} 14259 size(4); 14260 ins_encode %{ 14261 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister); 14262 %} 14263 ins_pipe(pipe_class_default); 14264 %} 14265 14266 instruct vneg2D_reg(vecX dst, vecX src) %{ 14267 match(Set dst (NegVD src)); 14268 predicate(n->as_Vector()->length() == 2); 14269 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %} 14270 size(4); 14271 ins_encode %{ 14272 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister); 14273 %} 14274 ins_pipe(pipe_class_default); 14275 %} 14276 14277 // Vector Square Root Instructions 14278 14279 instruct vsqrt4F_reg(vecX dst, vecX src) %{ 14280 match(Set dst (SqrtVF src)); 14281 predicate(n->as_Vector()->length() == 4); 14282 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %} 14283 size(4); 14284 ins_encode %{ 14285 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister); 14286 %} 14287 ins_pipe(pipe_class_default); 14288 %} 14289 14290 instruct vsqrt2D_reg(vecX dst, vecX src) %{ 14291 match(Set dst (SqrtVD src)); 14292 predicate(n->as_Vector()->length() == 2); 14293 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %} 14294 size(4); 14295 ins_encode %{ 14296 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister); 14297 %} 14298 ins_pipe(pipe_class_default); 14299 %} 14300 14301 // Vector Population Count Instructions 14302 14303 instruct vpopcnt4I_reg(vecX dst, vecX src) %{ 14304 match(Set dst (PopCountVI src)); 14305 predicate(n->as_Vector()->length() == 4); 14306 format %{ "VPOPCNTW $dst,$src\t// pop count packed4I" %} 14307 size(4); 14308 ins_encode %{ 14309 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14310 %} 14311 ins_pipe(pipe_class_default); 14312 %} 14313 14314 14315 //----------Overflow Math Instructions----------------------------------------- 14316 14317 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 14318 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14319 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14320 14321 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14322 match(Set cr0 (OverflowAddL op1 op2)); 14323 14324 format %{ "add_ $op1, $op2\t# overflow check long" %} 14325 ins_encode %{ 14326 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14327 __ li(R0, 0); 14328 __ mtxer(R0); // clear XER.SO 14329 __ addo_(R0, $op1$$Register, $op2$$Register); 14330 %} 14331 ins_pipe(pipe_class_default); 14332 %} 14333 14334 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14335 match(Set cr0 (OverflowSubL op1 op2)); 14336 14337 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14338 ins_encode %{ 14339 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14340 __ li(R0, 0); 14341 __ mtxer(R0); // clear XER.SO 14342 __ subfo_(R0, $op2$$Register, $op1$$Register); 14343 %} 14344 ins_pipe(pipe_class_default); 14345 %} 14346 14347 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14348 match(Set cr0 (OverflowSubL zero op2)); 14349 14350 format %{ "nego_ R0, $op2\t# overflow check long" %} 14351 ins_encode %{ 14352 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14353 __ li(R0, 0); 14354 __ mtxer(R0); // clear XER.SO 14355 __ nego_(R0, $op2$$Register); 14356 %} 14357 ins_pipe(pipe_class_default); 14358 %} 14359 14360 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14361 match(Set cr0 (OverflowMulL op1 op2)); 14362 14363 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14364 ins_encode %{ 14365 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14366 __ li(R0, 0); 14367 __ mtxer(R0); // clear XER.SO 14368 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14369 %} 14370 ins_pipe(pipe_class_default); 14371 %} 14372 14373 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14374 match(Set dst (ReplicateF src)); 14375 predicate(n->as_Vector()->length() == 4); 14376 ins_cost(DEFAULT_COST); 14377 expand %{ 14378 vecX tmpV; 14379 immI8 zero %{ (int) 0 %} 14380 14381 xscvdpspn_regF(tmpV, src); 14382 xxspltw(dst, tmpV, zero); 14383 %} 14384 %} 14385 14386 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14387 match(Set dst (ReplicateF src)); 14388 predicate(n->as_Vector()->length() == 4); 14389 effect(TEMP tmp); 14390 ins_cost(10 * DEFAULT_COST); 14391 14392 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14393 %} 14394 14395 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14396 match(Set dst (ReplicateF zero)); 14397 predicate(n->as_Vector()->length() == 4); 14398 14399 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14400 ins_encode %{ 14401 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14402 %} 14403 ins_pipe(pipe_class_default); 14404 %} 14405 14406 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14407 match(Set dst (ReplicateD src)); 14408 predicate(n->as_Vector()->length() == 2); 14409 14410 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Permute 16-byte register"%} 14411 size(4); 14412 ins_encode %{ 14413 __ xxpermdi($dst$$VectorSRegister, $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0); 14414 %} 14415 ins_pipe(pipe_class_default); 14416 %} 14417 14418 instruct repl2D_immI0(vecX dst, immI_0 zero) %{ 14419 match(Set dst (ReplicateD zero)); 14420 predicate(n->as_Vector()->length() == 2); 14421 14422 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14423 size(4); 14424 ins_encode %{ 14425 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14426 %} 14427 ins_pipe(pipe_class_default); 14428 %} 14429 14430 instruct repl2D_immIminus1(vecX dst, immI_minus1 src) %{ 14431 match(Set dst (ReplicateD src)); 14432 predicate(n->as_Vector()->length() == 2); 14433 14434 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14435 size(4); 14436 ins_encode %{ 14437 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14438 %} 14439 ins_pipe(pipe_class_default); 14440 %} 14441 14442 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14443 predicate(false); 14444 effect(DEF dst, USE src); 14445 14446 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register"%} 14447 size(4); 14448 ins_encode %{ 14449 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14450 %} 14451 ins_pipe(pipe_class_default); 14452 %} 14453 14454 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14455 effect(DEF dst, USE src, USE zero); 14456 14457 format %{ "XXSPLATD $dst, $src, $zero \t// Permute 16-byte register"%} 14458 size(4); 14459 ins_encode %{ 14460 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14461 %} 14462 ins_pipe(pipe_class_default); 14463 %} 14464 14465 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14466 effect(DEF dst, USE src1, USE src2, USE zero); 14467 14468 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Permute 16-byte register"%} 14469 size(4); 14470 ins_encode %{ 14471 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14472 %} 14473 ins_pipe(pipe_class_default); 14474 %} 14475 14476 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14477 match(Set dst (ReplicateL src)); 14478 predicate(n->as_Vector()->length() == 2); 14479 expand %{ 14480 vecX tmpV; 14481 immI8 zero %{ (int) 0 %} 14482 mtvsrd(tmpV, src); 14483 xxpermdi(dst, tmpV, tmpV, zero); 14484 %} 14485 %} 14486 14487 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14488 match(Set dst (ReplicateL zero)); 14489 predicate(n->as_Vector()->length() == 2); 14490 14491 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14492 size(4); 14493 ins_encode %{ 14494 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14495 %} 14496 ins_pipe(pipe_class_default); 14497 %} 14498 14499 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14500 match(Set dst (ReplicateL src)); 14501 predicate(n->as_Vector()->length() == 2); 14502 14503 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14504 size(4); 14505 ins_encode %{ 14506 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14507 %} 14508 ins_pipe(pipe_class_default); 14509 %} 14510 14511 // ============================================================================ 14512 // Safepoint Instruction 14513 14514 instruct safePoint_poll(iRegPdst poll) %{ 14515 match(SafePoint poll); 14516 14517 // It caused problems to add the effect that r0 is killed, but this 14518 // effect no longer needs to be mentioned, since r0 is not contained 14519 // in a reg_class. 14520 14521 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14522 size(4); 14523 ins_encode( enc_poll(0x0, poll) ); 14524 ins_pipe(pipe_class_default); 14525 %} 14526 14527 // ============================================================================ 14528 // Call Instructions 14529 14530 // Call Java Static Instruction 14531 14532 // Schedulable version of call static node. 14533 instruct CallStaticJavaDirect(method meth) %{ 14534 match(CallStaticJava); 14535 effect(USE meth); 14536 ins_cost(CALL_COST); 14537 14538 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14539 14540 format %{ "CALL,static $meth \t// ==> " %} 14541 size(4); 14542 ins_encode( enc_java_static_call(meth) ); 14543 ins_pipe(pipe_class_call); 14544 %} 14545 14546 // Call Java Dynamic Instruction 14547 14548 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14549 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14550 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14551 // The call destination must still be placed in the constant pool. 14552 instruct CallDynamicJavaDirectSched(method meth) %{ 14553 match(CallDynamicJava); // To get all the data fields we need ... 14554 effect(USE meth); 14555 predicate(false); // ... but never match. 14556 14557 ins_field_load_ic_hi_node(loadConL_hiNode*); 14558 ins_field_load_ic_node(loadConLNode*); 14559 ins_num_consts(1 /* 1 patchable constant: call destination */); 14560 14561 format %{ "BL \t// dynamic $meth ==> " %} 14562 size(4); 14563 ins_encode( enc_java_dynamic_call_sched(meth) ); 14564 ins_pipe(pipe_class_call); 14565 %} 14566 14567 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14568 // We use postalloc expanded calls if we use inline caches 14569 // and do not update method data. 14570 // 14571 // This instruction has two constants: inline cache (IC) and call destination. 14572 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14573 // one constant. 14574 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14575 match(CallDynamicJava); 14576 effect(USE meth); 14577 predicate(UseInlineCaches); 14578 ins_cost(CALL_COST); 14579 14580 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14581 14582 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14583 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14584 %} 14585 14586 // Compound version of call dynamic java 14587 // We use postalloc expanded calls if we use inline caches 14588 // and do not update method data. 14589 instruct CallDynamicJavaDirect(method meth) %{ 14590 match(CallDynamicJava); 14591 effect(USE meth); 14592 predicate(!UseInlineCaches); 14593 ins_cost(CALL_COST); 14594 14595 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14596 ins_num_consts(4); 14597 14598 format %{ "CALL,dynamic $meth \t// ==> " %} 14599 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14600 ins_pipe(pipe_class_call); 14601 %} 14602 14603 // Call Runtime Instruction 14604 14605 instruct CallRuntimeDirect(method meth) %{ 14606 match(CallRuntime); 14607 effect(USE meth); 14608 ins_cost(CALL_COST); 14609 14610 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14611 // env for callee, C-toc. 14612 ins_num_consts(3); 14613 14614 format %{ "CALL,runtime" %} 14615 ins_encode( enc_java_to_runtime_call(meth) ); 14616 ins_pipe(pipe_class_call); 14617 %} 14618 14619 // Call Leaf 14620 14621 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14622 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14623 effect(DEF dst, USE src); 14624 14625 ins_num_consts(1); 14626 14627 format %{ "MTCTR $src" %} 14628 size(4); 14629 ins_encode( enc_leaf_call_mtctr(src) ); 14630 ins_pipe(pipe_class_default); 14631 %} 14632 14633 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 14634 instruct CallLeafDirect(method meth) %{ 14635 match(CallLeaf); // To get the data all the data fields we need ... 14636 effect(USE meth); 14637 predicate(false); // but never match. 14638 14639 format %{ "BCTRL \t// leaf call $meth ==> " %} 14640 size(4); 14641 ins_encode %{ 14642 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 14643 __ bctrl(); 14644 %} 14645 ins_pipe(pipe_class_call); 14646 %} 14647 14648 // postalloc expand of CallLeafDirect. 14649 // Load adress to call from TOC, then bl to it. 14650 instruct CallLeafDirect_Ex(method meth) %{ 14651 match(CallLeaf); 14652 effect(USE meth); 14653 ins_cost(CALL_COST); 14654 14655 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14656 // env for callee, C-toc. 14657 ins_num_consts(3); 14658 14659 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14660 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14661 %} 14662 14663 // Call runtime without safepoint - same as CallLeaf. 14664 // postalloc expand of CallLeafNoFPDirect. 14665 // Load adress to call from TOC, then bl to it. 14666 instruct CallLeafNoFPDirect_Ex(method meth) %{ 14667 match(CallLeafNoFP); 14668 effect(USE meth); 14669 ins_cost(CALL_COST); 14670 14671 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14672 // env for callee, C-toc. 14673 ins_num_consts(3); 14674 14675 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14676 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14677 %} 14678 14679 // Tail Call; Jump from runtime stub to Java code. 14680 // Also known as an 'interprocedural jump'. 14681 // Target of jump will eventually return to caller. 14682 // TailJump below removes the return address. 14683 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 14684 match(TailCall jump_target method_oop); 14685 ins_cost(CALL_COST); 14686 14687 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 14688 "BCTR \t// tail call" %} 14689 size(8); 14690 ins_encode %{ 14691 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14692 __ mtctr($jump_target$$Register); 14693 __ bctr(); 14694 %} 14695 ins_pipe(pipe_class_call); 14696 %} 14697 14698 // Return Instruction 14699 instruct Ret() %{ 14700 match(Return); 14701 format %{ "BLR \t// branch to link register" %} 14702 size(4); 14703 ins_encode %{ 14704 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 14705 // LR is restored in MachEpilogNode. Just do the RET here. 14706 __ blr(); 14707 %} 14708 ins_pipe(pipe_class_default); 14709 %} 14710 14711 // Tail Jump; remove the return address; jump to target. 14712 // TailCall above leaves the return address around. 14713 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14714 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14715 // "restore" before this instruction (in Epilogue), we need to materialize it 14716 // in %i0. 14717 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14718 match(TailJump jump_target ex_oop); 14719 ins_cost(CALL_COST); 14720 14721 format %{ "LD R4_ARG2 = LR\n\t" 14722 "MTCTR $jump_target\n\t" 14723 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14724 size(12); 14725 ins_encode %{ 14726 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14727 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 14728 __ mtctr($jump_target$$Register); 14729 __ bctr(); 14730 %} 14731 ins_pipe(pipe_class_call); 14732 %} 14733 14734 // Create exception oop: created by stack-crawling runtime code. 14735 // Created exception is now available to this handler, and is setup 14736 // just prior to jumping to this handler. No code emitted. 14737 instruct CreateException(rarg1RegP ex_oop) %{ 14738 match(Set ex_oop (CreateEx)); 14739 ins_cost(0); 14740 14741 format %{ " -- \t// exception oop; no code emitted" %} 14742 size(0); 14743 ins_encode( /*empty*/ ); 14744 ins_pipe(pipe_class_default); 14745 %} 14746 14747 // Rethrow exception: The exception oop will come in the first 14748 // argument position. Then JUMP (not call) to the rethrow stub code. 14749 instruct RethrowException() %{ 14750 match(Rethrow); 14751 ins_cost(CALL_COST); 14752 14753 format %{ "Jmp rethrow_stub" %} 14754 ins_encode %{ 14755 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14756 cbuf.set_insts_mark(); 14757 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 14758 %} 14759 ins_pipe(pipe_class_call); 14760 %} 14761 14762 // Die now. 14763 instruct ShouldNotReachHere() %{ 14764 match(Halt); 14765 ins_cost(CALL_COST); 14766 14767 format %{ "ShouldNotReachHere" %} 14768 size(4); 14769 ins_encode %{ 14770 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 14771 __ trap_should_not_reach_here(); 14772 %} 14773 ins_pipe(pipe_class_default); 14774 %} 14775 14776 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 14777 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 14778 // Get a DEF on threadRegP, no costs, no encoding, use 14779 // 'ins_should_rematerialize(true)' to avoid spilling. 14780 instruct tlsLoadP(threadRegP dst) %{ 14781 match(Set dst (ThreadLocal)); 14782 ins_cost(0); 14783 14784 ins_should_rematerialize(true); 14785 14786 format %{ " -- \t// $dst=Thread::current(), empty" %} 14787 size(0); 14788 ins_encode( /*empty*/ ); 14789 ins_pipe(pipe_class_empty); 14790 %} 14791 14792 //---Some PPC specific nodes--------------------------------------------------- 14793 14794 // Stop a group. 14795 instruct endGroup() %{ 14796 ins_cost(0); 14797 14798 ins_is_nop(true); 14799 14800 format %{ "End Bundle (ori r1, r1, 0)" %} 14801 size(4); 14802 ins_encode %{ 14803 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 14804 __ endgroup(); 14805 %} 14806 ins_pipe(pipe_class_default); 14807 %} 14808 14809 // Nop instructions 14810 14811 instruct fxNop() %{ 14812 ins_cost(0); 14813 14814 ins_is_nop(true); 14815 14816 format %{ "fxNop" %} 14817 size(4); 14818 ins_encode %{ 14819 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14820 __ nop(); 14821 %} 14822 ins_pipe(pipe_class_default); 14823 %} 14824 14825 instruct fpNop0() %{ 14826 ins_cost(0); 14827 14828 ins_is_nop(true); 14829 14830 format %{ "fpNop0" %} 14831 size(4); 14832 ins_encode %{ 14833 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14834 __ fpnop0(); 14835 %} 14836 ins_pipe(pipe_class_default); 14837 %} 14838 14839 instruct fpNop1() %{ 14840 ins_cost(0); 14841 14842 ins_is_nop(true); 14843 14844 format %{ "fpNop1" %} 14845 size(4); 14846 ins_encode %{ 14847 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14848 __ fpnop1(); 14849 %} 14850 ins_pipe(pipe_class_default); 14851 %} 14852 14853 instruct brNop0() %{ 14854 ins_cost(0); 14855 size(4); 14856 format %{ "brNop0" %} 14857 ins_encode %{ 14858 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14859 __ brnop0(); 14860 %} 14861 ins_is_nop(true); 14862 ins_pipe(pipe_class_default); 14863 %} 14864 14865 instruct brNop1() %{ 14866 ins_cost(0); 14867 14868 ins_is_nop(true); 14869 14870 format %{ "brNop1" %} 14871 size(4); 14872 ins_encode %{ 14873 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14874 __ brnop1(); 14875 %} 14876 ins_pipe(pipe_class_default); 14877 %} 14878 14879 instruct brNop2() %{ 14880 ins_cost(0); 14881 14882 ins_is_nop(true); 14883 14884 format %{ "brNop2" %} 14885 size(4); 14886 ins_encode %{ 14887 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14888 __ brnop2(); 14889 %} 14890 ins_pipe(pipe_class_default); 14891 %} 14892 14893 //----------PEEPHOLE RULES----------------------------------------------------- 14894 // These must follow all instruction definitions as they use the names 14895 // defined in the instructions definitions. 14896 // 14897 // peepmatch ( root_instr_name [preceeding_instruction]* ); 14898 // 14899 // peepconstraint %{ 14900 // (instruction_number.operand_name relational_op instruction_number.operand_name 14901 // [, ...] ); 14902 // // instruction numbers are zero-based using left to right order in peepmatch 14903 // 14904 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14905 // // provide an instruction_number.operand_name for each operand that appears 14906 // // in the replacement instruction's match rule 14907 // 14908 // ---------VM FLAGS--------------------------------------------------------- 14909 // 14910 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14911 // 14912 // Each peephole rule is given an identifying number starting with zero and 14913 // increasing by one in the order seen by the parser. An individual peephole 14914 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14915 // on the command-line. 14916 // 14917 // ---------CURRENT LIMITATIONS---------------------------------------------- 14918 // 14919 // Only match adjacent instructions in same basic block 14920 // Only equality constraints 14921 // Only constraints between operands, not (0.dest_reg == EAX_enc) 14922 // Only one replacement instruction 14923 // 14924 // ---------EXAMPLE---------------------------------------------------------- 14925 // 14926 // // pertinent parts of existing instructions in architecture description 14927 // instruct movI(eRegI dst, eRegI src) %{ 14928 // match(Set dst (CopyI src)); 14929 // %} 14930 // 14931 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 14932 // match(Set dst (AddI dst src)); 14933 // effect(KILL cr); 14934 // %} 14935 // 14936 // // Change (inc mov) to lea 14937 // peephole %{ 14938 // // increment preceeded by register-register move 14939 // peepmatch ( incI_eReg movI ); 14940 // // require that the destination register of the increment 14941 // // match the destination register of the move 14942 // peepconstraint ( 0.dst == 1.dst ); 14943 // // construct a replacement instruction that sets 14944 // // the destination to ( move's source register + one ) 14945 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14946 // %} 14947 // 14948 // Implementation no longer uses movX instructions since 14949 // machine-independent system no longer uses CopyX nodes. 14950 // 14951 // peephole %{ 14952 // peepmatch ( incI_eReg movI ); 14953 // peepconstraint ( 0.dst == 1.dst ); 14954 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14955 // %} 14956 // 14957 // peephole %{ 14958 // peepmatch ( decI_eReg movI ); 14959 // peepconstraint ( 0.dst == 1.dst ); 14960 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14961 // %} 14962 // 14963 // peephole %{ 14964 // peepmatch ( addI_eReg_imm movI ); 14965 // peepconstraint ( 0.dst == 1.dst ); 14966 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14967 // %} 14968 // 14969 // peephole %{ 14970 // peepmatch ( addP_eReg_imm movP ); 14971 // peepconstraint ( 0.dst == 1.dst ); 14972 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 14973 // %} 14974 14975 // // Change load of spilled value to only a spill 14976 // instruct storeI(memory mem, eRegI src) %{ 14977 // match(Set mem (StoreI mem src)); 14978 // %} 14979 // 14980 // instruct loadI(eRegI dst, memory mem) %{ 14981 // match(Set dst (LoadI mem)); 14982 // %} 14983 // 14984 peephole %{ 14985 peepmatch ( loadI storeI ); 14986 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14987 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 14988 %} 14989 14990 peephole %{ 14991 peepmatch ( loadL storeL ); 14992 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14993 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 14994 %} 14995 14996 peephole %{ 14997 peepmatch ( loadP storeP ); 14998 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 14999 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 15000 %} 15001 15002 //----------SMARTSPILL RULES--------------------------------------------------- 15003 // These must follow all instruction definitions as they use the names 15004 // defined in the instructions definitions.