1 // 2 // Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2018 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 if (!UseCountLeadingZerosInstructionsPPC64) 2213 return false; 2214 break; 2215 case Op_CountTrailingZerosI: 2216 case Op_CountTrailingZerosL: 2217 if (!UseCountLeadingZerosInstructionsPPC64 && 2218 !UseCountTrailingZerosInstructionsPPC64) 2219 return false; 2220 break; 2221 2222 case Op_PopCountI: 2223 case Op_PopCountL: 2224 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2225 2226 case Op_StrComp: 2227 return SpecialStringCompareTo; 2228 case Op_StrEquals: 2229 return SpecialStringEquals; 2230 case Op_StrIndexOf: 2231 case Op_StrIndexOfChar: 2232 return SpecialStringIndexOf; 2233 case Op_AddVB: 2234 case Op_AddVS: 2235 case Op_AddVI: 2236 case Op_AddVF: 2237 case Op_AddVD: 2238 case Op_SubVB: 2239 case Op_SubVS: 2240 case Op_SubVI: 2241 case Op_SubVF: 2242 case Op_SubVD: 2243 case Op_MulVS: 2244 case Op_MulVF: 2245 case Op_MulVD: 2246 case Op_DivVF: 2247 case Op_DivVD: 2248 case Op_AbsVF: 2249 case Op_AbsVD: 2250 case Op_NegVF: 2251 case Op_NegVD: 2252 case Op_SqrtVF: 2253 case Op_SqrtVD: 2254 case Op_AddVL: 2255 case Op_SubVL: 2256 case Op_MulVI: 2257 return SuperwordUseVSX; 2258 case Op_PopCountVI: 2259 return (SuperwordUseVSX && UsePopCountInstruction); 2260 } 2261 2262 return true; // Per default match rules are supported. 2263 } 2264 2265 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2266 2267 // TODO 2268 // identify extra cases that we might want to provide match rules for 2269 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2270 bool ret_value = match_rule_supported(opcode); 2271 // Add rules here. 2272 2273 return ret_value; // Per default match rules are supported. 2274 } 2275 2276 const bool Matcher::has_predicated_vectors(void) { 2277 return false; 2278 } 2279 2280 const int Matcher::float_pressure(int default_pressure_threshold) { 2281 return default_pressure_threshold; 2282 } 2283 2284 int Matcher::regnum_to_fpu_offset(int regnum) { 2285 // No user for this method? 2286 Unimplemented(); 2287 return 999; 2288 } 2289 2290 const bool Matcher::convL2FSupported(void) { 2291 // fcfids can do the conversion (>= Power7). 2292 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2293 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2294 } 2295 2296 // Vector width in bytes. 2297 const int Matcher::vector_width_in_bytes(BasicType bt) { 2298 if (SuperwordUseVSX) { 2299 assert(MaxVectorSize == 16, ""); 2300 return 16; 2301 } else { 2302 assert(MaxVectorSize == 8, ""); 2303 return 8; 2304 } 2305 } 2306 2307 // Vector ideal reg. 2308 const uint Matcher::vector_ideal_reg(int size) { 2309 if (SuperwordUseVSX) { 2310 assert(MaxVectorSize == 16 && size == 16, ""); 2311 return Op_VecX; 2312 } else { 2313 assert(MaxVectorSize == 8 && size == 8, ""); 2314 return Op_RegL; 2315 } 2316 } 2317 2318 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2319 fatal("vector shift is not supported"); 2320 return Node::NotAMachineReg; 2321 } 2322 2323 // Limits on vector size (number of elements) loaded into vector. 2324 const int Matcher::max_vector_size(const BasicType bt) { 2325 assert(is_java_primitive(bt), "only primitive type vectors"); 2326 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2327 } 2328 2329 const int Matcher::min_vector_size(const BasicType bt) { 2330 return max_vector_size(bt); // Same as max. 2331 } 2332 2333 // PPC doesn't support misaligned vectors store/load. 2334 const bool Matcher::misaligned_vectors_ok() { 2335 return !AlignVector; // can be changed by flag 2336 } 2337 2338 // PPC AES support not yet implemented 2339 const bool Matcher::pass_original_key_for_aes() { 2340 return false; 2341 } 2342 2343 // RETURNS: whether this branch offset is short enough that a short 2344 // branch can be used. 2345 // 2346 // If the platform does not provide any short branch variants, then 2347 // this method should return `false' for offset 0. 2348 // 2349 // `Compile::Fill_buffer' will decide on basis of this information 2350 // whether to do the pass `Compile::Shorten_branches' at all. 2351 // 2352 // And `Compile::Shorten_branches' will decide on basis of this 2353 // information whether to replace particular branch sites by short 2354 // ones. 2355 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2356 // Is the offset within the range of a ppc64 pc relative branch? 2357 bool b; 2358 2359 const int safety_zone = 3 * BytesPerInstWord; 2360 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2361 29 - 16 + 1 + 2); 2362 return b; 2363 } 2364 2365 const bool Matcher::isSimpleConstant64(jlong value) { 2366 // Probably always true, even if a temp register is required. 2367 return true; 2368 } 2369 /* TODO: PPC port 2370 // Make a new machine dependent decode node (with its operands). 2371 MachTypeNode *Matcher::make_decode_node() { 2372 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2373 "This method is only implemented for unscaled cOops mode so far"); 2374 MachTypeNode *decode = new decodeN_unscaledNode(); 2375 decode->set_opnd_array(0, new iRegPdstOper()); 2376 decode->set_opnd_array(1, new iRegNsrcOper()); 2377 return decode; 2378 } 2379 */ 2380 2381 // false => size gets scaled to BytesPerLong, ok. 2382 const bool Matcher::init_array_count_is_in_bytes = false; 2383 2384 // Use conditional move (CMOVL) on Power7. 2385 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2386 2387 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2388 // fsel doesn't accept a condition register as input, so this would be slightly different. 2389 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2390 2391 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2392 const bool Matcher::require_postalloc_expand = true; 2393 2394 // Do we need to mask the count passed to shift instructions or does 2395 // the cpu only look at the lower 5/6 bits anyway? 2396 // PowerPC requires masked shift counts. 2397 const bool Matcher::need_masked_shift_count = true; 2398 2399 // This affects two different things: 2400 // - how Decode nodes are matched 2401 // - how ImplicitNullCheck opportunities are recognized 2402 // If true, the matcher will try to remove all Decodes and match them 2403 // (as operands) into nodes. NullChecks are not prepared to deal with 2404 // Decodes by final_graph_reshaping(). 2405 // If false, final_graph_reshaping() forces the decode behind the Cmp 2406 // for a NullCheck. The matcher matches the Decode node into a register. 2407 // Implicit_null_check optimization moves the Decode along with the 2408 // memory operation back up before the NullCheck. 2409 bool Matcher::narrow_oop_use_complex_address() { 2410 // TODO: PPC port if (MatchDecodeNodes) return true; 2411 return false; 2412 } 2413 2414 bool Matcher::narrow_klass_use_complex_address() { 2415 NOT_LP64(ShouldNotCallThis()); 2416 assert(UseCompressedClassPointers, "only for compressed klass code"); 2417 // TODO: PPC port if (MatchDecodeNodes) return true; 2418 return false; 2419 } 2420 2421 bool Matcher::const_oop_prefer_decode() { 2422 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2423 return Universe::narrow_oop_base() == NULL; 2424 } 2425 2426 bool Matcher::const_klass_prefer_decode() { 2427 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2428 return Universe::narrow_klass_base() == NULL; 2429 } 2430 2431 // Is it better to copy float constants, or load them directly from memory? 2432 // Intel can load a float constant from a direct address, requiring no 2433 // extra registers. Most RISCs will have to materialize an address into a 2434 // register first, so they would do better to copy the constant from stack. 2435 const bool Matcher::rematerialize_float_constants = false; 2436 2437 // If CPU can load and store mis-aligned doubles directly then no fixup is 2438 // needed. Else we split the double into 2 integer pieces and move it 2439 // piece-by-piece. Only happens when passing doubles into C code as the 2440 // Java calling convention forces doubles to be aligned. 2441 const bool Matcher::misaligned_doubles_ok = true; 2442 2443 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2444 Unimplemented(); 2445 } 2446 2447 // Advertise here if the CPU requires explicit rounding operations 2448 // to implement the UseStrictFP mode. 2449 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2450 2451 // Do floats take an entire double register or just half? 2452 // 2453 // A float occupies a ppc64 double register. For the allocator, a 2454 // ppc64 double register appears as a pair of float registers. 2455 bool Matcher::float_in_double() { return true; } 2456 2457 // Do ints take an entire long register or just half? 2458 // The relevant question is how the int is callee-saved: 2459 // the whole long is written but de-opt'ing will have to extract 2460 // the relevant 32 bits. 2461 const bool Matcher::int_in_long = true; 2462 2463 // Constants for c2c and c calling conventions. 2464 2465 const MachRegisterNumbers iarg_reg[8] = { 2466 R3_num, R4_num, R5_num, R6_num, 2467 R7_num, R8_num, R9_num, R10_num 2468 }; 2469 2470 const MachRegisterNumbers farg_reg[13] = { 2471 F1_num, F2_num, F3_num, F4_num, 2472 F5_num, F6_num, F7_num, F8_num, 2473 F9_num, F10_num, F11_num, F12_num, 2474 F13_num 2475 }; 2476 2477 const MachRegisterNumbers vsarg_reg[64] = { 2478 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2479 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2480 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2481 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2482 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2483 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2484 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2485 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2486 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2487 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2488 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2489 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2490 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2491 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2492 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2493 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2494 }; 2495 2496 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2497 2498 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2499 2500 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2501 2502 // Return whether or not this register is ever used as an argument. This 2503 // function is used on startup to build the trampoline stubs in generateOptoStub. 2504 // Registers not mentioned will be killed by the VM call in the trampoline, and 2505 // arguments in those registers not be available to the callee. 2506 bool Matcher::can_be_java_arg(int reg) { 2507 // We return true for all registers contained in iarg_reg[] and 2508 // farg_reg[] and their virtual halves. 2509 // We must include the virtual halves in order to get STDs and LDs 2510 // instead of STWs and LWs in the trampoline stubs. 2511 2512 if ( reg == R3_num || reg == R3_H_num 2513 || reg == R4_num || reg == R4_H_num 2514 || reg == R5_num || reg == R5_H_num 2515 || reg == R6_num || reg == R6_H_num 2516 || reg == R7_num || reg == R7_H_num 2517 || reg == R8_num || reg == R8_H_num 2518 || reg == R9_num || reg == R9_H_num 2519 || reg == R10_num || reg == R10_H_num) 2520 return true; 2521 2522 if ( reg == F1_num || reg == F1_H_num 2523 || reg == F2_num || reg == F2_H_num 2524 || reg == F3_num || reg == F3_H_num 2525 || reg == F4_num || reg == F4_H_num 2526 || reg == F5_num || reg == F5_H_num 2527 || reg == F6_num || reg == F6_H_num 2528 || reg == F7_num || reg == F7_H_num 2529 || reg == F8_num || reg == F8_H_num 2530 || reg == F9_num || reg == F9_H_num 2531 || reg == F10_num || reg == F10_H_num 2532 || reg == F11_num || reg == F11_H_num 2533 || reg == F12_num || reg == F12_H_num 2534 || reg == F13_num || reg == F13_H_num) 2535 return true; 2536 2537 return false; 2538 } 2539 2540 bool Matcher::is_spillable_arg(int reg) { 2541 return can_be_java_arg(reg); 2542 } 2543 2544 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2545 return false; 2546 } 2547 2548 // Register for DIVI projection of divmodI. 2549 RegMask Matcher::divI_proj_mask() { 2550 ShouldNotReachHere(); 2551 return RegMask(); 2552 } 2553 2554 // Register for MODI projection of divmodI. 2555 RegMask Matcher::modI_proj_mask() { 2556 ShouldNotReachHere(); 2557 return RegMask(); 2558 } 2559 2560 // Register for DIVL projection of divmodL. 2561 RegMask Matcher::divL_proj_mask() { 2562 ShouldNotReachHere(); 2563 return RegMask(); 2564 } 2565 2566 // Register for MODL projection of divmodL. 2567 RegMask Matcher::modL_proj_mask() { 2568 ShouldNotReachHere(); 2569 return RegMask(); 2570 } 2571 2572 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2573 return RegMask(); 2574 } 2575 2576 const bool Matcher::convi2l_type_required = true; 2577 2578 %} 2579 2580 //----------ENCODING BLOCK----------------------------------------------------- 2581 // This block specifies the encoding classes used by the compiler to output 2582 // byte streams. Encoding classes are parameterized macros used by 2583 // Machine Instruction Nodes in order to generate the bit encoding of the 2584 // instruction. Operands specify their base encoding interface with the 2585 // interface keyword. There are currently supported four interfaces, 2586 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2587 // operand to generate a function which returns its register number when 2588 // queried. CONST_INTER causes an operand to generate a function which 2589 // returns the value of the constant when queried. MEMORY_INTER causes an 2590 // operand to generate four functions which return the Base Register, the 2591 // Index Register, the Scale Value, and the Offset Value of the operand when 2592 // queried. COND_INTER causes an operand to generate six functions which 2593 // return the encoding code (ie - encoding bits for the instruction) 2594 // associated with each basic boolean condition for a conditional instruction. 2595 // 2596 // Instructions specify two basic values for encoding. Again, a function 2597 // is available to check if the constant displacement is an oop. They use the 2598 // ins_encode keyword to specify their encoding classes (which must be 2599 // a sequence of enc_class names, and their parameters, specified in 2600 // the encoding block), and they use the 2601 // opcode keyword to specify, in order, their primary, secondary, and 2602 // tertiary opcode. Only the opcode sections which a particular instruction 2603 // needs for encoding need to be specified. 2604 encode %{ 2605 enc_class enc_unimplemented %{ 2606 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2607 MacroAssembler _masm(&cbuf); 2608 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2609 %} 2610 2611 enc_class enc_untested %{ 2612 #ifdef ASSERT 2613 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2614 MacroAssembler _masm(&cbuf); 2615 __ untested("Untested mach node encoding in AD file."); 2616 #else 2617 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2618 #endif 2619 %} 2620 2621 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2622 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2623 MacroAssembler _masm(&cbuf); 2624 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2625 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2626 %} 2627 2628 // Load acquire. 2629 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2630 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2631 MacroAssembler _masm(&cbuf); 2632 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2633 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2634 __ twi_0($dst$$Register); 2635 __ isync(); 2636 %} 2637 2638 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2639 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2640 2641 MacroAssembler _masm(&cbuf); 2642 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2643 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2644 %} 2645 2646 // Load acquire. 2647 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2648 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2649 2650 MacroAssembler _masm(&cbuf); 2651 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2652 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2653 __ twi_0($dst$$Register); 2654 __ isync(); 2655 %} 2656 2657 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2658 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2659 2660 MacroAssembler _masm(&cbuf); 2661 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2662 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2663 %} 2664 2665 // Load acquire. 2666 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2667 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2668 2669 MacroAssembler _masm(&cbuf); 2670 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2671 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2672 __ twi_0($dst$$Register); 2673 __ isync(); 2674 %} 2675 2676 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2677 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2678 MacroAssembler _masm(&cbuf); 2679 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2680 // Operand 'ds' requires 4-alignment. 2681 assert((Idisp & 0x3) == 0, "unaligned offset"); 2682 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2683 %} 2684 2685 // Load acquire. 2686 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2687 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2688 MacroAssembler _masm(&cbuf); 2689 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2690 // Operand 'ds' requires 4-alignment. 2691 assert((Idisp & 0x3) == 0, "unaligned offset"); 2692 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2693 __ twi_0($dst$$Register); 2694 __ isync(); 2695 %} 2696 2697 enc_class enc_lfd(RegF dst, memory mem) %{ 2698 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2699 MacroAssembler _masm(&cbuf); 2700 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2701 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2702 %} 2703 2704 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2705 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2706 2707 MacroAssembler _masm(&cbuf); 2708 int toc_offset = 0; 2709 2710 address const_toc_addr; 2711 // Create a non-oop constant, no relocation needed. 2712 // If it is an IC, it has a virtual_call_Relocation. 2713 const_toc_addr = __ long_constant((jlong)$src$$constant); 2714 if (const_toc_addr == NULL) { 2715 ciEnv::current()->record_out_of_memory_failure(); 2716 return; 2717 } 2718 2719 // Get the constant's TOC offset. 2720 toc_offset = __ offset_to_method_toc(const_toc_addr); 2721 2722 // Keep the current instruction offset in mind. 2723 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2724 2725 __ ld($dst$$Register, toc_offset, $toc$$Register); 2726 %} 2727 2728 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2729 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2730 2731 MacroAssembler _masm(&cbuf); 2732 2733 if (!ra_->C->in_scratch_emit_size()) { 2734 address const_toc_addr; 2735 // Create a non-oop constant, no relocation needed. 2736 // If it is an IC, it has a virtual_call_Relocation. 2737 const_toc_addr = __ long_constant((jlong)$src$$constant); 2738 if (const_toc_addr == NULL) { 2739 ciEnv::current()->record_out_of_memory_failure(); 2740 return; 2741 } 2742 2743 // Get the constant's TOC offset. 2744 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2745 // Store the toc offset of the constant. 2746 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2747 2748 // Also keep the current instruction offset in mind. 2749 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2750 } 2751 2752 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2753 %} 2754 2755 %} // encode 2756 2757 source %{ 2758 2759 typedef struct { 2760 loadConL_hiNode *_large_hi; 2761 loadConL_loNode *_large_lo; 2762 loadConLNode *_small; 2763 MachNode *_last; 2764 } loadConLNodesTuple; 2765 2766 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2767 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2768 loadConLNodesTuple nodes; 2769 2770 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2771 if (large_constant_pool) { 2772 // Create new nodes. 2773 loadConL_hiNode *m1 = new loadConL_hiNode(); 2774 loadConL_loNode *m2 = new loadConL_loNode(); 2775 2776 // inputs for new nodes 2777 m1->add_req(NULL, toc); 2778 m2->add_req(NULL, m1); 2779 2780 // operands for new nodes 2781 m1->_opnds[0] = new iRegLdstOper(); // dst 2782 m1->_opnds[1] = immSrc; // src 2783 m1->_opnds[2] = new iRegPdstOper(); // toc 2784 m2->_opnds[0] = new iRegLdstOper(); // dst 2785 m2->_opnds[1] = immSrc; // src 2786 m2->_opnds[2] = new iRegLdstOper(); // base 2787 2788 // Initialize ins_attrib TOC fields. 2789 m1->_const_toc_offset = -1; 2790 m2->_const_toc_offset_hi_node = m1; 2791 2792 // Initialize ins_attrib instruction offset. 2793 m1->_cbuf_insts_offset = -1; 2794 2795 // register allocation for new nodes 2796 ra_->set_pair(m1->_idx, reg_second, reg_first); 2797 ra_->set_pair(m2->_idx, reg_second, reg_first); 2798 2799 // Create result. 2800 nodes._large_hi = m1; 2801 nodes._large_lo = m2; 2802 nodes._small = NULL; 2803 nodes._last = nodes._large_lo; 2804 assert(m2->bottom_type()->isa_long(), "must be long"); 2805 } else { 2806 loadConLNode *m2 = new loadConLNode(); 2807 2808 // inputs for new nodes 2809 m2->add_req(NULL, toc); 2810 2811 // operands for new nodes 2812 m2->_opnds[0] = new iRegLdstOper(); // dst 2813 m2->_opnds[1] = immSrc; // src 2814 m2->_opnds[2] = new iRegPdstOper(); // toc 2815 2816 // Initialize ins_attrib instruction offset. 2817 m2->_cbuf_insts_offset = -1; 2818 2819 // register allocation for new nodes 2820 ra_->set_pair(m2->_idx, reg_second, reg_first); 2821 2822 // Create result. 2823 nodes._large_hi = NULL; 2824 nodes._large_lo = NULL; 2825 nodes._small = m2; 2826 nodes._last = nodes._small; 2827 assert(m2->bottom_type()->isa_long(), "must be long"); 2828 } 2829 2830 return nodes; 2831 } 2832 2833 typedef struct { 2834 loadConL_hiNode *_large_hi; 2835 loadConL_loNode *_large_lo; 2836 mtvsrdNode *_moved; 2837 xxspltdNode *_replicated; 2838 loadConLNode *_small; 2839 MachNode *_last; 2840 } loadConLReplicatedNodesTuple; 2841 2842 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2843 vecXOper *dst, immI_0Oper *zero, 2844 OptoReg::Name reg_second, OptoReg::Name reg_first, 2845 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2846 loadConLReplicatedNodesTuple nodes; 2847 2848 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2849 if (large_constant_pool) { 2850 // Create new nodes. 2851 loadConL_hiNode *m1 = new loadConL_hiNode(); 2852 loadConL_loNode *m2 = new loadConL_loNode(); 2853 mtvsrdNode *m3 = new mtvsrdNode(); 2854 xxspltdNode *m4 = new xxspltdNode(); 2855 2856 // inputs for new nodes 2857 m1->add_req(NULL, toc); 2858 m2->add_req(NULL, m1); 2859 m3->add_req(NULL, m2); 2860 m4->add_req(NULL, m3); 2861 2862 // operands for new nodes 2863 m1->_opnds[0] = new iRegLdstOper(); // dst 2864 m1->_opnds[1] = immSrc; // src 2865 m1->_opnds[2] = new iRegPdstOper(); // toc 2866 2867 m2->_opnds[0] = new iRegLdstOper(); // dst 2868 m2->_opnds[1] = immSrc; // src 2869 m2->_opnds[2] = new iRegLdstOper(); // base 2870 2871 m3->_opnds[0] = new vecXOper(); // dst 2872 m3->_opnds[1] = new iRegLdstOper(); // src 2873 2874 m4->_opnds[0] = new vecXOper(); // dst 2875 m4->_opnds[1] = new vecXOper(); // src 2876 m4->_opnds[2] = zero; 2877 2878 // Initialize ins_attrib TOC fields. 2879 m1->_const_toc_offset = -1; 2880 m2->_const_toc_offset_hi_node = m1; 2881 2882 // Initialize ins_attrib instruction offset. 2883 m1->_cbuf_insts_offset = -1; 2884 2885 // register allocation for new nodes 2886 ra_->set_pair(m1->_idx, reg_second, reg_first); 2887 ra_->set_pair(m2->_idx, reg_second, reg_first); 2888 ra_->set1(m3->_idx, reg_second); 2889 ra_->set2(m3->_idx, reg_vec_first); 2890 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2891 2892 // Create result. 2893 nodes._large_hi = m1; 2894 nodes._large_lo = m2; 2895 nodes._moved = m3; 2896 nodes._replicated = m4; 2897 nodes._small = NULL; 2898 nodes._last = nodes._replicated; 2899 assert(m2->bottom_type()->isa_long(), "must be long"); 2900 } else { 2901 loadConLNode *m2 = new loadConLNode(); 2902 mtvsrdNode *m3 = new mtvsrdNode(); 2903 xxspltdNode *m4 = new xxspltdNode(); 2904 2905 // inputs for new nodes 2906 m2->add_req(NULL, toc); 2907 2908 // operands for new nodes 2909 m2->_opnds[0] = new iRegLdstOper(); // dst 2910 m2->_opnds[1] = immSrc; // src 2911 m2->_opnds[2] = new iRegPdstOper(); // toc 2912 2913 m3->_opnds[0] = new vecXOper(); // dst 2914 m3->_opnds[1] = new iRegLdstOper(); // src 2915 2916 m4->_opnds[0] = new vecXOper(); // dst 2917 m4->_opnds[1] = new vecXOper(); // src 2918 m4->_opnds[2] = zero; 2919 2920 // Initialize ins_attrib instruction offset. 2921 m2->_cbuf_insts_offset = -1; 2922 ra_->set1(m3->_idx, reg_second); 2923 ra_->set2(m3->_idx, reg_vec_first); 2924 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2925 2926 // register allocation for new nodes 2927 ra_->set_pair(m2->_idx, reg_second, reg_first); 2928 2929 // Create result. 2930 nodes._large_hi = NULL; 2931 nodes._large_lo = NULL; 2932 nodes._small = m2; 2933 nodes._moved = m3; 2934 nodes._replicated = m4; 2935 nodes._last = nodes._replicated; 2936 assert(m2->bottom_type()->isa_long(), "must be long"); 2937 } 2938 2939 return nodes; 2940 } 2941 2942 %} // source 2943 2944 encode %{ 2945 // Postalloc expand emitter for loading a long constant from the method's TOC. 2946 // Enc_class needed as consttanttablebase is not supported by postalloc 2947 // expand. 2948 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2949 // Create new nodes. 2950 loadConLNodesTuple loadConLNodes = 2951 loadConLNodesTuple_create(ra_, n_toc, op_src, 2952 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2953 2954 // Push new nodes. 2955 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2956 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2957 2958 // some asserts 2959 assert(nodes->length() >= 1, "must have created at least 1 node"); 2960 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2961 %} 2962 2963 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2964 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2965 2966 MacroAssembler _masm(&cbuf); 2967 int toc_offset = 0; 2968 2969 intptr_t val = $src$$constant; 2970 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2971 address const_toc_addr; 2972 if (constant_reloc == relocInfo::oop_type) { 2973 // Create an oop constant and a corresponding relocation. 2974 AddressLiteral a = __ allocate_oop_address((jobject)val); 2975 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2976 __ relocate(a.rspec()); 2977 } else if (constant_reloc == relocInfo::metadata_type) { 2978 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2979 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2980 __ relocate(a.rspec()); 2981 } else { 2982 // Create a non-oop constant, no relocation needed. 2983 const_toc_addr = __ long_constant((jlong)$src$$constant); 2984 } 2985 2986 if (const_toc_addr == NULL) { 2987 ciEnv::current()->record_out_of_memory_failure(); 2988 return; 2989 } 2990 // Get the constant's TOC offset. 2991 toc_offset = __ offset_to_method_toc(const_toc_addr); 2992 2993 __ ld($dst$$Register, toc_offset, $toc$$Register); 2994 %} 2995 2996 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2997 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2998 2999 MacroAssembler _masm(&cbuf); 3000 if (!ra_->C->in_scratch_emit_size()) { 3001 intptr_t val = $src$$constant; 3002 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 3003 address const_toc_addr; 3004 if (constant_reloc == relocInfo::oop_type) { 3005 // Create an oop constant and a corresponding relocation. 3006 AddressLiteral a = __ allocate_oop_address((jobject)val); 3007 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3008 __ relocate(a.rspec()); 3009 } else if (constant_reloc == relocInfo::metadata_type) { 3010 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 3011 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3012 __ relocate(a.rspec()); 3013 } else { // non-oop pointers, e.g. card mark base, heap top 3014 // Create a non-oop constant, no relocation needed. 3015 const_toc_addr = __ long_constant((jlong)$src$$constant); 3016 } 3017 3018 if (const_toc_addr == NULL) { 3019 ciEnv::current()->record_out_of_memory_failure(); 3020 return; 3021 } 3022 // Get the constant's TOC offset. 3023 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 3024 // Store the toc offset of the constant. 3025 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 3026 } 3027 3028 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 3029 %} 3030 3031 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 3032 // Enc_class needed as consttanttablebase is not supported by postalloc 3033 // expand. 3034 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 3035 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3036 if (large_constant_pool) { 3037 // Create new nodes. 3038 loadConP_hiNode *m1 = new loadConP_hiNode(); 3039 loadConP_loNode *m2 = new loadConP_loNode(); 3040 3041 // inputs for new nodes 3042 m1->add_req(NULL, n_toc); 3043 m2->add_req(NULL, m1); 3044 3045 // operands for new nodes 3046 m1->_opnds[0] = new iRegPdstOper(); // dst 3047 m1->_opnds[1] = op_src; // src 3048 m1->_opnds[2] = new iRegPdstOper(); // toc 3049 m2->_opnds[0] = new iRegPdstOper(); // dst 3050 m2->_opnds[1] = op_src; // src 3051 m2->_opnds[2] = new iRegLdstOper(); // base 3052 3053 // Initialize ins_attrib TOC fields. 3054 m1->_const_toc_offset = -1; 3055 m2->_const_toc_offset_hi_node = m1; 3056 3057 // Register allocation for new nodes. 3058 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3059 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3060 3061 nodes->push(m1); 3062 nodes->push(m2); 3063 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3064 } else { 3065 loadConPNode *m2 = new loadConPNode(); 3066 3067 // inputs for new nodes 3068 m2->add_req(NULL, n_toc); 3069 3070 // operands for new nodes 3071 m2->_opnds[0] = new iRegPdstOper(); // dst 3072 m2->_opnds[1] = op_src; // src 3073 m2->_opnds[2] = new iRegPdstOper(); // toc 3074 3075 // Register allocation for new nodes. 3076 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3077 3078 nodes->push(m2); 3079 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3080 } 3081 %} 3082 3083 // Enc_class needed as consttanttablebase is not supported by postalloc 3084 // expand. 3085 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3086 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3087 3088 MachNode *m2; 3089 if (large_constant_pool) { 3090 m2 = new loadConFCompNode(); 3091 } else { 3092 m2 = new loadConFNode(); 3093 } 3094 // inputs for new nodes 3095 m2->add_req(NULL, n_toc); 3096 3097 // operands for new nodes 3098 m2->_opnds[0] = op_dst; 3099 m2->_opnds[1] = op_src; 3100 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3101 3102 // register allocation for new nodes 3103 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3104 nodes->push(m2); 3105 %} 3106 3107 // Enc_class needed as consttanttablebase is not supported by postalloc 3108 // expand. 3109 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3110 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3111 3112 MachNode *m2; 3113 if (large_constant_pool) { 3114 m2 = new loadConDCompNode(); 3115 } else { 3116 m2 = new loadConDNode(); 3117 } 3118 // inputs for new nodes 3119 m2->add_req(NULL, n_toc); 3120 3121 // operands for new nodes 3122 m2->_opnds[0] = op_dst; 3123 m2->_opnds[1] = op_src; 3124 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3125 3126 // register allocation for new nodes 3127 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3128 nodes->push(m2); 3129 %} 3130 3131 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3132 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3133 MacroAssembler _masm(&cbuf); 3134 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3135 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3136 %} 3137 3138 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3139 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3140 MacroAssembler _masm(&cbuf); 3141 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3142 // Operand 'ds' requires 4-alignment. 3143 assert((Idisp & 0x3) == 0, "unaligned offset"); 3144 __ std($src$$Register, Idisp, $mem$$base$$Register); 3145 %} 3146 3147 enc_class enc_stfs(RegF src, memory mem) %{ 3148 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3149 MacroAssembler _masm(&cbuf); 3150 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3151 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3152 %} 3153 3154 enc_class enc_stfd(RegF src, memory mem) %{ 3155 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3156 MacroAssembler _masm(&cbuf); 3157 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3158 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3159 %} 3160 3161 // Use release_store for card-marking to ensure that previous 3162 // oop-stores are visible before the card-mark change. 3163 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3164 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3165 // FIXME: Implement this as a cmove and use a fixed condition code 3166 // register which is written on every transition to compiled code, 3167 // e.g. in call-stub and when returning from runtime stubs. 3168 // 3169 // Proposed code sequence for the cmove implementation: 3170 // 3171 // Label skip_release; 3172 // __ beq(CCRfixed, skip_release); 3173 // __ release(); 3174 // __ bind(skip_release); 3175 // __ stb(card mark); 3176 3177 MacroAssembler _masm(&cbuf); 3178 Label skip_storestore; 3179 3180 #if 0 // TODO: PPC port 3181 // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the 3182 // StoreStore barrier conditionally. 3183 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3184 __ cmpwi($crx$$CondRegister, R0, 0); 3185 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3186 #endif 3187 __ li(R0, 0); 3188 __ membar(Assembler::StoreStore); 3189 #if 0 // TODO: PPC port 3190 __ bind(skip_storestore); 3191 #endif 3192 3193 // Do the store. 3194 if ($mem$$index == 0) { 3195 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3196 } else { 3197 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3198 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3199 } 3200 %} 3201 3202 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3203 3204 if (VM_Version::has_isel()) { 3205 // use isel instruction with Power 7 3206 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3207 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3208 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3209 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3210 3211 n_compare->add_req(n_region, n_src); 3212 n_compare->_opnds[0] = op_crx; 3213 n_compare->_opnds[1] = op_src; 3214 n_compare->_opnds[2] = new immL16Oper(0); 3215 3216 n_sub_base->add_req(n_region, n_src); 3217 n_sub_base->_opnds[0] = op_dst; 3218 n_sub_base->_opnds[1] = op_src; 3219 n_sub_base->_bottom_type = _bottom_type; 3220 3221 n_shift->add_req(n_region, n_sub_base); 3222 n_shift->_opnds[0] = op_dst; 3223 n_shift->_opnds[1] = op_dst; 3224 n_shift->_bottom_type = _bottom_type; 3225 3226 n_cond_set->add_req(n_region, n_compare, n_shift); 3227 n_cond_set->_opnds[0] = op_dst; 3228 n_cond_set->_opnds[1] = op_crx; 3229 n_cond_set->_opnds[2] = op_dst; 3230 n_cond_set->_bottom_type = _bottom_type; 3231 3232 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3233 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3234 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3235 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3236 3237 nodes->push(n_compare); 3238 nodes->push(n_sub_base); 3239 nodes->push(n_shift); 3240 nodes->push(n_cond_set); 3241 3242 } else { 3243 // before Power 7 3244 moveRegNode *n_move = new moveRegNode(); 3245 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3246 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3247 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3248 3249 n_move->add_req(n_region, n_src); 3250 n_move->_opnds[0] = op_dst; 3251 n_move->_opnds[1] = op_src; 3252 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3253 3254 n_compare->add_req(n_region, n_src); 3255 n_compare->add_prec(n_move); 3256 3257 n_compare->_opnds[0] = op_crx; 3258 n_compare->_opnds[1] = op_src; 3259 n_compare->_opnds[2] = new immL16Oper(0); 3260 3261 n_sub_base->add_req(n_region, n_compare, n_src); 3262 n_sub_base->_opnds[0] = op_dst; 3263 n_sub_base->_opnds[1] = op_crx; 3264 n_sub_base->_opnds[2] = op_src; 3265 n_sub_base->_bottom_type = _bottom_type; 3266 3267 n_shift->add_req(n_region, n_sub_base); 3268 n_shift->_opnds[0] = op_dst; 3269 n_shift->_opnds[1] = op_dst; 3270 n_shift->_bottom_type = _bottom_type; 3271 3272 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3273 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3274 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3275 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3276 3277 nodes->push(n_move); 3278 nodes->push(n_compare); 3279 nodes->push(n_sub_base); 3280 nodes->push(n_shift); 3281 } 3282 3283 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3284 %} 3285 3286 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3287 3288 encodeP_subNode *n1 = new encodeP_subNode(); 3289 n1->add_req(n_region, n_src); 3290 n1->_opnds[0] = op_dst; 3291 n1->_opnds[1] = op_src; 3292 n1->_bottom_type = _bottom_type; 3293 3294 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3295 n2->add_req(n_region, n1); 3296 n2->_opnds[0] = op_dst; 3297 n2->_opnds[1] = op_dst; 3298 n2->_bottom_type = _bottom_type; 3299 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3300 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3301 3302 nodes->push(n1); 3303 nodes->push(n2); 3304 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3305 %} 3306 3307 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3308 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3309 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3310 3311 n_compare->add_req(n_region, n_src); 3312 n_compare->_opnds[0] = op_crx; 3313 n_compare->_opnds[1] = op_src; 3314 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3315 3316 n_shift->add_req(n_region, n_src); 3317 n_shift->_opnds[0] = op_dst; 3318 n_shift->_opnds[1] = op_src; 3319 n_shift->_bottom_type = _bottom_type; 3320 3321 if (VM_Version::has_isel()) { 3322 // use isel instruction with Power 7 3323 3324 decodeN_addNode *n_add_base = new decodeN_addNode(); 3325 n_add_base->add_req(n_region, n_shift); 3326 n_add_base->_opnds[0] = op_dst; 3327 n_add_base->_opnds[1] = op_dst; 3328 n_add_base->_bottom_type = _bottom_type; 3329 3330 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3331 n_cond_set->add_req(n_region, n_compare, n_add_base); 3332 n_cond_set->_opnds[0] = op_dst; 3333 n_cond_set->_opnds[1] = op_crx; 3334 n_cond_set->_opnds[2] = op_dst; 3335 n_cond_set->_bottom_type = _bottom_type; 3336 3337 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3338 ra_->set_oop(n_cond_set, true); 3339 3340 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3341 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3342 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3343 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3344 3345 nodes->push(n_compare); 3346 nodes->push(n_shift); 3347 nodes->push(n_add_base); 3348 nodes->push(n_cond_set); 3349 3350 } else { 3351 // before Power 7 3352 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3353 3354 n_add_base->add_req(n_region, n_compare, n_shift); 3355 n_add_base->_opnds[0] = op_dst; 3356 n_add_base->_opnds[1] = op_crx; 3357 n_add_base->_opnds[2] = op_dst; 3358 n_add_base->_bottom_type = _bottom_type; 3359 3360 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3361 ra_->set_oop(n_add_base, true); 3362 3363 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3364 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3365 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3366 3367 nodes->push(n_compare); 3368 nodes->push(n_shift); 3369 nodes->push(n_add_base); 3370 } 3371 %} 3372 3373 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3374 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3375 n1->add_req(n_region, n_src); 3376 n1->_opnds[0] = op_dst; 3377 n1->_opnds[1] = op_src; 3378 n1->_bottom_type = _bottom_type; 3379 3380 decodeN_addNode *n2 = new decodeN_addNode(); 3381 n2->add_req(n_region, n1); 3382 n2->_opnds[0] = op_dst; 3383 n2->_opnds[1] = op_dst; 3384 n2->_bottom_type = _bottom_type; 3385 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3386 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3387 3388 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3389 ra_->set_oop(n2, true); 3390 3391 nodes->push(n1); 3392 nodes->push(n2); 3393 %} 3394 3395 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3396 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3397 3398 MacroAssembler _masm(&cbuf); 3399 int cc = $cmp$$cmpcode; 3400 int flags_reg = $crx$$reg; 3401 Label done; 3402 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3403 // Branch if not (cmp crx). 3404 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3405 __ mr($dst$$Register, $src$$Register); 3406 // TODO PPC port __ endgroup_if_needed(_size == 12); 3407 __ bind(done); 3408 %} 3409 3410 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3411 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3412 3413 MacroAssembler _masm(&cbuf); 3414 Label done; 3415 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3416 // Branch if not (cmp crx). 3417 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3418 __ li($dst$$Register, $src$$constant); 3419 // TODO PPC port __ endgroup_if_needed(_size == 12); 3420 __ bind(done); 3421 %} 3422 3423 // This enc_class is needed so that scheduler gets proper 3424 // input mapping for latency computation. 3425 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3426 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3427 MacroAssembler _masm(&cbuf); 3428 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3429 %} 3430 3431 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3432 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3433 3434 MacroAssembler _masm(&cbuf); 3435 3436 Label done; 3437 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3438 __ li($dst$$Register, $zero$$constant); 3439 __ beq($crx$$CondRegister, done); 3440 __ li($dst$$Register, $notzero$$constant); 3441 __ bind(done); 3442 %} 3443 3444 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3445 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3446 3447 MacroAssembler _masm(&cbuf); 3448 3449 Label done; 3450 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3451 __ li($dst$$Register, $zero$$constant); 3452 __ beq($crx$$CondRegister, done); 3453 __ li($dst$$Register, $notzero$$constant); 3454 __ bind(done); 3455 %} 3456 3457 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3458 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3459 3460 MacroAssembler _masm(&cbuf); 3461 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3462 Label done; 3463 __ bso($crx$$CondRegister, done); 3464 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3465 // TODO PPC port __ endgroup_if_needed(_size == 12); 3466 __ bind(done); 3467 %} 3468 3469 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3470 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3471 3472 MacroAssembler _masm(&cbuf); 3473 Label done; 3474 __ bso($crx$$CondRegister, done); 3475 __ mffprd($dst$$Register, $src$$FloatRegister); 3476 // TODO PPC port __ endgroup_if_needed(_size == 12); 3477 __ bind(done); 3478 %} 3479 3480 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3481 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3482 3483 MacroAssembler _masm(&cbuf); 3484 Label d; // dummy 3485 __ bind(d); 3486 Label* p = ($lbl$$label); 3487 // `p' is `NULL' when this encoding class is used only to 3488 // determine the size of the encoded instruction. 3489 Label& l = (NULL == p)? d : *(p); 3490 int cc = $cmp$$cmpcode; 3491 int flags_reg = $crx$$reg; 3492 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3493 int bhint = Assembler::bhintNoHint; 3494 3495 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3496 if (_prob <= PROB_NEVER) { 3497 bhint = Assembler::bhintIsNotTaken; 3498 } else if (_prob >= PROB_ALWAYS) { 3499 bhint = Assembler::bhintIsTaken; 3500 } 3501 } 3502 3503 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3504 cc_to_biint(cc, flags_reg), 3505 l); 3506 %} 3507 3508 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3509 // The scheduler doesn't know about branch shortening, so we set the opcode 3510 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3511 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3512 3513 MacroAssembler _masm(&cbuf); 3514 Label d; // dummy 3515 __ bind(d); 3516 Label* p = ($lbl$$label); 3517 // `p' is `NULL' when this encoding class is used only to 3518 // determine the size of the encoded instruction. 3519 Label& l = (NULL == p)? d : *(p); 3520 int cc = $cmp$$cmpcode; 3521 int flags_reg = $crx$$reg; 3522 int bhint = Assembler::bhintNoHint; 3523 3524 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3525 if (_prob <= PROB_NEVER) { 3526 bhint = Assembler::bhintIsNotTaken; 3527 } else if (_prob >= PROB_ALWAYS) { 3528 bhint = Assembler::bhintIsTaken; 3529 } 3530 } 3531 3532 // Tell the conditional far branch to optimize itself when being relocated. 3533 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3534 cc_to_biint(cc, flags_reg), 3535 l, 3536 MacroAssembler::bc_far_optimize_on_relocate); 3537 %} 3538 3539 // Branch used with Power6 scheduling (can be shortened without changing the node). 3540 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3541 // The scheduler doesn't know about branch shortening, so we set the opcode 3542 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3543 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3544 3545 MacroAssembler _masm(&cbuf); 3546 Label d; // dummy 3547 __ bind(d); 3548 Label* p = ($lbl$$label); 3549 // `p' is `NULL' when this encoding class is used only to 3550 // determine the size of the encoded instruction. 3551 Label& l = (NULL == p)? d : *(p); 3552 int cc = $cmp$$cmpcode; 3553 int flags_reg = $crx$$reg; 3554 int bhint = Assembler::bhintNoHint; 3555 3556 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3557 if (_prob <= PROB_NEVER) { 3558 bhint = Assembler::bhintIsNotTaken; 3559 } else if (_prob >= PROB_ALWAYS) { 3560 bhint = Assembler::bhintIsTaken; 3561 } 3562 } 3563 3564 #if 0 // TODO: PPC port 3565 if (_size == 8) { 3566 // Tell the conditional far branch to optimize itself when being relocated. 3567 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3568 cc_to_biint(cc, flags_reg), 3569 l, 3570 MacroAssembler::bc_far_optimize_on_relocate); 3571 } else { 3572 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3573 cc_to_biint(cc, flags_reg), 3574 l); 3575 } 3576 #endif 3577 Unimplemented(); 3578 %} 3579 3580 // Postalloc expand emitter for loading a replicatef float constant from 3581 // the method's TOC. 3582 // Enc_class needed as consttanttablebase is not supported by postalloc 3583 // expand. 3584 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3585 // Create new nodes. 3586 3587 // Make an operand with the bit pattern to load as float. 3588 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3589 3590 loadConLNodesTuple loadConLNodes = 3591 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3592 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3593 3594 // Push new nodes. 3595 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3596 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3597 3598 assert(nodes->length() >= 1, "must have created at least 1 node"); 3599 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3600 %} 3601 3602 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3603 // Create new nodes. 3604 3605 // Make an operand with the bit pattern to load as float. 3606 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3607 immI_0Oper *op_zero = new immI_0Oper(0); 3608 3609 loadConLReplicatedNodesTuple loadConLNodes = 3610 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3611 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3612 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3613 3614 // Push new nodes. 3615 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3616 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3617 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3618 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3619 3620 assert(nodes->length() >= 1, "must have created at least 1 node"); 3621 %} 3622 3623 // This enc_class is needed so that scheduler gets proper 3624 // input mapping for latency computation. 3625 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3626 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3627 // Fake operand dst needed for PPC scheduler. 3628 assert($dst$$constant == 0x0, "dst must be 0x0"); 3629 3630 MacroAssembler _masm(&cbuf); 3631 // Mark the code position where the load from the safepoint 3632 // polling page was emitted as relocInfo::poll_type. 3633 __ relocate(relocInfo::poll_type); 3634 __ load_from_polling_page($poll$$Register); 3635 %} 3636 3637 // A Java static call or a runtime call. 3638 // 3639 // Branch-and-link relative to a trampoline. 3640 // The trampoline loads the target address and does a long branch to there. 3641 // In case we call java, the trampoline branches to a interpreter_stub 3642 // which loads the inline cache and the real call target from the constant pool. 3643 // 3644 // This basically looks like this: 3645 // 3646 // >>>> consts -+ -+ 3647 // | |- offset1 3648 // [call target1] | <-+ 3649 // [IC cache] |- offset2 3650 // [call target2] <--+ 3651 // 3652 // <<<< consts 3653 // >>>> insts 3654 // 3655 // bl offset16 -+ -+ ??? // How many bits available? 3656 // | | 3657 // <<<< insts | | 3658 // >>>> stubs | | 3659 // | |- trampoline_stub_Reloc 3660 // trampoline stub: | <-+ 3661 // r2 = toc | 3662 // r2 = [r2 + offset1] | // Load call target1 from const section 3663 // mtctr r2 | 3664 // bctr |- static_stub_Reloc 3665 // comp_to_interp_stub: <---+ 3666 // r1 = toc 3667 // ICreg = [r1 + IC_offset] // Load IC from const section 3668 // r1 = [r1 + offset2] // Load call target2 from const section 3669 // mtctr r1 3670 // bctr 3671 // 3672 // <<<< stubs 3673 // 3674 // The call instruction in the code either 3675 // - Branches directly to a compiled method if the offset is encodable in instruction. 3676 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3677 // - Branches to the compiled_to_interp stub if the target is interpreted. 3678 // 3679 // Further there are three relocations from the loads to the constants in 3680 // the constant section. 3681 // 3682 // Usage of r1 and r2 in the stubs allows to distinguish them. 3683 enc_class enc_java_static_call(method meth) %{ 3684 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3685 3686 MacroAssembler _masm(&cbuf); 3687 address entry_point = (address)$meth$$method; 3688 3689 if (!_method) { 3690 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3691 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3692 } else { 3693 // Remember the offset not the address. 3694 const int start_offset = __ offset(); 3695 3696 // The trampoline stub. 3697 // No entry point given, use the current pc. 3698 // Make sure branch fits into 3699 if (entry_point == 0) entry_point = __ pc(); 3700 3701 // Put the entry point as a constant into the constant pool. 3702 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3703 if (entry_point_toc_addr == NULL) { 3704 ciEnv::current()->record_out_of_memory_failure(); 3705 return; 3706 } 3707 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3708 3709 // Emit the trampoline stub which will be related to the branch-and-link below. 3710 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3711 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3712 int method_index = resolved_method_index(cbuf); 3713 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3714 : static_call_Relocation::spec(method_index)); 3715 3716 // The real call. 3717 // Note: At this point we do not have the address of the trampoline 3718 // stub, and the entry point might be too far away for bl, so __ pc() 3719 // serves as dummy and the bl will be patched later. 3720 cbuf.set_insts_mark(); 3721 __ bl(__ pc()); // Emits a relocation. 3722 3723 // The stub for call to interpreter. 3724 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3725 if (stub == NULL) { 3726 ciEnv::current()->record_failure("CodeCache is full"); 3727 return; 3728 } 3729 } 3730 %} 3731 3732 // Second node of expanded dynamic call - the call. 3733 enc_class enc_java_dynamic_call_sched(method meth) %{ 3734 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3735 3736 MacroAssembler _masm(&cbuf); 3737 3738 if (!ra_->C->in_scratch_emit_size()) { 3739 // Create a call trampoline stub for the given method. 3740 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3741 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3742 if (entry_point_const == NULL) { 3743 ciEnv::current()->record_out_of_memory_failure(); 3744 return; 3745 } 3746 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3747 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3748 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3749 3750 // Build relocation at call site with ic position as data. 3751 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3752 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3753 "must have one, but can't have both"); 3754 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3755 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3756 "must contain instruction offset"); 3757 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3758 ? _load_ic_hi_node->_cbuf_insts_offset 3759 : _load_ic_node->_cbuf_insts_offset; 3760 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3761 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3762 "should be load from TOC"); 3763 int method_index = resolved_method_index(cbuf); 3764 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3765 } 3766 3767 // At this point I do not have the address of the trampoline stub, 3768 // and the entry point might be too far away for bl. Pc() serves 3769 // as dummy and bl will be patched later. 3770 __ bl((address) __ pc()); 3771 %} 3772 3773 // postalloc expand emitter for virtual calls. 3774 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3775 3776 // Create the nodes for loading the IC from the TOC. 3777 loadConLNodesTuple loadConLNodes_IC = 3778 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3779 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3780 3781 // Create the call node. 3782 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3783 call->_method_handle_invoke = _method_handle_invoke; 3784 call->_vtable_index = _vtable_index; 3785 call->_method = _method; 3786 call->_bci = _bci; 3787 call->_optimized_virtual = _optimized_virtual; 3788 call->_tf = _tf; 3789 call->_entry_point = _entry_point; 3790 call->_cnt = _cnt; 3791 call->_argsize = _argsize; 3792 call->_oop_map = _oop_map; 3793 call->_jvms = _jvms; 3794 call->_jvmadj = _jvmadj; 3795 call->_in_rms = _in_rms; 3796 call->_nesting = _nesting; 3797 call->_override_symbolic_info = _override_symbolic_info; 3798 3799 // New call needs all inputs of old call. 3800 // Req... 3801 for (uint i = 0; i < req(); ++i) { 3802 // The expanded node does not need toc any more. 3803 // Add the inline cache constant here instead. This expresses the 3804 // register of the inline cache must be live at the call. 3805 // Else we would have to adapt JVMState by -1. 3806 if (i == mach_constant_base_node_input()) { 3807 call->add_req(loadConLNodes_IC._last); 3808 } else { 3809 call->add_req(in(i)); 3810 } 3811 } 3812 // ...as well as prec 3813 for (uint i = req(); i < len(); ++i) { 3814 call->add_prec(in(i)); 3815 } 3816 3817 // Remember nodes loading the inline cache into r19. 3818 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3819 call->_load_ic_node = loadConLNodes_IC._small; 3820 3821 // Operands for new nodes. 3822 call->_opnds[0] = _opnds[0]; 3823 call->_opnds[1] = _opnds[1]; 3824 3825 // Only the inline cache is associated with a register. 3826 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3827 3828 // Push new nodes. 3829 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3830 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3831 nodes->push(call); 3832 %} 3833 3834 // Compound version of call dynamic 3835 // Toc is only passed so that it can be used in ins_encode statement. 3836 // In the code we have to use $constanttablebase. 3837 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3838 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3839 MacroAssembler _masm(&cbuf); 3840 int start_offset = __ offset(); 3841 3842 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3843 #if 0 3844 int vtable_index = this->_vtable_index; 3845 if (_vtable_index < 0) { 3846 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3847 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3848 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3849 3850 // Virtual call relocation will point to ic load. 3851 address virtual_call_meta_addr = __ pc(); 3852 // Load a clear inline cache. 3853 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3854 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3855 if (!success) { 3856 ciEnv::current()->record_out_of_memory_failure(); 3857 return; 3858 } 3859 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3860 // to determine who we intended to call. 3861 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3862 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3863 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3864 "Fix constant in ret_addr_offset()"); 3865 } else { 3866 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3867 // Go thru the vtable. Get receiver klass. Receiver already 3868 // checked for non-null. If we'll go thru a C2I adapter, the 3869 // interpreter expects method in R19_method. 3870 3871 __ load_klass(R11_scratch1, R3); 3872 3873 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3874 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3875 __ li(R19_method, v_off); 3876 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3877 // NOTE: for vtable dispatches, the vtable entry will never be 3878 // null. However it may very well end up in handle_wrong_method 3879 // if the method is abstract for the particular class. 3880 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3881 // Call target. Either compiled code or C2I adapter. 3882 __ mtctr(R11_scratch1); 3883 __ bctrl(); 3884 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3885 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3886 } 3887 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3888 "Fix constant in ret_addr_offset()"); 3889 } 3890 #endif 3891 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3892 %} 3893 3894 // a runtime call 3895 enc_class enc_java_to_runtime_call (method meth) %{ 3896 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3897 3898 MacroAssembler _masm(&cbuf); 3899 const address start_pc = __ pc(); 3900 3901 #if defined(ABI_ELFv2) 3902 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3903 __ call_c(entry, relocInfo::runtime_call_type); 3904 #else 3905 // The function we're going to call. 3906 FunctionDescriptor fdtemp; 3907 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3908 3909 Register Rtoc = R12_scratch2; 3910 // Calculate the method's TOC. 3911 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3912 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3913 // pool entries; call_c_using_toc will optimize the call. 3914 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3915 if (!success) { 3916 ciEnv::current()->record_out_of_memory_failure(); 3917 return; 3918 } 3919 #endif 3920 3921 // Check the ret_addr_offset. 3922 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3923 "Fix constant in ret_addr_offset()"); 3924 %} 3925 3926 // Move to ctr for leaf call. 3927 // This enc_class is needed so that scheduler gets proper 3928 // input mapping for latency computation. 3929 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3930 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3931 MacroAssembler _masm(&cbuf); 3932 __ mtctr($src$$Register); 3933 %} 3934 3935 // Postalloc expand emitter for runtime leaf calls. 3936 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3937 loadConLNodesTuple loadConLNodes_Entry; 3938 #if defined(ABI_ELFv2) 3939 jlong entry_address = (jlong) this->entry_point(); 3940 assert(entry_address, "need address here"); 3941 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3942 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3943 #else 3944 // Get the struct that describes the function we are about to call. 3945 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3946 assert(fd, "need fd here"); 3947 jlong entry_address = (jlong) fd->entry(); 3948 // new nodes 3949 loadConLNodesTuple loadConLNodes_Env; 3950 loadConLNodesTuple loadConLNodes_Toc; 3951 3952 // Create nodes and operands for loading the entry point. 3953 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3954 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3955 3956 3957 // Create nodes and operands for loading the env pointer. 3958 if (fd->env() != NULL) { 3959 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3960 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3961 } else { 3962 loadConLNodes_Env._large_hi = NULL; 3963 loadConLNodes_Env._large_lo = NULL; 3964 loadConLNodes_Env._small = NULL; 3965 loadConLNodes_Env._last = new loadConL16Node(); 3966 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3967 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3968 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3969 } 3970 3971 // Create nodes and operands for loading the Toc point. 3972 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3973 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3974 #endif // ABI_ELFv2 3975 // mtctr node 3976 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3977 3978 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3979 mtctr->add_req(0, loadConLNodes_Entry._last); 3980 3981 mtctr->_opnds[0] = new iRegLdstOper(); 3982 mtctr->_opnds[1] = new iRegLdstOper(); 3983 3984 // call node 3985 MachCallLeafNode *call = new CallLeafDirectNode(); 3986 3987 call->_opnds[0] = _opnds[0]; 3988 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3989 3990 // Make the new call node look like the old one. 3991 call->_name = _name; 3992 call->_tf = _tf; 3993 call->_entry_point = _entry_point; 3994 call->_cnt = _cnt; 3995 call->_argsize = _argsize; 3996 call->_oop_map = _oop_map; 3997 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3998 call->_jvms = NULL; 3999 call->_jvmadj = _jvmadj; 4000 call->_in_rms = _in_rms; 4001 call->_nesting = _nesting; 4002 4003 4004 // New call needs all inputs of old call. 4005 // Req... 4006 for (uint i = 0; i < req(); ++i) { 4007 if (i != mach_constant_base_node_input()) { 4008 call->add_req(in(i)); 4009 } 4010 } 4011 4012 // These must be reqired edges, as the registers are live up to 4013 // the call. Else the constants are handled as kills. 4014 call->add_req(mtctr); 4015 #if !defined(ABI_ELFv2) 4016 call->add_req(loadConLNodes_Env._last); 4017 call->add_req(loadConLNodes_Toc._last); 4018 #endif 4019 4020 // ...as well as prec 4021 for (uint i = req(); i < len(); ++i) { 4022 call->add_prec(in(i)); 4023 } 4024 4025 // registers 4026 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 4027 4028 // Insert the new nodes. 4029 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 4030 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 4031 #if !defined(ABI_ELFv2) 4032 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 4033 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 4034 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 4035 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 4036 #endif 4037 nodes->push(mtctr); 4038 nodes->push(call); 4039 %} 4040 %} 4041 4042 //----------FRAME-------------------------------------------------------------- 4043 // Definition of frame structure and management information. 4044 4045 frame %{ 4046 // What direction does stack grow in (assumed to be same for native & Java). 4047 stack_direction(TOWARDS_LOW); 4048 4049 // These two registers define part of the calling convention between 4050 // compiled code and the interpreter. 4051 4052 // Inline Cache Register or method for I2C. 4053 inline_cache_reg(R19); // R19_method 4054 4055 // Method Oop Register when calling interpreter. 4056 interpreter_method_oop_reg(R19); // R19_method 4057 4058 // Optional: name the operand used by cisc-spilling to access 4059 // [stack_pointer + offset]. 4060 cisc_spilling_operand_name(indOffset); 4061 4062 // Number of stack slots consumed by a Monitor enter. 4063 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 4064 4065 // Compiled code's Frame Pointer. 4066 frame_pointer(R1); // R1_SP 4067 4068 // Interpreter stores its frame pointer in a register which is 4069 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 4070 // interpreted java to compiled java. 4071 // 4072 // R14_state holds pointer to caller's cInterpreter. 4073 interpreter_frame_pointer(R14); // R14_state 4074 4075 stack_alignment(frame::alignment_in_bytes); 4076 4077 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4078 4079 // Number of outgoing stack slots killed above the 4080 // out_preserve_stack_slots for calls to C. Supports the var-args 4081 // backing area for register parms. 4082 // 4083 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4084 4085 // The after-PROLOG location of the return address. Location of 4086 // return address specifies a type (REG or STACK) and a number 4087 // representing the register number (i.e. - use a register name) or 4088 // stack slot. 4089 // 4090 // A: Link register is stored in stack slot ... 4091 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4092 // J: Therefore, we make sure that the link register is also in R11_scratch1 4093 // at the end of the prolog. 4094 // B: We use R20, now. 4095 //return_addr(REG R20); 4096 4097 // G: After reading the comments made by all the luminaries on their 4098 // failure to tell the compiler where the return address really is, 4099 // I hardly dare to try myself. However, I'm convinced it's in slot 4100 // 4 what apparently works and saves us some spills. 4101 return_addr(STACK 4); 4102 4103 // This is the body of the function 4104 // 4105 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4106 // uint length, // length of array 4107 // bool is_outgoing) 4108 // 4109 // The `sig' array is to be updated. sig[j] represents the location 4110 // of the j-th argument, either a register or a stack slot. 4111 4112 // Comment taken from i486.ad: 4113 // Body of function which returns an integer array locating 4114 // arguments either in registers or in stack slots. Passed an array 4115 // of ideal registers called "sig" and a "length" count. Stack-slot 4116 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4117 // arguments for a CALLEE. Incoming stack arguments are 4118 // automatically biased by the preserve_stack_slots field above. 4119 calling_convention %{ 4120 // No difference between ingoing/outgoing. Just pass false. 4121 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4122 %} 4123 4124 // Comment taken from i486.ad: 4125 // Body of function which returns an integer array locating 4126 // arguments either in registers or in stack slots. Passed an array 4127 // of ideal registers called "sig" and a "length" count. Stack-slot 4128 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4129 // arguments for a CALLEE. Incoming stack arguments are 4130 // automatically biased by the preserve_stack_slots field above. 4131 c_calling_convention %{ 4132 // This is obviously always outgoing. 4133 // C argument in register AND stack slot. 4134 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4135 %} 4136 4137 // Location of native (C/C++) and interpreter return values. This 4138 // is specified to be the same as Java. In the 32-bit VM, long 4139 // values are actually returned from native calls in O0:O1 and 4140 // returned to the interpreter in I0:I1. The copying to and from 4141 // the register pairs is done by the appropriate call and epilog 4142 // opcodes. This simplifies the register allocator. 4143 c_return_value %{ 4144 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4145 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4146 "only return normal values"); 4147 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4148 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4149 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4150 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4151 %} 4152 4153 // Location of compiled Java return values. Same as C 4154 return_value %{ 4155 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4156 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4157 "only return normal values"); 4158 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4159 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4160 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4161 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4162 %} 4163 %} 4164 4165 4166 //----------ATTRIBUTES--------------------------------------------------------- 4167 4168 //----------Operand Attributes------------------------------------------------- 4169 op_attrib op_cost(1); // Required cost attribute. 4170 4171 //----------Instruction Attributes--------------------------------------------- 4172 4173 // Cost attribute. required. 4174 ins_attrib ins_cost(DEFAULT_COST); 4175 4176 // Is this instruction a non-matching short branch variant of some 4177 // long branch? Not required. 4178 ins_attrib ins_short_branch(0); 4179 4180 ins_attrib ins_is_TrapBasedCheckNode(true); 4181 4182 // Number of constants. 4183 // This instruction uses the given number of constants 4184 // (optional attribute). 4185 // This is needed to determine in time whether the constant pool will 4186 // exceed 4000 entries. Before postalloc_expand the overall number of constants 4187 // is determined. It's also used to compute the constant pool size 4188 // in Output(). 4189 ins_attrib ins_num_consts(0); 4190 4191 // Required alignment attribute (must be a power of 2) specifies the 4192 // alignment that some part of the instruction (not necessarily the 4193 // start) requires. If > 1, a compute_padding() function must be 4194 // provided for the instruction. 4195 ins_attrib ins_alignment(1); 4196 4197 // Enforce/prohibit rematerializations. 4198 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4199 // then rematerialization of that instruction is prohibited and the 4200 // instruction's value will be spilled if necessary. 4201 // Causes that MachNode::rematerialize() returns false. 4202 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 4203 // then rematerialization should be enforced and a copy of the instruction 4204 // should be inserted if possible; rematerialization is not guaranteed. 4205 // Note: this may result in rematerializations in front of every use. 4206 // Causes that MachNode::rematerialize() can return true. 4207 // (optional attribute) 4208 ins_attrib ins_cannot_rematerialize(false); 4209 ins_attrib ins_should_rematerialize(false); 4210 4211 // Instruction has variable size depending on alignment. 4212 ins_attrib ins_variable_size_depending_on_alignment(false); 4213 4214 // Instruction is a nop. 4215 ins_attrib ins_is_nop(false); 4216 4217 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4218 ins_attrib ins_use_mach_if_fast_lock_node(false); 4219 4220 // Field for the toc offset of a constant. 4221 // 4222 // This is needed if the toc offset is not encodable as an immediate in 4223 // the PPC load instruction. If so, the upper (hi) bits of the offset are 4224 // added to the toc, and from this a load with immediate is performed. 4225 // With postalloc expand, we get two nodes that require the same offset 4226 // but which don't know about each other. The offset is only known 4227 // when the constant is added to the constant pool during emitting. 4228 // It is generated in the 'hi'-node adding the upper bits, and saved 4229 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 4230 // the offset from there when it gets encoded. 4231 ins_attrib ins_field_const_toc_offset(0); 4232 ins_attrib ins_field_const_toc_offset_hi_node(0); 4233 4234 // A field that can hold the instructions offset in the code buffer. 4235 // Set in the nodes emitter. 4236 ins_attrib ins_field_cbuf_insts_offset(-1); 4237 4238 // Fields for referencing a call's load-IC-node. 4239 // If the toc offset can not be encoded as an immediate in a load, we 4240 // use two nodes. 4241 ins_attrib ins_field_load_ic_hi_node(0); 4242 ins_attrib ins_field_load_ic_node(0); 4243 4244 //----------OPERANDS----------------------------------------------------------- 4245 // Operand definitions must precede instruction definitions for correct 4246 // parsing in the ADLC because operands constitute user defined types 4247 // which are used in instruction definitions. 4248 // 4249 // Formats are generated automatically for constants and base registers. 4250 4251 operand vecX() %{ 4252 constraint(ALLOC_IN_RC(vs_reg)); 4253 match(VecX); 4254 4255 format %{ %} 4256 interface(REG_INTER); 4257 %} 4258 4259 //----------Simple Operands---------------------------------------------------- 4260 // Immediate Operands 4261 4262 // Integer Immediate: 32-bit 4263 operand immI() %{ 4264 match(ConI); 4265 op_cost(40); 4266 format %{ %} 4267 interface(CONST_INTER); 4268 %} 4269 4270 operand immI8() %{ 4271 predicate(Assembler::is_simm(n->get_int(), 8)); 4272 op_cost(0); 4273 match(ConI); 4274 format %{ %} 4275 interface(CONST_INTER); 4276 %} 4277 4278 // Integer Immediate: 16-bit 4279 operand immI16() %{ 4280 predicate(Assembler::is_simm(n->get_int(), 16)); 4281 op_cost(0); 4282 match(ConI); 4283 format %{ %} 4284 interface(CONST_INTER); 4285 %} 4286 4287 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4288 operand immIhi16() %{ 4289 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4290 match(ConI); 4291 op_cost(0); 4292 format %{ %} 4293 interface(CONST_INTER); 4294 %} 4295 4296 operand immInegpow2() %{ 4297 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 4298 match(ConI); 4299 op_cost(0); 4300 format %{ %} 4301 interface(CONST_INTER); 4302 %} 4303 4304 operand immIpow2minus1() %{ 4305 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 4306 match(ConI); 4307 op_cost(0); 4308 format %{ %} 4309 interface(CONST_INTER); 4310 %} 4311 4312 operand immIpowerOf2() %{ 4313 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 4314 match(ConI); 4315 op_cost(0); 4316 format %{ %} 4317 interface(CONST_INTER); 4318 %} 4319 4320 // Unsigned Integer Immediate: the values 0-31 4321 operand uimmI5() %{ 4322 predicate(Assembler::is_uimm(n->get_int(), 5)); 4323 match(ConI); 4324 op_cost(0); 4325 format %{ %} 4326 interface(CONST_INTER); 4327 %} 4328 4329 // Unsigned Integer Immediate: 6-bit 4330 operand uimmI6() %{ 4331 predicate(Assembler::is_uimm(n->get_int(), 6)); 4332 match(ConI); 4333 op_cost(0); 4334 format %{ %} 4335 interface(CONST_INTER); 4336 %} 4337 4338 // Unsigned Integer Immediate: 6-bit int, greater than 32 4339 operand uimmI6_ge32() %{ 4340 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4341 match(ConI); 4342 op_cost(0); 4343 format %{ %} 4344 interface(CONST_INTER); 4345 %} 4346 4347 // Unsigned Integer Immediate: 15-bit 4348 operand uimmI15() %{ 4349 predicate(Assembler::is_uimm(n->get_int(), 15)); 4350 match(ConI); 4351 op_cost(0); 4352 format %{ %} 4353 interface(CONST_INTER); 4354 %} 4355 4356 // Unsigned Integer Immediate: 16-bit 4357 operand uimmI16() %{ 4358 predicate(Assembler::is_uimm(n->get_int(), 16)); 4359 match(ConI); 4360 op_cost(0); 4361 format %{ %} 4362 interface(CONST_INTER); 4363 %} 4364 4365 // constant 'int 0'. 4366 operand immI_0() %{ 4367 predicate(n->get_int() == 0); 4368 match(ConI); 4369 op_cost(0); 4370 format %{ %} 4371 interface(CONST_INTER); 4372 %} 4373 4374 // constant 'int 1'. 4375 operand immI_1() %{ 4376 predicate(n->get_int() == 1); 4377 match(ConI); 4378 op_cost(0); 4379 format %{ %} 4380 interface(CONST_INTER); 4381 %} 4382 4383 // constant 'int -1'. 4384 operand immI_minus1() %{ 4385 predicate(n->get_int() == -1); 4386 match(ConI); 4387 op_cost(0); 4388 format %{ %} 4389 interface(CONST_INTER); 4390 %} 4391 4392 // int value 16. 4393 operand immI_16() %{ 4394 predicate(n->get_int() == 16); 4395 match(ConI); 4396 op_cost(0); 4397 format %{ %} 4398 interface(CONST_INTER); 4399 %} 4400 4401 // int value 24. 4402 operand immI_24() %{ 4403 predicate(n->get_int() == 24); 4404 match(ConI); 4405 op_cost(0); 4406 format %{ %} 4407 interface(CONST_INTER); 4408 %} 4409 4410 // Compressed oops constants 4411 // Pointer Immediate 4412 operand immN() %{ 4413 match(ConN); 4414 4415 op_cost(10); 4416 format %{ %} 4417 interface(CONST_INTER); 4418 %} 4419 4420 // NULL Pointer Immediate 4421 operand immN_0() %{ 4422 predicate(n->get_narrowcon() == 0); 4423 match(ConN); 4424 4425 op_cost(0); 4426 format %{ %} 4427 interface(CONST_INTER); 4428 %} 4429 4430 // Compressed klass constants 4431 operand immNKlass() %{ 4432 match(ConNKlass); 4433 4434 op_cost(0); 4435 format %{ %} 4436 interface(CONST_INTER); 4437 %} 4438 4439 // This operand can be used to avoid matching of an instruct 4440 // with chain rule. 4441 operand immNKlass_NM() %{ 4442 match(ConNKlass); 4443 predicate(false); 4444 op_cost(0); 4445 format %{ %} 4446 interface(CONST_INTER); 4447 %} 4448 4449 // Pointer Immediate: 64-bit 4450 operand immP() %{ 4451 match(ConP); 4452 op_cost(0); 4453 format %{ %} 4454 interface(CONST_INTER); 4455 %} 4456 4457 // Operand to avoid match of loadConP. 4458 // This operand can be used to avoid matching of an instruct 4459 // with chain rule. 4460 operand immP_NM() %{ 4461 match(ConP); 4462 predicate(false); 4463 op_cost(0); 4464 format %{ %} 4465 interface(CONST_INTER); 4466 %} 4467 4468 // costant 'pointer 0'. 4469 operand immP_0() %{ 4470 predicate(n->get_ptr() == 0); 4471 match(ConP); 4472 op_cost(0); 4473 format %{ %} 4474 interface(CONST_INTER); 4475 %} 4476 4477 // pointer 0x0 or 0x1 4478 operand immP_0or1() %{ 4479 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4480 match(ConP); 4481 op_cost(0); 4482 format %{ %} 4483 interface(CONST_INTER); 4484 %} 4485 4486 operand immL() %{ 4487 match(ConL); 4488 op_cost(40); 4489 format %{ %} 4490 interface(CONST_INTER); 4491 %} 4492 4493 operand immLmax30() %{ 4494 predicate((n->get_long() <= 30)); 4495 match(ConL); 4496 op_cost(0); 4497 format %{ %} 4498 interface(CONST_INTER); 4499 %} 4500 4501 // Long Immediate: 16-bit 4502 operand immL16() %{ 4503 predicate(Assembler::is_simm(n->get_long(), 16)); 4504 match(ConL); 4505 op_cost(0); 4506 format %{ %} 4507 interface(CONST_INTER); 4508 %} 4509 4510 // Long Immediate: 16-bit, 4-aligned 4511 operand immL16Alg4() %{ 4512 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4513 match(ConL); 4514 op_cost(0); 4515 format %{ %} 4516 interface(CONST_INTER); 4517 %} 4518 4519 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4520 operand immL32hi16() %{ 4521 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4522 match(ConL); 4523 op_cost(0); 4524 format %{ %} 4525 interface(CONST_INTER); 4526 %} 4527 4528 // Long Immediate: 32-bit 4529 operand immL32() %{ 4530 predicate(Assembler::is_simm(n->get_long(), 32)); 4531 match(ConL); 4532 op_cost(0); 4533 format %{ %} 4534 interface(CONST_INTER); 4535 %} 4536 4537 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4538 operand immLhighest16() %{ 4539 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4540 match(ConL); 4541 op_cost(0); 4542 format %{ %} 4543 interface(CONST_INTER); 4544 %} 4545 4546 operand immLnegpow2() %{ 4547 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4548 match(ConL); 4549 op_cost(0); 4550 format %{ %} 4551 interface(CONST_INTER); 4552 %} 4553 4554 operand immLpow2minus1() %{ 4555 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4556 (n->get_long() != (jlong)0xffffffffffffffffL)); 4557 match(ConL); 4558 op_cost(0); 4559 format %{ %} 4560 interface(CONST_INTER); 4561 %} 4562 4563 // constant 'long 0'. 4564 operand immL_0() %{ 4565 predicate(n->get_long() == 0L); 4566 match(ConL); 4567 op_cost(0); 4568 format %{ %} 4569 interface(CONST_INTER); 4570 %} 4571 4572 // constat ' long -1'. 4573 operand immL_minus1() %{ 4574 predicate(n->get_long() == -1L); 4575 match(ConL); 4576 op_cost(0); 4577 format %{ %} 4578 interface(CONST_INTER); 4579 %} 4580 4581 // Long Immediate: low 32-bit mask 4582 operand immL_32bits() %{ 4583 predicate(n->get_long() == 0xFFFFFFFFL); 4584 match(ConL); 4585 op_cost(0); 4586 format %{ %} 4587 interface(CONST_INTER); 4588 %} 4589 4590 // Unsigned Long Immediate: 16-bit 4591 operand uimmL16() %{ 4592 predicate(Assembler::is_uimm(n->get_long(), 16)); 4593 match(ConL); 4594 op_cost(0); 4595 format %{ %} 4596 interface(CONST_INTER); 4597 %} 4598 4599 // Float Immediate 4600 operand immF() %{ 4601 match(ConF); 4602 op_cost(40); 4603 format %{ %} 4604 interface(CONST_INTER); 4605 %} 4606 4607 // Float Immediate: +0.0f. 4608 operand immF_0() %{ 4609 predicate(jint_cast(n->getf()) == 0); 4610 match(ConF); 4611 4612 op_cost(0); 4613 format %{ %} 4614 interface(CONST_INTER); 4615 %} 4616 4617 // Double Immediate 4618 operand immD() %{ 4619 match(ConD); 4620 op_cost(40); 4621 format %{ %} 4622 interface(CONST_INTER); 4623 %} 4624 4625 // Integer Register Operands 4626 // Integer Destination Register 4627 // See definition of reg_class bits32_reg_rw. 4628 operand iRegIdst() %{ 4629 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4630 match(RegI); 4631 match(rscratch1RegI); 4632 match(rscratch2RegI); 4633 match(rarg1RegI); 4634 match(rarg2RegI); 4635 match(rarg3RegI); 4636 match(rarg4RegI); 4637 format %{ %} 4638 interface(REG_INTER); 4639 %} 4640 4641 // Integer Source Register 4642 // See definition of reg_class bits32_reg_ro. 4643 operand iRegIsrc() %{ 4644 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4645 match(RegI); 4646 match(rscratch1RegI); 4647 match(rscratch2RegI); 4648 match(rarg1RegI); 4649 match(rarg2RegI); 4650 match(rarg3RegI); 4651 match(rarg4RegI); 4652 format %{ %} 4653 interface(REG_INTER); 4654 %} 4655 4656 operand rscratch1RegI() %{ 4657 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4658 match(iRegIdst); 4659 format %{ %} 4660 interface(REG_INTER); 4661 %} 4662 4663 operand rscratch2RegI() %{ 4664 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4665 match(iRegIdst); 4666 format %{ %} 4667 interface(REG_INTER); 4668 %} 4669 4670 operand rarg1RegI() %{ 4671 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4672 match(iRegIdst); 4673 format %{ %} 4674 interface(REG_INTER); 4675 %} 4676 4677 operand rarg2RegI() %{ 4678 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4679 match(iRegIdst); 4680 format %{ %} 4681 interface(REG_INTER); 4682 %} 4683 4684 operand rarg3RegI() %{ 4685 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4686 match(iRegIdst); 4687 format %{ %} 4688 interface(REG_INTER); 4689 %} 4690 4691 operand rarg4RegI() %{ 4692 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4693 match(iRegIdst); 4694 format %{ %} 4695 interface(REG_INTER); 4696 %} 4697 4698 operand rarg1RegL() %{ 4699 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4700 match(iRegLdst); 4701 format %{ %} 4702 interface(REG_INTER); 4703 %} 4704 4705 operand rarg2RegL() %{ 4706 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4707 match(iRegLdst); 4708 format %{ %} 4709 interface(REG_INTER); 4710 %} 4711 4712 operand rarg3RegL() %{ 4713 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4714 match(iRegLdst); 4715 format %{ %} 4716 interface(REG_INTER); 4717 %} 4718 4719 operand rarg4RegL() %{ 4720 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4721 match(iRegLdst); 4722 format %{ %} 4723 interface(REG_INTER); 4724 %} 4725 4726 // Pointer Destination Register 4727 // See definition of reg_class bits64_reg_rw. 4728 operand iRegPdst() %{ 4729 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4730 match(RegP); 4731 match(rscratch1RegP); 4732 match(rscratch2RegP); 4733 match(rarg1RegP); 4734 match(rarg2RegP); 4735 match(rarg3RegP); 4736 match(rarg4RegP); 4737 format %{ %} 4738 interface(REG_INTER); 4739 %} 4740 4741 // Pointer Destination Register 4742 // Operand not using r11 and r12 (killed in epilog). 4743 operand iRegPdstNoScratch() %{ 4744 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4745 match(RegP); 4746 match(rarg1RegP); 4747 match(rarg2RegP); 4748 match(rarg3RegP); 4749 match(rarg4RegP); 4750 format %{ %} 4751 interface(REG_INTER); 4752 %} 4753 4754 // Pointer Source Register 4755 // See definition of reg_class bits64_reg_ro. 4756 operand iRegPsrc() %{ 4757 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4758 match(RegP); 4759 match(iRegPdst); 4760 match(rscratch1RegP); 4761 match(rscratch2RegP); 4762 match(rarg1RegP); 4763 match(rarg2RegP); 4764 match(rarg3RegP); 4765 match(rarg4RegP); 4766 match(threadRegP); 4767 format %{ %} 4768 interface(REG_INTER); 4769 %} 4770 4771 // Thread operand. 4772 operand threadRegP() %{ 4773 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4774 match(iRegPdst); 4775 format %{ "R16" %} 4776 interface(REG_INTER); 4777 %} 4778 4779 operand rscratch1RegP() %{ 4780 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4781 match(iRegPdst); 4782 format %{ "R11" %} 4783 interface(REG_INTER); 4784 %} 4785 4786 operand rscratch2RegP() %{ 4787 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4788 match(iRegPdst); 4789 format %{ %} 4790 interface(REG_INTER); 4791 %} 4792 4793 operand rarg1RegP() %{ 4794 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4795 match(iRegPdst); 4796 format %{ %} 4797 interface(REG_INTER); 4798 %} 4799 4800 operand rarg2RegP() %{ 4801 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4802 match(iRegPdst); 4803 format %{ %} 4804 interface(REG_INTER); 4805 %} 4806 4807 operand rarg3RegP() %{ 4808 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4809 match(iRegPdst); 4810 format %{ %} 4811 interface(REG_INTER); 4812 %} 4813 4814 operand rarg4RegP() %{ 4815 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4816 match(iRegPdst); 4817 format %{ %} 4818 interface(REG_INTER); 4819 %} 4820 4821 operand iRegNsrc() %{ 4822 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4823 match(RegN); 4824 match(iRegNdst); 4825 4826 format %{ %} 4827 interface(REG_INTER); 4828 %} 4829 4830 operand iRegNdst() %{ 4831 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4832 match(RegN); 4833 4834 format %{ %} 4835 interface(REG_INTER); 4836 %} 4837 4838 // Long Destination Register 4839 // See definition of reg_class bits64_reg_rw. 4840 operand iRegLdst() %{ 4841 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4842 match(RegL); 4843 match(rscratch1RegL); 4844 match(rscratch2RegL); 4845 format %{ %} 4846 interface(REG_INTER); 4847 %} 4848 4849 // Long Source Register 4850 // See definition of reg_class bits64_reg_ro. 4851 operand iRegLsrc() %{ 4852 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4853 match(RegL); 4854 match(iRegLdst); 4855 match(rscratch1RegL); 4856 match(rscratch2RegL); 4857 format %{ %} 4858 interface(REG_INTER); 4859 %} 4860 4861 // Special operand for ConvL2I. 4862 operand iRegL2Isrc(iRegLsrc reg) %{ 4863 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4864 match(ConvL2I reg); 4865 format %{ "ConvL2I($reg)" %} 4866 interface(REG_INTER) 4867 %} 4868 4869 operand rscratch1RegL() %{ 4870 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4871 match(RegL); 4872 format %{ %} 4873 interface(REG_INTER); 4874 %} 4875 4876 operand rscratch2RegL() %{ 4877 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4878 match(RegL); 4879 format %{ %} 4880 interface(REG_INTER); 4881 %} 4882 4883 // Condition Code Flag Registers 4884 operand flagsReg() %{ 4885 constraint(ALLOC_IN_RC(int_flags)); 4886 match(RegFlags); 4887 format %{ %} 4888 interface(REG_INTER); 4889 %} 4890 4891 operand flagsRegSrc() %{ 4892 constraint(ALLOC_IN_RC(int_flags_ro)); 4893 match(RegFlags); 4894 match(flagsReg); 4895 match(flagsRegCR0); 4896 format %{ %} 4897 interface(REG_INTER); 4898 %} 4899 4900 // Condition Code Flag Register CR0 4901 operand flagsRegCR0() %{ 4902 constraint(ALLOC_IN_RC(int_flags_CR0)); 4903 match(RegFlags); 4904 format %{ "CR0" %} 4905 interface(REG_INTER); 4906 %} 4907 4908 operand flagsRegCR1() %{ 4909 constraint(ALLOC_IN_RC(int_flags_CR1)); 4910 match(RegFlags); 4911 format %{ "CR1" %} 4912 interface(REG_INTER); 4913 %} 4914 4915 operand flagsRegCR6() %{ 4916 constraint(ALLOC_IN_RC(int_flags_CR6)); 4917 match(RegFlags); 4918 format %{ "CR6" %} 4919 interface(REG_INTER); 4920 %} 4921 4922 operand regCTR() %{ 4923 constraint(ALLOC_IN_RC(ctr_reg)); 4924 // RegFlags should work. Introducing a RegSpecial type would cause a 4925 // lot of changes. 4926 match(RegFlags); 4927 format %{"SR_CTR" %} 4928 interface(REG_INTER); 4929 %} 4930 4931 operand regD() %{ 4932 constraint(ALLOC_IN_RC(dbl_reg)); 4933 match(RegD); 4934 format %{ %} 4935 interface(REG_INTER); 4936 %} 4937 4938 operand regF() %{ 4939 constraint(ALLOC_IN_RC(flt_reg)); 4940 match(RegF); 4941 format %{ %} 4942 interface(REG_INTER); 4943 %} 4944 4945 // Special Registers 4946 4947 // Method Register 4948 operand inline_cache_regP(iRegPdst reg) %{ 4949 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4950 match(reg); 4951 format %{ %} 4952 interface(REG_INTER); 4953 %} 4954 4955 operand compiler_method_oop_regP(iRegPdst reg) %{ 4956 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4957 match(reg); 4958 format %{ %} 4959 interface(REG_INTER); 4960 %} 4961 4962 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4963 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4964 match(reg); 4965 format %{ %} 4966 interface(REG_INTER); 4967 %} 4968 4969 // Operands to remove register moves in unscaled mode. 4970 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4971 operand iRegP2N(iRegPsrc reg) %{ 4972 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4973 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4974 match(EncodeP reg); 4975 format %{ "$reg" %} 4976 interface(REG_INTER) 4977 %} 4978 4979 operand iRegN2P(iRegNsrc reg) %{ 4980 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4981 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4982 match(DecodeN reg); 4983 format %{ "$reg" %} 4984 interface(REG_INTER) 4985 %} 4986 4987 operand iRegN2P_klass(iRegNsrc reg) %{ 4988 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4989 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4990 match(DecodeNKlass reg); 4991 format %{ "$reg" %} 4992 interface(REG_INTER) 4993 %} 4994 4995 //----------Complex Operands--------------------------------------------------- 4996 // Indirect Memory Reference 4997 operand indirect(iRegPsrc reg) %{ 4998 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4999 match(reg); 5000 op_cost(100); 5001 format %{ "[$reg]" %} 5002 interface(MEMORY_INTER) %{ 5003 base($reg); 5004 index(0x0); 5005 scale(0x0); 5006 disp(0x0); 5007 %} 5008 %} 5009 5010 // Indirect with Offset 5011 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 5012 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5013 match(AddP reg offset); 5014 op_cost(100); 5015 format %{ "[$reg + $offset]" %} 5016 interface(MEMORY_INTER) %{ 5017 base($reg); 5018 index(0x0); 5019 scale(0x0); 5020 disp($offset); 5021 %} 5022 %} 5023 5024 // Indirect with 4-aligned Offset 5025 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 5026 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5027 match(AddP reg offset); 5028 op_cost(100); 5029 format %{ "[$reg + $offset]" %} 5030 interface(MEMORY_INTER) %{ 5031 base($reg); 5032 index(0x0); 5033 scale(0x0); 5034 disp($offset); 5035 %} 5036 %} 5037 5038 //----------Complex Operands for Compressed OOPs------------------------------- 5039 // Compressed OOPs with narrow_oop_shift == 0. 5040 5041 // Indirect Memory Reference, compressed OOP 5042 operand indirectNarrow(iRegNsrc reg) %{ 5043 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5044 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5045 match(DecodeN reg); 5046 op_cost(100); 5047 format %{ "[$reg]" %} 5048 interface(MEMORY_INTER) %{ 5049 base($reg); 5050 index(0x0); 5051 scale(0x0); 5052 disp(0x0); 5053 %} 5054 %} 5055 5056 operand indirectNarrow_klass(iRegNsrc reg) %{ 5057 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5058 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5059 match(DecodeNKlass reg); 5060 op_cost(100); 5061 format %{ "[$reg]" %} 5062 interface(MEMORY_INTER) %{ 5063 base($reg); 5064 index(0x0); 5065 scale(0x0); 5066 disp(0x0); 5067 %} 5068 %} 5069 5070 // Indirect with Offset, compressed OOP 5071 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 5072 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5073 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5074 match(AddP (DecodeN reg) offset); 5075 op_cost(100); 5076 format %{ "[$reg + $offset]" %} 5077 interface(MEMORY_INTER) %{ 5078 base($reg); 5079 index(0x0); 5080 scale(0x0); 5081 disp($offset); 5082 %} 5083 %} 5084 5085 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5086 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5087 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5088 match(AddP (DecodeNKlass reg) offset); 5089 op_cost(100); 5090 format %{ "[$reg + $offset]" %} 5091 interface(MEMORY_INTER) %{ 5092 base($reg); 5093 index(0x0); 5094 scale(0x0); 5095 disp($offset); 5096 %} 5097 %} 5098 5099 // Indirect with 4-aligned Offset, compressed OOP 5100 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 5101 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5102 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5103 match(AddP (DecodeN reg) offset); 5104 op_cost(100); 5105 format %{ "[$reg + $offset]" %} 5106 interface(MEMORY_INTER) %{ 5107 base($reg); 5108 index(0x0); 5109 scale(0x0); 5110 disp($offset); 5111 %} 5112 %} 5113 5114 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5115 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5116 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5117 match(AddP (DecodeNKlass reg) offset); 5118 op_cost(100); 5119 format %{ "[$reg + $offset]" %} 5120 interface(MEMORY_INTER) %{ 5121 base($reg); 5122 index(0x0); 5123 scale(0x0); 5124 disp($offset); 5125 %} 5126 %} 5127 5128 //----------Special Memory Operands-------------------------------------------- 5129 // Stack Slot Operand 5130 // 5131 // This operand is used for loading and storing temporary values on 5132 // the stack where a match requires a value to flow through memory. 5133 operand stackSlotI(sRegI reg) %{ 5134 constraint(ALLOC_IN_RC(stack_slots)); 5135 op_cost(100); 5136 //match(RegI); 5137 format %{ "[sp+$reg]" %} 5138 interface(MEMORY_INTER) %{ 5139 base(0x1); // R1_SP 5140 index(0x0); 5141 scale(0x0); 5142 disp($reg); // Stack Offset 5143 %} 5144 %} 5145 5146 operand stackSlotL(sRegL reg) %{ 5147 constraint(ALLOC_IN_RC(stack_slots)); 5148 op_cost(100); 5149 //match(RegL); 5150 format %{ "[sp+$reg]" %} 5151 interface(MEMORY_INTER) %{ 5152 base(0x1); // R1_SP 5153 index(0x0); 5154 scale(0x0); 5155 disp($reg); // Stack Offset 5156 %} 5157 %} 5158 5159 operand stackSlotP(sRegP reg) %{ 5160 constraint(ALLOC_IN_RC(stack_slots)); 5161 op_cost(100); 5162 //match(RegP); 5163 format %{ "[sp+$reg]" %} 5164 interface(MEMORY_INTER) %{ 5165 base(0x1); // R1_SP 5166 index(0x0); 5167 scale(0x0); 5168 disp($reg); // Stack Offset 5169 %} 5170 %} 5171 5172 operand stackSlotF(sRegF reg) %{ 5173 constraint(ALLOC_IN_RC(stack_slots)); 5174 op_cost(100); 5175 //match(RegF); 5176 format %{ "[sp+$reg]" %} 5177 interface(MEMORY_INTER) %{ 5178 base(0x1); // R1_SP 5179 index(0x0); 5180 scale(0x0); 5181 disp($reg); // Stack Offset 5182 %} 5183 %} 5184 5185 operand stackSlotD(sRegD reg) %{ 5186 constraint(ALLOC_IN_RC(stack_slots)); 5187 op_cost(100); 5188 //match(RegD); 5189 format %{ "[sp+$reg]" %} 5190 interface(MEMORY_INTER) %{ 5191 base(0x1); // R1_SP 5192 index(0x0); 5193 scale(0x0); 5194 disp($reg); // Stack Offset 5195 %} 5196 %} 5197 5198 // Operands for expressing Control Flow 5199 // NOTE: Label is a predefined operand which should not be redefined in 5200 // the AD file. It is generically handled within the ADLC. 5201 5202 //----------Conditional Branch Operands---------------------------------------- 5203 // Comparison Op 5204 // 5205 // This is the operation of the comparison, and is limited to the 5206 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5207 // (!=). 5208 // 5209 // Other attributes of the comparison, such as unsignedness, are specified 5210 // by the comparison instruction that sets a condition code flags register. 5211 // That result is represented by a flags operand whose subtype is appropriate 5212 // to the unsignedness (etc.) of the comparison. 5213 // 5214 // Later, the instruction which matches both the Comparison Op (a Bool) and 5215 // the flags (produced by the Cmp) specifies the coding of the comparison op 5216 // by matching a specific subtype of Bool operand below. 5217 5218 // When used for floating point comparisons: unordered same as less. 5219 operand cmpOp() %{ 5220 match(Bool); 5221 format %{ "" %} 5222 interface(COND_INTER) %{ 5223 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5224 // BO & BI 5225 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5226 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5227 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5228 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5229 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5230 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5231 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5232 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5233 %} 5234 %} 5235 5236 //----------OPERAND CLASSES---------------------------------------------------- 5237 // Operand Classes are groups of operands that are used to simplify 5238 // instruction definitions by not requiring the AD writer to specify 5239 // seperate instructions for every form of operand when the 5240 // instruction accepts multiple operand types with the same basic 5241 // encoding and format. The classic case of this is memory operands. 5242 // Indirect is not included since its use is limited to Compare & Swap. 5243 5244 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5245 // Memory operand where offsets are 4-aligned. Required for ld, std. 5246 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5247 opclass indirectMemory(indirect, indirectNarrow); 5248 5249 // Special opclass for I and ConvL2I. 5250 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5251 5252 // Operand classes to match encode and decode. iRegN_P2N is only used 5253 // for storeN. I have never seen an encode node elsewhere. 5254 opclass iRegN_P2N(iRegNsrc, iRegP2N); 5255 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5256 5257 //----------PIPELINE----------------------------------------------------------- 5258 5259 pipeline %{ 5260 5261 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5262 // J. Res. & Dev., No. 1, Jan. 2002. 5263 5264 //----------ATTRIBUTES--------------------------------------------------------- 5265 attributes %{ 5266 5267 // Power4 instructions are of fixed length. 5268 fixed_size_instructions; 5269 5270 // TODO: if `bundle' means number of instructions fetched 5271 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5272 // max instructions issued per cycle, this is 5. 5273 max_instructions_per_bundle = 8; 5274 5275 // A Power4 instruction is 4 bytes long. 5276 instruction_unit_size = 4; 5277 5278 // The Power4 processor fetches 64 bytes... 5279 instruction_fetch_unit_size = 64; 5280 5281 // ...in one line 5282 instruction_fetch_units = 1 5283 5284 // Unused, list one so that array generated by adlc is not empty. 5285 // Aix compiler chokes if _nop_count = 0. 5286 nops(fxNop); 5287 %} 5288 5289 //----------RESOURCES---------------------------------------------------------- 5290 // Resources are the functional units available to the machine 5291 resources( 5292 PPC_BR, // branch unit 5293 PPC_CR, // condition unit 5294 PPC_FX1, // integer arithmetic unit 1 5295 PPC_FX2, // integer arithmetic unit 2 5296 PPC_LDST1, // load/store unit 1 5297 PPC_LDST2, // load/store unit 2 5298 PPC_FP1, // float arithmetic unit 1 5299 PPC_FP2, // float arithmetic unit 2 5300 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5301 PPC_FX = PPC_FX1 | PPC_FX2, 5302 PPC_FP = PPC_FP1 | PPC_FP2 5303 ); 5304 5305 //----------PIPELINE DESCRIPTION----------------------------------------------- 5306 // Pipeline Description specifies the stages in the machine's pipeline 5307 pipe_desc( 5308 // Power4 longest pipeline path 5309 PPC_IF, // instruction fetch 5310 PPC_IC, 5311 //PPC_BP, // branch prediction 5312 PPC_D0, // decode 5313 PPC_D1, // decode 5314 PPC_D2, // decode 5315 PPC_D3, // decode 5316 PPC_Xfer1, 5317 PPC_GD, // group definition 5318 PPC_MP, // map 5319 PPC_ISS, // issue 5320 PPC_RF, // resource fetch 5321 PPC_EX1, // execute (all units) 5322 PPC_EX2, // execute (FP, LDST) 5323 PPC_EX3, // execute (FP, LDST) 5324 PPC_EX4, // execute (FP) 5325 PPC_EX5, // execute (FP) 5326 PPC_EX6, // execute (FP) 5327 PPC_WB, // write back 5328 PPC_Xfer2, 5329 PPC_CP 5330 ); 5331 5332 //----------PIPELINE CLASSES--------------------------------------------------- 5333 // Pipeline Classes describe the stages in which input and output are 5334 // referenced by the hardware pipeline. 5335 5336 // Simple pipeline classes. 5337 5338 // Default pipeline class. 5339 pipe_class pipe_class_default() %{ 5340 single_instruction; 5341 fixed_latency(2); 5342 %} 5343 5344 // Pipeline class for empty instructions. 5345 pipe_class pipe_class_empty() %{ 5346 single_instruction; 5347 fixed_latency(0); 5348 %} 5349 5350 // Pipeline class for compares. 5351 pipe_class pipe_class_compare() %{ 5352 single_instruction; 5353 fixed_latency(16); 5354 %} 5355 5356 // Pipeline class for traps. 5357 pipe_class pipe_class_trap() %{ 5358 single_instruction; 5359 fixed_latency(100); 5360 %} 5361 5362 // Pipeline class for memory operations. 5363 pipe_class pipe_class_memory() %{ 5364 single_instruction; 5365 fixed_latency(16); 5366 %} 5367 5368 // Pipeline class for call. 5369 pipe_class pipe_class_call() %{ 5370 single_instruction; 5371 fixed_latency(100); 5372 %} 5373 5374 // Define the class for the Nop node. 5375 define %{ 5376 MachNop = pipe_class_default; 5377 %} 5378 5379 %} 5380 5381 //----------INSTRUCTIONS------------------------------------------------------- 5382 5383 // Naming of instructions: 5384 // opA_operB / opA_operB_operC: 5385 // Operation 'op' with one or two source operands 'oper'. Result 5386 // type is A, source operand types are B and C. 5387 // Iff A == B == C, B and C are left out. 5388 // 5389 // The instructions are ordered according to the following scheme: 5390 // - loads 5391 // - load constants 5392 // - prefetch 5393 // - store 5394 // - encode/decode 5395 // - membar 5396 // - conditional moves 5397 // - compare & swap 5398 // - arithmetic and logic operations 5399 // * int: Add, Sub, Mul, Div, Mod 5400 // * int: lShift, arShift, urShift, rot 5401 // * float: Add, Sub, Mul, Div 5402 // * and, or, xor ... 5403 // - register moves: float <-> int, reg <-> stack, repl 5404 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5405 // - conv (low level type cast requiring bit changes (sign extend etc) 5406 // - compares, range & zero checks. 5407 // - branches 5408 // - complex operations, intrinsics, min, max, replicate 5409 // - lock 5410 // - Calls 5411 // 5412 // If there are similar instructions with different types they are sorted: 5413 // int before float 5414 // small before big 5415 // signed before unsigned 5416 // e.g., loadS before loadUS before loadI before loadF. 5417 5418 5419 //----------Load/Store Instructions-------------------------------------------- 5420 5421 //----------Load Instructions-------------------------------------------------- 5422 5423 // Converts byte to int. 5424 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5425 // reuses the 'amount' operand, but adlc expects that operand specification 5426 // and operands in match rule are equivalent. 5427 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5428 effect(DEF dst, USE src); 5429 format %{ "EXTSB $dst, $src \t// byte->int" %} 5430 size(4); 5431 ins_encode %{ 5432 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5433 __ extsb($dst$$Register, $src$$Register); 5434 %} 5435 ins_pipe(pipe_class_default); 5436 %} 5437 5438 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5439 // match-rule, false predicate 5440 match(Set dst (LoadB mem)); 5441 predicate(false); 5442 5443 format %{ "LBZ $dst, $mem" %} 5444 size(4); 5445 ins_encode( enc_lbz(dst, mem) ); 5446 ins_pipe(pipe_class_memory); 5447 %} 5448 5449 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5450 // match-rule, false predicate 5451 match(Set dst (LoadB mem)); 5452 predicate(false); 5453 5454 format %{ "LBZ $dst, $mem\n\t" 5455 "TWI $dst\n\t" 5456 "ISYNC" %} 5457 size(12); 5458 ins_encode( enc_lbz_ac(dst, mem) ); 5459 ins_pipe(pipe_class_memory); 5460 %} 5461 5462 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5463 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5464 match(Set dst (LoadB mem)); 5465 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5466 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5467 expand %{ 5468 iRegIdst tmp; 5469 loadUB_indirect(tmp, mem); 5470 convB2I_reg_2(dst, tmp); 5471 %} 5472 %} 5473 5474 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5475 match(Set dst (LoadB mem)); 5476 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5477 expand %{ 5478 iRegIdst tmp; 5479 loadUB_indirect_ac(tmp, mem); 5480 convB2I_reg_2(dst, tmp); 5481 %} 5482 %} 5483 5484 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5485 // match-rule, false predicate 5486 match(Set dst (LoadB mem)); 5487 predicate(false); 5488 5489 format %{ "LBZ $dst, $mem" %} 5490 size(4); 5491 ins_encode( enc_lbz(dst, mem) ); 5492 ins_pipe(pipe_class_memory); 5493 %} 5494 5495 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5496 // match-rule, false predicate 5497 match(Set dst (LoadB mem)); 5498 predicate(false); 5499 5500 format %{ "LBZ $dst, $mem\n\t" 5501 "TWI $dst\n\t" 5502 "ISYNC" %} 5503 size(12); 5504 ins_encode( enc_lbz_ac(dst, mem) ); 5505 ins_pipe(pipe_class_memory); 5506 %} 5507 5508 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5509 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5510 match(Set dst (LoadB mem)); 5511 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5512 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5513 5514 expand %{ 5515 iRegIdst tmp; 5516 loadUB_indOffset16(tmp, mem); 5517 convB2I_reg_2(dst, tmp); 5518 %} 5519 %} 5520 5521 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5522 match(Set dst (LoadB mem)); 5523 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5524 5525 expand %{ 5526 iRegIdst tmp; 5527 loadUB_indOffset16_ac(tmp, mem); 5528 convB2I_reg_2(dst, tmp); 5529 %} 5530 %} 5531 5532 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5533 instruct loadUB(iRegIdst dst, memory mem) %{ 5534 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5535 match(Set dst (LoadUB mem)); 5536 ins_cost(MEMORY_REF_COST); 5537 5538 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5539 size(4); 5540 ins_encode( enc_lbz(dst, mem) ); 5541 ins_pipe(pipe_class_memory); 5542 %} 5543 5544 // Load Unsigned Byte (8bit UNsigned) acquire. 5545 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5546 match(Set dst (LoadUB mem)); 5547 ins_cost(3*MEMORY_REF_COST); 5548 5549 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5550 "TWI $dst\n\t" 5551 "ISYNC" %} 5552 size(12); 5553 ins_encode( enc_lbz_ac(dst, mem) ); 5554 ins_pipe(pipe_class_memory); 5555 %} 5556 5557 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5558 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5559 match(Set dst (ConvI2L (LoadUB mem))); 5560 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5561 ins_cost(MEMORY_REF_COST); 5562 5563 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5564 size(4); 5565 ins_encode( enc_lbz(dst, mem) ); 5566 ins_pipe(pipe_class_memory); 5567 %} 5568 5569 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5570 match(Set dst (ConvI2L (LoadUB mem))); 5571 ins_cost(3*MEMORY_REF_COST); 5572 5573 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5574 "TWI $dst\n\t" 5575 "ISYNC" %} 5576 size(12); 5577 ins_encode( enc_lbz_ac(dst, mem) ); 5578 ins_pipe(pipe_class_memory); 5579 %} 5580 5581 // Load Short (16bit signed) 5582 instruct loadS(iRegIdst dst, memory mem) %{ 5583 match(Set dst (LoadS mem)); 5584 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5585 ins_cost(MEMORY_REF_COST); 5586 5587 format %{ "LHA $dst, $mem" %} 5588 size(4); 5589 ins_encode %{ 5590 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5591 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5592 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5593 %} 5594 ins_pipe(pipe_class_memory); 5595 %} 5596 5597 // Load Short (16bit signed) acquire. 5598 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5599 match(Set dst (LoadS mem)); 5600 ins_cost(3*MEMORY_REF_COST); 5601 5602 format %{ "LHA $dst, $mem\t acquire\n\t" 5603 "TWI $dst\n\t" 5604 "ISYNC" %} 5605 size(12); 5606 ins_encode %{ 5607 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5608 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5609 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5610 __ twi_0($dst$$Register); 5611 __ isync(); 5612 %} 5613 ins_pipe(pipe_class_memory); 5614 %} 5615 5616 // Load Char (16bit unsigned) 5617 instruct loadUS(iRegIdst dst, memory mem) %{ 5618 match(Set dst (LoadUS mem)); 5619 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5620 ins_cost(MEMORY_REF_COST); 5621 5622 format %{ "LHZ $dst, $mem" %} 5623 size(4); 5624 ins_encode( enc_lhz(dst, mem) ); 5625 ins_pipe(pipe_class_memory); 5626 %} 5627 5628 // Load Char (16bit unsigned) acquire. 5629 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5630 match(Set dst (LoadUS mem)); 5631 ins_cost(3*MEMORY_REF_COST); 5632 5633 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5634 "TWI $dst\n\t" 5635 "ISYNC" %} 5636 size(12); 5637 ins_encode( enc_lhz_ac(dst, mem) ); 5638 ins_pipe(pipe_class_memory); 5639 %} 5640 5641 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5642 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5643 match(Set dst (ConvI2L (LoadUS mem))); 5644 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5645 ins_cost(MEMORY_REF_COST); 5646 5647 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5648 size(4); 5649 ins_encode( enc_lhz(dst, mem) ); 5650 ins_pipe(pipe_class_memory); 5651 %} 5652 5653 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5654 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5655 match(Set dst (ConvI2L (LoadUS mem))); 5656 ins_cost(3*MEMORY_REF_COST); 5657 5658 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5659 "TWI $dst\n\t" 5660 "ISYNC" %} 5661 size(12); 5662 ins_encode( enc_lhz_ac(dst, mem) ); 5663 ins_pipe(pipe_class_memory); 5664 %} 5665 5666 // Load Integer. 5667 instruct loadI(iRegIdst dst, memory mem) %{ 5668 match(Set dst (LoadI mem)); 5669 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5670 ins_cost(MEMORY_REF_COST); 5671 5672 format %{ "LWZ $dst, $mem" %} 5673 size(4); 5674 ins_encode( enc_lwz(dst, mem) ); 5675 ins_pipe(pipe_class_memory); 5676 %} 5677 5678 // Load Integer acquire. 5679 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5680 match(Set dst (LoadI mem)); 5681 ins_cost(3*MEMORY_REF_COST); 5682 5683 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5684 "TWI $dst\n\t" 5685 "ISYNC" %} 5686 size(12); 5687 ins_encode( enc_lwz_ac(dst, mem) ); 5688 ins_pipe(pipe_class_memory); 5689 %} 5690 5691 // Match loading integer and casting it to unsigned int in 5692 // long register. 5693 // LoadI + ConvI2L + AndL 0xffffffff. 5694 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5695 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5696 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5697 ins_cost(MEMORY_REF_COST); 5698 5699 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5700 size(4); 5701 ins_encode( enc_lwz(dst, mem) ); 5702 ins_pipe(pipe_class_memory); 5703 %} 5704 5705 // Match loading integer and casting it to long. 5706 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5707 match(Set dst (ConvI2L (LoadI mem))); 5708 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5709 ins_cost(MEMORY_REF_COST); 5710 5711 format %{ "LWA $dst, $mem \t// loadI2L" %} 5712 size(4); 5713 ins_encode %{ 5714 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5715 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5716 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5717 %} 5718 ins_pipe(pipe_class_memory); 5719 %} 5720 5721 // Match loading integer and casting it to long - acquire. 5722 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5723 match(Set dst (ConvI2L (LoadI mem))); 5724 ins_cost(3*MEMORY_REF_COST); 5725 5726 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5727 "TWI $dst\n\t" 5728 "ISYNC" %} 5729 size(12); 5730 ins_encode %{ 5731 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5732 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5733 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5734 __ twi_0($dst$$Register); 5735 __ isync(); 5736 %} 5737 ins_pipe(pipe_class_memory); 5738 %} 5739 5740 // Load Long - aligned 5741 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5742 match(Set dst (LoadL mem)); 5743 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5744 ins_cost(MEMORY_REF_COST); 5745 5746 format %{ "LD $dst, $mem \t// long" %} 5747 size(4); 5748 ins_encode( enc_ld(dst, mem) ); 5749 ins_pipe(pipe_class_memory); 5750 %} 5751 5752 // Load Long - aligned acquire. 5753 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5754 match(Set dst (LoadL mem)); 5755 ins_cost(3*MEMORY_REF_COST); 5756 5757 format %{ "LD $dst, $mem \t// long acquire\n\t" 5758 "TWI $dst\n\t" 5759 "ISYNC" %} 5760 size(12); 5761 ins_encode( enc_ld_ac(dst, mem) ); 5762 ins_pipe(pipe_class_memory); 5763 %} 5764 5765 // Load Long - UNaligned 5766 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5767 match(Set dst (LoadL_unaligned mem)); 5768 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5769 ins_cost(MEMORY_REF_COST); 5770 5771 format %{ "LD $dst, $mem \t// unaligned long" %} 5772 size(4); 5773 ins_encode( enc_ld(dst, mem) ); 5774 ins_pipe(pipe_class_memory); 5775 %} 5776 5777 // Load nodes for superwords 5778 5779 // Load Aligned Packed Byte 5780 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5781 predicate(n->as_LoadVector()->memory_size() == 8); 5782 match(Set dst (LoadVector mem)); 5783 ins_cost(MEMORY_REF_COST); 5784 5785 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5786 size(4); 5787 ins_encode( enc_ld(dst, mem) ); 5788 ins_pipe(pipe_class_memory); 5789 %} 5790 5791 // Load Aligned Packed Byte 5792 instruct loadV16(vecX dst, indirect mem) %{ 5793 predicate(n->as_LoadVector()->memory_size() == 16); 5794 match(Set dst (LoadVector mem)); 5795 ins_cost(MEMORY_REF_COST); 5796 5797 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5798 size(4); 5799 ins_encode %{ 5800 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5801 %} 5802 ins_pipe(pipe_class_default); 5803 %} 5804 5805 // Load Range, range = array length (=jint) 5806 instruct loadRange(iRegIdst dst, memory mem) %{ 5807 match(Set dst (LoadRange mem)); 5808 ins_cost(MEMORY_REF_COST); 5809 5810 format %{ "LWZ $dst, $mem \t// range" %} 5811 size(4); 5812 ins_encode( enc_lwz(dst, mem) ); 5813 ins_pipe(pipe_class_memory); 5814 %} 5815 5816 // Load Compressed Pointer 5817 instruct loadN(iRegNdst dst, memory mem) %{ 5818 match(Set dst (LoadN mem)); 5819 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5820 ins_cost(MEMORY_REF_COST); 5821 5822 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5823 size(4); 5824 ins_encode( enc_lwz(dst, mem) ); 5825 ins_pipe(pipe_class_memory); 5826 %} 5827 5828 // Load Compressed Pointer acquire. 5829 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5830 match(Set dst (LoadN mem)); 5831 ins_cost(3*MEMORY_REF_COST); 5832 5833 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5834 "TWI $dst\n\t" 5835 "ISYNC" %} 5836 size(12); 5837 ins_encode( enc_lwz_ac(dst, mem) ); 5838 ins_pipe(pipe_class_memory); 5839 %} 5840 5841 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5842 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5843 match(Set dst (DecodeN (LoadN mem))); 5844 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5845 ins_cost(MEMORY_REF_COST); 5846 5847 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5848 size(4); 5849 ins_encode( enc_lwz(dst, mem) ); 5850 ins_pipe(pipe_class_memory); 5851 %} 5852 5853 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5854 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5855 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5856 _kids[0]->_leaf->as_Load()->is_unordered()); 5857 ins_cost(MEMORY_REF_COST); 5858 5859 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5860 size(4); 5861 ins_encode( enc_lwz(dst, mem) ); 5862 ins_pipe(pipe_class_memory); 5863 %} 5864 5865 // Load Pointer 5866 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5867 match(Set dst (LoadP mem)); 5868 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5869 ins_cost(MEMORY_REF_COST); 5870 5871 format %{ "LD $dst, $mem \t// ptr" %} 5872 size(4); 5873 ins_encode( enc_ld(dst, mem) ); 5874 ins_pipe(pipe_class_memory); 5875 %} 5876 5877 // Load Pointer acquire. 5878 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5879 match(Set dst (LoadP mem)); 5880 ins_cost(3*MEMORY_REF_COST); 5881 5882 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5883 "TWI $dst\n\t" 5884 "ISYNC" %} 5885 size(12); 5886 ins_encode( enc_ld_ac(dst, mem) ); 5887 ins_pipe(pipe_class_memory); 5888 %} 5889 5890 // LoadP + CastP2L 5891 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5892 match(Set dst (CastP2X (LoadP mem))); 5893 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5894 ins_cost(MEMORY_REF_COST); 5895 5896 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5897 size(4); 5898 ins_encode( enc_ld(dst, mem) ); 5899 ins_pipe(pipe_class_memory); 5900 %} 5901 5902 // Load compressed klass pointer. 5903 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5904 match(Set dst (LoadNKlass mem)); 5905 ins_cost(MEMORY_REF_COST); 5906 5907 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5908 size(4); 5909 ins_encode( enc_lwz(dst, mem) ); 5910 ins_pipe(pipe_class_memory); 5911 %} 5912 5913 // Load Klass Pointer 5914 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5915 match(Set dst (LoadKlass mem)); 5916 ins_cost(MEMORY_REF_COST); 5917 5918 format %{ "LD $dst, $mem \t// klass ptr" %} 5919 size(4); 5920 ins_encode( enc_ld(dst, mem) ); 5921 ins_pipe(pipe_class_memory); 5922 %} 5923 5924 // Load Float 5925 instruct loadF(regF dst, memory mem) %{ 5926 match(Set dst (LoadF mem)); 5927 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5928 ins_cost(MEMORY_REF_COST); 5929 5930 format %{ "LFS $dst, $mem" %} 5931 size(4); 5932 ins_encode %{ 5933 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5934 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5935 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5936 %} 5937 ins_pipe(pipe_class_memory); 5938 %} 5939 5940 // Load Float acquire. 5941 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5942 match(Set dst (LoadF mem)); 5943 effect(TEMP cr0); 5944 ins_cost(3*MEMORY_REF_COST); 5945 5946 format %{ "LFS $dst, $mem \t// acquire\n\t" 5947 "FCMPU cr0, $dst, $dst\n\t" 5948 "BNE cr0, next\n" 5949 "next:\n\t" 5950 "ISYNC" %} 5951 size(16); 5952 ins_encode %{ 5953 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5954 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5955 Label next; 5956 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5957 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5958 __ bne(CCR0, next); 5959 __ bind(next); 5960 __ isync(); 5961 %} 5962 ins_pipe(pipe_class_memory); 5963 %} 5964 5965 // Load Double - aligned 5966 instruct loadD(regD dst, memory mem) %{ 5967 match(Set dst (LoadD mem)); 5968 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5969 ins_cost(MEMORY_REF_COST); 5970 5971 format %{ "LFD $dst, $mem" %} 5972 size(4); 5973 ins_encode( enc_lfd(dst, mem) ); 5974 ins_pipe(pipe_class_memory); 5975 %} 5976 5977 // Load Double - aligned acquire. 5978 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5979 match(Set dst (LoadD mem)); 5980 effect(TEMP cr0); 5981 ins_cost(3*MEMORY_REF_COST); 5982 5983 format %{ "LFD $dst, $mem \t// acquire\n\t" 5984 "FCMPU cr0, $dst, $dst\n\t" 5985 "BNE cr0, next\n" 5986 "next:\n\t" 5987 "ISYNC" %} 5988 size(16); 5989 ins_encode %{ 5990 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5991 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5992 Label next; 5993 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5994 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5995 __ bne(CCR0, next); 5996 __ bind(next); 5997 __ isync(); 5998 %} 5999 ins_pipe(pipe_class_memory); 6000 %} 6001 6002 // Load Double - UNaligned 6003 instruct loadD_unaligned(regD dst, memory mem) %{ 6004 match(Set dst (LoadD_unaligned mem)); 6005 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 6006 ins_cost(MEMORY_REF_COST); 6007 6008 format %{ "LFD $dst, $mem" %} 6009 size(4); 6010 ins_encode( enc_lfd(dst, mem) ); 6011 ins_pipe(pipe_class_memory); 6012 %} 6013 6014 //----------Constants-------------------------------------------------------- 6015 6016 // Load MachConstantTableBase: add hi offset to global toc. 6017 // TODO: Handle hidden register r29 in bundler! 6018 instruct loadToc_hi(iRegLdst dst) %{ 6019 effect(DEF dst); 6020 ins_cost(DEFAULT_COST); 6021 6022 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 6023 size(4); 6024 ins_encode %{ 6025 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6026 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 6027 %} 6028 ins_pipe(pipe_class_default); 6029 %} 6030 6031 // Load MachConstantTableBase: add lo offset to global toc. 6032 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 6033 effect(DEF dst, USE src); 6034 ins_cost(DEFAULT_COST); 6035 6036 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 6037 size(4); 6038 ins_encode %{ 6039 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6040 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 6041 %} 6042 ins_pipe(pipe_class_default); 6043 %} 6044 6045 // Load 16-bit integer constant 0xssss???? 6046 instruct loadConI16(iRegIdst dst, immI16 src) %{ 6047 match(Set dst src); 6048 6049 format %{ "LI $dst, $src" %} 6050 size(4); 6051 ins_encode %{ 6052 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6053 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6054 %} 6055 ins_pipe(pipe_class_default); 6056 %} 6057 6058 // Load integer constant 0x????0000 6059 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 6060 match(Set dst src); 6061 ins_cost(DEFAULT_COST); 6062 6063 format %{ "LIS $dst, $src.hi" %} 6064 size(4); 6065 ins_encode %{ 6066 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6067 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 6068 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6069 %} 6070 ins_pipe(pipe_class_default); 6071 %} 6072 6073 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 6074 // and sign extended), this adds the low 16 bits. 6075 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6076 // no match-rule, false predicate 6077 effect(DEF dst, USE src1, USE src2); 6078 predicate(false); 6079 6080 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6081 size(4); 6082 ins_encode %{ 6083 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6084 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6085 %} 6086 ins_pipe(pipe_class_default); 6087 %} 6088 6089 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6090 match(Set dst src); 6091 ins_cost(DEFAULT_COST*2); 6092 6093 expand %{ 6094 // Would like to use $src$$constant. 6095 immI16 srcLo %{ _opnds[1]->constant() %} 6096 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6097 immIhi16 srcHi %{ _opnds[1]->constant() %} 6098 iRegIdst tmpI; 6099 loadConIhi16(tmpI, srcHi); 6100 loadConI32_lo16(dst, tmpI, srcLo); 6101 %} 6102 %} 6103 6104 // No constant pool entries required. 6105 instruct loadConL16(iRegLdst dst, immL16 src) %{ 6106 match(Set dst src); 6107 6108 format %{ "LI $dst, $src \t// long" %} 6109 size(4); 6110 ins_encode %{ 6111 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6112 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6113 %} 6114 ins_pipe(pipe_class_default); 6115 %} 6116 6117 // Load long constant 0xssssssss????0000 6118 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6119 match(Set dst src); 6120 ins_cost(DEFAULT_COST); 6121 6122 format %{ "LIS $dst, $src.hi \t// long" %} 6123 size(4); 6124 ins_encode %{ 6125 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6126 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6127 %} 6128 ins_pipe(pipe_class_default); 6129 %} 6130 6131 // To load a 32 bit constant: merge lower 16 bits into already loaded 6132 // high 16 bits. 6133 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6134 // no match-rule, false predicate 6135 effect(DEF dst, USE src1, USE src2); 6136 predicate(false); 6137 6138 format %{ "ORI $dst, $src1, $src2.lo" %} 6139 size(4); 6140 ins_encode %{ 6141 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6142 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6143 %} 6144 ins_pipe(pipe_class_default); 6145 %} 6146 6147 // Load 32-bit long constant 6148 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6149 match(Set dst src); 6150 ins_cost(DEFAULT_COST*2); 6151 6152 expand %{ 6153 // Would like to use $src$$constant. 6154 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6155 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6156 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6157 iRegLdst tmpL; 6158 loadConL32hi16(tmpL, srcHi); 6159 loadConL32_lo16(dst, tmpL, srcLo); 6160 %} 6161 %} 6162 6163 // Load long constant 0x????000000000000. 6164 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6165 match(Set dst src); 6166 ins_cost(DEFAULT_COST); 6167 6168 expand %{ 6169 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6170 immI shift32 %{ 32 %} 6171 iRegLdst tmpL; 6172 loadConL32hi16(tmpL, srcHi); 6173 lshiftL_regL_immI(dst, tmpL, shift32); 6174 %} 6175 %} 6176 6177 // Expand node for constant pool load: small offset. 6178 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6179 effect(DEF dst, USE src, USE toc); 6180 ins_cost(MEMORY_REF_COST); 6181 6182 ins_num_consts(1); 6183 // Needed so that CallDynamicJavaDirect can compute the address of this 6184 // instruction for relocation. 6185 ins_field_cbuf_insts_offset(int); 6186 6187 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6188 size(4); 6189 ins_encode( enc_load_long_constL(dst, src, toc) ); 6190 ins_pipe(pipe_class_memory); 6191 %} 6192 6193 // Expand node for constant pool load: large offset. 6194 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6195 effect(DEF dst, USE src, USE toc); 6196 predicate(false); 6197 6198 ins_num_consts(1); 6199 ins_field_const_toc_offset(int); 6200 // Needed so that CallDynamicJavaDirect can compute the address of this 6201 // instruction for relocation. 6202 ins_field_cbuf_insts_offset(int); 6203 6204 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6205 size(4); 6206 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6207 ins_pipe(pipe_class_default); 6208 %} 6209 6210 // Expand node for constant pool load: large offset. 6211 // No constant pool entries required. 6212 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6213 effect(DEF dst, USE src, USE base); 6214 predicate(false); 6215 6216 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6217 6218 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6219 size(4); 6220 ins_encode %{ 6221 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6222 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6223 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6224 %} 6225 ins_pipe(pipe_class_memory); 6226 %} 6227 6228 // Load long constant from constant table. Expand in case of 6229 // offset > 16 bit is needed. 6230 // Adlc adds toc node MachConstantTableBase. 6231 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6232 match(Set dst src); 6233 ins_cost(MEMORY_REF_COST); 6234 6235 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6236 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6237 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6238 %} 6239 6240 // Load NULL as compressed oop. 6241 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6242 match(Set dst src); 6243 ins_cost(DEFAULT_COST); 6244 6245 format %{ "LI $dst, $src \t// compressed ptr" %} 6246 size(4); 6247 ins_encode %{ 6248 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6249 __ li($dst$$Register, 0); 6250 %} 6251 ins_pipe(pipe_class_default); 6252 %} 6253 6254 // Load hi part of compressed oop constant. 6255 instruct loadConN_hi(iRegNdst dst, immN src) %{ 6256 effect(DEF dst, USE src); 6257 ins_cost(DEFAULT_COST); 6258 6259 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6260 size(4); 6261 ins_encode %{ 6262 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6263 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6264 %} 6265 ins_pipe(pipe_class_default); 6266 %} 6267 6268 // Add lo part of compressed oop constant to already loaded hi part. 6269 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6270 effect(DEF dst, USE src1, USE src2); 6271 ins_cost(DEFAULT_COST); 6272 6273 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6274 size(4); 6275 ins_encode %{ 6276 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6277 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6278 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6279 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6280 __ relocate(rspec, 1); 6281 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6282 %} 6283 ins_pipe(pipe_class_default); 6284 %} 6285 6286 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6287 effect(DEF dst, USE src, USE shift, USE mask_begin); 6288 6289 size(4); 6290 ins_encode %{ 6291 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6292 %} 6293 ins_pipe(pipe_class_default); 6294 %} 6295 6296 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6297 // leaving the upper 32 bits with sign-extension bits. 6298 // This clears these bits: dst = src & 0xFFFFFFFF. 6299 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6300 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6301 effect(DEF dst, USE src); 6302 predicate(false); 6303 6304 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6305 size(4); 6306 ins_encode %{ 6307 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6308 __ clrldi($dst$$Register, $src$$Register, 0x20); 6309 %} 6310 ins_pipe(pipe_class_default); 6311 %} 6312 6313 // Optimize DecodeN for disjoint base. 6314 // Load base of compressed oops into a register 6315 instruct loadBase(iRegLdst dst) %{ 6316 effect(DEF dst); 6317 6318 format %{ "LoadConst $dst, heapbase" %} 6319 ins_encode %{ 6320 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6321 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 6322 %} 6323 ins_pipe(pipe_class_default); 6324 %} 6325 6326 // Loading ConN must be postalloc expanded so that edges between 6327 // the nodes are safe. They may not interfere with a safepoint. 6328 // GL TODO: This needs three instructions: better put this into the constant pool. 6329 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6330 match(Set dst src); 6331 ins_cost(DEFAULT_COST*2); 6332 6333 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6334 postalloc_expand %{ 6335 MachNode *m1 = new loadConN_hiNode(); 6336 MachNode *m2 = new loadConN_loNode(); 6337 MachNode *m3 = new clearMs32bNode(); 6338 m1->add_req(NULL); 6339 m2->add_req(NULL, m1); 6340 m3->add_req(NULL, m2); 6341 m1->_opnds[0] = op_dst; 6342 m1->_opnds[1] = op_src; 6343 m2->_opnds[0] = op_dst; 6344 m2->_opnds[1] = op_dst; 6345 m2->_opnds[2] = op_src; 6346 m3->_opnds[0] = op_dst; 6347 m3->_opnds[1] = op_dst; 6348 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6349 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6350 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6351 nodes->push(m1); 6352 nodes->push(m2); 6353 nodes->push(m3); 6354 %} 6355 %} 6356 6357 // We have seen a safepoint between the hi and lo parts, and this node was handled 6358 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6359 // not a narrow oop. 6360 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6361 match(Set dst src); 6362 effect(DEF dst, USE src); 6363 ins_cost(DEFAULT_COST); 6364 6365 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6366 size(4); 6367 ins_encode %{ 6368 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6369 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 6370 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6371 %} 6372 ins_pipe(pipe_class_default); 6373 %} 6374 6375 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6376 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6377 match(Set dst src1); 6378 effect(TEMP src2); 6379 ins_cost(DEFAULT_COST); 6380 6381 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6382 size(4); 6383 ins_encode %{ 6384 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6385 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6386 %} 6387 ins_pipe(pipe_class_default); 6388 %} 6389 6390 // This needs a match rule so that build_oop_map knows this is 6391 // not a narrow oop. 6392 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6393 match(Set dst src1); 6394 effect(TEMP src2); 6395 ins_cost(DEFAULT_COST); 6396 6397 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6398 size(4); 6399 ins_encode %{ 6400 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6401 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 6402 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6403 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6404 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6405 6406 __ relocate(rspec, 1); 6407 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6408 %} 6409 ins_pipe(pipe_class_default); 6410 %} 6411 6412 // Loading ConNKlass must be postalloc expanded so that edges between 6413 // the nodes are safe. They may not interfere with a safepoint. 6414 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6415 match(Set dst src); 6416 ins_cost(DEFAULT_COST*2); 6417 6418 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6419 postalloc_expand %{ 6420 // Load high bits into register. Sign extended. 6421 MachNode *m1 = new loadConNKlass_hiNode(); 6422 m1->add_req(NULL); 6423 m1->_opnds[0] = op_dst; 6424 m1->_opnds[1] = op_src; 6425 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6426 nodes->push(m1); 6427 6428 MachNode *m2 = m1; 6429 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 6430 // Value might be 1-extended. Mask out these bits. 6431 m2 = new loadConNKlass_maskNode(); 6432 m2->add_req(NULL, m1); 6433 m2->_opnds[0] = op_dst; 6434 m2->_opnds[1] = op_src; 6435 m2->_opnds[2] = op_dst; 6436 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6437 nodes->push(m2); 6438 } 6439 6440 MachNode *m3 = new loadConNKlass_loNode(); 6441 m3->add_req(NULL, m2); 6442 m3->_opnds[0] = op_dst; 6443 m3->_opnds[1] = op_src; 6444 m3->_opnds[2] = op_dst; 6445 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6446 nodes->push(m3); 6447 %} 6448 %} 6449 6450 // 0x1 is used in object initialization (initial object header). 6451 // No constant pool entries required. 6452 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6453 match(Set dst src); 6454 6455 format %{ "LI $dst, $src \t// ptr" %} 6456 size(4); 6457 ins_encode %{ 6458 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6459 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6460 %} 6461 ins_pipe(pipe_class_default); 6462 %} 6463 6464 // Expand node for constant pool load: small offset. 6465 // The match rule is needed to generate the correct bottom_type(), 6466 // however this node should never match. The use of predicate is not 6467 // possible since ADLC forbids predicates for chain rules. The higher 6468 // costs do not prevent matching in this case. For that reason the 6469 // operand immP_NM with predicate(false) is used. 6470 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6471 match(Set dst src); 6472 effect(TEMP toc); 6473 6474 ins_num_consts(1); 6475 6476 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6477 size(4); 6478 ins_encode( enc_load_long_constP(dst, src, toc) ); 6479 ins_pipe(pipe_class_memory); 6480 %} 6481 6482 // Expand node for constant pool load: large offset. 6483 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6484 effect(DEF dst, USE src, USE toc); 6485 predicate(false); 6486 6487 ins_num_consts(1); 6488 ins_field_const_toc_offset(int); 6489 6490 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6491 size(4); 6492 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6493 ins_pipe(pipe_class_default); 6494 %} 6495 6496 // Expand node for constant pool load: large offset. 6497 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6498 match(Set dst src); 6499 effect(TEMP base); 6500 6501 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6502 6503 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6504 size(4); 6505 ins_encode %{ 6506 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6507 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6508 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6509 %} 6510 ins_pipe(pipe_class_memory); 6511 %} 6512 6513 // Load pointer constant from constant table. Expand in case an 6514 // offset > 16 bit is needed. 6515 // Adlc adds toc node MachConstantTableBase. 6516 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6517 match(Set dst src); 6518 ins_cost(MEMORY_REF_COST); 6519 6520 // This rule does not use "expand" because then 6521 // the result type is not known to be an Oop. An ADLC 6522 // enhancement will be needed to make that work - not worth it! 6523 6524 // If this instruction rematerializes, it prolongs the live range 6525 // of the toc node, causing illegal graphs. 6526 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6527 ins_cannot_rematerialize(true); 6528 6529 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6530 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6531 %} 6532 6533 // Expand node for constant pool load: small offset. 6534 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6535 effect(DEF dst, USE src, USE toc); 6536 ins_cost(MEMORY_REF_COST); 6537 6538 ins_num_consts(1); 6539 6540 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6541 size(4); 6542 ins_encode %{ 6543 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6544 address float_address = __ float_constant($src$$constant); 6545 if (float_address == NULL) { 6546 ciEnv::current()->record_out_of_memory_failure(); 6547 return; 6548 } 6549 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6550 %} 6551 ins_pipe(pipe_class_memory); 6552 %} 6553 6554 // Expand node for constant pool load: large offset. 6555 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6556 effect(DEF dst, USE src, USE toc); 6557 ins_cost(MEMORY_REF_COST); 6558 6559 ins_num_consts(1); 6560 6561 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6562 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6563 "ADDIS $toc, $toc, -offset_hi"%} 6564 size(12); 6565 ins_encode %{ 6566 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6567 FloatRegister Rdst = $dst$$FloatRegister; 6568 Register Rtoc = $toc$$Register; 6569 address float_address = __ float_constant($src$$constant); 6570 if (float_address == NULL) { 6571 ciEnv::current()->record_out_of_memory_failure(); 6572 return; 6573 } 6574 int offset = __ offset_to_method_toc(float_address); 6575 int hi = (offset + (1<<15))>>16; 6576 int lo = offset - hi * (1<<16); 6577 6578 __ addis(Rtoc, Rtoc, hi); 6579 __ lfs(Rdst, lo, Rtoc); 6580 __ addis(Rtoc, Rtoc, -hi); 6581 %} 6582 ins_pipe(pipe_class_memory); 6583 %} 6584 6585 // Adlc adds toc node MachConstantTableBase. 6586 instruct loadConF_Ex(regF dst, immF src) %{ 6587 match(Set dst src); 6588 ins_cost(MEMORY_REF_COST); 6589 6590 // See loadConP. 6591 ins_cannot_rematerialize(true); 6592 6593 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6594 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6595 %} 6596 6597 // Expand node for constant pool load: small offset. 6598 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6599 effect(DEF dst, USE src, USE toc); 6600 ins_cost(MEMORY_REF_COST); 6601 6602 ins_num_consts(1); 6603 6604 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6605 size(4); 6606 ins_encode %{ 6607 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6608 address float_address = __ double_constant($src$$constant); 6609 if (float_address == NULL) { 6610 ciEnv::current()->record_out_of_memory_failure(); 6611 return; 6612 } 6613 int offset = __ offset_to_method_toc(float_address); 6614 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6615 %} 6616 ins_pipe(pipe_class_memory); 6617 %} 6618 6619 // Expand node for constant pool load: large offset. 6620 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6621 effect(DEF dst, USE src, USE toc); 6622 ins_cost(MEMORY_REF_COST); 6623 6624 ins_num_consts(1); 6625 6626 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6627 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6628 "ADDIS $toc, $toc, -offset_hi" %} 6629 size(12); 6630 ins_encode %{ 6631 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6632 FloatRegister Rdst = $dst$$FloatRegister; 6633 Register Rtoc = $toc$$Register; 6634 address float_address = __ double_constant($src$$constant); 6635 if (float_address == NULL) { 6636 ciEnv::current()->record_out_of_memory_failure(); 6637 return; 6638 } 6639 int offset = __ offset_to_method_toc(float_address); 6640 int hi = (offset + (1<<15))>>16; 6641 int lo = offset - hi * (1<<16); 6642 6643 __ addis(Rtoc, Rtoc, hi); 6644 __ lfd(Rdst, lo, Rtoc); 6645 __ addis(Rtoc, Rtoc, -hi); 6646 %} 6647 ins_pipe(pipe_class_memory); 6648 %} 6649 6650 // Adlc adds toc node MachConstantTableBase. 6651 instruct loadConD_Ex(regD dst, immD src) %{ 6652 match(Set dst src); 6653 ins_cost(MEMORY_REF_COST); 6654 6655 // See loadConP. 6656 ins_cannot_rematerialize(true); 6657 6658 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6659 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6660 %} 6661 6662 // Prefetch instructions. 6663 // Must be safe to execute with invalid address (cannot fault). 6664 6665 // Special prefetch versions which use the dcbz instruction. 6666 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6667 match(PrefetchAllocation (AddP mem src)); 6668 predicate(AllocatePrefetchStyle == 3); 6669 ins_cost(MEMORY_REF_COST); 6670 6671 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6672 size(4); 6673 ins_encode %{ 6674 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6675 __ dcbz($src$$Register, $mem$$base$$Register); 6676 %} 6677 ins_pipe(pipe_class_memory); 6678 %} 6679 6680 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6681 match(PrefetchAllocation mem); 6682 predicate(AllocatePrefetchStyle == 3); 6683 ins_cost(MEMORY_REF_COST); 6684 6685 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6686 size(4); 6687 ins_encode %{ 6688 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6689 __ dcbz($mem$$base$$Register); 6690 %} 6691 ins_pipe(pipe_class_memory); 6692 %} 6693 6694 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6695 match(PrefetchAllocation (AddP mem src)); 6696 predicate(AllocatePrefetchStyle != 3); 6697 ins_cost(MEMORY_REF_COST); 6698 6699 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6700 size(4); 6701 ins_encode %{ 6702 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6703 __ dcbtst($src$$Register, $mem$$base$$Register); 6704 %} 6705 ins_pipe(pipe_class_memory); 6706 %} 6707 6708 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6709 match(PrefetchAllocation mem); 6710 predicate(AllocatePrefetchStyle != 3); 6711 ins_cost(MEMORY_REF_COST); 6712 6713 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6714 size(4); 6715 ins_encode %{ 6716 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6717 __ dcbtst($mem$$base$$Register); 6718 %} 6719 ins_pipe(pipe_class_memory); 6720 %} 6721 6722 //----------Store Instructions------------------------------------------------- 6723 6724 // Store Byte 6725 instruct storeB(memory mem, iRegIsrc src) %{ 6726 match(Set mem (StoreB mem src)); 6727 ins_cost(MEMORY_REF_COST); 6728 6729 format %{ "STB $src, $mem \t// byte" %} 6730 size(4); 6731 ins_encode %{ 6732 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6733 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6734 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6735 %} 6736 ins_pipe(pipe_class_memory); 6737 %} 6738 6739 // Store Char/Short 6740 instruct storeC(memory mem, iRegIsrc src) %{ 6741 match(Set mem (StoreC mem src)); 6742 ins_cost(MEMORY_REF_COST); 6743 6744 format %{ "STH $src, $mem \t// short" %} 6745 size(4); 6746 ins_encode %{ 6747 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6748 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6749 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6750 %} 6751 ins_pipe(pipe_class_memory); 6752 %} 6753 6754 // Store Integer 6755 instruct storeI(memory mem, iRegIsrc src) %{ 6756 match(Set mem (StoreI mem src)); 6757 ins_cost(MEMORY_REF_COST); 6758 6759 format %{ "STW $src, $mem" %} 6760 size(4); 6761 ins_encode( enc_stw(src, mem) ); 6762 ins_pipe(pipe_class_memory); 6763 %} 6764 6765 // ConvL2I + StoreI. 6766 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6767 match(Set mem (StoreI mem (ConvL2I src))); 6768 ins_cost(MEMORY_REF_COST); 6769 6770 format %{ "STW l2i($src), $mem" %} 6771 size(4); 6772 ins_encode( enc_stw(src, mem) ); 6773 ins_pipe(pipe_class_memory); 6774 %} 6775 6776 // Store Long 6777 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6778 match(Set mem (StoreL mem src)); 6779 ins_cost(MEMORY_REF_COST); 6780 6781 format %{ "STD $src, $mem \t// long" %} 6782 size(4); 6783 ins_encode( enc_std(src, mem) ); 6784 ins_pipe(pipe_class_memory); 6785 %} 6786 6787 // Store super word nodes. 6788 6789 // Store Aligned Packed Byte long register to memory 6790 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6791 predicate(n->as_StoreVector()->memory_size() == 8); 6792 match(Set mem (StoreVector mem src)); 6793 ins_cost(MEMORY_REF_COST); 6794 6795 format %{ "STD $mem, $src \t// packed8B" %} 6796 size(4); 6797 ins_encode( enc_std(src, mem) ); 6798 ins_pipe(pipe_class_memory); 6799 %} 6800 6801 // Store Packed Byte long register to memory 6802 instruct storeV16(indirect mem, vecX src) %{ 6803 predicate(n->as_StoreVector()->memory_size() == 16); 6804 match(Set mem (StoreVector mem src)); 6805 ins_cost(MEMORY_REF_COST); 6806 6807 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6808 size(4); 6809 ins_encode %{ 6810 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6811 %} 6812 ins_pipe(pipe_class_default); 6813 %} 6814 6815 // Store Compressed Oop 6816 instruct storeN(memory dst, iRegN_P2N src) %{ 6817 match(Set dst (StoreN dst src)); 6818 ins_cost(MEMORY_REF_COST); 6819 6820 format %{ "STW $src, $dst \t// compressed oop" %} 6821 size(4); 6822 ins_encode( enc_stw(src, dst) ); 6823 ins_pipe(pipe_class_memory); 6824 %} 6825 6826 // Store Compressed KLass 6827 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6828 match(Set dst (StoreNKlass dst src)); 6829 ins_cost(MEMORY_REF_COST); 6830 6831 format %{ "STW $src, $dst \t// compressed klass" %} 6832 size(4); 6833 ins_encode( enc_stw(src, dst) ); 6834 ins_pipe(pipe_class_memory); 6835 %} 6836 6837 // Store Pointer 6838 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6839 match(Set dst (StoreP dst src)); 6840 ins_cost(MEMORY_REF_COST); 6841 6842 format %{ "STD $src, $dst \t// ptr" %} 6843 size(4); 6844 ins_encode( enc_std(src, dst) ); 6845 ins_pipe(pipe_class_memory); 6846 %} 6847 6848 // Store Float 6849 instruct storeF(memory mem, regF src) %{ 6850 match(Set mem (StoreF mem src)); 6851 ins_cost(MEMORY_REF_COST); 6852 6853 format %{ "STFS $src, $mem" %} 6854 size(4); 6855 ins_encode( enc_stfs(src, mem) ); 6856 ins_pipe(pipe_class_memory); 6857 %} 6858 6859 // Store Double 6860 instruct storeD(memory mem, regD src) %{ 6861 match(Set mem (StoreD mem src)); 6862 ins_cost(MEMORY_REF_COST); 6863 6864 format %{ "STFD $src, $mem" %} 6865 size(4); 6866 ins_encode( enc_stfd(src, mem) ); 6867 ins_pipe(pipe_class_memory); 6868 %} 6869 6870 //----------Store Instructions With Zeros-------------------------------------- 6871 6872 // Card-mark for CMS garbage collection. 6873 // This cardmark does an optimization so that it must not always 6874 // do a releasing store. For this, it gets the address of 6875 // CMSCollectorCardTableBarrierSetBSExt::_requires_release as input. 6876 // (Using releaseFieldAddr in the match rule is a hack.) 6877 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6878 match(Set mem (StoreCM mem releaseFieldAddr)); 6879 effect(TEMP crx); 6880 predicate(false); 6881 ins_cost(MEMORY_REF_COST); 6882 6883 // See loadConP. 6884 ins_cannot_rematerialize(true); 6885 6886 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6887 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6888 ins_pipe(pipe_class_memory); 6889 %} 6890 6891 // Card-mark for CMS garbage collection. 6892 // This cardmark does an optimization so that it must not always 6893 // do a releasing store. For this, it needs the constant address of 6894 // CMSCollectorCardTableBarrierSetBSExt::_requires_release. 6895 // This constant address is split off here by expand so we can use 6896 // adlc / matcher functionality to load it from the constant section. 6897 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6898 match(Set mem (StoreCM mem zero)); 6899 predicate(UseConcMarkSweepGC); 6900 6901 expand %{ 6902 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableBarrierSetBSExt::requires_release_address() */ %} 6903 iRegLdst releaseFieldAddress; 6904 flagsReg crx; 6905 loadConL_Ex(releaseFieldAddress, baseImm); 6906 storeCM_CMS(mem, releaseFieldAddress, crx); 6907 %} 6908 %} 6909 6910 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6911 match(Set mem (StoreCM mem zero)); 6912 predicate(UseG1GC); 6913 ins_cost(MEMORY_REF_COST); 6914 6915 ins_cannot_rematerialize(true); 6916 6917 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6918 size(8); 6919 ins_encode %{ 6920 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6921 __ li(R0, 0); 6922 //__ release(); // G1: oops are allowed to get visible after dirty marking 6923 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6924 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6925 %} 6926 ins_pipe(pipe_class_memory); 6927 %} 6928 6929 // Convert oop pointer into compressed form. 6930 6931 // Nodes for postalloc expand. 6932 6933 // Shift node for expand. 6934 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6935 // The match rule is needed to make it a 'MachTypeNode'! 6936 match(Set dst (EncodeP src)); 6937 predicate(false); 6938 6939 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6940 size(4); 6941 ins_encode %{ 6942 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6943 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6944 %} 6945 ins_pipe(pipe_class_default); 6946 %} 6947 6948 // Add node for expand. 6949 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6950 // The match rule is needed to make it a 'MachTypeNode'! 6951 match(Set dst (EncodeP src)); 6952 predicate(false); 6953 6954 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6955 ins_encode %{ 6956 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6957 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6958 %} 6959 ins_pipe(pipe_class_default); 6960 %} 6961 6962 // Conditional sub base. 6963 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6964 // The match rule is needed to make it a 'MachTypeNode'! 6965 match(Set dst (EncodeP (Binary crx src1))); 6966 predicate(false); 6967 6968 format %{ "BEQ $crx, done\n\t" 6969 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6970 "done:" %} 6971 ins_encode %{ 6972 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6973 Label done; 6974 __ beq($crx$$CondRegister, done); 6975 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6976 __ bind(done); 6977 %} 6978 ins_pipe(pipe_class_default); 6979 %} 6980 6981 // Power 7 can use isel instruction 6982 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6983 // The match rule is needed to make it a 'MachTypeNode'! 6984 match(Set dst (EncodeP (Binary crx src1))); 6985 predicate(false); 6986 6987 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6988 size(4); 6989 ins_encode %{ 6990 // This is a Power7 instruction for which no machine description exists. 6991 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6992 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6993 %} 6994 ins_pipe(pipe_class_default); 6995 %} 6996 6997 // Disjoint narrow oop base. 6998 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6999 match(Set dst (EncodeP src)); 7000 predicate(Universe::narrow_oop_base_disjoint()); 7001 7002 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7003 size(4); 7004 ins_encode %{ 7005 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7006 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 7007 %} 7008 ins_pipe(pipe_class_default); 7009 %} 7010 7011 // shift != 0, base != 0 7012 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 7013 match(Set dst (EncodeP src)); 7014 effect(TEMP crx); 7015 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 7016 Universe::narrow_oop_shift() != 0 && 7017 Universe::narrow_oop_base_overlaps()); 7018 7019 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 7020 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 7021 %} 7022 7023 // shift != 0, base != 0 7024 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 7025 match(Set dst (EncodeP src)); 7026 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 7027 Universe::narrow_oop_shift() != 0 && 7028 Universe::narrow_oop_base_overlaps()); 7029 7030 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 7031 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 7032 %} 7033 7034 // shift != 0, base == 0 7035 // TODO: This is the same as encodeP_shift. Merge! 7036 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 7037 match(Set dst (EncodeP src)); 7038 predicate(Universe::narrow_oop_shift() != 0 && 7039 Universe::narrow_oop_base() ==0); 7040 7041 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 7042 size(4); 7043 ins_encode %{ 7044 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7045 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 7046 %} 7047 ins_pipe(pipe_class_default); 7048 %} 7049 7050 // Compressed OOPs with narrow_oop_shift == 0. 7051 // shift == 0, base == 0 7052 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 7053 match(Set dst (EncodeP src)); 7054 predicate(Universe::narrow_oop_shift() == 0); 7055 7056 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 7057 // variable size, 0 or 4. 7058 ins_encode %{ 7059 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7060 __ mr_if_needed($dst$$Register, $src$$Register); 7061 %} 7062 ins_pipe(pipe_class_default); 7063 %} 7064 7065 // Decode nodes. 7066 7067 // Shift node for expand. 7068 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 7069 // The match rule is needed to make it a 'MachTypeNode'! 7070 match(Set dst (DecodeN src)); 7071 predicate(false); 7072 7073 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 7074 size(4); 7075 ins_encode %{ 7076 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7077 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7078 %} 7079 ins_pipe(pipe_class_default); 7080 %} 7081 7082 // Add node for expand. 7083 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7084 // The match rule is needed to make it a 'MachTypeNode'! 7085 match(Set dst (DecodeN src)); 7086 predicate(false); 7087 7088 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7089 ins_encode %{ 7090 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7091 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7092 %} 7093 ins_pipe(pipe_class_default); 7094 %} 7095 7096 // conditianal add base for expand 7097 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7098 // The match rule is needed to make it a 'MachTypeNode'! 7099 // NOTICE that the rule is nonsense - we just have to make sure that: 7100 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7101 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7102 match(Set dst (DecodeN (Binary crx src))); 7103 predicate(false); 7104 7105 format %{ "BEQ $crx, done\n\t" 7106 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7107 "done:" %} 7108 ins_encode %{ 7109 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7110 Label done; 7111 __ beq($crx$$CondRegister, done); 7112 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7113 __ bind(done); 7114 %} 7115 ins_pipe(pipe_class_default); 7116 %} 7117 7118 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7119 // The match rule is needed to make it a 'MachTypeNode'! 7120 // NOTICE that the rule is nonsense - we just have to make sure that: 7121 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7122 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7123 match(Set dst (DecodeN (Binary crx src1))); 7124 predicate(false); 7125 7126 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7127 size(4); 7128 ins_encode %{ 7129 // This is a Power7 instruction for which no machine description exists. 7130 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7131 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7132 %} 7133 ins_pipe(pipe_class_default); 7134 %} 7135 7136 // shift != 0, base != 0 7137 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7138 match(Set dst (DecodeN src)); 7139 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7140 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7141 Universe::narrow_oop_shift() != 0 && 7142 Universe::narrow_oop_base() != 0); 7143 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7144 effect(TEMP crx); 7145 7146 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7147 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7148 %} 7149 7150 // shift != 0, base == 0 7151 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7152 match(Set dst (DecodeN src)); 7153 predicate(Universe::narrow_oop_shift() != 0 && 7154 Universe::narrow_oop_base() == 0); 7155 7156 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7157 size(4); 7158 ins_encode %{ 7159 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7160 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7161 %} 7162 ins_pipe(pipe_class_default); 7163 %} 7164 7165 // Optimize DecodeN for disjoint base. 7166 // Shift narrow oop and or it into register that already contains the heap base. 7167 // Base == dst must hold, and is assured by construction in postaloc_expand. 7168 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7169 match(Set dst (DecodeN src)); 7170 effect(TEMP base); 7171 predicate(false); 7172 7173 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7174 size(4); 7175 ins_encode %{ 7176 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7177 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 7178 %} 7179 ins_pipe(pipe_class_default); 7180 %} 7181 7182 // Optimize DecodeN for disjoint base. 7183 // This node requires only one cycle on the critical path. 7184 // We must postalloc_expand as we can not express use_def effects where 7185 // the used register is L and the def'ed register P. 7186 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7187 match(Set dst (DecodeN src)); 7188 effect(TEMP_DEF dst); 7189 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7190 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7191 Universe::narrow_oop_base_disjoint()); 7192 ins_cost(DEFAULT_COST); 7193 7194 format %{ "MOV $dst, heapbase \t\n" 7195 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7196 postalloc_expand %{ 7197 loadBaseNode *n1 = new loadBaseNode(); 7198 n1->add_req(NULL); 7199 n1->_opnds[0] = op_dst; 7200 7201 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7202 n2->add_req(n_region, n_src, n1); 7203 n2->_opnds[0] = op_dst; 7204 n2->_opnds[1] = op_src; 7205 n2->_opnds[2] = op_dst; 7206 n2->_bottom_type = _bottom_type; 7207 7208 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7209 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7210 7211 nodes->push(n1); 7212 nodes->push(n2); 7213 %} 7214 %} 7215 7216 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7217 match(Set dst (DecodeN src)); 7218 effect(TEMP_DEF dst, TEMP crx); 7219 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7220 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7221 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 7222 ins_cost(3 * DEFAULT_COST); 7223 7224 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7225 postalloc_expand %{ 7226 loadBaseNode *n1 = new loadBaseNode(); 7227 n1->add_req(NULL); 7228 n1->_opnds[0] = op_dst; 7229 7230 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7231 n_compare->add_req(n_region, n_src); 7232 n_compare->_opnds[0] = op_crx; 7233 n_compare->_opnds[1] = op_src; 7234 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7235 7236 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7237 n2->add_req(n_region, n_src, n1); 7238 n2->_opnds[0] = op_dst; 7239 n2->_opnds[1] = op_src; 7240 n2->_opnds[2] = op_dst; 7241 n2->_bottom_type = _bottom_type; 7242 7243 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7244 n_cond_set->add_req(n_region, n_compare, n2); 7245 n_cond_set->_opnds[0] = op_dst; 7246 n_cond_set->_opnds[1] = op_crx; 7247 n_cond_set->_opnds[2] = op_dst; 7248 n_cond_set->_bottom_type = _bottom_type; 7249 7250 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7251 ra_->set_oop(n_cond_set, true); 7252 7253 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7254 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7255 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7256 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7257 7258 nodes->push(n1); 7259 nodes->push(n_compare); 7260 nodes->push(n2); 7261 nodes->push(n_cond_set); 7262 %} 7263 %} 7264 7265 // src != 0, shift != 0, base != 0 7266 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7267 match(Set dst (DecodeN src)); 7268 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7269 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7270 Universe::narrow_oop_shift() != 0 && 7271 Universe::narrow_oop_base() != 0); 7272 ins_cost(2 * DEFAULT_COST); 7273 7274 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7275 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7276 %} 7277 7278 // Compressed OOPs with narrow_oop_shift == 0. 7279 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7280 match(Set dst (DecodeN src)); 7281 predicate(Universe::narrow_oop_shift() == 0); 7282 ins_cost(DEFAULT_COST); 7283 7284 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7285 // variable size, 0 or 4. 7286 ins_encode %{ 7287 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7288 __ mr_if_needed($dst$$Register, $src$$Register); 7289 %} 7290 ins_pipe(pipe_class_default); 7291 %} 7292 7293 // Convert compressed oop into int for vectors alignment masking. 7294 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7295 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7296 predicate(Universe::narrow_oop_shift() == 0); 7297 ins_cost(DEFAULT_COST); 7298 7299 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7300 // variable size, 0 or 4. 7301 ins_encode %{ 7302 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7303 __ mr_if_needed($dst$$Register, $src$$Register); 7304 %} 7305 ins_pipe(pipe_class_default); 7306 %} 7307 7308 // Convert klass pointer into compressed form. 7309 7310 // Nodes for postalloc expand. 7311 7312 // Shift node for expand. 7313 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7314 // The match rule is needed to make it a 'MachTypeNode'! 7315 match(Set dst (EncodePKlass src)); 7316 predicate(false); 7317 7318 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7319 size(4); 7320 ins_encode %{ 7321 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7322 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7323 %} 7324 ins_pipe(pipe_class_default); 7325 %} 7326 7327 // Add node for expand. 7328 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7329 // The match rule is needed to make it a 'MachTypeNode'! 7330 match(Set dst (EncodePKlass (Binary base src))); 7331 predicate(false); 7332 7333 format %{ "SUB $dst, $base, $src \t// encode" %} 7334 size(4); 7335 ins_encode %{ 7336 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7337 __ subf($dst$$Register, $base$$Register, $src$$Register); 7338 %} 7339 ins_pipe(pipe_class_default); 7340 %} 7341 7342 // Disjoint narrow oop base. 7343 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7344 match(Set dst (EncodePKlass src)); 7345 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 7346 7347 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7348 size(4); 7349 ins_encode %{ 7350 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7351 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 7352 %} 7353 ins_pipe(pipe_class_default); 7354 %} 7355 7356 // shift != 0, base != 0 7357 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7358 match(Set dst (EncodePKlass (Binary base src))); 7359 predicate(false); 7360 7361 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7362 postalloc_expand %{ 7363 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7364 n1->add_req(n_region, n_base, n_src); 7365 n1->_opnds[0] = op_dst; 7366 n1->_opnds[1] = op_base; 7367 n1->_opnds[2] = op_src; 7368 n1->_bottom_type = _bottom_type; 7369 7370 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7371 n2->add_req(n_region, n1); 7372 n2->_opnds[0] = op_dst; 7373 n2->_opnds[1] = op_dst; 7374 n2->_bottom_type = _bottom_type; 7375 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7376 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7377 7378 nodes->push(n1); 7379 nodes->push(n2); 7380 %} 7381 %} 7382 7383 // shift != 0, base != 0 7384 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7385 match(Set dst (EncodePKlass src)); 7386 //predicate(Universe::narrow_klass_shift() != 0 && 7387 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 7388 7389 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7390 ins_cost(DEFAULT_COST*2); // Don't count constant. 7391 expand %{ 7392 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 7393 iRegLdst base; 7394 loadConL_Ex(base, baseImm); 7395 encodePKlass_not_null_Ex(dst, base, src); 7396 %} 7397 %} 7398 7399 // Decode nodes. 7400 7401 // Shift node for expand. 7402 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7403 // The match rule is needed to make it a 'MachTypeNode'! 7404 match(Set dst (DecodeNKlass src)); 7405 predicate(false); 7406 7407 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7408 size(4); 7409 ins_encode %{ 7410 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7411 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7412 %} 7413 ins_pipe(pipe_class_default); 7414 %} 7415 7416 // Add node for expand. 7417 7418 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7419 // The match rule is needed to make it a 'MachTypeNode'! 7420 match(Set dst (DecodeNKlass (Binary base src))); 7421 predicate(false); 7422 7423 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7424 size(4); 7425 ins_encode %{ 7426 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7427 __ add($dst$$Register, $base$$Register, $src$$Register); 7428 %} 7429 ins_pipe(pipe_class_default); 7430 %} 7431 7432 // src != 0, shift != 0, base != 0 7433 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7434 match(Set dst (DecodeNKlass (Binary base src))); 7435 //effect(kill src); // We need a register for the immediate result after shifting. 7436 predicate(false); 7437 7438 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7439 postalloc_expand %{ 7440 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7441 n1->add_req(n_region, n_base, n_src); 7442 n1->_opnds[0] = op_dst; 7443 n1->_opnds[1] = op_base; 7444 n1->_opnds[2] = op_src; 7445 n1->_bottom_type = _bottom_type; 7446 7447 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7448 n2->add_req(n_region, n1); 7449 n2->_opnds[0] = op_dst; 7450 n2->_opnds[1] = op_dst; 7451 n2->_bottom_type = _bottom_type; 7452 7453 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7454 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7455 7456 nodes->push(n1); 7457 nodes->push(n2); 7458 %} 7459 %} 7460 7461 // src != 0, shift != 0, base != 0 7462 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7463 match(Set dst (DecodeNKlass src)); 7464 // predicate(Universe::narrow_klass_shift() != 0 && 7465 // Universe::narrow_klass_base() != 0); 7466 7467 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7468 7469 ins_cost(DEFAULT_COST*2); // Don't count constant. 7470 expand %{ 7471 // We add first, then we shift. Like this, we can get along with one register less. 7472 // But we have to load the base pre-shifted. 7473 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7474 iRegLdst base; 7475 loadConL_Ex(base, baseImm); 7476 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7477 %} 7478 %} 7479 7480 //----------MemBar Instructions----------------------------------------------- 7481 // Memory barrier flavors 7482 7483 instruct membar_acquire() %{ 7484 match(LoadFence); 7485 ins_cost(4*MEMORY_REF_COST); 7486 7487 format %{ "MEMBAR-acquire" %} 7488 size(4); 7489 ins_encode %{ 7490 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7491 __ acquire(); 7492 %} 7493 ins_pipe(pipe_class_default); 7494 %} 7495 7496 instruct unnecessary_membar_acquire() %{ 7497 match(MemBarAcquire); 7498 ins_cost(0); 7499 7500 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7501 size(0); 7502 ins_encode( /*empty*/ ); 7503 ins_pipe(pipe_class_default); 7504 %} 7505 7506 instruct membar_acquire_lock() %{ 7507 match(MemBarAcquireLock); 7508 ins_cost(0); 7509 7510 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7511 size(0); 7512 ins_encode( /*empty*/ ); 7513 ins_pipe(pipe_class_default); 7514 %} 7515 7516 instruct membar_release() %{ 7517 match(MemBarRelease); 7518 match(StoreFence); 7519 ins_cost(4*MEMORY_REF_COST); 7520 7521 format %{ "MEMBAR-release" %} 7522 size(4); 7523 ins_encode %{ 7524 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7525 __ release(); 7526 %} 7527 ins_pipe(pipe_class_default); 7528 %} 7529 7530 instruct membar_storestore() %{ 7531 match(MemBarStoreStore); 7532 ins_cost(4*MEMORY_REF_COST); 7533 7534 format %{ "MEMBAR-store-store" %} 7535 size(4); 7536 ins_encode %{ 7537 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7538 __ membar(Assembler::StoreStore); 7539 %} 7540 ins_pipe(pipe_class_default); 7541 %} 7542 7543 instruct membar_release_lock() %{ 7544 match(MemBarReleaseLock); 7545 ins_cost(0); 7546 7547 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7548 size(0); 7549 ins_encode( /*empty*/ ); 7550 ins_pipe(pipe_class_default); 7551 %} 7552 7553 instruct membar_volatile() %{ 7554 match(MemBarVolatile); 7555 ins_cost(4*MEMORY_REF_COST); 7556 7557 format %{ "MEMBAR-volatile" %} 7558 size(4); 7559 ins_encode %{ 7560 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7561 __ fence(); 7562 %} 7563 ins_pipe(pipe_class_default); 7564 %} 7565 7566 // This optimization is wrong on PPC. The following pattern is not supported: 7567 // MemBarVolatile 7568 // ^ ^ 7569 // | | 7570 // CtrlProj MemProj 7571 // ^ ^ 7572 // | | 7573 // | Load 7574 // | 7575 // MemBarVolatile 7576 // 7577 // The first MemBarVolatile could get optimized out! According to 7578 // Vladimir, this pattern can not occur on Oracle platforms. 7579 // However, it does occur on PPC64 (because of membars in 7580 // inline_unsafe_load_store). 7581 // 7582 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7583 // Don't forget to look at the implementation of post_store_load_barrier again, 7584 // we did other fixes in that method. 7585 //instruct unnecessary_membar_volatile() %{ 7586 // match(MemBarVolatile); 7587 // predicate(Matcher::post_store_load_barrier(n)); 7588 // ins_cost(0); 7589 // 7590 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7591 // size(0); 7592 // ins_encode( /*empty*/ ); 7593 // ins_pipe(pipe_class_default); 7594 //%} 7595 7596 instruct membar_CPUOrder() %{ 7597 match(MemBarCPUOrder); 7598 ins_cost(0); 7599 7600 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7601 size(0); 7602 ins_encode( /*empty*/ ); 7603 ins_pipe(pipe_class_default); 7604 %} 7605 7606 //----------Conditional Move--------------------------------------------------- 7607 7608 // Cmove using isel. 7609 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7610 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7611 predicate(VM_Version::has_isel()); 7612 ins_cost(DEFAULT_COST); 7613 7614 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7615 size(4); 7616 ins_encode %{ 7617 // This is a Power7 instruction for which no machine description 7618 // exists. Anyways, the scheduler should be off on Power7. 7619 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7620 int cc = $cmp$$cmpcode; 7621 __ isel($dst$$Register, $crx$$CondRegister, 7622 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7623 %} 7624 ins_pipe(pipe_class_default); 7625 %} 7626 7627 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7628 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7629 predicate(!VM_Version::has_isel()); 7630 ins_cost(DEFAULT_COST+BRANCH_COST); 7631 7632 ins_variable_size_depending_on_alignment(true); 7633 7634 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7635 // Worst case is branch + move + stop, no stop without scheduler 7636 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7637 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7638 ins_pipe(pipe_class_default); 7639 %} 7640 7641 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7642 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7643 ins_cost(DEFAULT_COST+BRANCH_COST); 7644 7645 ins_variable_size_depending_on_alignment(true); 7646 7647 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7648 // Worst case is branch + move + stop, no stop without scheduler 7649 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7650 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7651 ins_pipe(pipe_class_default); 7652 %} 7653 7654 // Cmove using isel. 7655 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7656 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7657 predicate(VM_Version::has_isel()); 7658 ins_cost(DEFAULT_COST); 7659 7660 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7661 size(4); 7662 ins_encode %{ 7663 // This is a Power7 instruction for which no machine description 7664 // exists. Anyways, the scheduler should be off on Power7. 7665 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7666 int cc = $cmp$$cmpcode; 7667 __ isel($dst$$Register, $crx$$CondRegister, 7668 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7669 %} 7670 ins_pipe(pipe_class_default); 7671 %} 7672 7673 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7674 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7675 predicate(!VM_Version::has_isel()); 7676 ins_cost(DEFAULT_COST+BRANCH_COST); 7677 7678 ins_variable_size_depending_on_alignment(true); 7679 7680 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7681 // Worst case is branch + move + stop, no stop without scheduler. 7682 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7683 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7684 ins_pipe(pipe_class_default); 7685 %} 7686 7687 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7688 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7689 ins_cost(DEFAULT_COST+BRANCH_COST); 7690 7691 ins_variable_size_depending_on_alignment(true); 7692 7693 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7694 // Worst case is branch + move + stop, no stop without scheduler. 7695 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7696 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7697 ins_pipe(pipe_class_default); 7698 %} 7699 7700 // Cmove using isel. 7701 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7702 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7703 predicate(VM_Version::has_isel()); 7704 ins_cost(DEFAULT_COST); 7705 7706 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7707 size(4); 7708 ins_encode %{ 7709 // This is a Power7 instruction for which no machine description 7710 // exists. Anyways, the scheduler should be off on Power7. 7711 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7712 int cc = $cmp$$cmpcode; 7713 __ isel($dst$$Register, $crx$$CondRegister, 7714 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7715 %} 7716 ins_pipe(pipe_class_default); 7717 %} 7718 7719 // Conditional move for RegN. Only cmov(reg, reg). 7720 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7721 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7722 predicate(!VM_Version::has_isel()); 7723 ins_cost(DEFAULT_COST+BRANCH_COST); 7724 7725 ins_variable_size_depending_on_alignment(true); 7726 7727 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7728 // Worst case is branch + move + stop, no stop without scheduler. 7729 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7730 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7731 ins_pipe(pipe_class_default); 7732 %} 7733 7734 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7735 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7736 ins_cost(DEFAULT_COST+BRANCH_COST); 7737 7738 ins_variable_size_depending_on_alignment(true); 7739 7740 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7741 // Worst case is branch + move + stop, no stop without scheduler. 7742 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7743 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7744 ins_pipe(pipe_class_default); 7745 %} 7746 7747 // Cmove using isel. 7748 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7749 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7750 predicate(VM_Version::has_isel()); 7751 ins_cost(DEFAULT_COST); 7752 7753 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7754 size(4); 7755 ins_encode %{ 7756 // This is a Power7 instruction for which no machine description 7757 // exists. Anyways, the scheduler should be off on Power7. 7758 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7759 int cc = $cmp$$cmpcode; 7760 __ isel($dst$$Register, $crx$$CondRegister, 7761 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7762 %} 7763 ins_pipe(pipe_class_default); 7764 %} 7765 7766 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7767 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7768 predicate(!VM_Version::has_isel()); 7769 ins_cost(DEFAULT_COST+BRANCH_COST); 7770 7771 ins_variable_size_depending_on_alignment(true); 7772 7773 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7774 // Worst case is branch + move + stop, no stop without scheduler. 7775 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7776 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7777 ins_pipe(pipe_class_default); 7778 %} 7779 7780 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7781 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7782 ins_cost(DEFAULT_COST+BRANCH_COST); 7783 7784 ins_variable_size_depending_on_alignment(true); 7785 7786 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7787 // Worst case is branch + move + stop, no stop without scheduler. 7788 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7789 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7790 ins_pipe(pipe_class_default); 7791 %} 7792 7793 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7794 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7795 ins_cost(DEFAULT_COST+BRANCH_COST); 7796 7797 ins_variable_size_depending_on_alignment(true); 7798 7799 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7800 // Worst case is branch + move + stop, no stop without scheduler. 7801 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7802 ins_encode %{ 7803 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7804 Label done; 7805 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7806 // Branch if not (cmp crx). 7807 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7808 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7809 // TODO PPC port __ endgroup_if_needed(_size == 12); 7810 __ bind(done); 7811 %} 7812 ins_pipe(pipe_class_default); 7813 %} 7814 7815 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7816 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7817 ins_cost(DEFAULT_COST+BRANCH_COST); 7818 7819 ins_variable_size_depending_on_alignment(true); 7820 7821 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7822 // Worst case is branch + move + stop, no stop without scheduler. 7823 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7824 ins_encode %{ 7825 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7826 Label done; 7827 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7828 // Branch if not (cmp crx). 7829 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7830 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7831 // TODO PPC port __ endgroup_if_needed(_size == 12); 7832 __ bind(done); 7833 %} 7834 ins_pipe(pipe_class_default); 7835 %} 7836 7837 //----------Conditional_store-------------------------------------------------- 7838 // Conditional-store of the updated heap-top. 7839 // Used during allocation of the shared heap. 7840 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7841 7842 // As compareAndSwapL, but return flag register instead of boolean value in 7843 // int register. 7844 // Used by sun/misc/AtomicLongCSImpl.java. 7845 // Mem_ptr must be a memory operand, else this node does not get 7846 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7847 // can be rematerialized which leads to errors. 7848 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7849 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7850 effect(TEMP cr0); 7851 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7852 ins_encode %{ 7853 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7854 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7855 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7856 noreg, NULL, true); 7857 %} 7858 ins_pipe(pipe_class_default); 7859 %} 7860 7861 // As compareAndSwapP, but return flag register instead of boolean value in 7862 // int register. 7863 // This instruction is matched if UseTLAB is off. 7864 // Mem_ptr must be a memory operand, else this node does not get 7865 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7866 // can be rematerialized which leads to errors. 7867 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7868 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7869 ins_cost(2*MEMORY_REF_COST); 7870 7871 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7872 ins_encode %{ 7873 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7874 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7875 %} 7876 ins_pipe(pipe_class_memory); 7877 %} 7878 7879 // Implement LoadPLocked. Must be ordered against changes of the memory location 7880 // by storePConditional. 7881 // Don't know whether this is ever used. 7882 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7883 match(Set dst (LoadPLocked mem)); 7884 ins_cost(2*MEMORY_REF_COST); 7885 7886 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7887 size(4); 7888 ins_encode %{ 7889 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7890 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7891 %} 7892 ins_pipe(pipe_class_memory); 7893 %} 7894 7895 //----------Compare-And-Swap--------------------------------------------------- 7896 7897 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7898 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7899 // matched. 7900 7901 // Strong versions: 7902 7903 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7904 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7905 predicate(VM_Version::has_lqarx()); 7906 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7907 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7908 ins_encode %{ 7909 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7910 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7911 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7912 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7913 $res$$Register, true); 7914 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7915 __ isync(); 7916 } else { 7917 __ sync(); 7918 } 7919 %} 7920 ins_pipe(pipe_class_default); 7921 %} 7922 7923 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7924 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7925 predicate(!VM_Version::has_lqarx()); 7926 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7927 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7928 ins_encode %{ 7929 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7930 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7931 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7932 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7933 $res$$Register, true); 7934 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7935 __ isync(); 7936 } else { 7937 __ sync(); 7938 } 7939 %} 7940 ins_pipe(pipe_class_default); 7941 %} 7942 7943 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7944 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7945 predicate(VM_Version::has_lqarx()); 7946 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7947 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7948 ins_encode %{ 7949 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7950 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7951 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7952 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7953 $res$$Register, true); 7954 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7955 __ isync(); 7956 } else { 7957 __ sync(); 7958 } 7959 %} 7960 ins_pipe(pipe_class_default); 7961 %} 7962 7963 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7964 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7965 predicate(!VM_Version::has_lqarx()); 7966 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7967 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7968 ins_encode %{ 7969 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7970 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7971 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7972 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7973 $res$$Register, true); 7974 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7975 __ isync(); 7976 } else { 7977 __ sync(); 7978 } 7979 %} 7980 ins_pipe(pipe_class_default); 7981 %} 7982 7983 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7984 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7985 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7986 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7987 ins_encode %{ 7988 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7989 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7990 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7991 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7992 $res$$Register, true); 7993 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7994 __ isync(); 7995 } else { 7996 __ sync(); 7997 } 7998 %} 7999 ins_pipe(pipe_class_default); 8000 %} 8001 8002 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8003 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 8004 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8005 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8006 ins_encode %{ 8007 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8008 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8009 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8010 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8011 $res$$Register, true); 8012 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8013 __ isync(); 8014 } else { 8015 __ sync(); 8016 } 8017 %} 8018 ins_pipe(pipe_class_default); 8019 %} 8020 8021 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8022 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 8023 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8024 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8025 ins_encode %{ 8026 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8027 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8028 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8029 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8030 $res$$Register, NULL, true); 8031 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8032 __ isync(); 8033 } else { 8034 __ sync(); 8035 } 8036 %} 8037 ins_pipe(pipe_class_default); 8038 %} 8039 8040 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8041 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 8042 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8043 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8044 ins_encode %{ 8045 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8046 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8047 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8048 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8049 $res$$Register, NULL, true); 8050 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8051 __ isync(); 8052 } else { 8053 __ sync(); 8054 } 8055 %} 8056 ins_pipe(pipe_class_default); 8057 %} 8058 8059 // Weak versions: 8060 8061 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8062 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8063 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8064 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8065 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8066 ins_encode %{ 8067 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8068 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8069 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8070 MacroAssembler::MemBarNone, 8071 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8072 %} 8073 ins_pipe(pipe_class_default); 8074 %} 8075 8076 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8077 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8078 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8079 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8080 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8081 ins_encode %{ 8082 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8083 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8084 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8085 MacroAssembler::MemBarNone, 8086 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8087 %} 8088 ins_pipe(pipe_class_default); 8089 %} 8090 8091 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8092 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8093 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8094 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8095 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8096 ins_encode %{ 8097 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8098 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8099 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8100 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8101 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8102 %} 8103 ins_pipe(pipe_class_default); 8104 %} 8105 8106 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8107 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8108 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8109 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8110 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8111 ins_encode %{ 8112 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8113 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8114 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8115 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8116 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8117 %} 8118 ins_pipe(pipe_class_default); 8119 %} 8120 8121 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8122 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8123 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8124 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8125 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8126 ins_encode %{ 8127 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8128 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8129 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8130 MacroAssembler::MemBarNone, 8131 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8132 %} 8133 ins_pipe(pipe_class_default); 8134 %} 8135 8136 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8137 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8138 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8139 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8140 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8141 ins_encode %{ 8142 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8143 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8144 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8145 MacroAssembler::MemBarNone, 8146 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8147 %} 8148 ins_pipe(pipe_class_default); 8149 %} 8150 8151 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8152 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8153 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8154 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8155 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8156 ins_encode %{ 8157 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8158 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8159 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8160 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8161 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8162 %} 8163 ins_pipe(pipe_class_default); 8164 %} 8165 8166 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8167 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8168 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8169 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8170 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8171 ins_encode %{ 8172 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8173 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8174 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8175 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8176 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8177 %} 8178 ins_pipe(pipe_class_default); 8179 %} 8180 8181 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8182 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8183 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8184 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8185 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8186 ins_encode %{ 8187 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8188 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8189 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8190 MacroAssembler::MemBarNone, 8191 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8192 %} 8193 ins_pipe(pipe_class_default); 8194 %} 8195 8196 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8197 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8198 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8199 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8200 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8201 ins_encode %{ 8202 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8203 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8204 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8205 // value is never passed to caller. 8206 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8207 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8208 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8209 %} 8210 ins_pipe(pipe_class_default); 8211 %} 8212 8213 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8214 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8215 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8216 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8217 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8218 ins_encode %{ 8219 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8220 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8221 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8222 MacroAssembler::MemBarNone, 8223 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8224 %} 8225 ins_pipe(pipe_class_default); 8226 %} 8227 8228 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8229 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8230 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8231 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8232 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8233 ins_encode %{ 8234 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8235 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8236 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8237 // value is never passed to caller. 8238 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8239 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8240 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8241 %} 8242 ins_pipe(pipe_class_default); 8243 %} 8244 8245 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8246 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8247 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8248 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8249 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8250 ins_encode %{ 8251 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8252 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8253 // value is never passed to caller. 8254 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8255 MacroAssembler::MemBarNone, 8256 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8257 %} 8258 ins_pipe(pipe_class_default); 8259 %} 8260 8261 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8262 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8263 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8264 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8265 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 8266 ins_encode %{ 8267 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8268 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8269 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8270 // value is never passed to caller. 8271 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8272 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8273 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8274 %} 8275 ins_pipe(pipe_class_default); 8276 %} 8277 8278 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8279 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8280 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8281 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8282 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8283 ins_encode %{ 8284 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8285 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8286 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8287 MacroAssembler::MemBarNone, 8288 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8289 %} 8290 ins_pipe(pipe_class_default); 8291 %} 8292 8293 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8294 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8295 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8296 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8297 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8298 ins_encode %{ 8299 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8300 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8301 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8302 // value is never passed to caller. 8303 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8304 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8305 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8306 %} 8307 ins_pipe(pipe_class_default); 8308 %} 8309 8310 // CompareAndExchange 8311 8312 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8313 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8314 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8315 effect(TEMP_DEF res, TEMP cr0); 8316 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8317 ins_encode %{ 8318 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8319 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8320 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8321 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8322 noreg, true); 8323 %} 8324 ins_pipe(pipe_class_default); 8325 %} 8326 8327 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8328 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8329 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8330 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8331 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8332 ins_encode %{ 8333 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8334 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8335 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8336 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8337 noreg, true); 8338 %} 8339 ins_pipe(pipe_class_default); 8340 %} 8341 8342 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8343 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8344 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8345 effect(TEMP_DEF res, TEMP cr0); 8346 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8347 ins_encode %{ 8348 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8349 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8350 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8351 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8352 noreg, true); 8353 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8354 __ isync(); 8355 } else { 8356 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8357 __ sync(); 8358 } 8359 %} 8360 ins_pipe(pipe_class_default); 8361 %} 8362 8363 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8364 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8365 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8366 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8367 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8368 ins_encode %{ 8369 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8370 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8371 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8372 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8373 noreg, true); 8374 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8375 __ isync(); 8376 } else { 8377 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8378 __ sync(); 8379 } 8380 %} 8381 ins_pipe(pipe_class_default); 8382 %} 8383 8384 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8385 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8386 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8387 effect(TEMP_DEF res, TEMP cr0); 8388 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8389 ins_encode %{ 8390 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8391 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8392 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8393 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8394 noreg, true); 8395 %} 8396 ins_pipe(pipe_class_default); 8397 %} 8398 8399 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8400 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8401 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8402 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8403 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8404 ins_encode %{ 8405 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8406 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8407 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8408 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8409 noreg, true); 8410 %} 8411 ins_pipe(pipe_class_default); 8412 %} 8413 8414 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8415 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8416 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8417 effect(TEMP_DEF res, TEMP cr0); 8418 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8419 ins_encode %{ 8420 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8421 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8422 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8423 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8424 noreg, true); 8425 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8426 __ isync(); 8427 } else { 8428 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8429 __ sync(); 8430 } 8431 %} 8432 ins_pipe(pipe_class_default); 8433 %} 8434 8435 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8436 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8437 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8438 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8439 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8440 ins_encode %{ 8441 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8442 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8443 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8444 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8445 noreg, true); 8446 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8447 __ isync(); 8448 } else { 8449 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8450 __ sync(); 8451 } 8452 %} 8453 ins_pipe(pipe_class_default); 8454 %} 8455 8456 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8457 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8458 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8459 effect(TEMP_DEF res, TEMP cr0); 8460 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8461 ins_encode %{ 8462 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8463 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8464 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8465 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8466 noreg, true); 8467 %} 8468 ins_pipe(pipe_class_default); 8469 %} 8470 8471 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8472 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8473 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8474 effect(TEMP_DEF res, TEMP cr0); 8475 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8476 ins_encode %{ 8477 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8478 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8479 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8480 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8481 noreg, true); 8482 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8483 __ isync(); 8484 } else { 8485 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8486 __ sync(); 8487 } 8488 %} 8489 ins_pipe(pipe_class_default); 8490 %} 8491 8492 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8493 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8494 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8495 effect(TEMP_DEF res, TEMP cr0); 8496 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8497 ins_encode %{ 8498 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8499 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8500 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8501 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8502 noreg, true); 8503 %} 8504 ins_pipe(pipe_class_default); 8505 %} 8506 8507 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8508 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8509 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8510 effect(TEMP_DEF res, TEMP cr0); 8511 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8512 ins_encode %{ 8513 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8514 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8515 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8516 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8517 noreg, true); 8518 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8519 __ isync(); 8520 } else { 8521 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8522 __ sync(); 8523 } 8524 %} 8525 ins_pipe(pipe_class_default); 8526 %} 8527 8528 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8529 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8530 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8531 effect(TEMP_DEF res, TEMP cr0); 8532 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8533 ins_encode %{ 8534 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8535 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8536 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8537 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8538 noreg, NULL, true); 8539 %} 8540 ins_pipe(pipe_class_default); 8541 %} 8542 8543 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8544 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8545 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8546 effect(TEMP_DEF res, TEMP cr0); 8547 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8548 ins_encode %{ 8549 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8550 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8551 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8552 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8553 noreg, NULL, true); 8554 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8555 __ isync(); 8556 } else { 8557 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8558 __ sync(); 8559 } 8560 %} 8561 ins_pipe(pipe_class_default); 8562 %} 8563 8564 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8565 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8566 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8567 effect(TEMP_DEF res, TEMP cr0); 8568 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8569 ins_encode %{ 8570 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8571 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8572 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8573 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8574 noreg, NULL, true); 8575 %} 8576 ins_pipe(pipe_class_default); 8577 %} 8578 8579 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8580 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8581 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8582 effect(TEMP_DEF res, TEMP cr0); 8583 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8584 ins_encode %{ 8585 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8586 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8587 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8588 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8589 noreg, NULL, true); 8590 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8591 __ isync(); 8592 } else { 8593 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8594 __ sync(); 8595 } 8596 %} 8597 ins_pipe(pipe_class_default); 8598 %} 8599 8600 // Special RMW 8601 8602 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8603 match(Set res (GetAndAddB mem_ptr src)); 8604 predicate(VM_Version::has_lqarx()); 8605 effect(TEMP_DEF res, TEMP cr0); 8606 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8607 ins_encode %{ 8608 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8609 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8610 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8611 __ isync(); 8612 } else { 8613 __ sync(); 8614 } 8615 %} 8616 ins_pipe(pipe_class_default); 8617 %} 8618 8619 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8620 match(Set res (GetAndAddB mem_ptr src)); 8621 predicate(!VM_Version::has_lqarx()); 8622 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8623 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8624 ins_encode %{ 8625 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8626 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8627 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8628 __ isync(); 8629 } else { 8630 __ sync(); 8631 } 8632 %} 8633 ins_pipe(pipe_class_default); 8634 %} 8635 8636 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8637 match(Set res (GetAndAddS mem_ptr src)); 8638 predicate(VM_Version::has_lqarx()); 8639 effect(TEMP_DEF res, TEMP cr0); 8640 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8641 ins_encode %{ 8642 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8643 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8644 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8645 __ isync(); 8646 } else { 8647 __ sync(); 8648 } 8649 %} 8650 ins_pipe(pipe_class_default); 8651 %} 8652 8653 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8654 match(Set res (GetAndAddS mem_ptr src)); 8655 predicate(!VM_Version::has_lqarx()); 8656 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8657 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8658 ins_encode %{ 8659 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8660 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8661 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8662 __ isync(); 8663 } else { 8664 __ sync(); 8665 } 8666 %} 8667 ins_pipe(pipe_class_default); 8668 %} 8669 8670 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8671 match(Set res (GetAndAddI mem_ptr src)); 8672 effect(TEMP_DEF res, TEMP cr0); 8673 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8674 ins_encode %{ 8675 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8676 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8677 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8678 __ isync(); 8679 } else { 8680 __ sync(); 8681 } 8682 %} 8683 ins_pipe(pipe_class_default); 8684 %} 8685 8686 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8687 match(Set res (GetAndAddL mem_ptr src)); 8688 effect(TEMP_DEF res, TEMP cr0); 8689 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8690 ins_encode %{ 8691 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8692 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8693 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8694 __ isync(); 8695 } else { 8696 __ sync(); 8697 } 8698 %} 8699 ins_pipe(pipe_class_default); 8700 %} 8701 8702 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8703 match(Set res (GetAndSetB mem_ptr src)); 8704 predicate(VM_Version::has_lqarx()); 8705 effect(TEMP_DEF res, TEMP cr0); 8706 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8707 ins_encode %{ 8708 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8709 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8710 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8711 __ isync(); 8712 } else { 8713 __ sync(); 8714 } 8715 %} 8716 ins_pipe(pipe_class_default); 8717 %} 8718 8719 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8720 match(Set res (GetAndSetB mem_ptr src)); 8721 predicate(!VM_Version::has_lqarx()); 8722 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8723 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8724 ins_encode %{ 8725 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8726 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8727 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8728 __ isync(); 8729 } else { 8730 __ sync(); 8731 } 8732 %} 8733 ins_pipe(pipe_class_default); 8734 %} 8735 8736 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8737 match(Set res (GetAndSetS mem_ptr src)); 8738 predicate(VM_Version::has_lqarx()); 8739 effect(TEMP_DEF res, TEMP cr0); 8740 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8741 ins_encode %{ 8742 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8743 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8744 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8745 __ isync(); 8746 } else { 8747 __ sync(); 8748 } 8749 %} 8750 ins_pipe(pipe_class_default); 8751 %} 8752 8753 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8754 match(Set res (GetAndSetS mem_ptr src)); 8755 predicate(!VM_Version::has_lqarx()); 8756 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8757 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8758 ins_encode %{ 8759 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8760 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8761 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8762 __ isync(); 8763 } else { 8764 __ sync(); 8765 } 8766 %} 8767 ins_pipe(pipe_class_default); 8768 %} 8769 8770 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8771 match(Set res (GetAndSetI mem_ptr src)); 8772 effect(TEMP_DEF res, TEMP cr0); 8773 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8774 ins_encode %{ 8775 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8776 MacroAssembler::cmpxchgx_hint_atomic_update()); 8777 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8778 __ isync(); 8779 } else { 8780 __ sync(); 8781 } 8782 %} 8783 ins_pipe(pipe_class_default); 8784 %} 8785 8786 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8787 match(Set res (GetAndSetL mem_ptr src)); 8788 effect(TEMP_DEF res, TEMP cr0); 8789 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8790 ins_encode %{ 8791 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8792 MacroAssembler::cmpxchgx_hint_atomic_update()); 8793 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8794 __ isync(); 8795 } else { 8796 __ sync(); 8797 } 8798 %} 8799 ins_pipe(pipe_class_default); 8800 %} 8801 8802 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8803 match(Set res (GetAndSetP mem_ptr src)); 8804 effect(TEMP_DEF res, TEMP cr0); 8805 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8806 ins_encode %{ 8807 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8808 MacroAssembler::cmpxchgx_hint_atomic_update()); 8809 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8810 __ isync(); 8811 } else { 8812 __ sync(); 8813 } 8814 %} 8815 ins_pipe(pipe_class_default); 8816 %} 8817 8818 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8819 match(Set res (GetAndSetN mem_ptr src)); 8820 effect(TEMP_DEF res, TEMP cr0); 8821 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8822 ins_encode %{ 8823 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8824 MacroAssembler::cmpxchgx_hint_atomic_update()); 8825 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8826 __ isync(); 8827 } else { 8828 __ sync(); 8829 } 8830 %} 8831 ins_pipe(pipe_class_default); 8832 %} 8833 8834 //----------Arithmetic Instructions-------------------------------------------- 8835 // Addition Instructions 8836 8837 // Register Addition 8838 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8839 match(Set dst (AddI src1 src2)); 8840 format %{ "ADD $dst, $src1, $src2" %} 8841 size(4); 8842 ins_encode %{ 8843 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8844 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8845 %} 8846 ins_pipe(pipe_class_default); 8847 %} 8848 8849 // Expand does not work with above instruct. (??) 8850 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8851 // no match-rule 8852 effect(DEF dst, USE src1, USE src2); 8853 format %{ "ADD $dst, $src1, $src2" %} 8854 size(4); 8855 ins_encode %{ 8856 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8857 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8858 %} 8859 ins_pipe(pipe_class_default); 8860 %} 8861 8862 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8863 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8864 ins_cost(DEFAULT_COST*3); 8865 8866 expand %{ 8867 // FIXME: we should do this in the ideal world. 8868 iRegIdst tmp1; 8869 iRegIdst tmp2; 8870 addI_reg_reg(tmp1, src1, src2); 8871 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8872 addI_reg_reg(dst, tmp1, tmp2); 8873 %} 8874 %} 8875 8876 // Immediate Addition 8877 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8878 match(Set dst (AddI src1 src2)); 8879 format %{ "ADDI $dst, $src1, $src2" %} 8880 size(4); 8881 ins_encode %{ 8882 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8883 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8884 %} 8885 ins_pipe(pipe_class_default); 8886 %} 8887 8888 // Immediate Addition with 16-bit shifted operand 8889 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8890 match(Set dst (AddI src1 src2)); 8891 format %{ "ADDIS $dst, $src1, $src2" %} 8892 size(4); 8893 ins_encode %{ 8894 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8895 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8896 %} 8897 ins_pipe(pipe_class_default); 8898 %} 8899 8900 // Long Addition 8901 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8902 match(Set dst (AddL src1 src2)); 8903 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8904 size(4); 8905 ins_encode %{ 8906 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8907 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8908 %} 8909 ins_pipe(pipe_class_default); 8910 %} 8911 8912 // Expand does not work with above instruct. (??) 8913 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8914 // no match-rule 8915 effect(DEF dst, USE src1, USE src2); 8916 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8917 size(4); 8918 ins_encode %{ 8919 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8920 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8921 %} 8922 ins_pipe(pipe_class_default); 8923 %} 8924 8925 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8926 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8927 ins_cost(DEFAULT_COST*3); 8928 8929 expand %{ 8930 // FIXME: we should do this in the ideal world. 8931 iRegLdst tmp1; 8932 iRegLdst tmp2; 8933 addL_reg_reg(tmp1, src1, src2); 8934 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8935 addL_reg_reg(dst, tmp1, tmp2); 8936 %} 8937 %} 8938 8939 // AddL + ConvL2I. 8940 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8941 match(Set dst (ConvL2I (AddL src1 src2))); 8942 8943 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8944 size(4); 8945 ins_encode %{ 8946 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8947 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8948 %} 8949 ins_pipe(pipe_class_default); 8950 %} 8951 8952 // No constant pool entries required. 8953 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8954 match(Set dst (AddL src1 src2)); 8955 8956 format %{ "ADDI $dst, $src1, $src2" %} 8957 size(4); 8958 ins_encode %{ 8959 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8960 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8961 %} 8962 ins_pipe(pipe_class_default); 8963 %} 8964 8965 // Long Immediate Addition with 16-bit shifted operand. 8966 // No constant pool entries required. 8967 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8968 match(Set dst (AddL src1 src2)); 8969 8970 format %{ "ADDIS $dst, $src1, $src2" %} 8971 size(4); 8972 ins_encode %{ 8973 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8974 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8975 %} 8976 ins_pipe(pipe_class_default); 8977 %} 8978 8979 // Pointer Register Addition 8980 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8981 match(Set dst (AddP src1 src2)); 8982 format %{ "ADD $dst, $src1, $src2" %} 8983 size(4); 8984 ins_encode %{ 8985 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8986 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8987 %} 8988 ins_pipe(pipe_class_default); 8989 %} 8990 8991 // Pointer Immediate Addition 8992 // No constant pool entries required. 8993 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8994 match(Set dst (AddP src1 src2)); 8995 8996 format %{ "ADDI $dst, $src1, $src2" %} 8997 size(4); 8998 ins_encode %{ 8999 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 9000 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 9001 %} 9002 ins_pipe(pipe_class_default); 9003 %} 9004 9005 // Pointer Immediate Addition with 16-bit shifted operand. 9006 // No constant pool entries required. 9007 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 9008 match(Set dst (AddP src1 src2)); 9009 9010 format %{ "ADDIS $dst, $src1, $src2" %} 9011 size(4); 9012 ins_encode %{ 9013 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 9014 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 9015 %} 9016 ins_pipe(pipe_class_default); 9017 %} 9018 9019 //--------------------- 9020 // Subtraction Instructions 9021 9022 // Register Subtraction 9023 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9024 match(Set dst (SubI src1 src2)); 9025 format %{ "SUBF $dst, $src2, $src1" %} 9026 size(4); 9027 ins_encode %{ 9028 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9029 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9030 %} 9031 ins_pipe(pipe_class_default); 9032 %} 9033 9034 // Immediate Subtraction 9035 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 9036 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 9037 9038 // SubI from constant (using subfic). 9039 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 9040 match(Set dst (SubI src1 src2)); 9041 format %{ "SUBI $dst, $src1, $src2" %} 9042 9043 size(4); 9044 ins_encode %{ 9045 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 9046 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 9047 %} 9048 ins_pipe(pipe_class_default); 9049 %} 9050 9051 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 9052 // positive integers and 0xF...F for negative ones. 9053 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 9054 // no match-rule, false predicate 9055 effect(DEF dst, USE src); 9056 predicate(false); 9057 9058 format %{ "SRAWI $dst, $src, #31" %} 9059 size(4); 9060 ins_encode %{ 9061 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9062 __ srawi($dst$$Register, $src$$Register, 0x1f); 9063 %} 9064 ins_pipe(pipe_class_default); 9065 %} 9066 9067 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 9068 match(Set dst (AbsI src)); 9069 ins_cost(DEFAULT_COST*3); 9070 9071 expand %{ 9072 iRegIdst tmp1; 9073 iRegIdst tmp2; 9074 signmask32I_regI(tmp1, src); 9075 xorI_reg_reg(tmp2, tmp1, src); 9076 subI_reg_reg(dst, tmp2, tmp1); 9077 %} 9078 %} 9079 9080 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9081 match(Set dst (SubI zero src2)); 9082 format %{ "NEG $dst, $src2" %} 9083 size(4); 9084 ins_encode %{ 9085 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9086 __ neg($dst$$Register, $src2$$Register); 9087 %} 9088 ins_pipe(pipe_class_default); 9089 %} 9090 9091 // Long subtraction 9092 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9093 match(Set dst (SubL src1 src2)); 9094 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9095 size(4); 9096 ins_encode %{ 9097 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9098 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9099 %} 9100 ins_pipe(pipe_class_default); 9101 %} 9102 9103 // SubL + convL2I. 9104 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9105 match(Set dst (ConvL2I (SubL src1 src2))); 9106 9107 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9108 size(4); 9109 ins_encode %{ 9110 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9111 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9112 %} 9113 ins_pipe(pipe_class_default); 9114 %} 9115 9116 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9117 // positive longs and 0xF...F for negative ones. 9118 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9119 // no match-rule, false predicate 9120 effect(DEF dst, USE src); 9121 predicate(false); 9122 9123 format %{ "SRADI $dst, $src, #63" %} 9124 size(4); 9125 ins_encode %{ 9126 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9127 __ sradi($dst$$Register, $src$$Register, 0x3f); 9128 %} 9129 ins_pipe(pipe_class_default); 9130 %} 9131 9132 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9133 // positive longs and 0xF...F for negative ones. 9134 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9135 // no match-rule, false predicate 9136 effect(DEF dst, USE src); 9137 predicate(false); 9138 9139 format %{ "SRADI $dst, $src, #63" %} 9140 size(4); 9141 ins_encode %{ 9142 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9143 __ sradi($dst$$Register, $src$$Register, 0x3f); 9144 %} 9145 ins_pipe(pipe_class_default); 9146 %} 9147 9148 // Long negation 9149 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9150 match(Set dst (SubL zero src2)); 9151 format %{ "NEG $dst, $src2 \t// long" %} 9152 size(4); 9153 ins_encode %{ 9154 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9155 __ neg($dst$$Register, $src2$$Register); 9156 %} 9157 ins_pipe(pipe_class_default); 9158 %} 9159 9160 // NegL + ConvL2I. 9161 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9162 match(Set dst (ConvL2I (SubL zero src2))); 9163 9164 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9165 size(4); 9166 ins_encode %{ 9167 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9168 __ neg($dst$$Register, $src2$$Register); 9169 %} 9170 ins_pipe(pipe_class_default); 9171 %} 9172 9173 // Multiplication Instructions 9174 // Integer Multiplication 9175 9176 // Register Multiplication 9177 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9178 match(Set dst (MulI src1 src2)); 9179 ins_cost(DEFAULT_COST); 9180 9181 format %{ "MULLW $dst, $src1, $src2" %} 9182 size(4); 9183 ins_encode %{ 9184 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9185 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9186 %} 9187 ins_pipe(pipe_class_default); 9188 %} 9189 9190 // Immediate Multiplication 9191 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9192 match(Set dst (MulI src1 src2)); 9193 ins_cost(DEFAULT_COST); 9194 9195 format %{ "MULLI $dst, $src1, $src2" %} 9196 size(4); 9197 ins_encode %{ 9198 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9199 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9200 %} 9201 ins_pipe(pipe_class_default); 9202 %} 9203 9204 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9205 match(Set dst (MulL src1 src2)); 9206 ins_cost(DEFAULT_COST); 9207 9208 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9209 size(4); 9210 ins_encode %{ 9211 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9212 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9213 %} 9214 ins_pipe(pipe_class_default); 9215 %} 9216 9217 // Multiply high for optimized long division by constant. 9218 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9219 match(Set dst (MulHiL src1 src2)); 9220 ins_cost(DEFAULT_COST); 9221 9222 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9223 size(4); 9224 ins_encode %{ 9225 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9226 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9227 %} 9228 ins_pipe(pipe_class_default); 9229 %} 9230 9231 // Immediate Multiplication 9232 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9233 match(Set dst (MulL src1 src2)); 9234 ins_cost(DEFAULT_COST); 9235 9236 format %{ "MULLI $dst, $src1, $src2" %} 9237 size(4); 9238 ins_encode %{ 9239 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9240 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9241 %} 9242 ins_pipe(pipe_class_default); 9243 %} 9244 9245 // Integer Division with Immediate -1: Negate. 9246 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9247 match(Set dst (DivI src1 src2)); 9248 ins_cost(DEFAULT_COST); 9249 9250 format %{ "NEG $dst, $src1 \t// /-1" %} 9251 size(4); 9252 ins_encode %{ 9253 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9254 __ neg($dst$$Register, $src1$$Register); 9255 %} 9256 ins_pipe(pipe_class_default); 9257 %} 9258 9259 // Integer Division with constant, but not -1. 9260 // We should be able to improve this by checking the type of src2. 9261 // It might well be that src2 is known to be positive. 9262 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9263 match(Set dst (DivI src1 src2)); 9264 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9265 ins_cost(2*DEFAULT_COST); 9266 9267 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9268 size(4); 9269 ins_encode %{ 9270 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9271 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9272 %} 9273 ins_pipe(pipe_class_default); 9274 %} 9275 9276 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9277 effect(USE_DEF dst, USE src1, USE crx); 9278 predicate(false); 9279 9280 ins_variable_size_depending_on_alignment(true); 9281 9282 format %{ "CMOVE $dst, neg($src1), $crx" %} 9283 // Worst case is branch + move + stop, no stop without scheduler. 9284 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9285 ins_encode %{ 9286 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9287 Label done; 9288 __ bne($crx$$CondRegister, done); 9289 __ neg($dst$$Register, $src1$$Register); 9290 // TODO PPC port __ endgroup_if_needed(_size == 12); 9291 __ bind(done); 9292 %} 9293 ins_pipe(pipe_class_default); 9294 %} 9295 9296 // Integer Division with Registers not containing constants. 9297 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9298 match(Set dst (DivI src1 src2)); 9299 ins_cost(10*DEFAULT_COST); 9300 9301 expand %{ 9302 immI16 imm %{ (int)-1 %} 9303 flagsReg tmp1; 9304 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9305 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9306 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9307 %} 9308 %} 9309 9310 // Long Division with Immediate -1: Negate. 9311 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9312 match(Set dst (DivL src1 src2)); 9313 ins_cost(DEFAULT_COST); 9314 9315 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9316 size(4); 9317 ins_encode %{ 9318 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9319 __ neg($dst$$Register, $src1$$Register); 9320 %} 9321 ins_pipe(pipe_class_default); 9322 %} 9323 9324 // Long Division with constant, but not -1. 9325 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9326 match(Set dst (DivL src1 src2)); 9327 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9328 ins_cost(2*DEFAULT_COST); 9329 9330 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9331 size(4); 9332 ins_encode %{ 9333 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9334 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9335 %} 9336 ins_pipe(pipe_class_default); 9337 %} 9338 9339 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9340 effect(USE_DEF dst, USE src1, USE crx); 9341 predicate(false); 9342 9343 ins_variable_size_depending_on_alignment(true); 9344 9345 format %{ "CMOVE $dst, neg($src1), $crx" %} 9346 // Worst case is branch + move + stop, no stop without scheduler. 9347 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9348 ins_encode %{ 9349 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9350 Label done; 9351 __ bne($crx$$CondRegister, done); 9352 __ neg($dst$$Register, $src1$$Register); 9353 // TODO PPC port __ endgroup_if_needed(_size == 12); 9354 __ bind(done); 9355 %} 9356 ins_pipe(pipe_class_default); 9357 %} 9358 9359 // Long Division with Registers not containing constants. 9360 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9361 match(Set dst (DivL src1 src2)); 9362 ins_cost(10*DEFAULT_COST); 9363 9364 expand %{ 9365 immL16 imm %{ (int)-1 %} 9366 flagsReg tmp1; 9367 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9368 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9369 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9370 %} 9371 %} 9372 9373 // Integer Remainder with registers. 9374 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9375 match(Set dst (ModI src1 src2)); 9376 ins_cost(10*DEFAULT_COST); 9377 9378 expand %{ 9379 immI16 imm %{ (int)-1 %} 9380 flagsReg tmp1; 9381 iRegIdst tmp2; 9382 iRegIdst tmp3; 9383 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9384 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9385 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9386 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9387 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9388 %} 9389 %} 9390 9391 // Long Remainder with registers 9392 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9393 match(Set dst (ModL src1 src2)); 9394 ins_cost(10*DEFAULT_COST); 9395 9396 expand %{ 9397 immL16 imm %{ (int)-1 %} 9398 flagsReg tmp1; 9399 iRegLdst tmp2; 9400 iRegLdst tmp3; 9401 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9402 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9403 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9404 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9405 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9406 %} 9407 %} 9408 9409 // Integer Shift Instructions 9410 9411 // Register Shift Left 9412 9413 // Clear all but the lowest #mask bits. 9414 // Used to normalize shift amounts in registers. 9415 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9416 // no match-rule, false predicate 9417 effect(DEF dst, USE src, USE mask); 9418 predicate(false); 9419 9420 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9421 size(4); 9422 ins_encode %{ 9423 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9424 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9425 %} 9426 ins_pipe(pipe_class_default); 9427 %} 9428 9429 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9430 // no match-rule, false predicate 9431 effect(DEF dst, USE src1, USE src2); 9432 predicate(false); 9433 9434 format %{ "SLW $dst, $src1, $src2" %} 9435 size(4); 9436 ins_encode %{ 9437 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9438 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9439 %} 9440 ins_pipe(pipe_class_default); 9441 %} 9442 9443 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9444 match(Set dst (LShiftI src1 src2)); 9445 ins_cost(DEFAULT_COST*2); 9446 expand %{ 9447 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9448 iRegIdst tmpI; 9449 maskI_reg_imm(tmpI, src2, mask); 9450 lShiftI_reg_reg(dst, src1, tmpI); 9451 %} 9452 %} 9453 9454 // Register Shift Left Immediate 9455 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9456 match(Set dst (LShiftI src1 src2)); 9457 9458 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9459 size(4); 9460 ins_encode %{ 9461 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9462 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9463 %} 9464 ins_pipe(pipe_class_default); 9465 %} 9466 9467 // AndI with negpow2-constant + LShiftI 9468 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9469 match(Set dst (LShiftI (AndI src1 src2) src3)); 9470 predicate(UseRotateAndMaskInstructionsPPC64); 9471 9472 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9473 size(4); 9474 ins_encode %{ 9475 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9476 long src2 = $src2$$constant; 9477 long src3 = $src3$$constant; 9478 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9479 if (maskbits >= 32) { 9480 __ li($dst$$Register, 0); // addi 9481 } else { 9482 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9483 } 9484 %} 9485 ins_pipe(pipe_class_default); 9486 %} 9487 9488 // RShiftI + AndI with negpow2-constant + LShiftI 9489 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9490 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9491 predicate(UseRotateAndMaskInstructionsPPC64); 9492 9493 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9494 size(4); 9495 ins_encode %{ 9496 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9497 long src2 = $src2$$constant; 9498 long src3 = $src3$$constant; 9499 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9500 if (maskbits >= 32) { 9501 __ li($dst$$Register, 0); // addi 9502 } else { 9503 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9504 } 9505 %} 9506 ins_pipe(pipe_class_default); 9507 %} 9508 9509 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9510 // no match-rule, false predicate 9511 effect(DEF dst, USE src1, USE src2); 9512 predicate(false); 9513 9514 format %{ "SLD $dst, $src1, $src2" %} 9515 size(4); 9516 ins_encode %{ 9517 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9518 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9519 %} 9520 ins_pipe(pipe_class_default); 9521 %} 9522 9523 // Register Shift Left 9524 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9525 match(Set dst (LShiftL src1 src2)); 9526 ins_cost(DEFAULT_COST*2); 9527 expand %{ 9528 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9529 iRegIdst tmpI; 9530 maskI_reg_imm(tmpI, src2, mask); 9531 lShiftL_regL_regI(dst, src1, tmpI); 9532 %} 9533 %} 9534 9535 // Register Shift Left Immediate 9536 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9537 match(Set dst (LShiftL src1 src2)); 9538 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9539 size(4); 9540 ins_encode %{ 9541 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9542 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9543 %} 9544 ins_pipe(pipe_class_default); 9545 %} 9546 9547 // If we shift more than 32 bits, we need not convert I2L. 9548 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9549 match(Set dst (LShiftL (ConvI2L src1) src2)); 9550 ins_cost(DEFAULT_COST); 9551 9552 size(4); 9553 format %{ "SLDI $dst, i2l($src1), $src2" %} 9554 ins_encode %{ 9555 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9556 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9557 %} 9558 ins_pipe(pipe_class_default); 9559 %} 9560 9561 // Shift a postivie int to the left. 9562 // Clrlsldi clears the upper 32 bits and shifts. 9563 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9564 match(Set dst (LShiftL (ConvI2L src1) src2)); 9565 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9566 9567 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9568 size(4); 9569 ins_encode %{ 9570 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9571 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9572 %} 9573 ins_pipe(pipe_class_default); 9574 %} 9575 9576 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9577 // no match-rule, false predicate 9578 effect(DEF dst, USE src1, USE src2); 9579 predicate(false); 9580 9581 format %{ "SRAW $dst, $src1, $src2" %} 9582 size(4); 9583 ins_encode %{ 9584 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9585 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9586 %} 9587 ins_pipe(pipe_class_default); 9588 %} 9589 9590 // Register Arithmetic Shift Right 9591 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9592 match(Set dst (RShiftI src1 src2)); 9593 ins_cost(DEFAULT_COST*2); 9594 expand %{ 9595 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9596 iRegIdst tmpI; 9597 maskI_reg_imm(tmpI, src2, mask); 9598 arShiftI_reg_reg(dst, src1, tmpI); 9599 %} 9600 %} 9601 9602 // Register Arithmetic Shift Right Immediate 9603 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9604 match(Set dst (RShiftI src1 src2)); 9605 9606 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9607 size(4); 9608 ins_encode %{ 9609 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9610 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9611 %} 9612 ins_pipe(pipe_class_default); 9613 %} 9614 9615 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9616 // no match-rule, false predicate 9617 effect(DEF dst, USE src1, USE src2); 9618 predicate(false); 9619 9620 format %{ "SRAD $dst, $src1, $src2" %} 9621 size(4); 9622 ins_encode %{ 9623 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9624 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9625 %} 9626 ins_pipe(pipe_class_default); 9627 %} 9628 9629 // Register Shift Right Arithmetic Long 9630 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9631 match(Set dst (RShiftL src1 src2)); 9632 ins_cost(DEFAULT_COST*2); 9633 9634 expand %{ 9635 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9636 iRegIdst tmpI; 9637 maskI_reg_imm(tmpI, src2, mask); 9638 arShiftL_regL_regI(dst, src1, tmpI); 9639 %} 9640 %} 9641 9642 // Register Shift Right Immediate 9643 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9644 match(Set dst (RShiftL src1 src2)); 9645 9646 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9647 size(4); 9648 ins_encode %{ 9649 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9650 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9651 %} 9652 ins_pipe(pipe_class_default); 9653 %} 9654 9655 // RShiftL + ConvL2I 9656 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9657 match(Set dst (ConvL2I (RShiftL src1 src2))); 9658 9659 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9660 size(4); 9661 ins_encode %{ 9662 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9663 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9664 %} 9665 ins_pipe(pipe_class_default); 9666 %} 9667 9668 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9669 // no match-rule, false predicate 9670 effect(DEF dst, USE src1, USE src2); 9671 predicate(false); 9672 9673 format %{ "SRW $dst, $src1, $src2" %} 9674 size(4); 9675 ins_encode %{ 9676 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9677 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9678 %} 9679 ins_pipe(pipe_class_default); 9680 %} 9681 9682 // Register Shift Right 9683 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9684 match(Set dst (URShiftI src1 src2)); 9685 ins_cost(DEFAULT_COST*2); 9686 9687 expand %{ 9688 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9689 iRegIdst tmpI; 9690 maskI_reg_imm(tmpI, src2, mask); 9691 urShiftI_reg_reg(dst, src1, tmpI); 9692 %} 9693 %} 9694 9695 // Register Shift Right Immediate 9696 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9697 match(Set dst (URShiftI src1 src2)); 9698 9699 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9700 size(4); 9701 ins_encode %{ 9702 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9703 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9704 %} 9705 ins_pipe(pipe_class_default); 9706 %} 9707 9708 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9709 // no match-rule, false predicate 9710 effect(DEF dst, USE src1, USE src2); 9711 predicate(false); 9712 9713 format %{ "SRD $dst, $src1, $src2" %} 9714 size(4); 9715 ins_encode %{ 9716 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9717 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9718 %} 9719 ins_pipe(pipe_class_default); 9720 %} 9721 9722 // Register Shift Right 9723 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9724 match(Set dst (URShiftL src1 src2)); 9725 ins_cost(DEFAULT_COST*2); 9726 9727 expand %{ 9728 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9729 iRegIdst tmpI; 9730 maskI_reg_imm(tmpI, src2, mask); 9731 urShiftL_regL_regI(dst, src1, tmpI); 9732 %} 9733 %} 9734 9735 // Register Shift Right Immediate 9736 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9737 match(Set dst (URShiftL src1 src2)); 9738 9739 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9740 size(4); 9741 ins_encode %{ 9742 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9743 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9744 %} 9745 ins_pipe(pipe_class_default); 9746 %} 9747 9748 // URShiftL + ConvL2I. 9749 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9750 match(Set dst (ConvL2I (URShiftL src1 src2))); 9751 9752 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9753 size(4); 9754 ins_encode %{ 9755 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9756 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9757 %} 9758 ins_pipe(pipe_class_default); 9759 %} 9760 9761 // Register Shift Right Immediate with a CastP2X 9762 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9763 match(Set dst (URShiftL (CastP2X src1) src2)); 9764 9765 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9766 size(4); 9767 ins_encode %{ 9768 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9769 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9770 %} 9771 ins_pipe(pipe_class_default); 9772 %} 9773 9774 // Bitfield Extract: URShiftI + AndI 9775 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9776 match(Set dst (AndI (URShiftI src1 src2) src3)); 9777 9778 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9779 size(4); 9780 ins_encode %{ 9781 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9782 int rshift = ($src2$$constant) & 0x1f; 9783 int length = log2_long(((jlong) $src3$$constant) + 1); 9784 if (rshift + length > 32) { 9785 // if necessary, adjust mask to omit rotated bits. 9786 length = 32 - rshift; 9787 } 9788 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9789 %} 9790 ins_pipe(pipe_class_default); 9791 %} 9792 9793 // Bitfield Extract: URShiftL + AndL 9794 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9795 match(Set dst (AndL (URShiftL src1 src2) src3)); 9796 9797 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9798 size(4); 9799 ins_encode %{ 9800 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9801 int rshift = ($src2$$constant) & 0x3f; 9802 int length = log2_long(((jlong) $src3$$constant) + 1); 9803 if (rshift + length > 64) { 9804 // if necessary, adjust mask to omit rotated bits. 9805 length = 64 - rshift; 9806 } 9807 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9808 %} 9809 ins_pipe(pipe_class_default); 9810 %} 9811 9812 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9813 match(Set dst (ConvL2I (ConvI2L src))); 9814 9815 format %{ "EXTSW $dst, $src \t// int->int" %} 9816 size(4); 9817 ins_encode %{ 9818 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9819 __ extsw($dst$$Register, $src$$Register); 9820 %} 9821 ins_pipe(pipe_class_default); 9822 %} 9823 9824 //----------Rotate Instructions------------------------------------------------ 9825 9826 // Rotate Left by 8-bit immediate 9827 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9828 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9829 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9830 9831 format %{ "ROTLWI $dst, $src, $lshift" %} 9832 size(4); 9833 ins_encode %{ 9834 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9835 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9836 %} 9837 ins_pipe(pipe_class_default); 9838 %} 9839 9840 // Rotate Right by 8-bit immediate 9841 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9842 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9843 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9844 9845 format %{ "ROTRWI $dst, $rshift" %} 9846 size(4); 9847 ins_encode %{ 9848 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9849 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9850 %} 9851 ins_pipe(pipe_class_default); 9852 %} 9853 9854 //----------Floating Point Arithmetic Instructions----------------------------- 9855 9856 // Add float single precision 9857 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9858 match(Set dst (AddF src1 src2)); 9859 9860 format %{ "FADDS $dst, $src1, $src2" %} 9861 size(4); 9862 ins_encode %{ 9863 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9864 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9865 %} 9866 ins_pipe(pipe_class_default); 9867 %} 9868 9869 // Add float double precision 9870 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9871 match(Set dst (AddD src1 src2)); 9872 9873 format %{ "FADD $dst, $src1, $src2" %} 9874 size(4); 9875 ins_encode %{ 9876 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9877 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9878 %} 9879 ins_pipe(pipe_class_default); 9880 %} 9881 9882 // Sub float single precision 9883 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9884 match(Set dst (SubF src1 src2)); 9885 9886 format %{ "FSUBS $dst, $src1, $src2" %} 9887 size(4); 9888 ins_encode %{ 9889 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9890 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9891 %} 9892 ins_pipe(pipe_class_default); 9893 %} 9894 9895 // Sub float double precision 9896 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9897 match(Set dst (SubD src1 src2)); 9898 format %{ "FSUB $dst, $src1, $src2" %} 9899 size(4); 9900 ins_encode %{ 9901 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9902 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9903 %} 9904 ins_pipe(pipe_class_default); 9905 %} 9906 9907 // Mul float single precision 9908 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9909 match(Set dst (MulF src1 src2)); 9910 format %{ "FMULS $dst, $src1, $src2" %} 9911 size(4); 9912 ins_encode %{ 9913 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9914 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9915 %} 9916 ins_pipe(pipe_class_default); 9917 %} 9918 9919 // Mul float double precision 9920 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9921 match(Set dst (MulD src1 src2)); 9922 format %{ "FMUL $dst, $src1, $src2" %} 9923 size(4); 9924 ins_encode %{ 9925 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9926 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9927 %} 9928 ins_pipe(pipe_class_default); 9929 %} 9930 9931 // Div float single precision 9932 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9933 match(Set dst (DivF src1 src2)); 9934 format %{ "FDIVS $dst, $src1, $src2" %} 9935 size(4); 9936 ins_encode %{ 9937 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9938 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9939 %} 9940 ins_pipe(pipe_class_default); 9941 %} 9942 9943 // Div float double precision 9944 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9945 match(Set dst (DivD src1 src2)); 9946 format %{ "FDIV $dst, $src1, $src2" %} 9947 size(4); 9948 ins_encode %{ 9949 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9950 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9951 %} 9952 ins_pipe(pipe_class_default); 9953 %} 9954 9955 // Absolute float single precision 9956 instruct absF_reg(regF dst, regF src) %{ 9957 match(Set dst (AbsF src)); 9958 format %{ "FABS $dst, $src \t// float" %} 9959 size(4); 9960 ins_encode %{ 9961 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9962 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9963 %} 9964 ins_pipe(pipe_class_default); 9965 %} 9966 9967 // Absolute float double precision 9968 instruct absD_reg(regD dst, regD src) %{ 9969 match(Set dst (AbsD src)); 9970 format %{ "FABS $dst, $src \t// double" %} 9971 size(4); 9972 ins_encode %{ 9973 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9974 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9975 %} 9976 ins_pipe(pipe_class_default); 9977 %} 9978 9979 instruct negF_reg(regF dst, regF src) %{ 9980 match(Set dst (NegF src)); 9981 format %{ "FNEG $dst, $src \t// float" %} 9982 size(4); 9983 ins_encode %{ 9984 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9985 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9986 %} 9987 ins_pipe(pipe_class_default); 9988 %} 9989 9990 instruct negD_reg(regD dst, regD src) %{ 9991 match(Set dst (NegD src)); 9992 format %{ "FNEG $dst, $src \t// double" %} 9993 size(4); 9994 ins_encode %{ 9995 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9996 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9997 %} 9998 ins_pipe(pipe_class_default); 9999 %} 10000 10001 // AbsF + NegF. 10002 instruct negF_absF_reg(regF dst, regF src) %{ 10003 match(Set dst (NegF (AbsF src))); 10004 format %{ "FNABS $dst, $src \t// float" %} 10005 size(4); 10006 ins_encode %{ 10007 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10008 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10009 %} 10010 ins_pipe(pipe_class_default); 10011 %} 10012 10013 // AbsD + NegD. 10014 instruct negD_absD_reg(regD dst, regD src) %{ 10015 match(Set dst (NegD (AbsD src))); 10016 format %{ "FNABS $dst, $src \t// double" %} 10017 size(4); 10018 ins_encode %{ 10019 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10020 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10021 %} 10022 ins_pipe(pipe_class_default); 10023 %} 10024 10025 // VM_Version::has_fsqrt() decides if this node will be used. 10026 // Sqrt float double precision 10027 instruct sqrtD_reg(regD dst, regD src) %{ 10028 match(Set dst (SqrtD src)); 10029 format %{ "FSQRT $dst, $src" %} 10030 size(4); 10031 ins_encode %{ 10032 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 10033 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 10034 %} 10035 ins_pipe(pipe_class_default); 10036 %} 10037 10038 // Single-precision sqrt. 10039 instruct sqrtF_reg(regF dst, regF src) %{ 10040 match(Set dst (SqrtF src)); 10041 predicate(VM_Version::has_fsqrts()); 10042 ins_cost(DEFAULT_COST); 10043 10044 format %{ "FSQRTS $dst, $src" %} 10045 size(4); 10046 ins_encode %{ 10047 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 10048 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 10049 %} 10050 ins_pipe(pipe_class_default); 10051 %} 10052 10053 instruct roundDouble_nop(regD dst) %{ 10054 match(Set dst (RoundDouble dst)); 10055 ins_cost(0); 10056 10057 format %{ " -- \t// RoundDouble not needed - empty" %} 10058 size(0); 10059 // PPC results are already "rounded" (i.e., normal-format IEEE). 10060 ins_encode( /*empty*/ ); 10061 ins_pipe(pipe_class_default); 10062 %} 10063 10064 instruct roundFloat_nop(regF dst) %{ 10065 match(Set dst (RoundFloat dst)); 10066 ins_cost(0); 10067 10068 format %{ " -- \t// RoundFloat not needed - empty" %} 10069 size(0); 10070 // PPC results are already "rounded" (i.e., normal-format IEEE). 10071 ins_encode( /*empty*/ ); 10072 ins_pipe(pipe_class_default); 10073 %} 10074 10075 10076 // Multiply-Accumulate 10077 // src1 * src2 + src3 10078 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10079 match(Set dst (FmaF src3 (Binary src1 src2))); 10080 10081 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10082 size(4); 10083 ins_encode %{ 10084 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10085 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10086 %} 10087 ins_pipe(pipe_class_default); 10088 %} 10089 10090 // src1 * src2 + src3 10091 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10092 match(Set dst (FmaD src3 (Binary src1 src2))); 10093 10094 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10095 size(4); 10096 ins_encode %{ 10097 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10098 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10099 %} 10100 ins_pipe(pipe_class_default); 10101 %} 10102 10103 // -src1 * src2 + src3 = -(src1*src2-src3) 10104 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10105 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10106 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10107 10108 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10109 size(4); 10110 ins_encode %{ 10111 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10112 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10113 %} 10114 ins_pipe(pipe_class_default); 10115 %} 10116 10117 // -src1 * src2 + src3 = -(src1*src2-src3) 10118 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10119 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10120 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10121 10122 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10123 size(4); 10124 ins_encode %{ 10125 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10126 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10127 %} 10128 ins_pipe(pipe_class_default); 10129 %} 10130 10131 // -src1 * src2 - src3 = -(src1*src2+src3) 10132 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10133 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10134 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10135 10136 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10137 size(4); 10138 ins_encode %{ 10139 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10140 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10141 %} 10142 ins_pipe(pipe_class_default); 10143 %} 10144 10145 // -src1 * src2 - src3 = -(src1*src2+src3) 10146 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10147 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10148 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10149 10150 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10151 size(4); 10152 ins_encode %{ 10153 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10154 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10155 %} 10156 ins_pipe(pipe_class_default); 10157 %} 10158 10159 // src1 * src2 - src3 10160 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10161 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10162 10163 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10164 size(4); 10165 ins_encode %{ 10166 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10167 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10168 %} 10169 ins_pipe(pipe_class_default); 10170 %} 10171 10172 // src1 * src2 - src3 10173 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10174 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10175 10176 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10177 size(4); 10178 ins_encode %{ 10179 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10180 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10181 %} 10182 ins_pipe(pipe_class_default); 10183 %} 10184 10185 10186 //----------Logical Instructions----------------------------------------------- 10187 10188 // And Instructions 10189 10190 // Register And 10191 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10192 match(Set dst (AndI src1 src2)); 10193 format %{ "AND $dst, $src1, $src2" %} 10194 size(4); 10195 ins_encode %{ 10196 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10197 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10198 %} 10199 ins_pipe(pipe_class_default); 10200 %} 10201 10202 // Left shifted Immediate And 10203 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10204 match(Set dst (AndI src1 src2)); 10205 effect(KILL cr0); 10206 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10207 size(4); 10208 ins_encode %{ 10209 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10210 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10211 %} 10212 ins_pipe(pipe_class_default); 10213 %} 10214 10215 // Immediate And 10216 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10217 match(Set dst (AndI src1 src2)); 10218 effect(KILL cr0); 10219 10220 format %{ "ANDI $dst, $src1, $src2" %} 10221 size(4); 10222 ins_encode %{ 10223 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10224 // FIXME: avoid andi_ ? 10225 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10226 %} 10227 ins_pipe(pipe_class_default); 10228 %} 10229 10230 // Immediate And where the immediate is a negative power of 2. 10231 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10232 match(Set dst (AndI src1 src2)); 10233 format %{ "ANDWI $dst, $src1, $src2" %} 10234 size(4); 10235 ins_encode %{ 10236 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10237 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10238 %} 10239 ins_pipe(pipe_class_default); 10240 %} 10241 10242 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10243 match(Set dst (AndI src1 src2)); 10244 format %{ "ANDWI $dst, $src1, $src2" %} 10245 size(4); 10246 ins_encode %{ 10247 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10248 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10249 %} 10250 ins_pipe(pipe_class_default); 10251 %} 10252 10253 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10254 match(Set dst (AndI src1 src2)); 10255 predicate(UseRotateAndMaskInstructionsPPC64); 10256 format %{ "ANDWI $dst, $src1, $src2" %} 10257 size(4); 10258 ins_encode %{ 10259 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10260 __ rlwinm($dst$$Register, $src1$$Register, 0, 10261 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10262 %} 10263 ins_pipe(pipe_class_default); 10264 %} 10265 10266 // Register And Long 10267 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10268 match(Set dst (AndL src1 src2)); 10269 ins_cost(DEFAULT_COST); 10270 10271 format %{ "AND $dst, $src1, $src2 \t// long" %} 10272 size(4); 10273 ins_encode %{ 10274 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10275 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10276 %} 10277 ins_pipe(pipe_class_default); 10278 %} 10279 10280 // Immediate And long 10281 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10282 match(Set dst (AndL src1 src2)); 10283 effect(KILL cr0); 10284 10285 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10286 size(4); 10287 ins_encode %{ 10288 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10289 // FIXME: avoid andi_ ? 10290 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10291 %} 10292 ins_pipe(pipe_class_default); 10293 %} 10294 10295 // Immediate And Long where the immediate is a negative power of 2. 10296 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10297 match(Set dst (AndL src1 src2)); 10298 format %{ "ANDDI $dst, $src1, $src2" %} 10299 size(4); 10300 ins_encode %{ 10301 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10302 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10303 %} 10304 ins_pipe(pipe_class_default); 10305 %} 10306 10307 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10308 match(Set dst (AndL src1 src2)); 10309 format %{ "ANDDI $dst, $src1, $src2" %} 10310 size(4); 10311 ins_encode %{ 10312 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10313 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10314 %} 10315 ins_pipe(pipe_class_default); 10316 %} 10317 10318 // AndL + ConvL2I. 10319 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10320 match(Set dst (ConvL2I (AndL src1 src2))); 10321 ins_cost(DEFAULT_COST); 10322 10323 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10324 size(4); 10325 ins_encode %{ 10326 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10327 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10328 %} 10329 ins_pipe(pipe_class_default); 10330 %} 10331 10332 // Or Instructions 10333 10334 // Register Or 10335 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10336 match(Set dst (OrI src1 src2)); 10337 format %{ "OR $dst, $src1, $src2" %} 10338 size(4); 10339 ins_encode %{ 10340 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10341 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10342 %} 10343 ins_pipe(pipe_class_default); 10344 %} 10345 10346 // Expand does not work with above instruct. (??) 10347 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10348 // no match-rule 10349 effect(DEF dst, USE src1, USE src2); 10350 format %{ "OR $dst, $src1, $src2" %} 10351 size(4); 10352 ins_encode %{ 10353 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10354 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10355 %} 10356 ins_pipe(pipe_class_default); 10357 %} 10358 10359 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10360 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10361 ins_cost(DEFAULT_COST*3); 10362 10363 expand %{ 10364 // FIXME: we should do this in the ideal world. 10365 iRegIdst tmp1; 10366 iRegIdst tmp2; 10367 orI_reg_reg(tmp1, src1, src2); 10368 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10369 orI_reg_reg(dst, tmp1, tmp2); 10370 %} 10371 %} 10372 10373 // Immediate Or 10374 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10375 match(Set dst (OrI src1 src2)); 10376 format %{ "ORI $dst, $src1, $src2" %} 10377 size(4); 10378 ins_encode %{ 10379 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10380 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10381 %} 10382 ins_pipe(pipe_class_default); 10383 %} 10384 10385 // Register Or Long 10386 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10387 match(Set dst (OrL src1 src2)); 10388 ins_cost(DEFAULT_COST); 10389 10390 size(4); 10391 format %{ "OR $dst, $src1, $src2 \t// long" %} 10392 ins_encode %{ 10393 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10394 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10395 %} 10396 ins_pipe(pipe_class_default); 10397 %} 10398 10399 // OrL + ConvL2I. 10400 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10401 match(Set dst (ConvL2I (OrL src1 src2))); 10402 ins_cost(DEFAULT_COST); 10403 10404 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10405 size(4); 10406 ins_encode %{ 10407 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10408 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10409 %} 10410 ins_pipe(pipe_class_default); 10411 %} 10412 10413 // Immediate Or long 10414 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10415 match(Set dst (OrL src1 con)); 10416 ins_cost(DEFAULT_COST); 10417 10418 format %{ "ORI $dst, $src1, $con \t// long" %} 10419 size(4); 10420 ins_encode %{ 10421 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10422 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10423 %} 10424 ins_pipe(pipe_class_default); 10425 %} 10426 10427 // Xor Instructions 10428 10429 // Register Xor 10430 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10431 match(Set dst (XorI src1 src2)); 10432 format %{ "XOR $dst, $src1, $src2" %} 10433 size(4); 10434 ins_encode %{ 10435 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10436 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10437 %} 10438 ins_pipe(pipe_class_default); 10439 %} 10440 10441 // Expand does not work with above instruct. (??) 10442 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10443 // no match-rule 10444 effect(DEF dst, USE src1, USE src2); 10445 format %{ "XOR $dst, $src1, $src2" %} 10446 size(4); 10447 ins_encode %{ 10448 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10449 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10450 %} 10451 ins_pipe(pipe_class_default); 10452 %} 10453 10454 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10455 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10456 ins_cost(DEFAULT_COST*3); 10457 10458 expand %{ 10459 // FIXME: we should do this in the ideal world. 10460 iRegIdst tmp1; 10461 iRegIdst tmp2; 10462 xorI_reg_reg(tmp1, src1, src2); 10463 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10464 xorI_reg_reg(dst, tmp1, tmp2); 10465 %} 10466 %} 10467 10468 // Immediate Xor 10469 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10470 match(Set dst (XorI src1 src2)); 10471 format %{ "XORI $dst, $src1, $src2" %} 10472 size(4); 10473 ins_encode %{ 10474 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10475 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10476 %} 10477 ins_pipe(pipe_class_default); 10478 %} 10479 10480 // Register Xor Long 10481 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10482 match(Set dst (XorL src1 src2)); 10483 ins_cost(DEFAULT_COST); 10484 10485 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10486 size(4); 10487 ins_encode %{ 10488 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10489 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10490 %} 10491 ins_pipe(pipe_class_default); 10492 %} 10493 10494 // XorL + ConvL2I. 10495 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10496 match(Set dst (ConvL2I (XorL src1 src2))); 10497 ins_cost(DEFAULT_COST); 10498 10499 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10500 size(4); 10501 ins_encode %{ 10502 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10503 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10504 %} 10505 ins_pipe(pipe_class_default); 10506 %} 10507 10508 // Immediate Xor Long 10509 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10510 match(Set dst (XorL src1 src2)); 10511 ins_cost(DEFAULT_COST); 10512 10513 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10514 size(4); 10515 ins_encode %{ 10516 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10517 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10518 %} 10519 ins_pipe(pipe_class_default); 10520 %} 10521 10522 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10523 match(Set dst (XorI src1 src2)); 10524 ins_cost(DEFAULT_COST); 10525 10526 format %{ "NOT $dst, $src1 ($src2)" %} 10527 size(4); 10528 ins_encode %{ 10529 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10530 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10531 %} 10532 ins_pipe(pipe_class_default); 10533 %} 10534 10535 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10536 match(Set dst (XorL src1 src2)); 10537 ins_cost(DEFAULT_COST); 10538 10539 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10540 size(4); 10541 ins_encode %{ 10542 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10543 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10544 %} 10545 ins_pipe(pipe_class_default); 10546 %} 10547 10548 // And-complement 10549 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10550 match(Set dst (AndI (XorI src1 src2) src3)); 10551 ins_cost(DEFAULT_COST); 10552 10553 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10554 size(4); 10555 ins_encode( enc_andc(dst, src3, src1) ); 10556 ins_pipe(pipe_class_default); 10557 %} 10558 10559 // And-complement 10560 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10561 // no match-rule, false predicate 10562 effect(DEF dst, USE src1, USE src2); 10563 predicate(false); 10564 10565 format %{ "ANDC $dst, $src1, $src2" %} 10566 size(4); 10567 ins_encode %{ 10568 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10569 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10570 %} 10571 ins_pipe(pipe_class_default); 10572 %} 10573 10574 //----------Moves between int/long and float/double---------------------------- 10575 // 10576 // The following rules move values from int/long registers/stack-locations 10577 // to float/double registers/stack-locations and vice versa, without doing any 10578 // conversions. These rules are used to implement the bit-conversion methods 10579 // of java.lang.Float etc., e.g. 10580 // int floatToIntBits(float value) 10581 // float intBitsToFloat(int bits) 10582 // 10583 // Notes on the implementation on ppc64: 10584 // For Power7 and earlier, the rules are limited to those which move between a 10585 // register and a stack-location, because we always have to go through memory 10586 // when moving between a float register and an integer register. 10587 // This restriction is removed in Power8 with the introduction of the mtfprd 10588 // and mffprd instructions. 10589 10590 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10591 match(Set dst (MoveL2D src)); 10592 predicate(VM_Version::has_mtfprd()); 10593 10594 format %{ "MTFPRD $dst, $src" %} 10595 size(4); 10596 ins_encode %{ 10597 __ mtfprd($dst$$FloatRegister, $src$$Register); 10598 %} 10599 ins_pipe(pipe_class_default); 10600 %} 10601 10602 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10603 // no match-rule, false predicate 10604 effect(DEF dst, USE src); 10605 predicate(false); 10606 10607 format %{ "MTFPRWA $dst, $src" %} 10608 size(4); 10609 ins_encode %{ 10610 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10611 %} 10612 ins_pipe(pipe_class_default); 10613 %} 10614 10615 //---------- Chain stack slots between similar types -------- 10616 10617 // These are needed so that the rules below can match. 10618 10619 // Load integer from stack slot 10620 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10621 match(Set dst src); 10622 ins_cost(MEMORY_REF_COST); 10623 10624 format %{ "LWZ $dst, $src" %} 10625 size(4); 10626 ins_encode( enc_lwz(dst, src) ); 10627 ins_pipe(pipe_class_memory); 10628 %} 10629 10630 // Store integer to stack slot 10631 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10632 match(Set dst src); 10633 ins_cost(MEMORY_REF_COST); 10634 10635 format %{ "STW $src, $dst \t// stk" %} 10636 size(4); 10637 ins_encode( enc_stw(src, dst) ); // rs=rt 10638 ins_pipe(pipe_class_memory); 10639 %} 10640 10641 // Load long from stack slot 10642 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10643 match(Set dst src); 10644 ins_cost(MEMORY_REF_COST); 10645 10646 format %{ "LD $dst, $src \t// long" %} 10647 size(4); 10648 ins_encode( enc_ld(dst, src) ); 10649 ins_pipe(pipe_class_memory); 10650 %} 10651 10652 // Store long to stack slot 10653 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10654 match(Set dst src); 10655 ins_cost(MEMORY_REF_COST); 10656 10657 format %{ "STD $src, $dst \t// long" %} 10658 size(4); 10659 ins_encode( enc_std(src, dst) ); // rs=rt 10660 ins_pipe(pipe_class_memory); 10661 %} 10662 10663 //----------Moves between int and float 10664 10665 // Move float value from float stack-location to integer register. 10666 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10667 match(Set dst (MoveF2I src)); 10668 ins_cost(MEMORY_REF_COST); 10669 10670 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10671 size(4); 10672 ins_encode( enc_lwz(dst, src) ); 10673 ins_pipe(pipe_class_memory); 10674 %} 10675 10676 // Move float value from float register to integer stack-location. 10677 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10678 match(Set dst (MoveF2I src)); 10679 ins_cost(MEMORY_REF_COST); 10680 10681 format %{ "STFS $src, $dst \t// MoveF2I" %} 10682 size(4); 10683 ins_encode( enc_stfs(src, dst) ); 10684 ins_pipe(pipe_class_memory); 10685 %} 10686 10687 // Move integer value from integer stack-location to float register. 10688 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10689 match(Set dst (MoveI2F src)); 10690 ins_cost(MEMORY_REF_COST); 10691 10692 format %{ "LFS $dst, $src \t// MoveI2F" %} 10693 size(4); 10694 ins_encode %{ 10695 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10696 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10697 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10698 %} 10699 ins_pipe(pipe_class_memory); 10700 %} 10701 10702 // Move integer value from integer register to float stack-location. 10703 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10704 match(Set dst (MoveI2F src)); 10705 ins_cost(MEMORY_REF_COST); 10706 10707 format %{ "STW $src, $dst \t// MoveI2F" %} 10708 size(4); 10709 ins_encode( enc_stw(src, dst) ); 10710 ins_pipe(pipe_class_memory); 10711 %} 10712 10713 //----------Moves between long and float 10714 10715 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10716 // no match-rule, false predicate 10717 effect(DEF dst, USE src); 10718 predicate(false); 10719 10720 format %{ "storeD $src, $dst \t// STACK" %} 10721 size(4); 10722 ins_encode( enc_stfd(src, dst) ); 10723 ins_pipe(pipe_class_default); 10724 %} 10725 10726 //----------Moves between long and double 10727 10728 // Move double value from double stack-location to long register. 10729 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10730 match(Set dst (MoveD2L src)); 10731 ins_cost(MEMORY_REF_COST); 10732 size(4); 10733 format %{ "LD $dst, $src \t// MoveD2L" %} 10734 ins_encode( enc_ld(dst, src) ); 10735 ins_pipe(pipe_class_memory); 10736 %} 10737 10738 // Move double value from double register to long stack-location. 10739 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10740 match(Set dst (MoveD2L src)); 10741 effect(DEF dst, USE src); 10742 ins_cost(MEMORY_REF_COST); 10743 10744 format %{ "STFD $src, $dst \t// MoveD2L" %} 10745 size(4); 10746 ins_encode( enc_stfd(src, dst) ); 10747 ins_pipe(pipe_class_memory); 10748 %} 10749 10750 // Move long value from long stack-location to double register. 10751 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10752 match(Set dst (MoveL2D src)); 10753 ins_cost(MEMORY_REF_COST); 10754 10755 format %{ "LFD $dst, $src \t// MoveL2D" %} 10756 size(4); 10757 ins_encode( enc_lfd(dst, src) ); 10758 ins_pipe(pipe_class_memory); 10759 %} 10760 10761 // Move long value from long register to double stack-location. 10762 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10763 match(Set dst (MoveL2D src)); 10764 ins_cost(MEMORY_REF_COST); 10765 10766 format %{ "STD $src, $dst \t// MoveL2D" %} 10767 size(4); 10768 ins_encode( enc_std(src, dst) ); 10769 ins_pipe(pipe_class_memory); 10770 %} 10771 10772 //----------Register Move Instructions----------------------------------------- 10773 10774 // Replicate for Superword 10775 10776 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10777 predicate(false); 10778 effect(DEF dst, USE src); 10779 10780 format %{ "MR $dst, $src \t// replicate " %} 10781 // variable size, 0 or 4. 10782 ins_encode %{ 10783 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10784 __ mr_if_needed($dst$$Register, $src$$Register); 10785 %} 10786 ins_pipe(pipe_class_default); 10787 %} 10788 10789 //----------Cast instructions (Java-level type cast)--------------------------- 10790 10791 // Cast Long to Pointer for unsafe natives. 10792 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10793 match(Set dst (CastX2P src)); 10794 10795 format %{ "MR $dst, $src \t// Long->Ptr" %} 10796 // variable size, 0 or 4. 10797 ins_encode %{ 10798 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10799 __ mr_if_needed($dst$$Register, $src$$Register); 10800 %} 10801 ins_pipe(pipe_class_default); 10802 %} 10803 10804 // Cast Pointer to Long for unsafe natives. 10805 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10806 match(Set dst (CastP2X src)); 10807 10808 format %{ "MR $dst, $src \t// Ptr->Long" %} 10809 // variable size, 0 or 4. 10810 ins_encode %{ 10811 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10812 __ mr_if_needed($dst$$Register, $src$$Register); 10813 %} 10814 ins_pipe(pipe_class_default); 10815 %} 10816 10817 instruct castPP(iRegPdst dst) %{ 10818 match(Set dst (CastPP dst)); 10819 format %{ " -- \t// castPP of $dst" %} 10820 size(0); 10821 ins_encode( /*empty*/ ); 10822 ins_pipe(pipe_class_default); 10823 %} 10824 10825 instruct castII(iRegIdst dst) %{ 10826 match(Set dst (CastII dst)); 10827 format %{ " -- \t// castII of $dst" %} 10828 size(0); 10829 ins_encode( /*empty*/ ); 10830 ins_pipe(pipe_class_default); 10831 %} 10832 10833 instruct checkCastPP(iRegPdst dst) %{ 10834 match(Set dst (CheckCastPP dst)); 10835 format %{ " -- \t// checkcastPP of $dst" %} 10836 size(0); 10837 ins_encode( /*empty*/ ); 10838 ins_pipe(pipe_class_default); 10839 %} 10840 10841 //----------Convert instructions----------------------------------------------- 10842 10843 // Convert to boolean. 10844 10845 // int_to_bool(src) : { 1 if src != 0 10846 // { 0 else 10847 // 10848 // strategy: 10849 // 1) Count leading zeros of 32 bit-value src, 10850 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10851 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10852 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10853 10854 // convI2Bool 10855 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10856 match(Set dst (Conv2B src)); 10857 predicate(UseCountLeadingZerosInstructionsPPC64); 10858 ins_cost(DEFAULT_COST); 10859 10860 expand %{ 10861 immI shiftAmount %{ 0x5 %} 10862 uimmI16 mask %{ 0x1 %} 10863 iRegIdst tmp1; 10864 iRegIdst tmp2; 10865 countLeadingZerosI(tmp1, src); 10866 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10867 xorI_reg_uimm16(dst, tmp2, mask); 10868 %} 10869 %} 10870 10871 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10872 match(Set dst (Conv2B src)); 10873 effect(TEMP crx); 10874 predicate(!UseCountLeadingZerosInstructionsPPC64); 10875 ins_cost(DEFAULT_COST); 10876 10877 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10878 "LI $dst, #0\n\t" 10879 "BEQ $crx, done\n\t" 10880 "LI $dst, #1\n" 10881 "done:" %} 10882 size(16); 10883 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10884 ins_pipe(pipe_class_compare); 10885 %} 10886 10887 // ConvI2B + XorI 10888 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10889 match(Set dst (XorI (Conv2B src) mask)); 10890 predicate(UseCountLeadingZerosInstructionsPPC64); 10891 ins_cost(DEFAULT_COST); 10892 10893 expand %{ 10894 immI shiftAmount %{ 0x5 %} 10895 iRegIdst tmp1; 10896 countLeadingZerosI(tmp1, src); 10897 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10898 %} 10899 %} 10900 10901 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10902 match(Set dst (XorI (Conv2B src) mask)); 10903 effect(TEMP crx); 10904 predicate(!UseCountLeadingZerosInstructionsPPC64); 10905 ins_cost(DEFAULT_COST); 10906 10907 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10908 "LI $dst, #1\n\t" 10909 "BEQ $crx, done\n\t" 10910 "LI $dst, #0\n" 10911 "done:" %} 10912 size(16); 10913 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10914 ins_pipe(pipe_class_compare); 10915 %} 10916 10917 // AndI 0b0..010..0 + ConvI2B 10918 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10919 match(Set dst (Conv2B (AndI src mask))); 10920 predicate(UseRotateAndMaskInstructionsPPC64); 10921 ins_cost(DEFAULT_COST); 10922 10923 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10924 size(4); 10925 ins_encode %{ 10926 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10927 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10928 %} 10929 ins_pipe(pipe_class_default); 10930 %} 10931 10932 // Convert pointer to boolean. 10933 // 10934 // ptr_to_bool(src) : { 1 if src != 0 10935 // { 0 else 10936 // 10937 // strategy: 10938 // 1) Count leading zeros of 64 bit-value src, 10939 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10940 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10941 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10942 10943 // ConvP2B 10944 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10945 match(Set dst (Conv2B src)); 10946 predicate(UseCountLeadingZerosInstructionsPPC64); 10947 ins_cost(DEFAULT_COST); 10948 10949 expand %{ 10950 immI shiftAmount %{ 0x6 %} 10951 uimmI16 mask %{ 0x1 %} 10952 iRegIdst tmp1; 10953 iRegIdst tmp2; 10954 countLeadingZerosP(tmp1, src); 10955 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10956 xorI_reg_uimm16(dst, tmp2, mask); 10957 %} 10958 %} 10959 10960 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10961 match(Set dst (Conv2B src)); 10962 effect(TEMP crx); 10963 predicate(!UseCountLeadingZerosInstructionsPPC64); 10964 ins_cost(DEFAULT_COST); 10965 10966 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10967 "LI $dst, #0\n\t" 10968 "BEQ $crx, done\n\t" 10969 "LI $dst, #1\n" 10970 "done:" %} 10971 size(16); 10972 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10973 ins_pipe(pipe_class_compare); 10974 %} 10975 10976 // ConvP2B + XorI 10977 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10978 match(Set dst (XorI (Conv2B src) mask)); 10979 predicate(UseCountLeadingZerosInstructionsPPC64); 10980 ins_cost(DEFAULT_COST); 10981 10982 expand %{ 10983 immI shiftAmount %{ 0x6 %} 10984 iRegIdst tmp1; 10985 countLeadingZerosP(tmp1, src); 10986 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10987 %} 10988 %} 10989 10990 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10991 match(Set dst (XorI (Conv2B src) mask)); 10992 effect(TEMP crx); 10993 predicate(!UseCountLeadingZerosInstructionsPPC64); 10994 ins_cost(DEFAULT_COST); 10995 10996 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10997 "LI $dst, #1\n\t" 10998 "BEQ $crx, done\n\t" 10999 "LI $dst, #0\n" 11000 "done:" %} 11001 size(16); 11002 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 11003 ins_pipe(pipe_class_compare); 11004 %} 11005 11006 // if src1 < src2, return -1 else return 0 11007 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 11008 match(Set dst (CmpLTMask src1 src2)); 11009 ins_cost(DEFAULT_COST*4); 11010 11011 expand %{ 11012 iRegLdst src1s; 11013 iRegLdst src2s; 11014 iRegLdst diff; 11015 convI2L_reg(src1s, src1); // Ensure proper sign extension. 11016 convI2L_reg(src2s, src2); // Ensure proper sign extension. 11017 subL_reg_reg(diff, src1s, src2s); 11018 // Need to consider >=33 bit result, therefore we need signmaskL. 11019 signmask64I_regL(dst, diff); 11020 %} 11021 %} 11022 11023 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 11024 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 11025 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 11026 size(4); 11027 ins_encode %{ 11028 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 11029 __ srawi($dst$$Register, $src1$$Register, 0x1f); 11030 %} 11031 ins_pipe(pipe_class_default); 11032 %} 11033 11034 //----------Arithmetic Conversion Instructions--------------------------------- 11035 11036 // Convert to Byte -- nop 11037 // Convert to Short -- nop 11038 11039 // Convert to Int 11040 11041 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 11042 match(Set dst (RShiftI (LShiftI src amount) amount)); 11043 format %{ "EXTSB $dst, $src \t// byte->int" %} 11044 size(4); 11045 ins_encode %{ 11046 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 11047 __ extsb($dst$$Register, $src$$Register); 11048 %} 11049 ins_pipe(pipe_class_default); 11050 %} 11051 11052 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 11053 effect(DEF dst, USE src); 11054 11055 size(4); 11056 ins_encode %{ 11057 __ extsh($dst$$Register, $src$$Register); 11058 %} 11059 ins_pipe(pipe_class_default); 11060 %} 11061 11062 // LShiftI 16 + RShiftI 16 converts short to int. 11063 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 11064 match(Set dst (RShiftI (LShiftI src amount) amount)); 11065 format %{ "EXTSH $dst, $src \t// short->int" %} 11066 size(4); 11067 ins_encode %{ 11068 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 11069 __ extsh($dst$$Register, $src$$Register); 11070 %} 11071 ins_pipe(pipe_class_default); 11072 %} 11073 11074 // ConvL2I + ConvI2L: Sign extend int in long register. 11075 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11076 match(Set dst (ConvI2L (ConvL2I src))); 11077 11078 format %{ "EXTSW $dst, $src \t// long->long" %} 11079 size(4); 11080 ins_encode %{ 11081 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11082 __ extsw($dst$$Register, $src$$Register); 11083 %} 11084 ins_pipe(pipe_class_default); 11085 %} 11086 11087 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11088 match(Set dst (ConvL2I src)); 11089 format %{ "MR $dst, $src \t// long->int" %} 11090 // variable size, 0 or 4 11091 ins_encode %{ 11092 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11093 __ mr_if_needed($dst$$Register, $src$$Register); 11094 %} 11095 ins_pipe(pipe_class_default); 11096 %} 11097 11098 instruct convD2IRaw_regD(regD dst, regD src) %{ 11099 // no match-rule, false predicate 11100 effect(DEF dst, USE src); 11101 predicate(false); 11102 11103 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11104 size(4); 11105 ins_encode %{ 11106 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11107 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11108 %} 11109 ins_pipe(pipe_class_default); 11110 %} 11111 11112 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 11113 // no match-rule, false predicate 11114 effect(DEF dst, USE crx, USE src); 11115 predicate(false); 11116 11117 ins_variable_size_depending_on_alignment(true); 11118 11119 format %{ "cmovI $crx, $dst, $src" %} 11120 // Worst case is branch + move + stop, no stop without scheduler. 11121 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11122 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11123 ins_pipe(pipe_class_default); 11124 %} 11125 11126 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11127 // no match-rule, false predicate 11128 effect(DEF dst, USE crx, USE src); 11129 predicate(false); 11130 11131 ins_variable_size_depending_on_alignment(true); 11132 11133 format %{ "cmovI $crx, $dst, $src" %} 11134 // Worst case is branch + move + stop, no stop without scheduler. 11135 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11136 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11137 ins_pipe(pipe_class_default); 11138 %} 11139 11140 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11141 // no match-rule, false predicate 11142 effect(DEF dst, USE crx, USE mem); 11143 predicate(false); 11144 11145 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11146 postalloc_expand %{ 11147 // 11148 // replaces 11149 // 11150 // region dst crx mem 11151 // \ | | / 11152 // dst=cmovI_bso_stackSlotL_conLvalue0 11153 // 11154 // with 11155 // 11156 // region dst 11157 // \ / 11158 // dst=loadConI16(0) 11159 // | 11160 // ^ region dst crx mem 11161 // | \ | | / 11162 // dst=cmovI_bso_stackSlotL 11163 // 11164 11165 // Create new nodes. 11166 MachNode *m1 = new loadConI16Node(); 11167 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11168 11169 // inputs for new nodes 11170 m1->add_req(n_region); 11171 m2->add_req(n_region, n_crx, n_mem); 11172 11173 // precedences for new nodes 11174 m2->add_prec(m1); 11175 11176 // operands for new nodes 11177 m1->_opnds[0] = op_dst; 11178 m1->_opnds[1] = new immI16Oper(0); 11179 11180 m2->_opnds[0] = op_dst; 11181 m2->_opnds[1] = op_crx; 11182 m2->_opnds[2] = op_mem; 11183 11184 // registers for new nodes 11185 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11186 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11187 11188 // Insert new nodes. 11189 nodes->push(m1); 11190 nodes->push(m2); 11191 %} 11192 %} 11193 11194 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11195 // no match-rule, false predicate 11196 effect(DEF dst, USE crx, USE src); 11197 predicate(false); 11198 11199 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11200 postalloc_expand %{ 11201 // 11202 // replaces 11203 // 11204 // region dst crx src 11205 // \ | | / 11206 // dst=cmovI_bso_reg_conLvalue0 11207 // 11208 // with 11209 // 11210 // region dst 11211 // \ / 11212 // dst=loadConI16(0) 11213 // | 11214 // ^ region dst crx src 11215 // | \ | | / 11216 // dst=cmovI_bso_reg 11217 // 11218 11219 // Create new nodes. 11220 MachNode *m1 = new loadConI16Node(); 11221 MachNode *m2 = new cmovI_bso_regNode(); 11222 11223 // inputs for new nodes 11224 m1->add_req(n_region); 11225 m2->add_req(n_region, n_crx, n_src); 11226 11227 // precedences for new nodes 11228 m2->add_prec(m1); 11229 11230 // operands for new nodes 11231 m1->_opnds[0] = op_dst; 11232 m1->_opnds[1] = new immI16Oper(0); 11233 11234 m2->_opnds[0] = op_dst; 11235 m2->_opnds[1] = op_crx; 11236 m2->_opnds[2] = op_src; 11237 11238 // registers for new nodes 11239 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11240 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11241 11242 // Insert new nodes. 11243 nodes->push(m1); 11244 nodes->push(m2); 11245 %} 11246 %} 11247 11248 // Double to Int conversion, NaN is mapped to 0. 11249 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11250 match(Set dst (ConvD2I src)); 11251 predicate(!VM_Version::has_mtfprd()); 11252 ins_cost(DEFAULT_COST); 11253 11254 expand %{ 11255 regD tmpD; 11256 stackSlotL tmpS; 11257 flagsReg crx; 11258 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11259 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11260 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11261 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11262 %} 11263 %} 11264 11265 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11266 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11267 match(Set dst (ConvD2I src)); 11268 predicate(VM_Version::has_mtfprd()); 11269 ins_cost(DEFAULT_COST); 11270 11271 expand %{ 11272 regD tmpD; 11273 flagsReg crx; 11274 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11275 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11276 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11277 %} 11278 %} 11279 11280 instruct convF2IRaw_regF(regF dst, regF src) %{ 11281 // no match-rule, false predicate 11282 effect(DEF dst, USE src); 11283 predicate(false); 11284 11285 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11286 size(4); 11287 ins_encode %{ 11288 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11289 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11290 %} 11291 ins_pipe(pipe_class_default); 11292 %} 11293 11294 // Float to Int conversion, NaN is mapped to 0. 11295 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11296 match(Set dst (ConvF2I src)); 11297 predicate(!VM_Version::has_mtfprd()); 11298 ins_cost(DEFAULT_COST); 11299 11300 expand %{ 11301 regF tmpF; 11302 stackSlotL tmpS; 11303 flagsReg crx; 11304 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11305 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11306 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11307 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11308 %} 11309 %} 11310 11311 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11312 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11313 match(Set dst (ConvF2I src)); 11314 predicate(VM_Version::has_mtfprd()); 11315 ins_cost(DEFAULT_COST); 11316 11317 expand %{ 11318 regF tmpF; 11319 flagsReg crx; 11320 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11321 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11322 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11323 %} 11324 %} 11325 11326 // Convert to Long 11327 11328 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11329 match(Set dst (ConvI2L src)); 11330 format %{ "EXTSW $dst, $src \t// int->long" %} 11331 size(4); 11332 ins_encode %{ 11333 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11334 __ extsw($dst$$Register, $src$$Register); 11335 %} 11336 ins_pipe(pipe_class_default); 11337 %} 11338 11339 // Zero-extend: convert unsigned int to long (convUI2L). 11340 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11341 match(Set dst (AndL (ConvI2L src) mask)); 11342 ins_cost(DEFAULT_COST); 11343 11344 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11345 size(4); 11346 ins_encode %{ 11347 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11348 __ clrldi($dst$$Register, $src$$Register, 32); 11349 %} 11350 ins_pipe(pipe_class_default); 11351 %} 11352 11353 // Zero-extend: convert unsigned int to long in long register. 11354 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11355 match(Set dst (AndL src mask)); 11356 ins_cost(DEFAULT_COST); 11357 11358 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11359 size(4); 11360 ins_encode %{ 11361 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11362 __ clrldi($dst$$Register, $src$$Register, 32); 11363 %} 11364 ins_pipe(pipe_class_default); 11365 %} 11366 11367 instruct convF2LRaw_regF(regF dst, regF src) %{ 11368 // no match-rule, false predicate 11369 effect(DEF dst, USE src); 11370 predicate(false); 11371 11372 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11373 size(4); 11374 ins_encode %{ 11375 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11376 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11377 %} 11378 ins_pipe(pipe_class_default); 11379 %} 11380 11381 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 11382 // no match-rule, false predicate 11383 effect(DEF dst, USE crx, USE src); 11384 predicate(false); 11385 11386 ins_variable_size_depending_on_alignment(true); 11387 11388 format %{ "cmovL $crx, $dst, $src" %} 11389 // Worst case is branch + move + stop, no stop without scheduler. 11390 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11391 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11392 ins_pipe(pipe_class_default); 11393 %} 11394 11395 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11396 // no match-rule, false predicate 11397 effect(DEF dst, USE crx, USE src); 11398 predicate(false); 11399 11400 ins_variable_size_depending_on_alignment(true); 11401 11402 format %{ "cmovL $crx, $dst, $src" %} 11403 // Worst case is branch + move + stop, no stop without scheduler. 11404 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11405 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11406 ins_pipe(pipe_class_default); 11407 %} 11408 11409 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11410 // no match-rule, false predicate 11411 effect(DEF dst, USE crx, USE mem); 11412 predicate(false); 11413 11414 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11415 postalloc_expand %{ 11416 // 11417 // replaces 11418 // 11419 // region dst crx mem 11420 // \ | | / 11421 // dst=cmovL_bso_stackSlotL_conLvalue0 11422 // 11423 // with 11424 // 11425 // region dst 11426 // \ / 11427 // dst=loadConL16(0) 11428 // | 11429 // ^ region dst crx mem 11430 // | \ | | / 11431 // dst=cmovL_bso_stackSlotL 11432 // 11433 11434 // Create new nodes. 11435 MachNode *m1 = new loadConL16Node(); 11436 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11437 11438 // inputs for new nodes 11439 m1->add_req(n_region); 11440 m2->add_req(n_region, n_crx, n_mem); 11441 m2->add_prec(m1); 11442 11443 // operands for new nodes 11444 m1->_opnds[0] = op_dst; 11445 m1->_opnds[1] = new immL16Oper(0); 11446 m2->_opnds[0] = op_dst; 11447 m2->_opnds[1] = op_crx; 11448 m2->_opnds[2] = op_mem; 11449 11450 // registers for new nodes 11451 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11452 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11453 11454 // Insert new nodes. 11455 nodes->push(m1); 11456 nodes->push(m2); 11457 %} 11458 %} 11459 11460 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11461 // no match-rule, false predicate 11462 effect(DEF dst, USE crx, USE src); 11463 predicate(false); 11464 11465 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11466 postalloc_expand %{ 11467 // 11468 // replaces 11469 // 11470 // region dst crx src 11471 // \ | | / 11472 // dst=cmovL_bso_reg_conLvalue0 11473 // 11474 // with 11475 // 11476 // region dst 11477 // \ / 11478 // dst=loadConL16(0) 11479 // | 11480 // ^ region dst crx src 11481 // | \ | | / 11482 // dst=cmovL_bso_reg 11483 // 11484 11485 // Create new nodes. 11486 MachNode *m1 = new loadConL16Node(); 11487 MachNode *m2 = new cmovL_bso_regNode(); 11488 11489 // inputs for new nodes 11490 m1->add_req(n_region); 11491 m2->add_req(n_region, n_crx, n_src); 11492 m2->add_prec(m1); 11493 11494 // operands for new nodes 11495 m1->_opnds[0] = op_dst; 11496 m1->_opnds[1] = new immL16Oper(0); 11497 m2->_opnds[0] = op_dst; 11498 m2->_opnds[1] = op_crx; 11499 m2->_opnds[2] = op_src; 11500 11501 // registers for new nodes 11502 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11503 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11504 11505 // Insert new nodes. 11506 nodes->push(m1); 11507 nodes->push(m2); 11508 %} 11509 %} 11510 11511 // Float to Long conversion, NaN is mapped to 0. 11512 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11513 match(Set dst (ConvF2L src)); 11514 predicate(!VM_Version::has_mtfprd()); 11515 ins_cost(DEFAULT_COST); 11516 11517 expand %{ 11518 regF tmpF; 11519 stackSlotL tmpS; 11520 flagsReg crx; 11521 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11522 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11523 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11524 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11525 %} 11526 %} 11527 11528 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11529 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11530 match(Set dst (ConvF2L src)); 11531 predicate(VM_Version::has_mtfprd()); 11532 ins_cost(DEFAULT_COST); 11533 11534 expand %{ 11535 regF tmpF; 11536 flagsReg crx; 11537 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11538 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11539 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11540 %} 11541 %} 11542 11543 instruct convD2LRaw_regD(regD dst, regD src) %{ 11544 // no match-rule, false predicate 11545 effect(DEF dst, USE src); 11546 predicate(false); 11547 11548 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11549 size(4); 11550 ins_encode %{ 11551 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11552 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11553 %} 11554 ins_pipe(pipe_class_default); 11555 %} 11556 11557 // Double to Long conversion, NaN is mapped to 0. 11558 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11559 match(Set dst (ConvD2L src)); 11560 predicate(!VM_Version::has_mtfprd()); 11561 ins_cost(DEFAULT_COST); 11562 11563 expand %{ 11564 regD tmpD; 11565 stackSlotL tmpS; 11566 flagsReg crx; 11567 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11568 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11569 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11570 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11571 %} 11572 %} 11573 11574 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11575 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11576 match(Set dst (ConvD2L src)); 11577 predicate(VM_Version::has_mtfprd()); 11578 ins_cost(DEFAULT_COST); 11579 11580 expand %{ 11581 regD tmpD; 11582 flagsReg crx; 11583 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11584 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11585 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11586 %} 11587 %} 11588 11589 // Convert to Float 11590 11591 // Placed here as needed in expand. 11592 instruct convL2DRaw_regD(regD dst, regD src) %{ 11593 // no match-rule, false predicate 11594 effect(DEF dst, USE src); 11595 predicate(false); 11596 11597 format %{ "FCFID $dst, $src \t// convL2D" %} 11598 size(4); 11599 ins_encode %{ 11600 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11601 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11602 %} 11603 ins_pipe(pipe_class_default); 11604 %} 11605 11606 // Placed here as needed in expand. 11607 instruct convD2F_reg(regF dst, regD src) %{ 11608 match(Set dst (ConvD2F src)); 11609 format %{ "FRSP $dst, $src \t// convD2F" %} 11610 size(4); 11611 ins_encode %{ 11612 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11613 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11614 %} 11615 ins_pipe(pipe_class_default); 11616 %} 11617 11618 // Integer to Float conversion. 11619 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11620 match(Set dst (ConvI2F src)); 11621 predicate(!VM_Version::has_fcfids()); 11622 ins_cost(DEFAULT_COST); 11623 11624 expand %{ 11625 iRegLdst tmpL; 11626 stackSlotL tmpS; 11627 regD tmpD; 11628 regD tmpD2; 11629 convI2L_reg(tmpL, src); // Sign-extension int to long. 11630 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11631 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11632 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11633 convD2F_reg(dst, tmpD2); // Convert double to float. 11634 %} 11635 %} 11636 11637 instruct convL2FRaw_regF(regF dst, regD src) %{ 11638 // no match-rule, false predicate 11639 effect(DEF dst, USE src); 11640 predicate(false); 11641 11642 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11643 size(4); 11644 ins_encode %{ 11645 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11646 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11647 %} 11648 ins_pipe(pipe_class_default); 11649 %} 11650 11651 // Integer to Float conversion. Special version for Power7. 11652 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11653 match(Set dst (ConvI2F src)); 11654 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11655 ins_cost(DEFAULT_COST); 11656 11657 expand %{ 11658 iRegLdst tmpL; 11659 stackSlotL tmpS; 11660 regD tmpD; 11661 convI2L_reg(tmpL, src); // Sign-extension int to long. 11662 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11663 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11664 convL2FRaw_regF(dst, tmpD); // Convert to float. 11665 %} 11666 %} 11667 11668 // Integer to Float conversion. Special version for Power8. 11669 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11670 match(Set dst (ConvI2F src)); 11671 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11672 ins_cost(DEFAULT_COST); 11673 11674 expand %{ 11675 regD tmpD; 11676 moveI2D_reg(tmpD, src); 11677 convL2FRaw_regF(dst, tmpD); // Convert to float. 11678 %} 11679 %} 11680 11681 // L2F to avoid runtime call. 11682 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11683 match(Set dst (ConvL2F src)); 11684 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11685 ins_cost(DEFAULT_COST); 11686 11687 expand %{ 11688 stackSlotL tmpS; 11689 regD tmpD; 11690 regL_to_stkL(tmpS, src); // Store long to stack. 11691 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11692 convL2FRaw_regF(dst, tmpD); // Convert to float. 11693 %} 11694 %} 11695 11696 // L2F to avoid runtime call. Special version for Power8. 11697 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11698 match(Set dst (ConvL2F src)); 11699 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11700 ins_cost(DEFAULT_COST); 11701 11702 expand %{ 11703 regD tmpD; 11704 moveL2D_reg(tmpD, src); 11705 convL2FRaw_regF(dst, tmpD); // Convert to float. 11706 %} 11707 %} 11708 11709 // Moved up as used in expand. 11710 //instruct convD2F_reg(regF dst, regD src) %{%} 11711 11712 // Convert to Double 11713 11714 // Integer to Double conversion. 11715 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11716 match(Set dst (ConvI2D src)); 11717 predicate(!VM_Version::has_mtfprd()); 11718 ins_cost(DEFAULT_COST); 11719 11720 expand %{ 11721 iRegLdst tmpL; 11722 stackSlotL tmpS; 11723 regD tmpD; 11724 convI2L_reg(tmpL, src); // Sign-extension int to long. 11725 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11726 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11727 convL2DRaw_regD(dst, tmpD); // Convert to double. 11728 %} 11729 %} 11730 11731 // Integer to Double conversion. Special version for Power8. 11732 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11733 match(Set dst (ConvI2D src)); 11734 predicate(VM_Version::has_mtfprd()); 11735 ins_cost(DEFAULT_COST); 11736 11737 expand %{ 11738 regD tmpD; 11739 moveI2D_reg(tmpD, src); 11740 convL2DRaw_regD(dst, tmpD); // Convert to double. 11741 %} 11742 %} 11743 11744 // Long to Double conversion 11745 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11746 match(Set dst (ConvL2D src)); 11747 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11748 11749 expand %{ 11750 regD tmpD; 11751 moveL2D_stack_reg(tmpD, src); 11752 convL2DRaw_regD(dst, tmpD); 11753 %} 11754 %} 11755 11756 // Long to Double conversion. Special version for Power8. 11757 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11758 match(Set dst (ConvL2D src)); 11759 predicate(VM_Version::has_mtfprd()); 11760 ins_cost(DEFAULT_COST); 11761 11762 expand %{ 11763 regD tmpD; 11764 moveL2D_reg(tmpD, src); 11765 convL2DRaw_regD(dst, tmpD); // Convert to double. 11766 %} 11767 %} 11768 11769 instruct convF2D_reg(regD dst, regF src) %{ 11770 match(Set dst (ConvF2D src)); 11771 format %{ "FMR $dst, $src \t// float->double" %} 11772 // variable size, 0 or 4 11773 ins_encode %{ 11774 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11775 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11776 %} 11777 ins_pipe(pipe_class_default); 11778 %} 11779 11780 //----------Control Flow Instructions------------------------------------------ 11781 // Compare Instructions 11782 11783 // Compare Integers 11784 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11785 match(Set crx (CmpI src1 src2)); 11786 size(4); 11787 format %{ "CMPW $crx, $src1, $src2" %} 11788 ins_encode %{ 11789 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11790 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11791 %} 11792 ins_pipe(pipe_class_compare); 11793 %} 11794 11795 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11796 match(Set crx (CmpI src1 src2)); 11797 format %{ "CMPWI $crx, $src1, $src2" %} 11798 size(4); 11799 ins_encode %{ 11800 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11801 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11802 %} 11803 ins_pipe(pipe_class_compare); 11804 %} 11805 11806 // (src1 & src2) == 0? 11807 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11808 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11809 // r0 is killed 11810 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11811 size(4); 11812 ins_encode %{ 11813 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11814 __ andi_(R0, $src1$$Register, $src2$$constant); 11815 %} 11816 ins_pipe(pipe_class_compare); 11817 %} 11818 11819 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11820 match(Set crx (CmpL src1 src2)); 11821 format %{ "CMPD $crx, $src1, $src2" %} 11822 size(4); 11823 ins_encode %{ 11824 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11825 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11826 %} 11827 ins_pipe(pipe_class_compare); 11828 %} 11829 11830 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11831 match(Set crx (CmpL src1 src2)); 11832 format %{ "CMPDI $crx, $src1, $src2" %} 11833 size(4); 11834 ins_encode %{ 11835 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11836 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11837 %} 11838 ins_pipe(pipe_class_compare); 11839 %} 11840 11841 // Added CmpUL for LoopPredicate. 11842 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11843 match(Set crx (CmpUL src1 src2)); 11844 format %{ "CMPLD $crx, $src1, $src2" %} 11845 size(4); 11846 ins_encode %{ 11847 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11848 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11849 %} 11850 ins_pipe(pipe_class_compare); 11851 %} 11852 11853 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11854 match(Set crx (CmpUL src1 src2)); 11855 format %{ "CMPLDI $crx, $src1, $src2" %} 11856 size(4); 11857 ins_encode %{ 11858 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11859 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11860 %} 11861 ins_pipe(pipe_class_compare); 11862 %} 11863 11864 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11865 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11866 // r0 is killed 11867 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11868 size(4); 11869 ins_encode %{ 11870 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11871 __ and_(R0, $src1$$Register, $src2$$Register); 11872 %} 11873 ins_pipe(pipe_class_compare); 11874 %} 11875 11876 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11877 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11878 // r0 is killed 11879 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11880 size(4); 11881 ins_encode %{ 11882 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11883 __ andi_(R0, $src1$$Register, $src2$$constant); 11884 %} 11885 ins_pipe(pipe_class_compare); 11886 %} 11887 11888 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11889 // no match-rule, false predicate 11890 effect(DEF dst, USE crx); 11891 predicate(false); 11892 11893 ins_variable_size_depending_on_alignment(true); 11894 11895 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11896 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11897 size((false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16)); 11898 ins_encode %{ 11899 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11900 Label done; 11901 // li(Rdst, 0); // equal -> 0 11902 __ beq($crx$$CondRegister, done); 11903 __ li($dst$$Register, 1); // greater -> +1 11904 __ bgt($crx$$CondRegister, done); 11905 __ li($dst$$Register, -1); // unordered or less -> -1 11906 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11907 __ bind(done); 11908 %} 11909 ins_pipe(pipe_class_compare); 11910 %} 11911 11912 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11913 // no match-rule, false predicate 11914 effect(DEF dst, USE crx); 11915 predicate(false); 11916 11917 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11918 postalloc_expand %{ 11919 // 11920 // replaces 11921 // 11922 // region crx 11923 // \ | 11924 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11925 // 11926 // with 11927 // 11928 // region 11929 // \ 11930 // dst=loadConI16(0) 11931 // | 11932 // ^ region crx 11933 // | \ | 11934 // dst=cmovI_conIvalueMinus1_conIvalue1 11935 // 11936 11937 // Create new nodes. 11938 MachNode *m1 = new loadConI16Node(); 11939 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11940 11941 // inputs for new nodes 11942 m1->add_req(n_region); 11943 m2->add_req(n_region, n_crx); 11944 m2->add_prec(m1); 11945 11946 // operands for new nodes 11947 m1->_opnds[0] = op_dst; 11948 m1->_opnds[1] = new immI16Oper(0); 11949 m2->_opnds[0] = op_dst; 11950 m2->_opnds[1] = op_crx; 11951 11952 // registers for new nodes 11953 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11954 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11955 11956 // Insert new nodes. 11957 nodes->push(m1); 11958 nodes->push(m2); 11959 %} 11960 %} 11961 11962 // Manifest a CmpL3 result in an integer register. Very painful. 11963 // This is the test to avoid. 11964 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11965 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11966 match(Set dst (CmpL3 src1 src2)); 11967 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11968 11969 expand %{ 11970 flagsReg tmp1; 11971 cmpL_reg_reg(tmp1, src1, src2); 11972 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11973 %} 11974 %} 11975 11976 // Implicit range checks. 11977 // A range check in the ideal world has one of the following shapes: 11978 // - (If le (CmpU length index)), (IfTrue throw exception) 11979 // - (If lt (CmpU index length)), (IfFalse throw exception) 11980 // 11981 // Match range check 'If le (CmpU length index)'. 11982 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11983 match(If cmp (CmpU src_length index)); 11984 effect(USE labl); 11985 predicate(TrapBasedRangeChecks && 11986 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11987 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11988 (Matcher::branches_to_uncommon_trap(_leaf))); 11989 11990 ins_is_TrapBasedCheckNode(true); 11991 11992 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11993 size(4); 11994 ins_encode %{ 11995 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11996 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11997 __ trap_range_check_le($src_length$$Register, $index$$constant); 11998 } else { 11999 // Both successors are uncommon traps, probability is 0. 12000 // Node got flipped during fixup flow. 12001 assert($cmp$$cmpcode == 0x9, "must be greater"); 12002 __ trap_range_check_g($src_length$$Register, $index$$constant); 12003 } 12004 %} 12005 ins_pipe(pipe_class_trap); 12006 %} 12007 12008 // Match range check 'If lt (CmpU index length)'. 12009 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 12010 match(If cmp (CmpU src_index src_length)); 12011 effect(USE labl); 12012 predicate(TrapBasedRangeChecks && 12013 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12014 _leaf->as_If()->_prob >= PROB_ALWAYS && 12015 (Matcher::branches_to_uncommon_trap(_leaf))); 12016 12017 ins_is_TrapBasedCheckNode(true); 12018 12019 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 12020 size(4); 12021 ins_encode %{ 12022 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 12023 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12024 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 12025 } else { 12026 // Both successors are uncommon traps, probability is 0. 12027 // Node got flipped during fixup flow. 12028 assert($cmp$$cmpcode == 0x8, "must be less"); 12029 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 12030 } 12031 %} 12032 ins_pipe(pipe_class_trap); 12033 %} 12034 12035 // Match range check 'If lt (CmpU index length)'. 12036 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 12037 match(If cmp (CmpU src_index length)); 12038 effect(USE labl); 12039 predicate(TrapBasedRangeChecks && 12040 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12041 _leaf->as_If()->_prob >= PROB_ALWAYS && 12042 (Matcher::branches_to_uncommon_trap(_leaf))); 12043 12044 ins_is_TrapBasedCheckNode(true); 12045 12046 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 12047 size(4); 12048 ins_encode %{ 12049 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12050 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12051 __ trap_range_check_ge($src_index$$Register, $length$$constant); 12052 } else { 12053 // Both successors are uncommon traps, probability is 0. 12054 // Node got flipped during fixup flow. 12055 assert($cmp$$cmpcode == 0x8, "must be less"); 12056 __ trap_range_check_l($src_index$$Register, $length$$constant); 12057 } 12058 %} 12059 ins_pipe(pipe_class_trap); 12060 %} 12061 12062 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 12063 match(Set crx (CmpU src1 src2)); 12064 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 12065 size(4); 12066 ins_encode %{ 12067 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12068 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12069 %} 12070 ins_pipe(pipe_class_compare); 12071 %} 12072 12073 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 12074 match(Set crx (CmpU src1 src2)); 12075 size(4); 12076 format %{ "CMPLWI $crx, $src1, $src2" %} 12077 ins_encode %{ 12078 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12079 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12080 %} 12081 ins_pipe(pipe_class_compare); 12082 %} 12083 12084 // Implicit zero checks (more implicit null checks). 12085 // No constant pool entries required. 12086 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12087 match(If cmp (CmpN value zero)); 12088 effect(USE labl); 12089 predicate(TrapBasedNullChecks && 12090 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12091 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12092 Matcher::branches_to_uncommon_trap(_leaf)); 12093 ins_cost(1); 12094 12095 ins_is_TrapBasedCheckNode(true); 12096 12097 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12098 size(4); 12099 ins_encode %{ 12100 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12101 if ($cmp$$cmpcode == 0xA) { 12102 __ trap_null_check($value$$Register); 12103 } else { 12104 // Both successors are uncommon traps, probability is 0. 12105 // Node got flipped during fixup flow. 12106 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12107 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12108 } 12109 %} 12110 ins_pipe(pipe_class_trap); 12111 %} 12112 12113 // Compare narrow oops. 12114 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12115 match(Set crx (CmpN src1 src2)); 12116 12117 size(4); 12118 ins_cost(2); 12119 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12120 ins_encode %{ 12121 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12122 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12123 %} 12124 ins_pipe(pipe_class_compare); 12125 %} 12126 12127 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12128 match(Set crx (CmpN src1 src2)); 12129 // Make this more expensive than zeroCheckN_iReg_imm0. 12130 ins_cost(2); 12131 12132 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12133 size(4); 12134 ins_encode %{ 12135 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12136 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12137 %} 12138 ins_pipe(pipe_class_compare); 12139 %} 12140 12141 // Implicit zero checks (more implicit null checks). 12142 // No constant pool entries required. 12143 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12144 match(If cmp (CmpP value zero)); 12145 effect(USE labl); 12146 predicate(TrapBasedNullChecks && 12147 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12148 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12149 Matcher::branches_to_uncommon_trap(_leaf)); 12150 ins_cost(1); // Should not be cheaper than zeroCheckN. 12151 12152 ins_is_TrapBasedCheckNode(true); 12153 12154 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12155 size(4); 12156 ins_encode %{ 12157 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12158 if ($cmp$$cmpcode == 0xA) { 12159 __ trap_null_check($value$$Register); 12160 } else { 12161 // Both successors are uncommon traps, probability is 0. 12162 // Node got flipped during fixup flow. 12163 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12164 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12165 } 12166 %} 12167 ins_pipe(pipe_class_trap); 12168 %} 12169 12170 // Compare Pointers 12171 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12172 match(Set crx (CmpP src1 src2)); 12173 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12174 size(4); 12175 ins_encode %{ 12176 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12177 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12178 %} 12179 ins_pipe(pipe_class_compare); 12180 %} 12181 12182 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12183 match(Set crx (CmpP src1 src2)); 12184 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12185 size(4); 12186 ins_encode %{ 12187 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12188 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12189 %} 12190 ins_pipe(pipe_class_compare); 12191 %} 12192 12193 // Used in postalloc expand. 12194 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12195 // This match rule prevents reordering of node before a safepoint. 12196 // This only makes sense if this instructions is used exclusively 12197 // for the expansion of EncodeP! 12198 match(Set crx (CmpP src1 src2)); 12199 predicate(false); 12200 12201 format %{ "CMPDI $crx, $src1, $src2" %} 12202 size(4); 12203 ins_encode %{ 12204 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12205 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12206 %} 12207 ins_pipe(pipe_class_compare); 12208 %} 12209 12210 //----------Float Compares---------------------------------------------------- 12211 12212 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12213 // Needs matchrule, see cmpDUnordered. 12214 match(Set crx (CmpF src1 src2)); 12215 // no match-rule, false predicate 12216 predicate(false); 12217 12218 format %{ "cmpFUrd $crx, $src1, $src2" %} 12219 size(4); 12220 ins_encode %{ 12221 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12222 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12223 %} 12224 ins_pipe(pipe_class_default); 12225 %} 12226 12227 instruct cmov_bns_less(flagsReg crx) %{ 12228 // no match-rule, false predicate 12229 effect(DEF crx); 12230 predicate(false); 12231 12232 ins_variable_size_depending_on_alignment(true); 12233 12234 format %{ "cmov $crx" %} 12235 // Worst case is branch + move + stop, no stop without scheduler. 12236 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12)); 12237 ins_encode %{ 12238 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12239 Label done; 12240 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12241 __ li(R0, 0); 12242 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12243 // TODO PPC port __ endgroup_if_needed(_size == 16); 12244 __ bind(done); 12245 %} 12246 ins_pipe(pipe_class_default); 12247 %} 12248 12249 // Compare floating, generate condition code. 12250 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12251 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12252 // 12253 // The following code sequence occurs a lot in mpegaudio: 12254 // 12255 // block BXX: 12256 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12257 // cmpFUrd CCR6, F11, F9 12258 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12259 // cmov CCR6 12260 // 8: instruct branchConSched: 12261 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12262 match(Set crx (CmpF src1 src2)); 12263 ins_cost(DEFAULT_COST+BRANCH_COST); 12264 12265 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12266 postalloc_expand %{ 12267 // 12268 // replaces 12269 // 12270 // region src1 src2 12271 // \ | | 12272 // crx=cmpF_reg_reg 12273 // 12274 // with 12275 // 12276 // region src1 src2 12277 // \ | | 12278 // crx=cmpFUnordered_reg_reg 12279 // | 12280 // ^ region 12281 // | \ 12282 // crx=cmov_bns_less 12283 // 12284 12285 // Create new nodes. 12286 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12287 MachNode *m2 = new cmov_bns_lessNode(); 12288 12289 // inputs for new nodes 12290 m1->add_req(n_region, n_src1, n_src2); 12291 m2->add_req(n_region); 12292 m2->add_prec(m1); 12293 12294 // operands for new nodes 12295 m1->_opnds[0] = op_crx; 12296 m1->_opnds[1] = op_src1; 12297 m1->_opnds[2] = op_src2; 12298 m2->_opnds[0] = op_crx; 12299 12300 // registers for new nodes 12301 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12302 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12303 12304 // Insert new nodes. 12305 nodes->push(m1); 12306 nodes->push(m2); 12307 %} 12308 %} 12309 12310 // Compare float, generate -1,0,1 12311 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12312 match(Set dst (CmpF3 src1 src2)); 12313 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12314 12315 expand %{ 12316 flagsReg tmp1; 12317 cmpFUnordered_reg_reg(tmp1, src1, src2); 12318 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12319 %} 12320 %} 12321 12322 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12323 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12324 // node right before the conditional move using it. 12325 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12326 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12327 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12328 // conditional move was supposed to be spilled. 12329 match(Set crx (CmpD src1 src2)); 12330 // False predicate, shall not be matched. 12331 predicate(false); 12332 12333 format %{ "cmpFUrd $crx, $src1, $src2" %} 12334 size(4); 12335 ins_encode %{ 12336 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12337 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12338 %} 12339 ins_pipe(pipe_class_default); 12340 %} 12341 12342 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12343 match(Set crx (CmpD src1 src2)); 12344 ins_cost(DEFAULT_COST+BRANCH_COST); 12345 12346 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12347 postalloc_expand %{ 12348 // 12349 // replaces 12350 // 12351 // region src1 src2 12352 // \ | | 12353 // crx=cmpD_reg_reg 12354 // 12355 // with 12356 // 12357 // region src1 src2 12358 // \ | | 12359 // crx=cmpDUnordered_reg_reg 12360 // | 12361 // ^ region 12362 // | \ 12363 // crx=cmov_bns_less 12364 // 12365 12366 // create new nodes 12367 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12368 MachNode *m2 = new cmov_bns_lessNode(); 12369 12370 // inputs for new nodes 12371 m1->add_req(n_region, n_src1, n_src2); 12372 m2->add_req(n_region); 12373 m2->add_prec(m1); 12374 12375 // operands for new nodes 12376 m1->_opnds[0] = op_crx; 12377 m1->_opnds[1] = op_src1; 12378 m1->_opnds[2] = op_src2; 12379 m2->_opnds[0] = op_crx; 12380 12381 // registers for new nodes 12382 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12383 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12384 12385 // Insert new nodes. 12386 nodes->push(m1); 12387 nodes->push(m2); 12388 %} 12389 %} 12390 12391 // Compare double, generate -1,0,1 12392 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12393 match(Set dst (CmpD3 src1 src2)); 12394 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12395 12396 expand %{ 12397 flagsReg tmp1; 12398 cmpDUnordered_reg_reg(tmp1, src1, src2); 12399 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12400 %} 12401 %} 12402 12403 //----------Branches--------------------------------------------------------- 12404 // Jump 12405 12406 // Direct Branch. 12407 instruct branch(label labl) %{ 12408 match(Goto); 12409 effect(USE labl); 12410 ins_cost(BRANCH_COST); 12411 12412 format %{ "B $labl" %} 12413 size(4); 12414 ins_encode %{ 12415 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12416 Label d; // dummy 12417 __ bind(d); 12418 Label* p = $labl$$label; 12419 // `p' is `NULL' when this encoding class is used only to 12420 // determine the size of the encoded instruction. 12421 Label& l = (NULL == p)? d : *(p); 12422 __ b(l); 12423 %} 12424 ins_pipe(pipe_class_default); 12425 %} 12426 12427 // Conditional Near Branch 12428 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12429 // Same match rule as `branchConFar'. 12430 match(If cmp crx); 12431 effect(USE lbl); 12432 ins_cost(BRANCH_COST); 12433 12434 // If set to 1 this indicates that the current instruction is a 12435 // short variant of a long branch. This avoids using this 12436 // instruction in first-pass matching. It will then only be used in 12437 // the `Shorten_branches' pass. 12438 ins_short_branch(1); 12439 12440 format %{ "B$cmp $crx, $lbl" %} 12441 size(4); 12442 ins_encode( enc_bc(crx, cmp, lbl) ); 12443 ins_pipe(pipe_class_default); 12444 %} 12445 12446 // This is for cases when the ppc64 `bc' instruction does not 12447 // reach far enough. So we emit a far branch here, which is more 12448 // expensive. 12449 // 12450 // Conditional Far Branch 12451 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12452 // Same match rule as `branchCon'. 12453 match(If cmp crx); 12454 effect(USE crx, USE lbl); 12455 predicate(!false /* TODO: PPC port HB_Schedule*/); 12456 // Higher cost than `branchCon'. 12457 ins_cost(5*BRANCH_COST); 12458 12459 // This is not a short variant of a branch, but the long variant. 12460 ins_short_branch(0); 12461 12462 format %{ "B_FAR$cmp $crx, $lbl" %} 12463 size(8); 12464 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12465 ins_pipe(pipe_class_default); 12466 %} 12467 12468 // Conditional Branch used with Power6 scheduler (can be far or short). 12469 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12470 // Same match rule as `branchCon'. 12471 match(If cmp crx); 12472 effect(USE crx, USE lbl); 12473 predicate(false /* TODO: PPC port HB_Schedule*/); 12474 // Higher cost than `branchCon'. 12475 ins_cost(5*BRANCH_COST); 12476 12477 // Actually size doesn't depend on alignment but on shortening. 12478 ins_variable_size_depending_on_alignment(true); 12479 // long variant. 12480 ins_short_branch(0); 12481 12482 format %{ "B_FAR$cmp $crx, $lbl" %} 12483 size(8); // worst case 12484 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12485 ins_pipe(pipe_class_default); 12486 %} 12487 12488 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12489 match(CountedLoopEnd cmp crx); 12490 effect(USE labl); 12491 ins_cost(BRANCH_COST); 12492 12493 // short variant. 12494 ins_short_branch(1); 12495 12496 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12497 size(4); 12498 ins_encode( enc_bc(crx, cmp, labl) ); 12499 ins_pipe(pipe_class_default); 12500 %} 12501 12502 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12503 match(CountedLoopEnd cmp crx); 12504 effect(USE labl); 12505 predicate(!false /* TODO: PPC port HB_Schedule */); 12506 ins_cost(BRANCH_COST); 12507 12508 // Long variant. 12509 ins_short_branch(0); 12510 12511 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12512 size(8); 12513 ins_encode( enc_bc_far(crx, cmp, labl) ); 12514 ins_pipe(pipe_class_default); 12515 %} 12516 12517 // Conditional Branch used with Power6 scheduler (can be far or short). 12518 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12519 match(CountedLoopEnd cmp crx); 12520 effect(USE labl); 12521 predicate(false /* TODO: PPC port HB_Schedule */); 12522 // Higher cost than `branchCon'. 12523 ins_cost(5*BRANCH_COST); 12524 12525 // Actually size doesn't depend on alignment but on shortening. 12526 ins_variable_size_depending_on_alignment(true); 12527 // Long variant. 12528 ins_short_branch(0); 12529 12530 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12531 size(8); // worst case 12532 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12533 ins_pipe(pipe_class_default); 12534 %} 12535 12536 // ============================================================================ 12537 // Java runtime operations, intrinsics and other complex operations. 12538 12539 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12540 // array for an instance of the superklass. Set a hidden internal cache on a 12541 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12542 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12543 // 12544 // GL TODO: Improve this. 12545 // - result should not be a TEMP 12546 // - Add match rule as on sparc avoiding additional Cmp. 12547 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12548 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12549 match(Set result (PartialSubtypeCheck subklass superklass)); 12550 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12551 ins_cost(DEFAULT_COST*10); 12552 12553 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12554 ins_encode %{ 12555 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12556 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12557 $tmp_klass$$Register, NULL, $result$$Register); 12558 %} 12559 ins_pipe(pipe_class_default); 12560 %} 12561 12562 // inlined locking and unlocking 12563 12564 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12565 match(Set crx (FastLock oop box)); 12566 effect(TEMP tmp1, TEMP tmp2); 12567 predicate(!Compile::current()->use_rtm()); 12568 12569 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12570 ins_encode %{ 12571 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12572 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12573 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12574 UseBiasedLocking && !UseOptoBiasInlining); 12575 // If locking was successfull, crx should indicate 'EQ'. 12576 // The compiler generates a branch to the runtime call to 12577 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12578 %} 12579 ins_pipe(pipe_class_compare); 12580 %} 12581 12582 // Separate version for TM. Use bound register for box to enable USE_KILL. 12583 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12584 match(Set crx (FastLock oop box)); 12585 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12586 predicate(Compile::current()->use_rtm()); 12587 12588 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12589 ins_encode %{ 12590 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12591 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12592 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12593 /*Biased Locking*/ false, 12594 _rtm_counters, _stack_rtm_counters, 12595 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12596 /*TM*/ true, ra_->C->profile_rtm()); 12597 // If locking was successfull, crx should indicate 'EQ'. 12598 // The compiler generates a branch to the runtime call to 12599 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12600 %} 12601 ins_pipe(pipe_class_compare); 12602 %} 12603 12604 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12605 match(Set crx (FastUnlock oop box)); 12606 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12607 predicate(!Compile::current()->use_rtm()); 12608 12609 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12610 ins_encode %{ 12611 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12612 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12613 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12614 UseBiasedLocking && !UseOptoBiasInlining, 12615 false); 12616 // If unlocking was successfull, crx should indicate 'EQ'. 12617 // The compiler generates a branch to the runtime call to 12618 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12619 %} 12620 ins_pipe(pipe_class_compare); 12621 %} 12622 12623 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12624 match(Set crx (FastUnlock oop box)); 12625 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12626 predicate(Compile::current()->use_rtm()); 12627 12628 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12629 ins_encode %{ 12630 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12631 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12632 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12633 /*Biased Locking*/ false, /*TM*/ true); 12634 // If unlocking was successfull, crx should indicate 'EQ'. 12635 // The compiler generates a branch to the runtime call to 12636 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12637 %} 12638 ins_pipe(pipe_class_compare); 12639 %} 12640 12641 // Align address. 12642 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12643 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12644 12645 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12646 size(4); 12647 ins_encode %{ 12648 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12649 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12650 %} 12651 ins_pipe(pipe_class_default); 12652 %} 12653 12654 // Array size computation. 12655 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12656 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12657 12658 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12659 size(4); 12660 ins_encode %{ 12661 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12662 __ subf($dst$$Register, $start$$Register, $end$$Register); 12663 %} 12664 ins_pipe(pipe_class_default); 12665 %} 12666 12667 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12668 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12669 match(Set dummy (ClearArray cnt base)); 12670 effect(USE_KILL base, KILL ctr); 12671 ins_cost(2 * MEMORY_REF_COST); 12672 12673 format %{ "ClearArray $cnt, $base" %} 12674 ins_encode %{ 12675 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12676 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12677 %} 12678 ins_pipe(pipe_class_default); 12679 %} 12680 12681 // Clear-array with constant large array length. 12682 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12683 match(Set dummy (ClearArray cnt base)); 12684 effect(USE_KILL base, TEMP tmp, KILL ctr); 12685 ins_cost(3 * MEMORY_REF_COST); 12686 12687 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12688 ins_encode %{ 12689 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12690 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12691 %} 12692 ins_pipe(pipe_class_default); 12693 %} 12694 12695 // Clear-array with dynamic array length. 12696 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12697 match(Set dummy (ClearArray cnt base)); 12698 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12699 ins_cost(4 * MEMORY_REF_COST); 12700 12701 format %{ "ClearArray $cnt, $base" %} 12702 ins_encode %{ 12703 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12704 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12705 %} 12706 ins_pipe(pipe_class_default); 12707 %} 12708 12709 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12710 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12711 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12712 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12713 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12714 ins_cost(300); 12715 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12716 ins_encode %{ 12717 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12718 __ string_compare($str1$$Register, $str2$$Register, 12719 $cnt1$$Register, $cnt2$$Register, 12720 $tmp$$Register, 12721 $result$$Register, StrIntrinsicNode::LL); 12722 %} 12723 ins_pipe(pipe_class_default); 12724 %} 12725 12726 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12727 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12728 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12729 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12730 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12731 ins_cost(300); 12732 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12733 ins_encode %{ 12734 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12735 __ string_compare($str1$$Register, $str2$$Register, 12736 $cnt1$$Register, $cnt2$$Register, 12737 $tmp$$Register, 12738 $result$$Register, StrIntrinsicNode::UU); 12739 %} 12740 ins_pipe(pipe_class_default); 12741 %} 12742 12743 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12744 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12745 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12746 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12747 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12748 ins_cost(300); 12749 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12750 ins_encode %{ 12751 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12752 __ string_compare($str1$$Register, $str2$$Register, 12753 $cnt1$$Register, $cnt2$$Register, 12754 $tmp$$Register, 12755 $result$$Register, StrIntrinsicNode::LU); 12756 %} 12757 ins_pipe(pipe_class_default); 12758 %} 12759 12760 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12761 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12762 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12763 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12764 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12765 ins_cost(300); 12766 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12767 ins_encode %{ 12768 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12769 __ string_compare($str2$$Register, $str1$$Register, 12770 $cnt2$$Register, $cnt1$$Register, 12771 $tmp$$Register, 12772 $result$$Register, StrIntrinsicNode::UL); 12773 %} 12774 ins_pipe(pipe_class_default); 12775 %} 12776 12777 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12778 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12779 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12780 match(Set result (StrEquals (Binary str1 str2) cnt)); 12781 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12782 ins_cost(300); 12783 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12784 ins_encode %{ 12785 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12786 __ array_equals(false, $str1$$Register, $str2$$Register, 12787 $cnt$$Register, $tmp$$Register, 12788 $result$$Register, true /* byte */); 12789 %} 12790 ins_pipe(pipe_class_default); 12791 %} 12792 12793 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12794 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12795 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12796 match(Set result (StrEquals (Binary str1 str2) cnt)); 12797 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12798 ins_cost(300); 12799 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12800 ins_encode %{ 12801 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12802 __ array_equals(false, $str1$$Register, $str2$$Register, 12803 $cnt$$Register, $tmp$$Register, 12804 $result$$Register, false /* byte */); 12805 %} 12806 ins_pipe(pipe_class_default); 12807 %} 12808 12809 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12810 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12811 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12812 match(Set result (AryEq ary1 ary2)); 12813 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12814 ins_cost(300); 12815 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12816 ins_encode %{ 12817 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12818 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12819 $tmp1$$Register, $tmp2$$Register, 12820 $result$$Register, true /* byte */); 12821 %} 12822 ins_pipe(pipe_class_default); 12823 %} 12824 12825 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12826 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12827 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12828 match(Set result (AryEq ary1 ary2)); 12829 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12830 ins_cost(300); 12831 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12832 ins_encode %{ 12833 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12834 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12835 $tmp1$$Register, $tmp2$$Register, 12836 $result$$Register, false /* byte */); 12837 %} 12838 ins_pipe(pipe_class_default); 12839 %} 12840 12841 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12842 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12843 iRegIdst tmp1, iRegIdst tmp2, 12844 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12845 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12846 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12847 // Required for EA: check if it is still a type_array. 12848 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12849 ins_cost(150); 12850 12851 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12852 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12853 12854 ins_encode %{ 12855 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12856 immPOper *needleOper = (immPOper *)$needleImm; 12857 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12858 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12859 jchar chr; 12860 #ifdef VM_LITTLE_ENDIAN 12861 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12862 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12863 #else 12864 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12865 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12866 #endif 12867 __ string_indexof_char($result$$Register, 12868 $haystack$$Register, $haycnt$$Register, 12869 R0, chr, 12870 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12871 %} 12872 ins_pipe(pipe_class_compare); 12873 %} 12874 12875 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12876 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12877 iRegIdst tmp1, iRegIdst tmp2, 12878 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12879 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12880 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12881 // Required for EA: check if it is still a type_array. 12882 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12883 ins_cost(150); 12884 12885 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12886 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12887 12888 ins_encode %{ 12889 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12890 immPOper *needleOper = (immPOper *)$needleImm; 12891 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12892 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12893 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12894 __ string_indexof_char($result$$Register, 12895 $haystack$$Register, $haycnt$$Register, 12896 R0, chr, 12897 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12898 %} 12899 ins_pipe(pipe_class_compare); 12900 %} 12901 12902 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12903 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12904 iRegIdst tmp1, iRegIdst tmp2, 12905 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12906 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12907 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12908 // Required for EA: check if it is still a type_array. 12909 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12910 ins_cost(150); 12911 12912 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12913 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12914 12915 ins_encode %{ 12916 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12917 immPOper *needleOper = (immPOper *)$needleImm; 12918 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12919 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12920 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12921 __ string_indexof_char($result$$Register, 12922 $haystack$$Register, $haycnt$$Register, 12923 R0, chr, 12924 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12925 %} 12926 ins_pipe(pipe_class_compare); 12927 %} 12928 12929 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12930 rscratch2RegP needle, immI_1 needlecntImm, 12931 iRegIdst tmp1, iRegIdst tmp2, 12932 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12933 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12934 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12935 // Required for EA: check if it is still a type_array. 12936 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12937 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12938 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12939 ins_cost(180); 12940 12941 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12942 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12943 ins_encode %{ 12944 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12945 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12946 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12947 guarantee(needle_values, "sanity"); 12948 jchar chr; 12949 #ifdef VM_LITTLE_ENDIAN 12950 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12951 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12952 #else 12953 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12954 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12955 #endif 12956 __ string_indexof_char($result$$Register, 12957 $haystack$$Register, $haycnt$$Register, 12958 R0, chr, 12959 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12960 %} 12961 ins_pipe(pipe_class_compare); 12962 %} 12963 12964 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12965 rscratch2RegP needle, immI_1 needlecntImm, 12966 iRegIdst tmp1, iRegIdst tmp2, 12967 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12968 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12969 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12970 // Required for EA: check if it is still a type_array. 12971 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12972 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12973 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12974 ins_cost(180); 12975 12976 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12977 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12978 ins_encode %{ 12979 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12980 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12981 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12982 guarantee(needle_values, "sanity"); 12983 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12984 __ string_indexof_char($result$$Register, 12985 $haystack$$Register, $haycnt$$Register, 12986 R0, chr, 12987 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12988 %} 12989 ins_pipe(pipe_class_compare); 12990 %} 12991 12992 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12993 rscratch2RegP needle, immI_1 needlecntImm, 12994 iRegIdst tmp1, iRegIdst tmp2, 12995 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12996 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12997 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12998 // Required for EA: check if it is still a type_array. 12999 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13000 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13001 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13002 ins_cost(180); 13003 13004 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13005 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13006 ins_encode %{ 13007 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13008 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13009 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13010 guarantee(needle_values, "sanity"); 13011 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13012 __ string_indexof_char($result$$Register, 13013 $haystack$$Register, $haycnt$$Register, 13014 R0, chr, 13015 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13016 %} 13017 ins_pipe(pipe_class_compare); 13018 %} 13019 13020 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13021 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 13022 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13023 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 13024 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13025 ins_cost(180); 13026 13027 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 13028 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13029 ins_encode %{ 13030 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13031 __ string_indexof_char($result$$Register, 13032 $haystack$$Register, $haycnt$$Register, 13033 $ch$$Register, 0 /* this is not used if the character is already in a register */, 13034 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13035 %} 13036 ins_pipe(pipe_class_compare); 13037 %} 13038 13039 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13040 iRegPsrc needle, uimmI15 needlecntImm, 13041 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13042 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13043 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13044 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13045 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13046 // Required for EA: check if it is still a type_array. 13047 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13048 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13049 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13050 ins_cost(250); 13051 13052 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13053 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13054 ins_encode %{ 13055 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13056 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13057 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13058 13059 __ string_indexof($result$$Register, 13060 $haystack$$Register, $haycnt$$Register, 13061 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13062 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13063 %} 13064 ins_pipe(pipe_class_compare); 13065 %} 13066 13067 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13068 iRegPsrc needle, uimmI15 needlecntImm, 13069 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13070 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13071 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13072 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13073 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13074 // Required for EA: check if it is still a type_array. 13075 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13076 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13077 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13078 ins_cost(250); 13079 13080 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13081 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13082 ins_encode %{ 13083 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13084 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13085 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13086 13087 __ string_indexof($result$$Register, 13088 $haystack$$Register, $haycnt$$Register, 13089 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13090 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13091 %} 13092 ins_pipe(pipe_class_compare); 13093 %} 13094 13095 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13096 iRegPsrc needle, uimmI15 needlecntImm, 13097 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13098 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13099 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13100 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13101 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13102 // Required for EA: check if it is still a type_array. 13103 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13104 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13105 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13106 ins_cost(250); 13107 13108 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13109 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13110 ins_encode %{ 13111 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13112 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13113 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13114 13115 __ string_indexof($result$$Register, 13116 $haystack$$Register, $haycnt$$Register, 13117 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13118 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13119 %} 13120 ins_pipe(pipe_class_compare); 13121 %} 13122 13123 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13124 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13125 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13126 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13127 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13128 TEMP_DEF result, 13129 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13130 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13131 ins_cost(300); 13132 13133 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13134 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13135 ins_encode %{ 13136 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13137 __ string_indexof($result$$Register, 13138 $haystack$$Register, $haycnt$$Register, 13139 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13140 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13141 %} 13142 ins_pipe(pipe_class_compare); 13143 %} 13144 13145 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13146 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13147 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13148 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13149 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13150 TEMP_DEF result, 13151 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13152 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13153 ins_cost(300); 13154 13155 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13156 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13157 ins_encode %{ 13158 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13159 __ string_indexof($result$$Register, 13160 $haystack$$Register, $haycnt$$Register, 13161 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13162 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13163 %} 13164 ins_pipe(pipe_class_compare); 13165 %} 13166 13167 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13168 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13169 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13170 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13171 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13172 TEMP_DEF result, 13173 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13174 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13175 ins_cost(300); 13176 13177 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13178 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13179 ins_encode %{ 13180 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13181 __ string_indexof($result$$Register, 13182 $haystack$$Register, $haycnt$$Register, 13183 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13184 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13185 %} 13186 ins_pipe(pipe_class_compare); 13187 %} 13188 13189 // char[] to byte[] compression 13190 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13191 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13192 match(Set result (StrCompressedCopy src (Binary dst len))); 13193 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13194 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13195 ins_cost(300); 13196 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13197 ins_encode %{ 13198 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13199 Label Lskip, Ldone; 13200 __ li($result$$Register, 0); 13201 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13202 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13203 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13204 __ beq(CCR0, Lskip); 13205 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13206 __ bind(Lskip); 13207 __ mr($result$$Register, $len$$Register); 13208 __ bind(Ldone); 13209 %} 13210 ins_pipe(pipe_class_default); 13211 %} 13212 13213 // byte[] to char[] inflation 13214 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13215 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13216 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13217 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13218 ins_cost(300); 13219 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13220 ins_encode %{ 13221 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13222 Label Ldone; 13223 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13224 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13225 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13226 __ beq(CCR0, Ldone); 13227 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13228 __ bind(Ldone); 13229 %} 13230 ins_pipe(pipe_class_default); 13231 %} 13232 13233 // StringCoding.java intrinsics 13234 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13235 regCTR ctr, flagsRegCR0 cr0) 13236 %{ 13237 match(Set result (HasNegatives ary1 len)); 13238 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13239 ins_cost(300); 13240 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13241 ins_encode %{ 13242 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13243 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13244 $tmp1$$Register, $tmp2$$Register); 13245 %} 13246 ins_pipe(pipe_class_default); 13247 %} 13248 13249 // encode char[] to byte[] in ISO_8859_1 13250 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13251 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13252 match(Set result (EncodeISOArray src (Binary dst len))); 13253 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13254 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13255 ins_cost(300); 13256 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13257 ins_encode %{ 13258 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13259 Label Lslow, Lfailure1, Lfailure2, Ldone; 13260 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13261 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13262 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13263 __ beq(CCR0, Ldone); 13264 __ bind(Lslow); 13265 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13266 __ li($result$$Register, 0); 13267 __ b(Ldone); 13268 13269 __ bind(Lfailure1); 13270 __ mr($result$$Register, $len$$Register); 13271 __ mfctr($tmp1$$Register); 13272 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13273 __ beq(CCR0, Ldone); 13274 __ b(Lslow); 13275 13276 __ bind(Lfailure2); 13277 __ mfctr($result$$Register); // Remaining characters. 13278 13279 __ bind(Ldone); 13280 __ subf($result$$Register, $result$$Register, $len$$Register); 13281 %} 13282 ins_pipe(pipe_class_default); 13283 %} 13284 13285 13286 //---------- Min/Max Instructions --------------------------------------------- 13287 13288 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13289 match(Set dst (MinI src1 src2)); 13290 ins_cost(DEFAULT_COST*6); 13291 13292 expand %{ 13293 iRegLdst src1s; 13294 iRegLdst src2s; 13295 iRegLdst diff; 13296 iRegLdst sm; 13297 iRegLdst doz; // difference or zero 13298 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13299 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13300 subL_reg_reg(diff, src2s, src1s); 13301 // Need to consider >=33 bit result, therefore we need signmaskL. 13302 signmask64L_regL(sm, diff); 13303 andL_reg_reg(doz, diff, sm); // <=0 13304 addI_regL_regL(dst, doz, src1s); 13305 %} 13306 %} 13307 13308 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13309 match(Set dst (MinI src1 src2)); 13310 effect(KILL cr0); 13311 predicate(VM_Version::has_isel()); 13312 ins_cost(DEFAULT_COST*2); 13313 13314 ins_encode %{ 13315 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13316 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13317 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13318 %} 13319 ins_pipe(pipe_class_default); 13320 %} 13321 13322 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13323 match(Set dst (MaxI src1 src2)); 13324 ins_cost(DEFAULT_COST*6); 13325 13326 expand %{ 13327 iRegLdst src1s; 13328 iRegLdst src2s; 13329 iRegLdst diff; 13330 iRegLdst sm; 13331 iRegLdst doz; // difference or zero 13332 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13333 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13334 subL_reg_reg(diff, src2s, src1s); 13335 // Need to consider >=33 bit result, therefore we need signmaskL. 13336 signmask64L_regL(sm, diff); 13337 andcL_reg_reg(doz, diff, sm); // >=0 13338 addI_regL_regL(dst, doz, src1s); 13339 %} 13340 %} 13341 13342 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13343 match(Set dst (MaxI src1 src2)); 13344 effect(KILL cr0); 13345 predicate(VM_Version::has_isel()); 13346 ins_cost(DEFAULT_COST*2); 13347 13348 ins_encode %{ 13349 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13350 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13351 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13352 %} 13353 ins_pipe(pipe_class_default); 13354 %} 13355 13356 //---------- Population Count Instructions ------------------------------------ 13357 13358 // Popcnt for Power7. 13359 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13360 match(Set dst (PopCountI src)); 13361 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13362 ins_cost(DEFAULT_COST); 13363 13364 format %{ "POPCNTW $dst, $src" %} 13365 size(4); 13366 ins_encode %{ 13367 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13368 __ popcntw($dst$$Register, $src$$Register); 13369 %} 13370 ins_pipe(pipe_class_default); 13371 %} 13372 13373 // Popcnt for Power7. 13374 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13375 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13376 match(Set dst (PopCountL src)); 13377 ins_cost(DEFAULT_COST); 13378 13379 format %{ "POPCNTD $dst, $src" %} 13380 size(4); 13381 ins_encode %{ 13382 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13383 __ popcntd($dst$$Register, $src$$Register); 13384 %} 13385 ins_pipe(pipe_class_default); 13386 %} 13387 13388 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13389 match(Set dst (CountLeadingZerosI src)); 13390 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13391 ins_cost(DEFAULT_COST); 13392 13393 format %{ "CNTLZW $dst, $src" %} 13394 size(4); 13395 ins_encode %{ 13396 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13397 __ cntlzw($dst$$Register, $src$$Register); 13398 %} 13399 ins_pipe(pipe_class_default); 13400 %} 13401 13402 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13403 match(Set dst (CountLeadingZerosL src)); 13404 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13405 ins_cost(DEFAULT_COST); 13406 13407 format %{ "CNTLZD $dst, $src" %} 13408 size(4); 13409 ins_encode %{ 13410 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13411 __ cntlzd($dst$$Register, $src$$Register); 13412 %} 13413 ins_pipe(pipe_class_default); 13414 %} 13415 13416 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13417 // no match-rule, false predicate 13418 effect(DEF dst, USE src); 13419 predicate(false); 13420 13421 format %{ "CNTLZD $dst, $src" %} 13422 size(4); 13423 ins_encode %{ 13424 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13425 __ cntlzd($dst$$Register, $src$$Register); 13426 %} 13427 ins_pipe(pipe_class_default); 13428 %} 13429 13430 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13431 match(Set dst (CountTrailingZerosI src)); 13432 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13433 ins_cost(DEFAULT_COST); 13434 13435 expand %{ 13436 immI16 imm1 %{ (int)-1 %} 13437 immI16 imm2 %{ (int)32 %} 13438 immI_minus1 m1 %{ -1 %} 13439 iRegIdst tmpI1; 13440 iRegIdst tmpI2; 13441 iRegIdst tmpI3; 13442 addI_reg_imm16(tmpI1, src, imm1); 13443 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13444 countLeadingZerosI(tmpI3, tmpI2); 13445 subI_imm16_reg(dst, imm2, tmpI3); 13446 %} 13447 %} 13448 13449 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{ 13450 match(Set dst (CountTrailingZerosI src)); 13451 predicate(UseCountTrailingZerosInstructionsPPC64); 13452 ins_cost(DEFAULT_COST); 13453 13454 format %{ "CNTTZW $dst, $src" %} 13455 size(4); 13456 ins_encode %{ 13457 __ cnttzw($dst$$Register, $src$$Register); 13458 %} 13459 ins_pipe(pipe_class_default); 13460 %} 13461 13462 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13463 match(Set dst (CountTrailingZerosL src)); 13464 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13465 ins_cost(DEFAULT_COST); 13466 13467 expand %{ 13468 immL16 imm1 %{ (long)-1 %} 13469 immI16 imm2 %{ (int)64 %} 13470 iRegLdst tmpL1; 13471 iRegLdst tmpL2; 13472 iRegIdst tmpL3; 13473 addL_reg_imm16(tmpL1, src, imm1); 13474 andcL_reg_reg(tmpL2, tmpL1, src); 13475 countLeadingZerosL(tmpL3, tmpL2); 13476 subI_imm16_reg(dst, imm2, tmpL3); 13477 %} 13478 %} 13479 13480 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{ 13481 match(Set dst (CountTrailingZerosL src)); 13482 predicate(UseCountTrailingZerosInstructionsPPC64); 13483 ins_cost(DEFAULT_COST); 13484 13485 format %{ "CNTTZD $dst, $src" %} 13486 size(4); 13487 ins_encode %{ 13488 __ cnttzd($dst$$Register, $src$$Register); 13489 %} 13490 ins_pipe(pipe_class_default); 13491 %} 13492 13493 // Expand nodes for byte_reverse_int. 13494 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13495 effect(DEF dst, USE src, USE pos, USE shift); 13496 predicate(false); 13497 13498 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13499 size(4); 13500 ins_encode %{ 13501 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13502 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13503 %} 13504 ins_pipe(pipe_class_default); 13505 %} 13506 13507 // As insrwi_a, but with USE_DEF. 13508 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13509 effect(USE_DEF dst, USE src, USE pos, USE shift); 13510 predicate(false); 13511 13512 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13513 size(4); 13514 ins_encode %{ 13515 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13516 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13517 %} 13518 ins_pipe(pipe_class_default); 13519 %} 13520 13521 // Just slightly faster than java implementation. 13522 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13523 match(Set dst (ReverseBytesI src)); 13524 ins_cost(7*DEFAULT_COST); 13525 13526 expand %{ 13527 immI16 imm24 %{ (int) 24 %} 13528 immI16 imm16 %{ (int) 16 %} 13529 immI16 imm8 %{ (int) 8 %} 13530 immI16 imm4 %{ (int) 4 %} 13531 immI16 imm0 %{ (int) 0 %} 13532 iRegLdst tmpI1; 13533 iRegLdst tmpI2; 13534 iRegLdst tmpI3; 13535 13536 urShiftI_reg_imm(tmpI1, src, imm24); 13537 insrwi_a(dst, tmpI1, imm24, imm8); 13538 urShiftI_reg_imm(tmpI2, src, imm16); 13539 insrwi(dst, tmpI2, imm8, imm16); 13540 urShiftI_reg_imm(tmpI3, src, imm8); 13541 insrwi(dst, tmpI3, imm8, imm8); 13542 insrwi(dst, src, imm0, imm8); 13543 %} 13544 %} 13545 13546 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13547 match(Set dst (ReverseBytesL src)); 13548 ins_cost(15*DEFAULT_COST); 13549 13550 expand %{ 13551 immI16 imm56 %{ (int) 56 %} 13552 immI16 imm48 %{ (int) 48 %} 13553 immI16 imm40 %{ (int) 40 %} 13554 immI16 imm32 %{ (int) 32 %} 13555 immI16 imm24 %{ (int) 24 %} 13556 immI16 imm16 %{ (int) 16 %} 13557 immI16 imm8 %{ (int) 8 %} 13558 immI16 imm0 %{ (int) 0 %} 13559 iRegLdst tmpL1; 13560 iRegLdst tmpL2; 13561 iRegLdst tmpL3; 13562 iRegLdst tmpL4; 13563 iRegLdst tmpL5; 13564 iRegLdst tmpL6; 13565 13566 // src : |a|b|c|d|e|f|g|h| 13567 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13568 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13569 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13570 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13571 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13572 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13573 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13574 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13575 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13576 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13577 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13578 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13579 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13580 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13581 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13582 %} 13583 %} 13584 13585 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13586 match(Set dst (ReverseBytesUS src)); 13587 ins_cost(2*DEFAULT_COST); 13588 13589 expand %{ 13590 immI16 imm16 %{ (int) 16 %} 13591 immI16 imm8 %{ (int) 8 %} 13592 13593 urShiftI_reg_imm(dst, src, imm8); 13594 insrwi(dst, src, imm16, imm8); 13595 %} 13596 %} 13597 13598 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13599 match(Set dst (ReverseBytesS src)); 13600 ins_cost(3*DEFAULT_COST); 13601 13602 expand %{ 13603 immI16 imm16 %{ (int) 16 %} 13604 immI16 imm8 %{ (int) 8 %} 13605 iRegLdst tmpI1; 13606 13607 urShiftI_reg_imm(tmpI1, src, imm8); 13608 insrwi(tmpI1, src, imm16, imm8); 13609 extsh(dst, tmpI1); 13610 %} 13611 %} 13612 13613 // Load Integer reversed byte order 13614 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13615 match(Set dst (ReverseBytesI (LoadI mem))); 13616 ins_cost(MEMORY_REF_COST); 13617 13618 size(4); 13619 ins_encode %{ 13620 __ lwbrx($dst$$Register, $mem$$Register); 13621 %} 13622 ins_pipe(pipe_class_default); 13623 %} 13624 13625 // Load Long - aligned and reversed 13626 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13627 match(Set dst (ReverseBytesL (LoadL mem))); 13628 predicate(VM_Version::has_ldbrx()); 13629 ins_cost(MEMORY_REF_COST); 13630 13631 size(4); 13632 ins_encode %{ 13633 __ ldbrx($dst$$Register, $mem$$Register); 13634 %} 13635 ins_pipe(pipe_class_default); 13636 %} 13637 13638 // Load unsigned short / char reversed byte order 13639 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13640 match(Set dst (ReverseBytesUS (LoadUS mem))); 13641 ins_cost(MEMORY_REF_COST); 13642 13643 size(4); 13644 ins_encode %{ 13645 __ lhbrx($dst$$Register, $mem$$Register); 13646 %} 13647 ins_pipe(pipe_class_default); 13648 %} 13649 13650 // Load short reversed byte order 13651 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13652 match(Set dst (ReverseBytesS (LoadS mem))); 13653 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13654 13655 size(8); 13656 ins_encode %{ 13657 __ lhbrx($dst$$Register, $mem$$Register); 13658 __ extsh($dst$$Register, $dst$$Register); 13659 %} 13660 ins_pipe(pipe_class_default); 13661 %} 13662 13663 // Store Integer reversed byte order 13664 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13665 match(Set mem (StoreI mem (ReverseBytesI src))); 13666 ins_cost(MEMORY_REF_COST); 13667 13668 size(4); 13669 ins_encode %{ 13670 __ stwbrx($src$$Register, $mem$$Register); 13671 %} 13672 ins_pipe(pipe_class_default); 13673 %} 13674 13675 // Store Long reversed byte order 13676 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13677 match(Set mem (StoreL mem (ReverseBytesL src))); 13678 predicate(VM_Version::has_stdbrx()); 13679 ins_cost(MEMORY_REF_COST); 13680 13681 size(4); 13682 ins_encode %{ 13683 __ stdbrx($src$$Register, $mem$$Register); 13684 %} 13685 ins_pipe(pipe_class_default); 13686 %} 13687 13688 // Store unsigned short / char reversed byte order 13689 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13690 match(Set mem (StoreC mem (ReverseBytesUS src))); 13691 ins_cost(MEMORY_REF_COST); 13692 13693 size(4); 13694 ins_encode %{ 13695 __ sthbrx($src$$Register, $mem$$Register); 13696 %} 13697 ins_pipe(pipe_class_default); 13698 %} 13699 13700 // Store short reversed byte order 13701 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13702 match(Set mem (StoreC mem (ReverseBytesS src))); 13703 ins_cost(MEMORY_REF_COST); 13704 13705 size(4); 13706 ins_encode %{ 13707 __ sthbrx($src$$Register, $mem$$Register); 13708 %} 13709 ins_pipe(pipe_class_default); 13710 %} 13711 13712 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13713 effect(DEF temp1, USE src); 13714 13715 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %} 13716 size(4); 13717 ins_encode %{ 13718 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13719 %} 13720 ins_pipe(pipe_class_default); 13721 %} 13722 13723 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13724 effect(DEF dst, USE src, USE imm1); 13725 13726 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %} 13727 size(4); 13728 ins_encode %{ 13729 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13730 %} 13731 ins_pipe(pipe_class_default); 13732 %} 13733 13734 instruct xscvdpspn_regF(vecX dst, regF src) %{ 13735 effect(DEF dst, USE src); 13736 13737 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %} 13738 size(4); 13739 ins_encode %{ 13740 __ xscvdpspn($dst$$VectorSRegister, $src$$FloatRegister->to_vsr()); 13741 %} 13742 ins_pipe(pipe_class_default); 13743 %} 13744 13745 //---------- Replicate Vector Instructions ------------------------------------ 13746 13747 // Insrdi does replicate if src == dst. 13748 instruct repl32(iRegLdst dst) %{ 13749 predicate(false); 13750 effect(USE_DEF dst); 13751 13752 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13753 size(4); 13754 ins_encode %{ 13755 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13756 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13757 %} 13758 ins_pipe(pipe_class_default); 13759 %} 13760 13761 // Insrdi does replicate if src == dst. 13762 instruct repl48(iRegLdst dst) %{ 13763 predicate(false); 13764 effect(USE_DEF dst); 13765 13766 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13767 size(4); 13768 ins_encode %{ 13769 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13770 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13771 %} 13772 ins_pipe(pipe_class_default); 13773 %} 13774 13775 // Insrdi does replicate if src == dst. 13776 instruct repl56(iRegLdst dst) %{ 13777 predicate(false); 13778 effect(USE_DEF dst); 13779 13780 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13781 size(4); 13782 ins_encode %{ 13783 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13784 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 13785 %} 13786 ins_pipe(pipe_class_default); 13787 %} 13788 13789 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13790 match(Set dst (ReplicateB src)); 13791 predicate(n->as_Vector()->length() == 8); 13792 expand %{ 13793 moveReg(dst, src); 13794 repl56(dst); 13795 repl48(dst); 13796 repl32(dst); 13797 %} 13798 %} 13799 13800 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 13801 match(Set dst (ReplicateB zero)); 13802 predicate(n->as_Vector()->length() == 8); 13803 format %{ "LI $dst, #0 \t// replicate8B" %} 13804 size(4); 13805 ins_encode %{ 13806 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13807 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13808 %} 13809 ins_pipe(pipe_class_default); 13810 %} 13811 13812 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13813 match(Set dst (ReplicateB src)); 13814 predicate(n->as_Vector()->length() == 8); 13815 format %{ "LI $dst, #-1 \t// replicate8B" %} 13816 size(4); 13817 ins_encode %{ 13818 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13819 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13820 %} 13821 ins_pipe(pipe_class_default); 13822 %} 13823 13824 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 13825 match(Set dst (ReplicateB src)); 13826 predicate(n->as_Vector()->length() == 16); 13827 13828 expand %{ 13829 iRegLdst tmpL; 13830 vecX tmpV; 13831 immI8 imm1 %{ (int) 1 %} 13832 moveReg(tmpL, src); 13833 repl56(tmpL); 13834 repl48(tmpL); 13835 mtvsrwz(tmpV, tmpL); 13836 xxspltw(dst, tmpV, imm1); 13837 %} 13838 %} 13839 13840 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 13841 match(Set dst (ReplicateB zero)); 13842 predicate(n->as_Vector()->length() == 16); 13843 13844 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 13845 size(4); 13846 ins_encode %{ 13847 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13848 %} 13849 ins_pipe(pipe_class_default); 13850 %} 13851 13852 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 13853 match(Set dst (ReplicateB src)); 13854 predicate(n->as_Vector()->length() == 16); 13855 13856 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13857 size(4); 13858 ins_encode %{ 13859 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13860 %} 13861 ins_pipe(pipe_class_default); 13862 %} 13863 13864 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13865 match(Set dst (ReplicateS src)); 13866 predicate(n->as_Vector()->length() == 4); 13867 expand %{ 13868 moveReg(dst, src); 13869 repl48(dst); 13870 repl32(dst); 13871 %} 13872 %} 13873 13874 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 13875 match(Set dst (ReplicateS zero)); 13876 predicate(n->as_Vector()->length() == 4); 13877 format %{ "LI $dst, #0 \t// replicate4C" %} 13878 size(4); 13879 ins_encode %{ 13880 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13881 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13882 %} 13883 ins_pipe(pipe_class_default); 13884 %} 13885 13886 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13887 match(Set dst (ReplicateS src)); 13888 predicate(n->as_Vector()->length() == 4); 13889 format %{ "LI $dst, -1 \t// replicate4C" %} 13890 size(4); 13891 ins_encode %{ 13892 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13893 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13894 %} 13895 ins_pipe(pipe_class_default); 13896 %} 13897 13898 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 13899 match(Set dst (ReplicateS src)); 13900 predicate(n->as_Vector()->length() == 8); 13901 13902 expand %{ 13903 iRegLdst tmpL; 13904 vecX tmpV; 13905 immI8 zero %{ (int) 0 %} 13906 moveReg(tmpL, src); 13907 repl48(tmpL); 13908 repl32(tmpL); 13909 mtvsrd(tmpV, tmpL); 13910 xxpermdi(dst, tmpV, tmpV, zero); 13911 %} 13912 %} 13913 13914 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 13915 match(Set dst (ReplicateS zero)); 13916 predicate(n->as_Vector()->length() == 8); 13917 13918 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 13919 size(4); 13920 ins_encode %{ 13921 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13922 %} 13923 ins_pipe(pipe_class_default); 13924 %} 13925 13926 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 13927 match(Set dst (ReplicateS src)); 13928 predicate(n->as_Vector()->length() == 8); 13929 13930 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13931 size(4); 13932 ins_encode %{ 13933 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13934 %} 13935 ins_pipe(pipe_class_default); 13936 %} 13937 13938 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13939 match(Set dst (ReplicateI src)); 13940 predicate(n->as_Vector()->length() == 2); 13941 ins_cost(2 * DEFAULT_COST); 13942 expand %{ 13943 moveReg(dst, src); 13944 repl32(dst); 13945 %} 13946 %} 13947 13948 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 13949 match(Set dst (ReplicateI zero)); 13950 predicate(n->as_Vector()->length() == 2); 13951 format %{ "LI $dst, #0 \t// replicate4C" %} 13952 size(4); 13953 ins_encode %{ 13954 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13955 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13956 %} 13957 ins_pipe(pipe_class_default); 13958 %} 13959 13960 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13961 match(Set dst (ReplicateI src)); 13962 predicate(n->as_Vector()->length() == 2); 13963 format %{ "LI $dst, -1 \t// replicate4C" %} 13964 size(4); 13965 ins_encode %{ 13966 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13967 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13968 %} 13969 ins_pipe(pipe_class_default); 13970 %} 13971 13972 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 13973 match(Set dst (ReplicateI src)); 13974 predicate(n->as_Vector()->length() == 4); 13975 ins_cost(2 * DEFAULT_COST); 13976 13977 expand %{ 13978 iRegLdst tmpL; 13979 vecX tmpV; 13980 immI8 zero %{ (int) 0 %} 13981 moveReg(tmpL, src); 13982 repl32(tmpL); 13983 mtvsrd(tmpV, tmpL); 13984 xxpermdi(dst, tmpV, tmpV, zero); 13985 %} 13986 %} 13987 13988 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 13989 match(Set dst (ReplicateI zero)); 13990 predicate(n->as_Vector()->length() == 4); 13991 13992 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 13993 size(4); 13994 ins_encode %{ 13995 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13996 %} 13997 ins_pipe(pipe_class_default); 13998 %} 13999 14000 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 14001 match(Set dst (ReplicateI src)); 14002 predicate(n->as_Vector()->length() == 4); 14003 14004 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 14005 size(4); 14006 ins_encode %{ 14007 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14008 %} 14009 ins_pipe(pipe_class_default); 14010 %} 14011 14012 // Move float to int register via stack, replicate. 14013 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 14014 match(Set dst (ReplicateF src)); 14015 predicate(n->as_Vector()->length() == 2); 14016 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14017 expand %{ 14018 stackSlotL tmpS; 14019 iRegIdst tmpI; 14020 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14021 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14022 moveReg(dst, tmpI); // Move int to long reg. 14023 repl32(dst); // Replicate bitpattern. 14024 %} 14025 %} 14026 14027 // Replicate scalar constant to packed float values in Double register 14028 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 14029 match(Set dst (ReplicateF src)); 14030 predicate(n->as_Vector()->length() == 2); 14031 ins_cost(5 * DEFAULT_COST); 14032 14033 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 14034 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 14035 %} 14036 14037 // Replicate scalar zero constant to packed float values in Double register 14038 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 14039 match(Set dst (ReplicateF zero)); 14040 predicate(n->as_Vector()->length() == 2); 14041 14042 format %{ "LI $dst, #0 \t// replicate2F" %} 14043 ins_encode %{ 14044 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14045 __ li($dst$$Register, 0x0); 14046 %} 14047 ins_pipe(pipe_class_default); 14048 %} 14049 14050 14051 //----------Vector Arithmetic Instructions-------------------------------------- 14052 14053 // Vector Addition Instructions 14054 14055 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{ 14056 match(Set dst (AddVB src1 src2)); 14057 predicate(n->as_Vector()->length() == 16); 14058 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %} 14059 size(4); 14060 ins_encode %{ 14061 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14062 %} 14063 ins_pipe(pipe_class_default); 14064 %} 14065 14066 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{ 14067 match(Set dst (AddVS src1 src2)); 14068 predicate(n->as_Vector()->length() == 8); 14069 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %} 14070 size(4); 14071 ins_encode %{ 14072 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14073 %} 14074 ins_pipe(pipe_class_default); 14075 %} 14076 14077 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{ 14078 match(Set dst (AddVI src1 src2)); 14079 predicate(n->as_Vector()->length() == 4); 14080 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %} 14081 size(4); 14082 ins_encode %{ 14083 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14084 %} 14085 ins_pipe(pipe_class_default); 14086 %} 14087 14088 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{ 14089 match(Set dst (AddVF src1 src2)); 14090 predicate(n->as_Vector()->length() == 4); 14091 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %} 14092 size(4); 14093 ins_encode %{ 14094 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14095 %} 14096 ins_pipe(pipe_class_default); 14097 %} 14098 14099 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{ 14100 match(Set dst (AddVL src1 src2)); 14101 predicate(n->as_Vector()->length() == 2); 14102 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %} 14103 size(4); 14104 ins_encode %{ 14105 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14106 %} 14107 ins_pipe(pipe_class_default); 14108 %} 14109 14110 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{ 14111 match(Set dst (AddVD src1 src2)); 14112 predicate(n->as_Vector()->length() == 2); 14113 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %} 14114 size(4); 14115 ins_encode %{ 14116 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14117 %} 14118 ins_pipe(pipe_class_default); 14119 %} 14120 14121 // Vector Subtraction Instructions 14122 14123 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{ 14124 match(Set dst (SubVB src1 src2)); 14125 predicate(n->as_Vector()->length() == 16); 14126 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %} 14127 size(4); 14128 ins_encode %{ 14129 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14130 %} 14131 ins_pipe(pipe_class_default); 14132 %} 14133 14134 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{ 14135 match(Set dst (SubVS src1 src2)); 14136 predicate(n->as_Vector()->length() == 8); 14137 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %} 14138 size(4); 14139 ins_encode %{ 14140 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14141 %} 14142 ins_pipe(pipe_class_default); 14143 %} 14144 14145 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{ 14146 match(Set dst (SubVI src1 src2)); 14147 predicate(n->as_Vector()->length() == 4); 14148 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %} 14149 size(4); 14150 ins_encode %{ 14151 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14152 %} 14153 ins_pipe(pipe_class_default); 14154 %} 14155 14156 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{ 14157 match(Set dst (SubVF src1 src2)); 14158 predicate(n->as_Vector()->length() == 4); 14159 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %} 14160 size(4); 14161 ins_encode %{ 14162 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14163 %} 14164 ins_pipe(pipe_class_default); 14165 %} 14166 14167 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{ 14168 match(Set dst (SubVL src1 src2)); 14169 predicate(n->as_Vector()->length() == 2); 14170 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %} 14171 size(4); 14172 ins_encode %{ 14173 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14174 %} 14175 ins_pipe(pipe_class_default); 14176 %} 14177 14178 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{ 14179 match(Set dst (SubVD src1 src2)); 14180 predicate(n->as_Vector()->length() == 2); 14181 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %} 14182 size(4); 14183 ins_encode %{ 14184 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14185 %} 14186 ins_pipe(pipe_class_default); 14187 %} 14188 14189 // Vector Multiplication Instructions 14190 14191 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 14192 match(Set dst (MulVS src1 src2)); 14193 predicate(n->as_Vector()->length() == 8); 14194 effect(TEMP tmp); 14195 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %} 14196 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %} 14197 size(8); 14198 ins_encode %{ 14199 __ vspltish($tmp$$VectorSRegister->to_vr(), 0); 14200 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr()); 14201 %} 14202 ins_pipe(pipe_class_default); 14203 %} 14204 14205 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{ 14206 match(Set dst (MulVI src1 src2)); 14207 predicate(n->as_Vector()->length() == 4); 14208 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %} 14209 size(4); 14210 ins_encode %{ 14211 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14212 %} 14213 ins_pipe(pipe_class_default); 14214 %} 14215 14216 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{ 14217 match(Set dst (MulVF src1 src2)); 14218 predicate(n->as_Vector()->length() == 4); 14219 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %} 14220 size(4); 14221 ins_encode %{ 14222 __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14223 %} 14224 ins_pipe(pipe_class_default); 14225 %} 14226 14227 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{ 14228 match(Set dst (MulVD src1 src2)); 14229 predicate(n->as_Vector()->length() == 2); 14230 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %} 14231 size(4); 14232 ins_encode %{ 14233 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14234 %} 14235 ins_pipe(pipe_class_default); 14236 %} 14237 14238 // Vector Division Instructions 14239 14240 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{ 14241 match(Set dst (DivVF src1 src2)); 14242 predicate(n->as_Vector()->length() == 4); 14243 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %} 14244 size(4); 14245 ins_encode %{ 14246 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14247 %} 14248 ins_pipe(pipe_class_default); 14249 %} 14250 14251 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ 14252 match(Set dst (DivVD src1 src2)); 14253 predicate(n->as_Vector()->length() == 2); 14254 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %} 14255 size(4); 14256 ins_encode %{ 14257 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14258 %} 14259 ins_pipe(pipe_class_default); 14260 %} 14261 14262 // Vector Absolute Instructions 14263 14264 instruct vabs4F_reg(vecX dst, vecX src) %{ 14265 match(Set dst (AbsVF src)); 14266 predicate(n->as_Vector()->length() == 4); 14267 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %} 14268 size(4); 14269 ins_encode %{ 14270 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister); 14271 %} 14272 ins_pipe(pipe_class_default); 14273 %} 14274 14275 instruct vabs2D_reg(vecX dst, vecX src) %{ 14276 match(Set dst (AbsVD src)); 14277 predicate(n->as_Vector()->length() == 2); 14278 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %} 14279 size(4); 14280 ins_encode %{ 14281 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister); 14282 %} 14283 ins_pipe(pipe_class_default); 14284 %} 14285 14286 // Vector Negate Instructions 14287 14288 instruct vneg4F_reg(vecX dst, vecX src) %{ 14289 match(Set dst (NegVF src)); 14290 predicate(n->as_Vector()->length() == 4); 14291 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %} 14292 size(4); 14293 ins_encode %{ 14294 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister); 14295 %} 14296 ins_pipe(pipe_class_default); 14297 %} 14298 14299 instruct vneg2D_reg(vecX dst, vecX src) %{ 14300 match(Set dst (NegVD src)); 14301 predicate(n->as_Vector()->length() == 2); 14302 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %} 14303 size(4); 14304 ins_encode %{ 14305 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister); 14306 %} 14307 ins_pipe(pipe_class_default); 14308 %} 14309 14310 // Vector Square Root Instructions 14311 14312 instruct vsqrt4F_reg(vecX dst, vecX src) %{ 14313 match(Set dst (SqrtVF src)); 14314 predicate(n->as_Vector()->length() == 4); 14315 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %} 14316 size(4); 14317 ins_encode %{ 14318 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister); 14319 %} 14320 ins_pipe(pipe_class_default); 14321 %} 14322 14323 instruct vsqrt2D_reg(vecX dst, vecX src) %{ 14324 match(Set dst (SqrtVD src)); 14325 predicate(n->as_Vector()->length() == 2); 14326 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %} 14327 size(4); 14328 ins_encode %{ 14329 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister); 14330 %} 14331 ins_pipe(pipe_class_default); 14332 %} 14333 14334 // Vector Population Count Instructions 14335 14336 instruct vpopcnt4I_reg(vecX dst, vecX src) %{ 14337 match(Set dst (PopCountVI src)); 14338 predicate(n->as_Vector()->length() == 4); 14339 format %{ "VPOPCNTW $dst,$src\t// pop count packed4I" %} 14340 size(4); 14341 ins_encode %{ 14342 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14343 %} 14344 ins_pipe(pipe_class_default); 14345 %} 14346 14347 14348 //----------Overflow Math Instructions----------------------------------------- 14349 14350 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 14351 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14352 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14353 14354 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14355 match(Set cr0 (OverflowAddL op1 op2)); 14356 14357 format %{ "add_ $op1, $op2\t# overflow check long" %} 14358 ins_encode %{ 14359 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14360 __ li(R0, 0); 14361 __ mtxer(R0); // clear XER.SO 14362 __ addo_(R0, $op1$$Register, $op2$$Register); 14363 %} 14364 ins_pipe(pipe_class_default); 14365 %} 14366 14367 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14368 match(Set cr0 (OverflowSubL op1 op2)); 14369 14370 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14371 ins_encode %{ 14372 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14373 __ li(R0, 0); 14374 __ mtxer(R0); // clear XER.SO 14375 __ subfo_(R0, $op2$$Register, $op1$$Register); 14376 %} 14377 ins_pipe(pipe_class_default); 14378 %} 14379 14380 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14381 match(Set cr0 (OverflowSubL zero op2)); 14382 14383 format %{ "nego_ R0, $op2\t# overflow check long" %} 14384 ins_encode %{ 14385 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14386 __ li(R0, 0); 14387 __ mtxer(R0); // clear XER.SO 14388 __ nego_(R0, $op2$$Register); 14389 %} 14390 ins_pipe(pipe_class_default); 14391 %} 14392 14393 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14394 match(Set cr0 (OverflowMulL op1 op2)); 14395 14396 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14397 ins_encode %{ 14398 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14399 __ li(R0, 0); 14400 __ mtxer(R0); // clear XER.SO 14401 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14402 %} 14403 ins_pipe(pipe_class_default); 14404 %} 14405 14406 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14407 match(Set dst (ReplicateF src)); 14408 predicate(n->as_Vector()->length() == 4); 14409 ins_cost(DEFAULT_COST); 14410 expand %{ 14411 vecX tmpV; 14412 immI8 zero %{ (int) 0 %} 14413 14414 xscvdpspn_regF(tmpV, src); 14415 xxspltw(dst, tmpV, zero); 14416 %} 14417 %} 14418 14419 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14420 match(Set dst (ReplicateF src)); 14421 predicate(n->as_Vector()->length() == 4); 14422 effect(TEMP tmp); 14423 ins_cost(10 * DEFAULT_COST); 14424 14425 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14426 %} 14427 14428 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14429 match(Set dst (ReplicateF zero)); 14430 predicate(n->as_Vector()->length() == 4); 14431 14432 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14433 ins_encode %{ 14434 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14435 %} 14436 ins_pipe(pipe_class_default); 14437 %} 14438 14439 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14440 match(Set dst (ReplicateD src)); 14441 predicate(n->as_Vector()->length() == 2); 14442 14443 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %} 14444 size(4); 14445 ins_encode %{ 14446 __ xxpermdi($dst$$VectorSRegister, $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0); 14447 %} 14448 ins_pipe(pipe_class_default); 14449 %} 14450 14451 instruct repl2D_immI0(vecX dst, immI_0 zero) %{ 14452 match(Set dst (ReplicateD zero)); 14453 predicate(n->as_Vector()->length() == 2); 14454 14455 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14456 size(4); 14457 ins_encode %{ 14458 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14459 %} 14460 ins_pipe(pipe_class_default); 14461 %} 14462 14463 instruct repl2D_immIminus1(vecX dst, immI_minus1 src) %{ 14464 match(Set dst (ReplicateD src)); 14465 predicate(n->as_Vector()->length() == 2); 14466 14467 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14468 size(4); 14469 ins_encode %{ 14470 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14471 %} 14472 ins_pipe(pipe_class_default); 14473 %} 14474 14475 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14476 predicate(false); 14477 effect(DEF dst, USE src); 14478 14479 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %} 14480 size(4); 14481 ins_encode %{ 14482 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14483 %} 14484 ins_pipe(pipe_class_default); 14485 %} 14486 14487 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14488 effect(DEF dst, USE src, USE zero); 14489 14490 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %} 14491 size(4); 14492 ins_encode %{ 14493 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14494 %} 14495 ins_pipe(pipe_class_default); 14496 %} 14497 14498 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14499 effect(DEF dst, USE src1, USE src2, USE zero); 14500 14501 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %} 14502 size(4); 14503 ins_encode %{ 14504 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14505 %} 14506 ins_pipe(pipe_class_default); 14507 %} 14508 14509 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14510 match(Set dst (ReplicateL src)); 14511 predicate(n->as_Vector()->length() == 2); 14512 expand %{ 14513 vecX tmpV; 14514 immI8 zero %{ (int) 0 %} 14515 mtvsrd(tmpV, src); 14516 xxpermdi(dst, tmpV, tmpV, zero); 14517 %} 14518 %} 14519 14520 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14521 match(Set dst (ReplicateL zero)); 14522 predicate(n->as_Vector()->length() == 2); 14523 14524 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14525 size(4); 14526 ins_encode %{ 14527 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14528 %} 14529 ins_pipe(pipe_class_default); 14530 %} 14531 14532 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14533 match(Set dst (ReplicateL src)); 14534 predicate(n->as_Vector()->length() == 2); 14535 14536 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14537 size(4); 14538 ins_encode %{ 14539 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14540 %} 14541 ins_pipe(pipe_class_default); 14542 %} 14543 14544 // ============================================================================ 14545 // Safepoint Instruction 14546 14547 instruct safePoint_poll(iRegPdst poll) %{ 14548 match(SafePoint poll); 14549 14550 // It caused problems to add the effect that r0 is killed, but this 14551 // effect no longer needs to be mentioned, since r0 is not contained 14552 // in a reg_class. 14553 14554 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14555 size(4); 14556 ins_encode( enc_poll(0x0, poll) ); 14557 ins_pipe(pipe_class_default); 14558 %} 14559 14560 // ============================================================================ 14561 // Call Instructions 14562 14563 // Call Java Static Instruction 14564 14565 // Schedulable version of call static node. 14566 instruct CallStaticJavaDirect(method meth) %{ 14567 match(CallStaticJava); 14568 effect(USE meth); 14569 ins_cost(CALL_COST); 14570 14571 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14572 14573 format %{ "CALL,static $meth \t// ==> " %} 14574 size(4); 14575 ins_encode( enc_java_static_call(meth) ); 14576 ins_pipe(pipe_class_call); 14577 %} 14578 14579 // Call Java Dynamic Instruction 14580 14581 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14582 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14583 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14584 // The call destination must still be placed in the constant pool. 14585 instruct CallDynamicJavaDirectSched(method meth) %{ 14586 match(CallDynamicJava); // To get all the data fields we need ... 14587 effect(USE meth); 14588 predicate(false); // ... but never match. 14589 14590 ins_field_load_ic_hi_node(loadConL_hiNode*); 14591 ins_field_load_ic_node(loadConLNode*); 14592 ins_num_consts(1 /* 1 patchable constant: call destination */); 14593 14594 format %{ "BL \t// dynamic $meth ==> " %} 14595 size(4); 14596 ins_encode( enc_java_dynamic_call_sched(meth) ); 14597 ins_pipe(pipe_class_call); 14598 %} 14599 14600 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14601 // We use postalloc expanded calls if we use inline caches 14602 // and do not update method data. 14603 // 14604 // This instruction has two constants: inline cache (IC) and call destination. 14605 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14606 // one constant. 14607 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14608 match(CallDynamicJava); 14609 effect(USE meth); 14610 predicate(UseInlineCaches); 14611 ins_cost(CALL_COST); 14612 14613 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14614 14615 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14616 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14617 %} 14618 14619 // Compound version of call dynamic java 14620 // We use postalloc expanded calls if we use inline caches 14621 // and do not update method data. 14622 instruct CallDynamicJavaDirect(method meth) %{ 14623 match(CallDynamicJava); 14624 effect(USE meth); 14625 predicate(!UseInlineCaches); 14626 ins_cost(CALL_COST); 14627 14628 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14629 ins_num_consts(4); 14630 14631 format %{ "CALL,dynamic $meth \t// ==> " %} 14632 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14633 ins_pipe(pipe_class_call); 14634 %} 14635 14636 // Call Runtime Instruction 14637 14638 instruct CallRuntimeDirect(method meth) %{ 14639 match(CallRuntime); 14640 effect(USE meth); 14641 ins_cost(CALL_COST); 14642 14643 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14644 // env for callee, C-toc. 14645 ins_num_consts(3); 14646 14647 format %{ "CALL,runtime" %} 14648 ins_encode( enc_java_to_runtime_call(meth) ); 14649 ins_pipe(pipe_class_call); 14650 %} 14651 14652 // Call Leaf 14653 14654 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14655 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14656 effect(DEF dst, USE src); 14657 14658 ins_num_consts(1); 14659 14660 format %{ "MTCTR $src" %} 14661 size(4); 14662 ins_encode( enc_leaf_call_mtctr(src) ); 14663 ins_pipe(pipe_class_default); 14664 %} 14665 14666 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 14667 instruct CallLeafDirect(method meth) %{ 14668 match(CallLeaf); // To get the data all the data fields we need ... 14669 effect(USE meth); 14670 predicate(false); // but never match. 14671 14672 format %{ "BCTRL \t// leaf call $meth ==> " %} 14673 size(4); 14674 ins_encode %{ 14675 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 14676 __ bctrl(); 14677 %} 14678 ins_pipe(pipe_class_call); 14679 %} 14680 14681 // postalloc expand of CallLeafDirect. 14682 // Load adress to call from TOC, then bl to it. 14683 instruct CallLeafDirect_Ex(method meth) %{ 14684 match(CallLeaf); 14685 effect(USE meth); 14686 ins_cost(CALL_COST); 14687 14688 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14689 // env for callee, C-toc. 14690 ins_num_consts(3); 14691 14692 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14693 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14694 %} 14695 14696 // Call runtime without safepoint - same as CallLeaf. 14697 // postalloc expand of CallLeafNoFPDirect. 14698 // Load adress to call from TOC, then bl to it. 14699 instruct CallLeafNoFPDirect_Ex(method meth) %{ 14700 match(CallLeafNoFP); 14701 effect(USE meth); 14702 ins_cost(CALL_COST); 14703 14704 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14705 // env for callee, C-toc. 14706 ins_num_consts(3); 14707 14708 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14709 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14710 %} 14711 14712 // Tail Call; Jump from runtime stub to Java code. 14713 // Also known as an 'interprocedural jump'. 14714 // Target of jump will eventually return to caller. 14715 // TailJump below removes the return address. 14716 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 14717 match(TailCall jump_target method_oop); 14718 ins_cost(CALL_COST); 14719 14720 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 14721 "BCTR \t// tail call" %} 14722 size(8); 14723 ins_encode %{ 14724 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14725 __ mtctr($jump_target$$Register); 14726 __ bctr(); 14727 %} 14728 ins_pipe(pipe_class_call); 14729 %} 14730 14731 // Return Instruction 14732 instruct Ret() %{ 14733 match(Return); 14734 format %{ "BLR \t// branch to link register" %} 14735 size(4); 14736 ins_encode %{ 14737 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 14738 // LR is restored in MachEpilogNode. Just do the RET here. 14739 __ blr(); 14740 %} 14741 ins_pipe(pipe_class_default); 14742 %} 14743 14744 // Tail Jump; remove the return address; jump to target. 14745 // TailCall above leaves the return address around. 14746 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14747 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14748 // "restore" before this instruction (in Epilogue), we need to materialize it 14749 // in %i0. 14750 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14751 match(TailJump jump_target ex_oop); 14752 ins_cost(CALL_COST); 14753 14754 format %{ "LD R4_ARG2 = LR\n\t" 14755 "MTCTR $jump_target\n\t" 14756 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14757 size(12); 14758 ins_encode %{ 14759 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14760 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 14761 __ mtctr($jump_target$$Register); 14762 __ bctr(); 14763 %} 14764 ins_pipe(pipe_class_call); 14765 %} 14766 14767 // Create exception oop: created by stack-crawling runtime code. 14768 // Created exception is now available to this handler, and is setup 14769 // just prior to jumping to this handler. No code emitted. 14770 instruct CreateException(rarg1RegP ex_oop) %{ 14771 match(Set ex_oop (CreateEx)); 14772 ins_cost(0); 14773 14774 format %{ " -- \t// exception oop; no code emitted" %} 14775 size(0); 14776 ins_encode( /*empty*/ ); 14777 ins_pipe(pipe_class_default); 14778 %} 14779 14780 // Rethrow exception: The exception oop will come in the first 14781 // argument position. Then JUMP (not call) to the rethrow stub code. 14782 instruct RethrowException() %{ 14783 match(Rethrow); 14784 ins_cost(CALL_COST); 14785 14786 format %{ "Jmp rethrow_stub" %} 14787 ins_encode %{ 14788 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14789 cbuf.set_insts_mark(); 14790 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 14791 %} 14792 ins_pipe(pipe_class_call); 14793 %} 14794 14795 // Die now. 14796 instruct ShouldNotReachHere() %{ 14797 match(Halt); 14798 ins_cost(CALL_COST); 14799 14800 format %{ "ShouldNotReachHere" %} 14801 size(4); 14802 ins_encode %{ 14803 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 14804 __ trap_should_not_reach_here(); 14805 %} 14806 ins_pipe(pipe_class_default); 14807 %} 14808 14809 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 14810 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 14811 // Get a DEF on threadRegP, no costs, no encoding, use 14812 // 'ins_should_rematerialize(true)' to avoid spilling. 14813 instruct tlsLoadP(threadRegP dst) %{ 14814 match(Set dst (ThreadLocal)); 14815 ins_cost(0); 14816 14817 ins_should_rematerialize(true); 14818 14819 format %{ " -- \t// $dst=Thread::current(), empty" %} 14820 size(0); 14821 ins_encode( /*empty*/ ); 14822 ins_pipe(pipe_class_empty); 14823 %} 14824 14825 //---Some PPC specific nodes--------------------------------------------------- 14826 14827 // Stop a group. 14828 instruct endGroup() %{ 14829 ins_cost(0); 14830 14831 ins_is_nop(true); 14832 14833 format %{ "End Bundle (ori r1, r1, 0)" %} 14834 size(4); 14835 ins_encode %{ 14836 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 14837 __ endgroup(); 14838 %} 14839 ins_pipe(pipe_class_default); 14840 %} 14841 14842 // Nop instructions 14843 14844 instruct fxNop() %{ 14845 ins_cost(0); 14846 14847 ins_is_nop(true); 14848 14849 format %{ "fxNop" %} 14850 size(4); 14851 ins_encode %{ 14852 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14853 __ nop(); 14854 %} 14855 ins_pipe(pipe_class_default); 14856 %} 14857 14858 instruct fpNop0() %{ 14859 ins_cost(0); 14860 14861 ins_is_nop(true); 14862 14863 format %{ "fpNop0" %} 14864 size(4); 14865 ins_encode %{ 14866 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14867 __ fpnop0(); 14868 %} 14869 ins_pipe(pipe_class_default); 14870 %} 14871 14872 instruct fpNop1() %{ 14873 ins_cost(0); 14874 14875 ins_is_nop(true); 14876 14877 format %{ "fpNop1" %} 14878 size(4); 14879 ins_encode %{ 14880 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14881 __ fpnop1(); 14882 %} 14883 ins_pipe(pipe_class_default); 14884 %} 14885 14886 instruct brNop0() %{ 14887 ins_cost(0); 14888 size(4); 14889 format %{ "brNop0" %} 14890 ins_encode %{ 14891 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14892 __ brnop0(); 14893 %} 14894 ins_is_nop(true); 14895 ins_pipe(pipe_class_default); 14896 %} 14897 14898 instruct brNop1() %{ 14899 ins_cost(0); 14900 14901 ins_is_nop(true); 14902 14903 format %{ "brNop1" %} 14904 size(4); 14905 ins_encode %{ 14906 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14907 __ brnop1(); 14908 %} 14909 ins_pipe(pipe_class_default); 14910 %} 14911 14912 instruct brNop2() %{ 14913 ins_cost(0); 14914 14915 ins_is_nop(true); 14916 14917 format %{ "brNop2" %} 14918 size(4); 14919 ins_encode %{ 14920 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14921 __ brnop2(); 14922 %} 14923 ins_pipe(pipe_class_default); 14924 %} 14925 14926 //----------PEEPHOLE RULES----------------------------------------------------- 14927 // These must follow all instruction definitions as they use the names 14928 // defined in the instructions definitions. 14929 // 14930 // peepmatch ( root_instr_name [preceeding_instruction]* ); 14931 // 14932 // peepconstraint %{ 14933 // (instruction_number.operand_name relational_op instruction_number.operand_name 14934 // [, ...] ); 14935 // // instruction numbers are zero-based using left to right order in peepmatch 14936 // 14937 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14938 // // provide an instruction_number.operand_name for each operand that appears 14939 // // in the replacement instruction's match rule 14940 // 14941 // ---------VM FLAGS--------------------------------------------------------- 14942 // 14943 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14944 // 14945 // Each peephole rule is given an identifying number starting with zero and 14946 // increasing by one in the order seen by the parser. An individual peephole 14947 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14948 // on the command-line. 14949 // 14950 // ---------CURRENT LIMITATIONS---------------------------------------------- 14951 // 14952 // Only match adjacent instructions in same basic block 14953 // Only equality constraints 14954 // Only constraints between operands, not (0.dest_reg == EAX_enc) 14955 // Only one replacement instruction 14956 // 14957 // ---------EXAMPLE---------------------------------------------------------- 14958 // 14959 // // pertinent parts of existing instructions in architecture description 14960 // instruct movI(eRegI dst, eRegI src) %{ 14961 // match(Set dst (CopyI src)); 14962 // %} 14963 // 14964 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 14965 // match(Set dst (AddI dst src)); 14966 // effect(KILL cr); 14967 // %} 14968 // 14969 // // Change (inc mov) to lea 14970 // peephole %{ 14971 // // increment preceeded by register-register move 14972 // peepmatch ( incI_eReg movI ); 14973 // // require that the destination register of the increment 14974 // // match the destination register of the move 14975 // peepconstraint ( 0.dst == 1.dst ); 14976 // // construct a replacement instruction that sets 14977 // // the destination to ( move's source register + one ) 14978 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14979 // %} 14980 // 14981 // Implementation no longer uses movX instructions since 14982 // machine-independent system no longer uses CopyX nodes. 14983 // 14984 // peephole %{ 14985 // peepmatch ( incI_eReg movI ); 14986 // peepconstraint ( 0.dst == 1.dst ); 14987 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14988 // %} 14989 // 14990 // peephole %{ 14991 // peepmatch ( decI_eReg movI ); 14992 // peepconstraint ( 0.dst == 1.dst ); 14993 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14994 // %} 14995 // 14996 // peephole %{ 14997 // peepmatch ( addI_eReg_imm movI ); 14998 // peepconstraint ( 0.dst == 1.dst ); 14999 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15000 // %} 15001 // 15002 // peephole %{ 15003 // peepmatch ( addP_eReg_imm movP ); 15004 // peepconstraint ( 0.dst == 1.dst ); 15005 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 15006 // %} 15007 15008 // // Change load of spilled value to only a spill 15009 // instruct storeI(memory mem, eRegI src) %{ 15010 // match(Set mem (StoreI mem src)); 15011 // %} 15012 // 15013 // instruct loadI(eRegI dst, memory mem) %{ 15014 // match(Set dst (LoadI mem)); 15015 // %} 15016 // 15017 peephole %{ 15018 peepmatch ( loadI storeI ); 15019 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15020 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 15021 %} 15022 15023 peephole %{ 15024 peepmatch ( loadL storeL ); 15025 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15026 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 15027 %} 15028 15029 peephole %{ 15030 peepmatch ( loadP storeP ); 15031 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 15032 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 15033 %} 15034 15035 //----------SMARTSPILL RULES--------------------------------------------------- 15036 // These must follow all instruction definitions as they use the names 15037 // defined in the instructions definitions.