1 // 2 // Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2019 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 if (C->clinit_barrier_on_entry()) { 1404 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1405 1406 Label L_skip_barrier; 1407 Register klass = toc_temp; 1408 1409 // Notify OOP recorder (don't need the relocation) 1410 AddressLiteral md = __ constant_metadata_address(C->method()->holder()->constant_encoding()); 1411 __ load_const_optimized(klass, md.value(), R0); 1412 __ clinit_barrier(klass, R16_thread, &L_skip_barrier /*L_fast_path*/); 1413 1414 __ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub(), R0); 1415 __ mtctr(klass); 1416 __ bctr(); 1417 1418 __ bind(L_skip_barrier); 1419 } 1420 1421 // Calls to C2R adapters often do not accept exceptional returns. 1422 // We require that their callers must bang for them. But be 1423 // careful, because some VM calls (such as call site linkage) can 1424 // use several kilobytes of stack. But the stack safety zone should 1425 // account for that. See bugs 4446381, 4468289, 4497237. 1426 1427 int bangsize = C->bang_size_in_bytes(); 1428 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1429 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1430 // Unfortunately we cannot use the function provided in 1431 // assembler.cpp as we have to emulate the pipes. So I had to 1432 // insert the code of generate_stack_overflow_check(), see 1433 // assembler.cpp for some illuminative comments. 1434 const int page_size = os::vm_page_size(); 1435 int bang_end = JavaThread::stack_shadow_zone_size(); 1436 1437 // This is how far the previous frame's stack banging extended. 1438 const int bang_end_safe = bang_end; 1439 1440 if (bangsize > page_size) { 1441 bang_end += bangsize; 1442 } 1443 1444 int bang_offset = bang_end_safe; 1445 1446 while (bang_offset <= bang_end) { 1447 // Need at least one stack bang at end of shadow zone. 1448 1449 // Again I had to copy code, this time from assembler_ppc.cpp, 1450 // bang_stack_with_offset - see there for comments. 1451 1452 // Stack grows down, caller passes positive offset. 1453 assert(bang_offset > 0, "must bang with positive offset"); 1454 1455 long stdoffset = -bang_offset; 1456 1457 if (Assembler::is_simm(stdoffset, 16)) { 1458 // Signed 16 bit offset, a simple std is ok. 1459 if (UseLoadInstructionsForStackBangingPPC64) { 1460 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1461 } else { 1462 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1463 } 1464 } else if (Assembler::is_simm(stdoffset, 31)) { 1465 // Use largeoffset calculations for addis & ld/std. 1466 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1467 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1468 1469 Register tmp = R11; 1470 ___(addis) addis(tmp, R1_SP, hi); 1471 if (UseLoadInstructionsForStackBangingPPC64) { 1472 ___(ld) ld(R0, lo, tmp); 1473 } else { 1474 ___(std) std(R0, lo, tmp); 1475 } 1476 } else { 1477 ShouldNotReachHere(); 1478 } 1479 1480 bang_offset += page_size; 1481 } 1482 // R11 trashed 1483 } // C->need_stack_bang(framesize) && UseStackBanging 1484 1485 unsigned int bytes = (unsigned int)framesize; 1486 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1487 ciMethod *currMethod = C->method(); 1488 1489 // Optimized version for most common case. 1490 if (UsePower6SchedulerPPC64 && 1491 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1492 !(false /* ConstantsALot TODO: PPC port*/)) { 1493 ___(or) mr(callers_sp, R1_SP); 1494 ___(std) std(return_pc, _abi(lr), R1_SP); 1495 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1496 return; 1497 } 1498 1499 if (!method_is_frameless) { 1500 // Get callers sp. 1501 ___(or) mr(callers_sp, R1_SP); 1502 1503 // Push method's frame, modifies SP. 1504 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1505 // The ABI is already accounted for in 'framesize' via the 1506 // 'out_preserve' area. 1507 Register tmp = push_frame_temp; 1508 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1509 if (Assembler::is_simm(-offset, 16)) { 1510 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1511 } else { 1512 long x = -offset; 1513 // Had to insert load_const(tmp, -offset). 1514 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1515 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1516 ___(rldicr) sldi(tmp, tmp, 32); 1517 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1518 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1519 1520 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1521 } 1522 } 1523 #if 0 // TODO: PPC port 1524 // For testing large constant pools, emit a lot of constants to constant pool. 1525 // "Randomize" const_size. 1526 if (ConstantsALot) { 1527 const int num_consts = const_size(); 1528 for (int i = 0; i < num_consts; i++) { 1529 __ long_constant(0xB0B5B00BBABE); 1530 } 1531 } 1532 #endif 1533 if (!method_is_frameless) { 1534 // Save return pc. 1535 ___(std) std(return_pc, _abi(lr), callers_sp); 1536 } 1537 1538 C->set_frame_complete(cbuf.insts_size()); 1539 } 1540 #undef ___ 1541 #undef ___stop 1542 #undef ___advance 1543 1544 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1545 // Variable size. determine dynamically. 1546 return MachNode::size(ra_); 1547 } 1548 1549 int MachPrologNode::reloc() const { 1550 // Return number of relocatable values contained in this instruction. 1551 return 1; // 1 reloc entry for load_const(toc). 1552 } 1553 1554 //============================================================================= 1555 1556 #ifndef PRODUCT 1557 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1558 Compile* C = ra_->C; 1559 1560 st->print("EPILOG\n\t"); 1561 st->print("restore return pc\n\t"); 1562 st->print("pop frame\n\t"); 1563 1564 if (do_polling() && C->is_method_compilation()) { 1565 st->print("touch polling page\n\t"); 1566 } 1567 } 1568 #endif 1569 1570 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1571 Compile* C = ra_->C; 1572 MacroAssembler _masm(&cbuf); 1573 1574 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1575 assert(framesize >= 0, "negative frame-size?"); 1576 1577 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1578 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1579 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1580 const Register polling_page = R12; 1581 1582 if (!method_is_frameless) { 1583 // Restore return pc relative to callers' sp. 1584 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1585 } 1586 1587 if (method_needs_polling) { 1588 if (SafepointMechanism::uses_thread_local_poll()) { 1589 __ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread); 1590 } else { 1591 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); 1592 } 1593 } 1594 1595 if (!method_is_frameless) { 1596 // Move return pc to LR. 1597 __ mtlr(return_pc); 1598 // Pop frame (fixed frame-size). 1599 __ addi(R1_SP, R1_SP, (int)framesize); 1600 } 1601 1602 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1603 __ reserved_stack_check(return_pc); 1604 } 1605 1606 if (method_needs_polling) { 1607 // We need to mark the code position where the load from the safepoint 1608 // polling page was emitted as relocInfo::poll_return_type here. 1609 __ relocate(relocInfo::poll_return_type); 1610 __ load_from_polling_page(polling_page); 1611 } 1612 } 1613 1614 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1615 // Variable size. Determine dynamically. 1616 return MachNode::size(ra_); 1617 } 1618 1619 int MachEpilogNode::reloc() const { 1620 // Return number of relocatable values contained in this instruction. 1621 return 1; // 1 for load_from_polling_page. 1622 } 1623 1624 const Pipeline * MachEpilogNode::pipeline() const { 1625 return MachNode::pipeline_class(); 1626 } 1627 1628 // This method seems to be obsolete. It is declared in machnode.hpp 1629 // and defined in all *.ad files, but it is never called. Should we 1630 // get rid of it? 1631 int MachEpilogNode::safepoint_offset() const { 1632 assert(do_polling(), "no return for this epilog node"); 1633 return 0; 1634 } 1635 1636 #if 0 // TODO: PPC port 1637 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1638 MacroAssembler _masm(&cbuf); 1639 if (LoadPollAddressFromThread) { 1640 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1641 } else { 1642 _masm.nop(); 1643 } 1644 } 1645 1646 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1647 if (LoadPollAddressFromThread) { 1648 return 4; 1649 } else { 1650 return 4; 1651 } 1652 } 1653 1654 #ifndef PRODUCT 1655 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1656 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1657 } 1658 #endif 1659 1660 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1661 return RSCRATCH1_BITS64_REG_mask(); 1662 } 1663 #endif // PPC port 1664 1665 // ============================================================================= 1666 1667 // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or 1668 // rc_stack. 1669 enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack }; 1670 1671 static enum RC rc_class(OptoReg::Name reg) { 1672 // Return the register class for the given register. The given register 1673 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1674 // enumeration in adGlobals_ppc.hpp. 1675 1676 if (reg == OptoReg::Bad) return rc_bad; 1677 1678 // We have 64 integer register halves, starting at index 0. 1679 if (reg < 64) return rc_int; 1680 1681 // We have 64 floating-point register halves, starting at index 64. 1682 if (reg < 64+64) return rc_float; 1683 1684 // We have 64 vector-scalar registers, starting at index 128. 1685 if (reg < 64+64+64) return rc_vs; 1686 1687 // Between float regs & stack are the flags regs. 1688 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1689 1690 return rc_stack; 1691 } 1692 1693 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1694 bool do_print, Compile* C, outputStream *st) { 1695 1696 assert(opcode == Assembler::LD_OPCODE || 1697 opcode == Assembler::STD_OPCODE || 1698 opcode == Assembler::LWZ_OPCODE || 1699 opcode == Assembler::STW_OPCODE || 1700 opcode == Assembler::LFD_OPCODE || 1701 opcode == Assembler::STFD_OPCODE || 1702 opcode == Assembler::LFS_OPCODE || 1703 opcode == Assembler::STFS_OPCODE, 1704 "opcode not supported"); 1705 1706 if (cbuf) { 1707 int d = 1708 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1709 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1710 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1711 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1712 } 1713 #ifndef PRODUCT 1714 else if (do_print) { 1715 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1716 op_str, 1717 Matcher::regName[reg], 1718 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1719 } 1720 #endif 1721 return 4; // size 1722 } 1723 1724 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1725 Compile* C = ra_->C; 1726 1727 // Get registers to move. 1728 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1729 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1730 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1731 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1732 1733 enum RC src_hi_rc = rc_class(src_hi); 1734 enum RC src_lo_rc = rc_class(src_lo); 1735 enum RC dst_hi_rc = rc_class(dst_hi); 1736 enum RC dst_lo_rc = rc_class(dst_lo); 1737 1738 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1739 if (src_hi != OptoReg::Bad) 1740 assert((src_lo&1)==0 && src_lo+1==src_hi && 1741 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1742 "expected aligned-adjacent pairs"); 1743 // Generate spill code! 1744 int size = 0; 1745 1746 if (src_lo == dst_lo && src_hi == dst_hi) 1747 return size; // Self copy, no move. 1748 1749 if (bottom_type()->isa_vect() != NULL && ideal_reg() == Op_VecX) { 1750 // Memory->Memory Spill. 1751 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1752 int src_offset = ra_->reg2offset(src_lo); 1753 int dst_offset = ra_->reg2offset(dst_lo); 1754 if (cbuf) { 1755 MacroAssembler _masm(cbuf); 1756 __ ld(R0, src_offset, R1_SP); 1757 __ std(R0, dst_offset, R1_SP); 1758 __ ld(R0, src_offset+8, R1_SP); 1759 __ std(R0, dst_offset+8, R1_SP); 1760 } 1761 size += 16; 1762 } 1763 // VectorSRegister->Memory Spill. 1764 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) { 1765 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1766 int dst_offset = ra_->reg2offset(dst_lo); 1767 if (cbuf) { 1768 MacroAssembler _masm(cbuf); 1769 __ addi(R0, R1_SP, dst_offset); 1770 __ stxvd2x(Rsrc, R0); 1771 } 1772 size += 8; 1773 } 1774 // Memory->VectorSRegister Spill. 1775 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) { 1776 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1777 int src_offset = ra_->reg2offset(src_lo); 1778 if (cbuf) { 1779 MacroAssembler _masm(cbuf); 1780 __ addi(R0, R1_SP, src_offset); 1781 __ lxvd2x(Rdst, R0); 1782 } 1783 size += 8; 1784 } 1785 // VectorSRegister->VectorSRegister. 1786 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) { 1787 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1788 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1789 if (cbuf) { 1790 MacroAssembler _masm(cbuf); 1791 __ xxlor(Rdst, Rsrc, Rsrc); 1792 } 1793 size += 4; 1794 } 1795 else { 1796 ShouldNotReachHere(); // No VSR spill. 1797 } 1798 return size; 1799 } 1800 1801 // -------------------------------------- 1802 // Memory->Memory Spill. Use R0 to hold the value. 1803 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1804 int src_offset = ra_->reg2offset(src_lo); 1805 int dst_offset = ra_->reg2offset(dst_lo); 1806 if (src_hi != OptoReg::Bad) { 1807 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1808 "expected same type of move for high parts"); 1809 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1810 if (!cbuf && !do_size) st->print("\n\t"); 1811 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1812 } else { 1813 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1814 if (!cbuf && !do_size) st->print("\n\t"); 1815 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1816 } 1817 return size; 1818 } 1819 1820 // -------------------------------------- 1821 // Check for float->int copy; requires a trip through memory. 1822 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1823 Unimplemented(); 1824 } 1825 1826 // -------------------------------------- 1827 // Check for integer reg-reg copy. 1828 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1829 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1830 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1831 size = (Rsrc != Rdst) ? 4 : 0; 1832 1833 if (cbuf) { 1834 MacroAssembler _masm(cbuf); 1835 if (size) { 1836 __ mr(Rdst, Rsrc); 1837 } 1838 } 1839 #ifndef PRODUCT 1840 else if (!do_size) { 1841 if (size) { 1842 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1843 } else { 1844 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1845 } 1846 } 1847 #endif 1848 return size; 1849 } 1850 1851 // Check for integer store. 1852 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1853 int dst_offset = ra_->reg2offset(dst_lo); 1854 if (src_hi != OptoReg::Bad) { 1855 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1856 "expected same type of move for high parts"); 1857 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1858 } else { 1859 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1860 } 1861 return size; 1862 } 1863 1864 // Check for integer load. 1865 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1866 int src_offset = ra_->reg2offset(src_lo); 1867 if (src_hi != OptoReg::Bad) { 1868 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1869 "expected same type of move for high parts"); 1870 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1871 } else { 1872 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1873 } 1874 return size; 1875 } 1876 1877 // Check for float reg-reg copy. 1878 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1879 if (cbuf) { 1880 MacroAssembler _masm(cbuf); 1881 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1882 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1883 __ fmr(Rdst, Rsrc); 1884 } 1885 #ifndef PRODUCT 1886 else if (!do_size) { 1887 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1888 } 1889 #endif 1890 return 4; 1891 } 1892 1893 // Check for float store. 1894 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1895 int dst_offset = ra_->reg2offset(dst_lo); 1896 if (src_hi != OptoReg::Bad) { 1897 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1898 "expected same type of move for high parts"); 1899 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1900 } else { 1901 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1902 } 1903 return size; 1904 } 1905 1906 // Check for float load. 1907 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1908 int src_offset = ra_->reg2offset(src_lo); 1909 if (src_hi != OptoReg::Bad) { 1910 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1911 "expected same type of move for high parts"); 1912 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1913 } else { 1914 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1915 } 1916 return size; 1917 } 1918 1919 // -------------------------------------------------------------------- 1920 // Check for hi bits still needing moving. Only happens for misaligned 1921 // arguments to native calls. 1922 if (src_hi == dst_hi) 1923 return size; // Self copy; no move. 1924 1925 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1926 ShouldNotReachHere(); // Unimplemented 1927 return 0; 1928 } 1929 1930 #ifndef PRODUCT 1931 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1932 if (!ra_) 1933 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1934 else 1935 implementation(NULL, ra_, false, st); 1936 } 1937 #endif 1938 1939 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1940 implementation(&cbuf, ra_, false, NULL); 1941 } 1942 1943 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1944 return implementation(NULL, ra_, true, NULL); 1945 } 1946 1947 #if 0 // TODO: PPC port 1948 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1949 #ifndef PRODUCT 1950 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1951 #endif 1952 assert(ra_->node_regs_max_index() != 0, ""); 1953 1954 // Get registers to move. 1955 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1956 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1957 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1958 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1959 1960 enum RC src_lo_rc = rc_class(src_lo); 1961 enum RC dst_lo_rc = rc_class(dst_lo); 1962 1963 if (src_lo == dst_lo && src_hi == dst_hi) 1964 return ppc64Opcode_none; // Self copy, no move. 1965 1966 // -------------------------------------- 1967 // Memory->Memory Spill. Use R0 to hold the value. 1968 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1969 return ppc64Opcode_compound; 1970 } 1971 1972 // -------------------------------------- 1973 // Check for float->int copy; requires a trip through memory. 1974 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1975 Unimplemented(); 1976 } 1977 1978 // -------------------------------------- 1979 // Check for integer reg-reg copy. 1980 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1981 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1982 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1983 if (Rsrc == Rdst) { 1984 return ppc64Opcode_none; 1985 } else { 1986 return ppc64Opcode_or; 1987 } 1988 } 1989 1990 // Check for integer store. 1991 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1992 if (src_hi != OptoReg::Bad) { 1993 return ppc64Opcode_std; 1994 } else { 1995 return ppc64Opcode_stw; 1996 } 1997 } 1998 1999 // Check for integer load. 2000 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 2001 if (src_hi != OptoReg::Bad) { 2002 return ppc64Opcode_ld; 2003 } else { 2004 return ppc64Opcode_lwz; 2005 } 2006 } 2007 2008 // Check for float reg-reg copy. 2009 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 2010 return ppc64Opcode_fmr; 2011 } 2012 2013 // Check for float store. 2014 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 2015 if (src_hi != OptoReg::Bad) { 2016 return ppc64Opcode_stfd; 2017 } else { 2018 return ppc64Opcode_stfs; 2019 } 2020 } 2021 2022 // Check for float load. 2023 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 2024 if (src_hi != OptoReg::Bad) { 2025 return ppc64Opcode_lfd; 2026 } else { 2027 return ppc64Opcode_lfs; 2028 } 2029 } 2030 2031 // -------------------------------------------------------------------- 2032 // Check for hi bits still needing moving. Only happens for misaligned 2033 // arguments to native calls. 2034 if (src_hi == dst_hi) { 2035 return ppc64Opcode_none; // Self copy; no move. 2036 } 2037 2038 ShouldNotReachHere(); 2039 return ppc64Opcode_undefined; 2040 } 2041 #endif // PPC port 2042 2043 #ifndef PRODUCT 2044 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2045 st->print("NOP \t// %d nops to pad for loops.", _count); 2046 } 2047 #endif 2048 2049 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 2050 MacroAssembler _masm(&cbuf); 2051 // _count contains the number of nops needed for padding. 2052 for (int i = 0; i < _count; i++) { 2053 __ nop(); 2054 } 2055 } 2056 2057 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 2058 return _count * 4; 2059 } 2060 2061 #ifndef PRODUCT 2062 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2063 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2064 char reg_str[128]; 2065 ra_->dump_register(this, reg_str); 2066 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 2067 } 2068 #endif 2069 2070 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2071 MacroAssembler _masm(&cbuf); 2072 2073 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2074 int reg = ra_->get_encode(this); 2075 2076 if (Assembler::is_simm(offset, 16)) { 2077 __ addi(as_Register(reg), R1, offset); 2078 } else { 2079 ShouldNotReachHere(); 2080 } 2081 } 2082 2083 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2084 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2085 return 4; 2086 } 2087 2088 #ifndef PRODUCT 2089 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2090 st->print_cr("---- MachUEPNode ----"); 2091 st->print_cr("..."); 2092 } 2093 #endif 2094 2095 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2096 // This is the unverified entry point. 2097 MacroAssembler _masm(&cbuf); 2098 2099 // Inline_cache contains a klass. 2100 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 2101 Register receiver_klass = R12_scratch2; // tmp 2102 2103 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 2104 assert(R11_scratch1 == R11, "need prologue scratch register"); 2105 2106 // Check for NULL argument if we don't have implicit null checks. 2107 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 2108 if (TrapBasedNullChecks) { 2109 __ trap_null_check(R3_ARG1); 2110 } else { 2111 Label valid; 2112 __ cmpdi(CCR0, R3_ARG1, 0); 2113 __ bne_predict_taken(CCR0, valid); 2114 // We have a null argument, branch to ic_miss_stub. 2115 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2116 relocInfo::runtime_call_type); 2117 __ bind(valid); 2118 } 2119 } 2120 // Assume argument is not NULL, load klass from receiver. 2121 __ load_klass(receiver_klass, R3_ARG1); 2122 2123 if (TrapBasedICMissChecks) { 2124 __ trap_ic_miss_check(receiver_klass, ic_klass); 2125 } else { 2126 Label valid; 2127 __ cmpd(CCR0, receiver_klass, ic_klass); 2128 __ beq_predict_taken(CCR0, valid); 2129 // We have an unexpected klass, branch to ic_miss_stub. 2130 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2131 relocInfo::runtime_call_type); 2132 __ bind(valid); 2133 } 2134 2135 // Argument is valid and klass is as expected, continue. 2136 } 2137 2138 #if 0 // TODO: PPC port 2139 // Optimize UEP code on z (save a load_const() call in main path). 2140 int MachUEPNode::ep_offset() { 2141 return 0; 2142 } 2143 #endif 2144 2145 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2146 // Variable size. Determine dynamically. 2147 return MachNode::size(ra_); 2148 } 2149 2150 //============================================================================= 2151 2152 %} // interrupt source 2153 2154 source_hpp %{ // Header information of the source block. 2155 2156 class HandlerImpl { 2157 2158 public: 2159 2160 static int emit_exception_handler(CodeBuffer &cbuf); 2161 static int emit_deopt_handler(CodeBuffer& cbuf); 2162 2163 static uint size_exception_handler() { 2164 // The exception_handler is a b64_patchable. 2165 return MacroAssembler::b64_patchable_size; 2166 } 2167 2168 static uint size_deopt_handler() { 2169 // The deopt_handler is a bl64_patchable. 2170 return MacroAssembler::bl64_patchable_size; 2171 } 2172 2173 }; 2174 2175 %} // end source_hpp 2176 2177 source %{ 2178 2179 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2180 MacroAssembler _masm(&cbuf); 2181 2182 address base = __ start_a_stub(size_exception_handler()); 2183 if (base == NULL) return 0; // CodeBuffer::expand failed 2184 2185 int offset = __ offset(); 2186 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2187 relocInfo::runtime_call_type); 2188 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2189 __ end_a_stub(); 2190 2191 return offset; 2192 } 2193 2194 // The deopt_handler is like the exception handler, but it calls to 2195 // the deoptimization blob instead of jumping to the exception blob. 2196 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2197 MacroAssembler _masm(&cbuf); 2198 2199 address base = __ start_a_stub(size_deopt_handler()); 2200 if (base == NULL) return 0; // CodeBuffer::expand failed 2201 2202 int offset = __ offset(); 2203 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2204 relocInfo::runtime_call_type); 2205 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2206 __ end_a_stub(); 2207 2208 return offset; 2209 } 2210 2211 //============================================================================= 2212 2213 // Use a frame slots bias for frameless methods if accessing the stack. 2214 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2215 if (as_Register(reg_enc) == R1_SP) { 2216 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2217 } 2218 return 0; 2219 } 2220 2221 const bool Matcher::match_rule_supported(int opcode) { 2222 if (!has_match_rule(opcode)) 2223 return false; 2224 2225 switch (opcode) { 2226 case Op_SqrtD: 2227 return VM_Version::has_fsqrt(); 2228 case Op_CountLeadingZerosI: 2229 case Op_CountLeadingZerosL: 2230 if (!UseCountLeadingZerosInstructionsPPC64) 2231 return false; 2232 break; 2233 case Op_CountTrailingZerosI: 2234 case Op_CountTrailingZerosL: 2235 if (!UseCountLeadingZerosInstructionsPPC64 && 2236 !UseCountTrailingZerosInstructionsPPC64) 2237 return false; 2238 break; 2239 2240 case Op_PopCountI: 2241 case Op_PopCountL: 2242 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2243 2244 case Op_StrComp: 2245 return SpecialStringCompareTo; 2246 case Op_StrEquals: 2247 return SpecialStringEquals; 2248 case Op_StrIndexOf: 2249 case Op_StrIndexOfChar: 2250 return SpecialStringIndexOf; 2251 case Op_AddVB: 2252 case Op_AddVS: 2253 case Op_AddVI: 2254 case Op_AddVF: 2255 case Op_AddVD: 2256 case Op_SubVB: 2257 case Op_SubVS: 2258 case Op_SubVI: 2259 case Op_SubVF: 2260 case Op_SubVD: 2261 case Op_MulVS: 2262 case Op_MulVF: 2263 case Op_MulVD: 2264 case Op_DivVF: 2265 case Op_DivVD: 2266 case Op_AbsVF: 2267 case Op_AbsVD: 2268 case Op_NegVF: 2269 case Op_NegVD: 2270 case Op_SqrtVF: 2271 case Op_SqrtVD: 2272 case Op_AddVL: 2273 case Op_SubVL: 2274 case Op_MulVI: 2275 return SuperwordUseVSX; 2276 case Op_PopCountVI: 2277 return (SuperwordUseVSX && UsePopCountInstruction); 2278 case Op_FmaVF: 2279 case Op_FmaVD: 2280 return (SuperwordUseVSX && UseFMA); 2281 case Op_Digit: 2282 case Op_LowerCase: 2283 case Op_UpperCase: 2284 case Op_Whitespace: 2285 return UseCharacterCompareIntrinsics; 2286 } 2287 2288 return true; // Per default match rules are supported. 2289 } 2290 2291 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2292 2293 // TODO 2294 // identify extra cases that we might want to provide match rules for 2295 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2296 bool ret_value = match_rule_supported(opcode); 2297 // Add rules here. 2298 2299 return ret_value; // Per default match rules are supported. 2300 } 2301 2302 const bool Matcher::has_predicated_vectors(void) { 2303 return false; 2304 } 2305 2306 const int Matcher::float_pressure(int default_pressure_threshold) { 2307 return default_pressure_threshold; 2308 } 2309 2310 int Matcher::regnum_to_fpu_offset(int regnum) { 2311 // No user for this method? 2312 Unimplemented(); 2313 return 999; 2314 } 2315 2316 const bool Matcher::convL2FSupported(void) { 2317 // fcfids can do the conversion (>= Power7). 2318 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2319 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2320 } 2321 2322 // Vector width in bytes. 2323 const int Matcher::vector_width_in_bytes(BasicType bt) { 2324 if (SuperwordUseVSX) { 2325 assert(MaxVectorSize == 16, ""); 2326 return 16; 2327 } else { 2328 assert(MaxVectorSize == 8, ""); 2329 return 8; 2330 } 2331 } 2332 2333 // Vector ideal reg. 2334 const uint Matcher::vector_ideal_reg(int size) { 2335 if (SuperwordUseVSX) { 2336 assert(MaxVectorSize == 16 && size == 16, ""); 2337 return Op_VecX; 2338 } else { 2339 assert(MaxVectorSize == 8 && size == 8, ""); 2340 return Op_RegL; 2341 } 2342 } 2343 2344 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2345 fatal("vector shift is not supported"); 2346 return Node::NotAMachineReg; 2347 } 2348 2349 // Limits on vector size (number of elements) loaded into vector. 2350 const int Matcher::max_vector_size(const BasicType bt) { 2351 assert(is_java_primitive(bt), "only primitive type vectors"); 2352 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2353 } 2354 2355 const int Matcher::min_vector_size(const BasicType bt) { 2356 return max_vector_size(bt); // Same as max. 2357 } 2358 2359 // PPC implementation uses VSX load/store instructions (if 2360 // SuperwordUseVSX) which support 4 byte but not arbitrary alignment 2361 const bool Matcher::misaligned_vectors_ok() { 2362 return false; 2363 } 2364 2365 // PPC AES support not yet implemented 2366 const bool Matcher::pass_original_key_for_aes() { 2367 return false; 2368 } 2369 2370 // RETURNS: whether this branch offset is short enough that a short 2371 // branch can be used. 2372 // 2373 // If the platform does not provide any short branch variants, then 2374 // this method should return `false' for offset 0. 2375 // 2376 // `Compile::Fill_buffer' will decide on basis of this information 2377 // whether to do the pass `Compile::Shorten_branches' at all. 2378 // 2379 // And `Compile::Shorten_branches' will decide on basis of this 2380 // information whether to replace particular branch sites by short 2381 // ones. 2382 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2383 // Is the offset within the range of a ppc64 pc relative branch? 2384 bool b; 2385 2386 const int safety_zone = 3 * BytesPerInstWord; 2387 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2388 29 - 16 + 1 + 2); 2389 return b; 2390 } 2391 2392 const bool Matcher::isSimpleConstant64(jlong value) { 2393 // Probably always true, even if a temp register is required. 2394 return true; 2395 } 2396 /* TODO: PPC port 2397 // Make a new machine dependent decode node (with its operands). 2398 MachTypeNode *Matcher::make_decode_node() { 2399 assert(CompressedOops::base() == NULL && CompressedOops::shift() == 0, 2400 "This method is only implemented for unscaled cOops mode so far"); 2401 MachTypeNode *decode = new decodeN_unscaledNode(); 2402 decode->set_opnd_array(0, new iRegPdstOper()); 2403 decode->set_opnd_array(1, new iRegNsrcOper()); 2404 return decode; 2405 } 2406 */ 2407 2408 // false => size gets scaled to BytesPerLong, ok. 2409 const bool Matcher::init_array_count_is_in_bytes = false; 2410 2411 // Use conditional move (CMOVL) on Power7. 2412 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2413 2414 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2415 // fsel doesn't accept a condition register as input, so this would be slightly different. 2416 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2417 2418 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2419 const bool Matcher::require_postalloc_expand = true; 2420 2421 // Do we need to mask the count passed to shift instructions or does 2422 // the cpu only look at the lower 5/6 bits anyway? 2423 // PowerPC requires masked shift counts. 2424 const bool Matcher::need_masked_shift_count = true; 2425 2426 // This affects two different things: 2427 // - how Decode nodes are matched 2428 // - how ImplicitNullCheck opportunities are recognized 2429 // If true, the matcher will try to remove all Decodes and match them 2430 // (as operands) into nodes. NullChecks are not prepared to deal with 2431 // Decodes by final_graph_reshaping(). 2432 // If false, final_graph_reshaping() forces the decode behind the Cmp 2433 // for a NullCheck. The matcher matches the Decode node into a register. 2434 // Implicit_null_check optimization moves the Decode along with the 2435 // memory operation back up before the NullCheck. 2436 bool Matcher::narrow_oop_use_complex_address() { 2437 // TODO: PPC port if (MatchDecodeNodes) return true; 2438 return false; 2439 } 2440 2441 bool Matcher::narrow_klass_use_complex_address() { 2442 NOT_LP64(ShouldNotCallThis()); 2443 assert(UseCompressedClassPointers, "only for compressed klass code"); 2444 // TODO: PPC port if (MatchDecodeNodes) return true; 2445 return false; 2446 } 2447 2448 bool Matcher::const_oop_prefer_decode() { 2449 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2450 return CompressedOops::base() == NULL; 2451 } 2452 2453 bool Matcher::const_klass_prefer_decode() { 2454 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2455 return CompressedKlassPointers::base() == NULL; 2456 } 2457 2458 // Is it better to copy float constants, or load them directly from memory? 2459 // Intel can load a float constant from a direct address, requiring no 2460 // extra registers. Most RISCs will have to materialize an address into a 2461 // register first, so they would do better to copy the constant from stack. 2462 const bool Matcher::rematerialize_float_constants = false; 2463 2464 // If CPU can load and store mis-aligned doubles directly then no fixup is 2465 // needed. Else we split the double into 2 integer pieces and move it 2466 // piece-by-piece. Only happens when passing doubles into C code as the 2467 // Java calling convention forces doubles to be aligned. 2468 const bool Matcher::misaligned_doubles_ok = true; 2469 2470 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2471 Unimplemented(); 2472 } 2473 2474 // Advertise here if the CPU requires explicit rounding operations 2475 // to implement the UseStrictFP mode. 2476 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2477 2478 // Do floats take an entire double register or just half? 2479 // 2480 // A float occupies a ppc64 double register. For the allocator, a 2481 // ppc64 double register appears as a pair of float registers. 2482 bool Matcher::float_in_double() { return true; } 2483 2484 // Do ints take an entire long register or just half? 2485 // The relevant question is how the int is callee-saved: 2486 // the whole long is written but de-opt'ing will have to extract 2487 // the relevant 32 bits. 2488 const bool Matcher::int_in_long = true; 2489 2490 // Constants for c2c and c calling conventions. 2491 2492 const MachRegisterNumbers iarg_reg[8] = { 2493 R3_num, R4_num, R5_num, R6_num, 2494 R7_num, R8_num, R9_num, R10_num 2495 }; 2496 2497 const MachRegisterNumbers farg_reg[13] = { 2498 F1_num, F2_num, F3_num, F4_num, 2499 F5_num, F6_num, F7_num, F8_num, 2500 F9_num, F10_num, F11_num, F12_num, 2501 F13_num 2502 }; 2503 2504 const MachRegisterNumbers vsarg_reg[64] = { 2505 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2506 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2507 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2508 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2509 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2510 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2511 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2512 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2513 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2514 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2515 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2516 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2517 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2518 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2519 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2520 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2521 }; 2522 2523 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2524 2525 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2526 2527 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2528 2529 // Return whether or not this register is ever used as an argument. This 2530 // function is used on startup to build the trampoline stubs in generateOptoStub. 2531 // Registers not mentioned will be killed by the VM call in the trampoline, and 2532 // arguments in those registers not be available to the callee. 2533 bool Matcher::can_be_java_arg(int reg) { 2534 // We return true for all registers contained in iarg_reg[] and 2535 // farg_reg[] and their virtual halves. 2536 // We must include the virtual halves in order to get STDs and LDs 2537 // instead of STWs and LWs in the trampoline stubs. 2538 2539 if ( reg == R3_num || reg == R3_H_num 2540 || reg == R4_num || reg == R4_H_num 2541 || reg == R5_num || reg == R5_H_num 2542 || reg == R6_num || reg == R6_H_num 2543 || reg == R7_num || reg == R7_H_num 2544 || reg == R8_num || reg == R8_H_num 2545 || reg == R9_num || reg == R9_H_num 2546 || reg == R10_num || reg == R10_H_num) 2547 return true; 2548 2549 if ( reg == F1_num || reg == F1_H_num 2550 || reg == F2_num || reg == F2_H_num 2551 || reg == F3_num || reg == F3_H_num 2552 || reg == F4_num || reg == F4_H_num 2553 || reg == F5_num || reg == F5_H_num 2554 || reg == F6_num || reg == F6_H_num 2555 || reg == F7_num || reg == F7_H_num 2556 || reg == F8_num || reg == F8_H_num 2557 || reg == F9_num || reg == F9_H_num 2558 || reg == F10_num || reg == F10_H_num 2559 || reg == F11_num || reg == F11_H_num 2560 || reg == F12_num || reg == F12_H_num 2561 || reg == F13_num || reg == F13_H_num) 2562 return true; 2563 2564 return false; 2565 } 2566 2567 bool Matcher::is_spillable_arg(int reg) { 2568 return can_be_java_arg(reg); 2569 } 2570 2571 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2572 return false; 2573 } 2574 2575 // Register for DIVI projection of divmodI. 2576 RegMask Matcher::divI_proj_mask() { 2577 ShouldNotReachHere(); 2578 return RegMask(); 2579 } 2580 2581 // Register for MODI projection of divmodI. 2582 RegMask Matcher::modI_proj_mask() { 2583 ShouldNotReachHere(); 2584 return RegMask(); 2585 } 2586 2587 // Register for DIVL projection of divmodL. 2588 RegMask Matcher::divL_proj_mask() { 2589 ShouldNotReachHere(); 2590 return RegMask(); 2591 } 2592 2593 // Register for MODL projection of divmodL. 2594 RegMask Matcher::modL_proj_mask() { 2595 ShouldNotReachHere(); 2596 return RegMask(); 2597 } 2598 2599 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2600 return RegMask(); 2601 } 2602 2603 const bool Matcher::convi2l_type_required = true; 2604 2605 %} 2606 2607 //----------ENCODING BLOCK----------------------------------------------------- 2608 // This block specifies the encoding classes used by the compiler to output 2609 // byte streams. Encoding classes are parameterized macros used by 2610 // Machine Instruction Nodes in order to generate the bit encoding of the 2611 // instruction. Operands specify their base encoding interface with the 2612 // interface keyword. There are currently supported four interfaces, 2613 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2614 // operand to generate a function which returns its register number when 2615 // queried. CONST_INTER causes an operand to generate a function which 2616 // returns the value of the constant when queried. MEMORY_INTER causes an 2617 // operand to generate four functions which return the Base Register, the 2618 // Index Register, the Scale Value, and the Offset Value of the operand when 2619 // queried. COND_INTER causes an operand to generate six functions which 2620 // return the encoding code (ie - encoding bits for the instruction) 2621 // associated with each basic boolean condition for a conditional instruction. 2622 // 2623 // Instructions specify two basic values for encoding. Again, a function 2624 // is available to check if the constant displacement is an oop. They use the 2625 // ins_encode keyword to specify their encoding classes (which must be 2626 // a sequence of enc_class names, and their parameters, specified in 2627 // the encoding block), and they use the 2628 // opcode keyword to specify, in order, their primary, secondary, and 2629 // tertiary opcode. Only the opcode sections which a particular instruction 2630 // needs for encoding need to be specified. 2631 encode %{ 2632 enc_class enc_unimplemented %{ 2633 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2634 MacroAssembler _masm(&cbuf); 2635 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2636 %} 2637 2638 enc_class enc_untested %{ 2639 #ifdef ASSERT 2640 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2641 MacroAssembler _masm(&cbuf); 2642 __ untested("Untested mach node encoding in AD file."); 2643 #else 2644 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2645 #endif 2646 %} 2647 2648 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2649 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2650 MacroAssembler _masm(&cbuf); 2651 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2652 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2653 %} 2654 2655 // Load acquire. 2656 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2657 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2658 MacroAssembler _masm(&cbuf); 2659 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2660 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2661 __ twi_0($dst$$Register); 2662 __ isync(); 2663 %} 2664 2665 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2666 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2667 2668 MacroAssembler _masm(&cbuf); 2669 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2670 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2671 %} 2672 2673 // Load acquire. 2674 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2675 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2676 2677 MacroAssembler _masm(&cbuf); 2678 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2679 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2680 __ twi_0($dst$$Register); 2681 __ isync(); 2682 %} 2683 2684 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2685 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2686 2687 MacroAssembler _masm(&cbuf); 2688 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2689 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2690 %} 2691 2692 // Load acquire. 2693 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2694 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2695 2696 MacroAssembler _masm(&cbuf); 2697 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2698 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2699 __ twi_0($dst$$Register); 2700 __ isync(); 2701 %} 2702 2703 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2704 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2705 MacroAssembler _masm(&cbuf); 2706 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2707 // Operand 'ds' requires 4-alignment. 2708 assert((Idisp & 0x3) == 0, "unaligned offset"); 2709 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2710 %} 2711 2712 // Load acquire. 2713 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2714 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2715 MacroAssembler _masm(&cbuf); 2716 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2717 // Operand 'ds' requires 4-alignment. 2718 assert((Idisp & 0x3) == 0, "unaligned offset"); 2719 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2720 __ twi_0($dst$$Register); 2721 __ isync(); 2722 %} 2723 2724 enc_class enc_lfd(RegF dst, memory mem) %{ 2725 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2726 MacroAssembler _masm(&cbuf); 2727 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2728 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2729 %} 2730 2731 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2732 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2733 2734 MacroAssembler _masm(&cbuf); 2735 int toc_offset = 0; 2736 2737 address const_toc_addr; 2738 // Create a non-oop constant, no relocation needed. 2739 // If it is an IC, it has a virtual_call_Relocation. 2740 const_toc_addr = __ long_constant((jlong)$src$$constant); 2741 if (const_toc_addr == NULL) { 2742 ciEnv::current()->record_out_of_memory_failure(); 2743 return; 2744 } 2745 2746 // Get the constant's TOC offset. 2747 toc_offset = __ offset_to_method_toc(const_toc_addr); 2748 2749 // Keep the current instruction offset in mind. 2750 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2751 2752 __ ld($dst$$Register, toc_offset, $toc$$Register); 2753 %} 2754 2755 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2756 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2757 2758 MacroAssembler _masm(&cbuf); 2759 2760 if (!ra_->C->in_scratch_emit_size()) { 2761 address const_toc_addr; 2762 // Create a non-oop constant, no relocation needed. 2763 // If it is an IC, it has a virtual_call_Relocation. 2764 const_toc_addr = __ long_constant((jlong)$src$$constant); 2765 if (const_toc_addr == NULL) { 2766 ciEnv::current()->record_out_of_memory_failure(); 2767 return; 2768 } 2769 2770 // Get the constant's TOC offset. 2771 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2772 // Store the toc offset of the constant. 2773 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2774 2775 // Also keep the current instruction offset in mind. 2776 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2777 } 2778 2779 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2780 %} 2781 2782 %} // encode 2783 2784 source %{ 2785 2786 typedef struct { 2787 loadConL_hiNode *_large_hi; 2788 loadConL_loNode *_large_lo; 2789 loadConLNode *_small; 2790 MachNode *_last; 2791 } loadConLNodesTuple; 2792 2793 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2794 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2795 loadConLNodesTuple nodes; 2796 2797 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2798 if (large_constant_pool) { 2799 // Create new nodes. 2800 loadConL_hiNode *m1 = new loadConL_hiNode(); 2801 loadConL_loNode *m2 = new loadConL_loNode(); 2802 2803 // inputs for new nodes 2804 m1->add_req(NULL, toc); 2805 m2->add_req(NULL, m1); 2806 2807 // operands for new nodes 2808 m1->_opnds[0] = new iRegLdstOper(); // dst 2809 m1->_opnds[1] = immSrc; // src 2810 m1->_opnds[2] = new iRegPdstOper(); // toc 2811 m2->_opnds[0] = new iRegLdstOper(); // dst 2812 m2->_opnds[1] = immSrc; // src 2813 m2->_opnds[2] = new iRegLdstOper(); // base 2814 2815 // Initialize ins_attrib TOC fields. 2816 m1->_const_toc_offset = -1; 2817 m2->_const_toc_offset_hi_node = m1; 2818 2819 // Initialize ins_attrib instruction offset. 2820 m1->_cbuf_insts_offset = -1; 2821 2822 // register allocation for new nodes 2823 ra_->set_pair(m1->_idx, reg_second, reg_first); 2824 ra_->set_pair(m2->_idx, reg_second, reg_first); 2825 2826 // Create result. 2827 nodes._large_hi = m1; 2828 nodes._large_lo = m2; 2829 nodes._small = NULL; 2830 nodes._last = nodes._large_lo; 2831 assert(m2->bottom_type()->isa_long(), "must be long"); 2832 } else { 2833 loadConLNode *m2 = new loadConLNode(); 2834 2835 // inputs for new nodes 2836 m2->add_req(NULL, toc); 2837 2838 // operands for new nodes 2839 m2->_opnds[0] = new iRegLdstOper(); // dst 2840 m2->_opnds[1] = immSrc; // src 2841 m2->_opnds[2] = new iRegPdstOper(); // toc 2842 2843 // Initialize ins_attrib instruction offset. 2844 m2->_cbuf_insts_offset = -1; 2845 2846 // register allocation for new nodes 2847 ra_->set_pair(m2->_idx, reg_second, reg_first); 2848 2849 // Create result. 2850 nodes._large_hi = NULL; 2851 nodes._large_lo = NULL; 2852 nodes._small = m2; 2853 nodes._last = nodes._small; 2854 assert(m2->bottom_type()->isa_long(), "must be long"); 2855 } 2856 2857 return nodes; 2858 } 2859 2860 typedef struct { 2861 loadConL_hiNode *_large_hi; 2862 loadConL_loNode *_large_lo; 2863 mtvsrdNode *_moved; 2864 xxspltdNode *_replicated; 2865 loadConLNode *_small; 2866 MachNode *_last; 2867 } loadConLReplicatedNodesTuple; 2868 2869 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2870 vecXOper *dst, immI_0Oper *zero, 2871 OptoReg::Name reg_second, OptoReg::Name reg_first, 2872 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2873 loadConLReplicatedNodesTuple nodes; 2874 2875 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2876 if (large_constant_pool) { 2877 // Create new nodes. 2878 loadConL_hiNode *m1 = new loadConL_hiNode(); 2879 loadConL_loNode *m2 = new loadConL_loNode(); 2880 mtvsrdNode *m3 = new mtvsrdNode(); 2881 xxspltdNode *m4 = new xxspltdNode(); 2882 2883 // inputs for new nodes 2884 m1->add_req(NULL, toc); 2885 m2->add_req(NULL, m1); 2886 m3->add_req(NULL, m2); 2887 m4->add_req(NULL, m3); 2888 2889 // operands for new nodes 2890 m1->_opnds[0] = new iRegLdstOper(); // dst 2891 m1->_opnds[1] = immSrc; // src 2892 m1->_opnds[2] = new iRegPdstOper(); // toc 2893 2894 m2->_opnds[0] = new iRegLdstOper(); // dst 2895 m2->_opnds[1] = immSrc; // src 2896 m2->_opnds[2] = new iRegLdstOper(); // base 2897 2898 m3->_opnds[0] = new vecXOper(); // dst 2899 m3->_opnds[1] = new iRegLdstOper(); // src 2900 2901 m4->_opnds[0] = new vecXOper(); // dst 2902 m4->_opnds[1] = new vecXOper(); // src 2903 m4->_opnds[2] = zero; 2904 2905 // Initialize ins_attrib TOC fields. 2906 m1->_const_toc_offset = -1; 2907 m2->_const_toc_offset_hi_node = m1; 2908 2909 // Initialize ins_attrib instruction offset. 2910 m1->_cbuf_insts_offset = -1; 2911 2912 // register allocation for new nodes 2913 ra_->set_pair(m1->_idx, reg_second, reg_first); 2914 ra_->set_pair(m2->_idx, reg_second, reg_first); 2915 ra_->set1(m3->_idx, reg_second); 2916 ra_->set2(m3->_idx, reg_vec_first); 2917 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2918 2919 // Create result. 2920 nodes._large_hi = m1; 2921 nodes._large_lo = m2; 2922 nodes._moved = m3; 2923 nodes._replicated = m4; 2924 nodes._small = NULL; 2925 nodes._last = nodes._replicated; 2926 assert(m2->bottom_type()->isa_long(), "must be long"); 2927 } else { 2928 loadConLNode *m2 = new loadConLNode(); 2929 mtvsrdNode *m3 = new mtvsrdNode(); 2930 xxspltdNode *m4 = new xxspltdNode(); 2931 2932 // inputs for new nodes 2933 m2->add_req(NULL, toc); 2934 2935 // operands for new nodes 2936 m2->_opnds[0] = new iRegLdstOper(); // dst 2937 m2->_opnds[1] = immSrc; // src 2938 m2->_opnds[2] = new iRegPdstOper(); // toc 2939 2940 m3->_opnds[0] = new vecXOper(); // dst 2941 m3->_opnds[1] = new iRegLdstOper(); // src 2942 2943 m4->_opnds[0] = new vecXOper(); // dst 2944 m4->_opnds[1] = new vecXOper(); // src 2945 m4->_opnds[2] = zero; 2946 2947 // Initialize ins_attrib instruction offset. 2948 m2->_cbuf_insts_offset = -1; 2949 ra_->set1(m3->_idx, reg_second); 2950 ra_->set2(m3->_idx, reg_vec_first); 2951 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2952 2953 // register allocation for new nodes 2954 ra_->set_pair(m2->_idx, reg_second, reg_first); 2955 2956 // Create result. 2957 nodes._large_hi = NULL; 2958 nodes._large_lo = NULL; 2959 nodes._small = m2; 2960 nodes._moved = m3; 2961 nodes._replicated = m4; 2962 nodes._last = nodes._replicated; 2963 assert(m2->bottom_type()->isa_long(), "must be long"); 2964 } 2965 2966 return nodes; 2967 } 2968 2969 %} // source 2970 2971 encode %{ 2972 // Postalloc expand emitter for loading a long constant from the method's TOC. 2973 // Enc_class needed as consttanttablebase is not supported by postalloc 2974 // expand. 2975 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2976 // Create new nodes. 2977 loadConLNodesTuple loadConLNodes = 2978 loadConLNodesTuple_create(ra_, n_toc, op_src, 2979 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2980 2981 // Push new nodes. 2982 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2983 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2984 2985 // some asserts 2986 assert(nodes->length() >= 1, "must have created at least 1 node"); 2987 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2988 %} 2989 2990 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2991 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2992 2993 MacroAssembler _masm(&cbuf); 2994 int toc_offset = 0; 2995 2996 intptr_t val = $src$$constant; 2997 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2998 address const_toc_addr; 2999 if (constant_reloc == relocInfo::oop_type) { 3000 // Create an oop constant and a corresponding relocation. 3001 AddressLiteral a = __ allocate_oop_address((jobject)val); 3002 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3003 __ relocate(a.rspec()); 3004 } else if (constant_reloc == relocInfo::metadata_type) { 3005 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 3006 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3007 __ relocate(a.rspec()); 3008 } else { 3009 // Create a non-oop constant, no relocation needed. 3010 const_toc_addr = __ long_constant((jlong)$src$$constant); 3011 } 3012 3013 if (const_toc_addr == NULL) { 3014 ciEnv::current()->record_out_of_memory_failure(); 3015 return; 3016 } 3017 // Get the constant's TOC offset. 3018 toc_offset = __ offset_to_method_toc(const_toc_addr); 3019 3020 __ ld($dst$$Register, toc_offset, $toc$$Register); 3021 %} 3022 3023 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 3024 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 3025 3026 MacroAssembler _masm(&cbuf); 3027 if (!ra_->C->in_scratch_emit_size()) { 3028 intptr_t val = $src$$constant; 3029 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 3030 address const_toc_addr; 3031 if (constant_reloc == relocInfo::oop_type) { 3032 // Create an oop constant and a corresponding relocation. 3033 AddressLiteral a = __ allocate_oop_address((jobject)val); 3034 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3035 __ relocate(a.rspec()); 3036 } else if (constant_reloc == relocInfo::metadata_type) { 3037 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 3038 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3039 __ relocate(a.rspec()); 3040 } else { // non-oop pointers, e.g. card mark base, heap top 3041 // Create a non-oop constant, no relocation needed. 3042 const_toc_addr = __ long_constant((jlong)$src$$constant); 3043 } 3044 3045 if (const_toc_addr == NULL) { 3046 ciEnv::current()->record_out_of_memory_failure(); 3047 return; 3048 } 3049 // Get the constant's TOC offset. 3050 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 3051 // Store the toc offset of the constant. 3052 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 3053 } 3054 3055 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 3056 %} 3057 3058 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 3059 // Enc_class needed as consttanttablebase is not supported by postalloc 3060 // expand. 3061 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 3062 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3063 if (large_constant_pool) { 3064 // Create new nodes. 3065 loadConP_hiNode *m1 = new loadConP_hiNode(); 3066 loadConP_loNode *m2 = new loadConP_loNode(); 3067 3068 // inputs for new nodes 3069 m1->add_req(NULL, n_toc); 3070 m2->add_req(NULL, m1); 3071 3072 // operands for new nodes 3073 m1->_opnds[0] = new iRegPdstOper(); // dst 3074 m1->_opnds[1] = op_src; // src 3075 m1->_opnds[2] = new iRegPdstOper(); // toc 3076 m2->_opnds[0] = new iRegPdstOper(); // dst 3077 m2->_opnds[1] = op_src; // src 3078 m2->_opnds[2] = new iRegLdstOper(); // base 3079 3080 // Initialize ins_attrib TOC fields. 3081 m1->_const_toc_offset = -1; 3082 m2->_const_toc_offset_hi_node = m1; 3083 3084 // Register allocation for new nodes. 3085 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3086 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3087 3088 nodes->push(m1); 3089 nodes->push(m2); 3090 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3091 } else { 3092 loadConPNode *m2 = new loadConPNode(); 3093 3094 // inputs for new nodes 3095 m2->add_req(NULL, n_toc); 3096 3097 // operands for new nodes 3098 m2->_opnds[0] = new iRegPdstOper(); // dst 3099 m2->_opnds[1] = op_src; // src 3100 m2->_opnds[2] = new iRegPdstOper(); // toc 3101 3102 // Register allocation for new nodes. 3103 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3104 3105 nodes->push(m2); 3106 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3107 } 3108 %} 3109 3110 // Enc_class needed as consttanttablebase is not supported by postalloc 3111 // expand. 3112 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3113 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3114 3115 MachNode *m2; 3116 if (large_constant_pool) { 3117 m2 = new loadConFCompNode(); 3118 } else { 3119 m2 = new loadConFNode(); 3120 } 3121 // inputs for new nodes 3122 m2->add_req(NULL, n_toc); 3123 3124 // operands for new nodes 3125 m2->_opnds[0] = op_dst; 3126 m2->_opnds[1] = op_src; 3127 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3128 3129 // register allocation for new nodes 3130 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3131 nodes->push(m2); 3132 %} 3133 3134 // Enc_class needed as consttanttablebase is not supported by postalloc 3135 // expand. 3136 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3137 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3138 3139 MachNode *m2; 3140 if (large_constant_pool) { 3141 m2 = new loadConDCompNode(); 3142 } else { 3143 m2 = new loadConDNode(); 3144 } 3145 // inputs for new nodes 3146 m2->add_req(NULL, n_toc); 3147 3148 // operands for new nodes 3149 m2->_opnds[0] = op_dst; 3150 m2->_opnds[1] = op_src; 3151 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3152 3153 // register allocation for new nodes 3154 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3155 nodes->push(m2); 3156 %} 3157 3158 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3159 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3160 MacroAssembler _masm(&cbuf); 3161 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3162 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3163 %} 3164 3165 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3166 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3167 MacroAssembler _masm(&cbuf); 3168 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3169 // Operand 'ds' requires 4-alignment. 3170 assert((Idisp & 0x3) == 0, "unaligned offset"); 3171 __ std($src$$Register, Idisp, $mem$$base$$Register); 3172 %} 3173 3174 enc_class enc_stfs(RegF src, memory mem) %{ 3175 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3176 MacroAssembler _masm(&cbuf); 3177 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3178 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3179 %} 3180 3181 enc_class enc_stfd(RegF src, memory mem) %{ 3182 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3183 MacroAssembler _masm(&cbuf); 3184 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3185 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3186 %} 3187 3188 // Use release_store for card-marking to ensure that previous 3189 // oop-stores are visible before the card-mark change. 3190 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3191 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3192 // FIXME: Implement this as a cmove and use a fixed condition code 3193 // register which is written on every transition to compiled code, 3194 // e.g. in call-stub and when returning from runtime stubs. 3195 // 3196 // Proposed code sequence for the cmove implementation: 3197 // 3198 // Label skip_release; 3199 // __ beq(CCRfixed, skip_release); 3200 // __ release(); 3201 // __ bind(skip_release); 3202 // __ stb(card mark); 3203 3204 MacroAssembler _masm(&cbuf); 3205 Label skip_storestore; 3206 3207 #if 0 // TODO: PPC port 3208 // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the 3209 // StoreStore barrier conditionally. 3210 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3211 __ cmpwi($crx$$CondRegister, R0, 0); 3212 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3213 #endif 3214 __ li(R0, 0); 3215 __ membar(Assembler::StoreStore); 3216 #if 0 // TODO: PPC port 3217 __ bind(skip_storestore); 3218 #endif 3219 3220 // Do the store. 3221 if ($mem$$index == 0) { 3222 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3223 } else { 3224 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3225 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3226 } 3227 %} 3228 3229 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3230 3231 if (VM_Version::has_isel()) { 3232 // use isel instruction with Power 7 3233 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3234 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3235 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3236 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3237 3238 n_compare->add_req(n_region, n_src); 3239 n_compare->_opnds[0] = op_crx; 3240 n_compare->_opnds[1] = op_src; 3241 n_compare->_opnds[2] = new immL16Oper(0); 3242 3243 n_sub_base->add_req(n_region, n_src); 3244 n_sub_base->_opnds[0] = op_dst; 3245 n_sub_base->_opnds[1] = op_src; 3246 n_sub_base->_bottom_type = _bottom_type; 3247 3248 n_shift->add_req(n_region, n_sub_base); 3249 n_shift->_opnds[0] = op_dst; 3250 n_shift->_opnds[1] = op_dst; 3251 n_shift->_bottom_type = _bottom_type; 3252 3253 n_cond_set->add_req(n_region, n_compare, n_shift); 3254 n_cond_set->_opnds[0] = op_dst; 3255 n_cond_set->_opnds[1] = op_crx; 3256 n_cond_set->_opnds[2] = op_dst; 3257 n_cond_set->_bottom_type = _bottom_type; 3258 3259 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3260 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3261 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3262 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3263 3264 nodes->push(n_compare); 3265 nodes->push(n_sub_base); 3266 nodes->push(n_shift); 3267 nodes->push(n_cond_set); 3268 3269 } else { 3270 // before Power 7 3271 moveRegNode *n_move = new moveRegNode(); 3272 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3273 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3274 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3275 3276 n_move->add_req(n_region, n_src); 3277 n_move->_opnds[0] = op_dst; 3278 n_move->_opnds[1] = op_src; 3279 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3280 3281 n_compare->add_req(n_region, n_src); 3282 n_compare->add_prec(n_move); 3283 3284 n_compare->_opnds[0] = op_crx; 3285 n_compare->_opnds[1] = op_src; 3286 n_compare->_opnds[2] = new immL16Oper(0); 3287 3288 n_sub_base->add_req(n_region, n_compare, n_src); 3289 n_sub_base->_opnds[0] = op_dst; 3290 n_sub_base->_opnds[1] = op_crx; 3291 n_sub_base->_opnds[2] = op_src; 3292 n_sub_base->_bottom_type = _bottom_type; 3293 3294 n_shift->add_req(n_region, n_sub_base); 3295 n_shift->_opnds[0] = op_dst; 3296 n_shift->_opnds[1] = op_dst; 3297 n_shift->_bottom_type = _bottom_type; 3298 3299 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3300 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3301 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3302 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3303 3304 nodes->push(n_move); 3305 nodes->push(n_compare); 3306 nodes->push(n_sub_base); 3307 nodes->push(n_shift); 3308 } 3309 3310 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3311 %} 3312 3313 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3314 3315 encodeP_subNode *n1 = new encodeP_subNode(); 3316 n1->add_req(n_region, n_src); 3317 n1->_opnds[0] = op_dst; 3318 n1->_opnds[1] = op_src; 3319 n1->_bottom_type = _bottom_type; 3320 3321 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3322 n2->add_req(n_region, n1); 3323 n2->_opnds[0] = op_dst; 3324 n2->_opnds[1] = op_dst; 3325 n2->_bottom_type = _bottom_type; 3326 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3327 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3328 3329 nodes->push(n1); 3330 nodes->push(n2); 3331 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3332 %} 3333 3334 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3335 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3336 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3337 3338 n_compare->add_req(n_region, n_src); 3339 n_compare->_opnds[0] = op_crx; 3340 n_compare->_opnds[1] = op_src; 3341 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3342 3343 n_shift->add_req(n_region, n_src); 3344 n_shift->_opnds[0] = op_dst; 3345 n_shift->_opnds[1] = op_src; 3346 n_shift->_bottom_type = _bottom_type; 3347 3348 if (VM_Version::has_isel()) { 3349 // use isel instruction with Power 7 3350 3351 decodeN_addNode *n_add_base = new decodeN_addNode(); 3352 n_add_base->add_req(n_region, n_shift); 3353 n_add_base->_opnds[0] = op_dst; 3354 n_add_base->_opnds[1] = op_dst; 3355 n_add_base->_bottom_type = _bottom_type; 3356 3357 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3358 n_cond_set->add_req(n_region, n_compare, n_add_base); 3359 n_cond_set->_opnds[0] = op_dst; 3360 n_cond_set->_opnds[1] = op_crx; 3361 n_cond_set->_opnds[2] = op_dst; 3362 n_cond_set->_bottom_type = _bottom_type; 3363 3364 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3365 ra_->set_oop(n_cond_set, true); 3366 3367 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3368 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3369 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3370 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3371 3372 nodes->push(n_compare); 3373 nodes->push(n_shift); 3374 nodes->push(n_add_base); 3375 nodes->push(n_cond_set); 3376 3377 } else { 3378 // before Power 7 3379 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3380 3381 n_add_base->add_req(n_region, n_compare, n_shift); 3382 n_add_base->_opnds[0] = op_dst; 3383 n_add_base->_opnds[1] = op_crx; 3384 n_add_base->_opnds[2] = op_dst; 3385 n_add_base->_bottom_type = _bottom_type; 3386 3387 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3388 ra_->set_oop(n_add_base, true); 3389 3390 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3391 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3392 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3393 3394 nodes->push(n_compare); 3395 nodes->push(n_shift); 3396 nodes->push(n_add_base); 3397 } 3398 %} 3399 3400 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3401 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3402 n1->add_req(n_region, n_src); 3403 n1->_opnds[0] = op_dst; 3404 n1->_opnds[1] = op_src; 3405 n1->_bottom_type = _bottom_type; 3406 3407 decodeN_addNode *n2 = new decodeN_addNode(); 3408 n2->add_req(n_region, n1); 3409 n2->_opnds[0] = op_dst; 3410 n2->_opnds[1] = op_dst; 3411 n2->_bottom_type = _bottom_type; 3412 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3413 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3414 3415 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3416 ra_->set_oop(n2, true); 3417 3418 nodes->push(n1); 3419 nodes->push(n2); 3420 %} 3421 3422 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3423 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3424 3425 MacroAssembler _masm(&cbuf); 3426 int cc = $cmp$$cmpcode; 3427 int flags_reg = $crx$$reg; 3428 Label done; 3429 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3430 // Branch if not (cmp crx). 3431 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3432 __ mr($dst$$Register, $src$$Register); 3433 // TODO PPC port __ endgroup_if_needed(_size == 12); 3434 __ bind(done); 3435 %} 3436 3437 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3438 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3439 3440 MacroAssembler _masm(&cbuf); 3441 Label done; 3442 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3443 // Branch if not (cmp crx). 3444 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3445 __ li($dst$$Register, $src$$constant); 3446 // TODO PPC port __ endgroup_if_needed(_size == 12); 3447 __ bind(done); 3448 %} 3449 3450 // This enc_class is needed so that scheduler gets proper 3451 // input mapping for latency computation. 3452 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3453 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3454 MacroAssembler _masm(&cbuf); 3455 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3456 %} 3457 3458 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3459 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3460 3461 MacroAssembler _masm(&cbuf); 3462 3463 Label done; 3464 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3465 __ li($dst$$Register, $zero$$constant); 3466 __ beq($crx$$CondRegister, done); 3467 __ li($dst$$Register, $notzero$$constant); 3468 __ bind(done); 3469 %} 3470 3471 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3472 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3473 3474 MacroAssembler _masm(&cbuf); 3475 3476 Label done; 3477 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3478 __ li($dst$$Register, $zero$$constant); 3479 __ beq($crx$$CondRegister, done); 3480 __ li($dst$$Register, $notzero$$constant); 3481 __ bind(done); 3482 %} 3483 3484 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3485 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3486 3487 MacroAssembler _masm(&cbuf); 3488 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3489 Label done; 3490 __ bso($crx$$CondRegister, done); 3491 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3492 // TODO PPC port __ endgroup_if_needed(_size == 12); 3493 __ bind(done); 3494 %} 3495 3496 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3497 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3498 3499 MacroAssembler _masm(&cbuf); 3500 Label done; 3501 __ bso($crx$$CondRegister, done); 3502 __ mffprd($dst$$Register, $src$$FloatRegister); 3503 // TODO PPC port __ endgroup_if_needed(_size == 12); 3504 __ bind(done); 3505 %} 3506 3507 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3508 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3509 3510 MacroAssembler _masm(&cbuf); 3511 Label d; // dummy 3512 __ bind(d); 3513 Label* p = ($lbl$$label); 3514 // `p' is `NULL' when this encoding class is used only to 3515 // determine the size of the encoded instruction. 3516 Label& l = (NULL == p)? d : *(p); 3517 int cc = $cmp$$cmpcode; 3518 int flags_reg = $crx$$reg; 3519 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3520 int bhint = Assembler::bhintNoHint; 3521 3522 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3523 if (_prob <= PROB_NEVER) { 3524 bhint = Assembler::bhintIsNotTaken; 3525 } else if (_prob >= PROB_ALWAYS) { 3526 bhint = Assembler::bhintIsTaken; 3527 } 3528 } 3529 3530 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3531 cc_to_biint(cc, flags_reg), 3532 l); 3533 %} 3534 3535 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3536 // The scheduler doesn't know about branch shortening, so we set the opcode 3537 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3538 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3539 3540 MacroAssembler _masm(&cbuf); 3541 Label d; // dummy 3542 __ bind(d); 3543 Label* p = ($lbl$$label); 3544 // `p' is `NULL' when this encoding class is used only to 3545 // determine the size of the encoded instruction. 3546 Label& l = (NULL == p)? d : *(p); 3547 int cc = $cmp$$cmpcode; 3548 int flags_reg = $crx$$reg; 3549 int bhint = Assembler::bhintNoHint; 3550 3551 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3552 if (_prob <= PROB_NEVER) { 3553 bhint = Assembler::bhintIsNotTaken; 3554 } else if (_prob >= PROB_ALWAYS) { 3555 bhint = Assembler::bhintIsTaken; 3556 } 3557 } 3558 3559 // Tell the conditional far branch to optimize itself when being relocated. 3560 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3561 cc_to_biint(cc, flags_reg), 3562 l, 3563 MacroAssembler::bc_far_optimize_on_relocate); 3564 %} 3565 3566 // Branch used with Power6 scheduling (can be shortened without changing the node). 3567 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3568 // The scheduler doesn't know about branch shortening, so we set the opcode 3569 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3570 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3571 3572 MacroAssembler _masm(&cbuf); 3573 Label d; // dummy 3574 __ bind(d); 3575 Label* p = ($lbl$$label); 3576 // `p' is `NULL' when this encoding class is used only to 3577 // determine the size of the encoded instruction. 3578 Label& l = (NULL == p)? d : *(p); 3579 int cc = $cmp$$cmpcode; 3580 int flags_reg = $crx$$reg; 3581 int bhint = Assembler::bhintNoHint; 3582 3583 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3584 if (_prob <= PROB_NEVER) { 3585 bhint = Assembler::bhintIsNotTaken; 3586 } else if (_prob >= PROB_ALWAYS) { 3587 bhint = Assembler::bhintIsTaken; 3588 } 3589 } 3590 3591 #if 0 // TODO: PPC port 3592 if (_size == 8) { 3593 // Tell the conditional far branch to optimize itself when being relocated. 3594 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3595 cc_to_biint(cc, flags_reg), 3596 l, 3597 MacroAssembler::bc_far_optimize_on_relocate); 3598 } else { 3599 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3600 cc_to_biint(cc, flags_reg), 3601 l); 3602 } 3603 #endif 3604 Unimplemented(); 3605 %} 3606 3607 // Postalloc expand emitter for loading a replicatef float constant from 3608 // the method's TOC. 3609 // Enc_class needed as consttanttablebase is not supported by postalloc 3610 // expand. 3611 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3612 // Create new nodes. 3613 3614 // Make an operand with the bit pattern to load as float. 3615 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3616 3617 loadConLNodesTuple loadConLNodes = 3618 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3619 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3620 3621 // Push new nodes. 3622 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3623 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3624 3625 assert(nodes->length() >= 1, "must have created at least 1 node"); 3626 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3627 %} 3628 3629 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3630 // Create new nodes. 3631 3632 // Make an operand with the bit pattern to load as float. 3633 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3634 immI_0Oper *op_zero = new immI_0Oper(0); 3635 3636 loadConLReplicatedNodesTuple loadConLNodes = 3637 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3638 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3639 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3640 3641 // Push new nodes. 3642 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3643 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3644 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3645 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3646 3647 assert(nodes->length() >= 1, "must have created at least 1 node"); 3648 %} 3649 3650 // This enc_class is needed so that scheduler gets proper 3651 // input mapping for latency computation. 3652 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3653 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3654 // Fake operand dst needed for PPC scheduler. 3655 assert($dst$$constant == 0x0, "dst must be 0x0"); 3656 3657 MacroAssembler _masm(&cbuf); 3658 // Mark the code position where the load from the safepoint 3659 // polling page was emitted as relocInfo::poll_type. 3660 __ relocate(relocInfo::poll_type); 3661 __ load_from_polling_page($poll$$Register); 3662 %} 3663 3664 // A Java static call or a runtime call. 3665 // 3666 // Branch-and-link relative to a trampoline. 3667 // The trampoline loads the target address and does a long branch to there. 3668 // In case we call java, the trampoline branches to a interpreter_stub 3669 // which loads the inline cache and the real call target from the constant pool. 3670 // 3671 // This basically looks like this: 3672 // 3673 // >>>> consts -+ -+ 3674 // | |- offset1 3675 // [call target1] | <-+ 3676 // [IC cache] |- offset2 3677 // [call target2] <--+ 3678 // 3679 // <<<< consts 3680 // >>>> insts 3681 // 3682 // bl offset16 -+ -+ ??? // How many bits available? 3683 // | | 3684 // <<<< insts | | 3685 // >>>> stubs | | 3686 // | |- trampoline_stub_Reloc 3687 // trampoline stub: | <-+ 3688 // r2 = toc | 3689 // r2 = [r2 + offset1] | // Load call target1 from const section 3690 // mtctr r2 | 3691 // bctr |- static_stub_Reloc 3692 // comp_to_interp_stub: <---+ 3693 // r1 = toc 3694 // ICreg = [r1 + IC_offset] // Load IC from const section 3695 // r1 = [r1 + offset2] // Load call target2 from const section 3696 // mtctr r1 3697 // bctr 3698 // 3699 // <<<< stubs 3700 // 3701 // The call instruction in the code either 3702 // - Branches directly to a compiled method if the offset is encodable in instruction. 3703 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3704 // - Branches to the compiled_to_interp stub if the target is interpreted. 3705 // 3706 // Further there are three relocations from the loads to the constants in 3707 // the constant section. 3708 // 3709 // Usage of r1 and r2 in the stubs allows to distinguish them. 3710 enc_class enc_java_static_call(method meth) %{ 3711 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3712 3713 MacroAssembler _masm(&cbuf); 3714 address entry_point = (address)$meth$$method; 3715 3716 if (!_method) { 3717 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3718 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3719 } else { 3720 // Remember the offset not the address. 3721 const int start_offset = __ offset(); 3722 3723 // The trampoline stub. 3724 // No entry point given, use the current pc. 3725 // Make sure branch fits into 3726 if (entry_point == 0) entry_point = __ pc(); 3727 3728 // Put the entry point as a constant into the constant pool. 3729 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3730 if (entry_point_toc_addr == NULL) { 3731 ciEnv::current()->record_out_of_memory_failure(); 3732 return; 3733 } 3734 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3735 3736 // Emit the trampoline stub which will be related to the branch-and-link below. 3737 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3738 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3739 int method_index = resolved_method_index(cbuf); 3740 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3741 : static_call_Relocation::spec(method_index)); 3742 3743 // The real call. 3744 // Note: At this point we do not have the address of the trampoline 3745 // stub, and the entry point might be too far away for bl, so __ pc() 3746 // serves as dummy and the bl will be patched later. 3747 cbuf.set_insts_mark(); 3748 __ bl(__ pc()); // Emits a relocation. 3749 3750 // The stub for call to interpreter. 3751 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3752 if (stub == NULL) { 3753 ciEnv::current()->record_failure("CodeCache is full"); 3754 return; 3755 } 3756 } 3757 %} 3758 3759 // Second node of expanded dynamic call - the call. 3760 enc_class enc_java_dynamic_call_sched(method meth) %{ 3761 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3762 3763 MacroAssembler _masm(&cbuf); 3764 3765 if (!ra_->C->in_scratch_emit_size()) { 3766 // Create a call trampoline stub for the given method. 3767 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3768 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3769 if (entry_point_const == NULL) { 3770 ciEnv::current()->record_out_of_memory_failure(); 3771 return; 3772 } 3773 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3774 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3775 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3776 3777 // Build relocation at call site with ic position as data. 3778 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3779 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3780 "must have one, but can't have both"); 3781 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3782 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3783 "must contain instruction offset"); 3784 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3785 ? _load_ic_hi_node->_cbuf_insts_offset 3786 : _load_ic_node->_cbuf_insts_offset; 3787 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3788 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3789 "should be load from TOC"); 3790 int method_index = resolved_method_index(cbuf); 3791 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3792 } 3793 3794 // At this point I do not have the address of the trampoline stub, 3795 // and the entry point might be too far away for bl. Pc() serves 3796 // as dummy and bl will be patched later. 3797 __ bl((address) __ pc()); 3798 %} 3799 3800 // postalloc expand emitter for virtual calls. 3801 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3802 3803 // Create the nodes for loading the IC from the TOC. 3804 loadConLNodesTuple loadConLNodes_IC = 3805 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3806 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3807 3808 // Create the call node. 3809 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3810 call->_method_handle_invoke = _method_handle_invoke; 3811 call->_vtable_index = _vtable_index; 3812 call->_method = _method; 3813 call->_bci = _bci; 3814 call->_optimized_virtual = _optimized_virtual; 3815 call->_tf = _tf; 3816 call->_entry_point = _entry_point; 3817 call->_cnt = _cnt; 3818 call->_argsize = _argsize; 3819 call->_oop_map = _oop_map; 3820 call->_jvms = _jvms; 3821 call->_jvmadj = _jvmadj; 3822 call->_in_rms = _in_rms; 3823 call->_nesting = _nesting; 3824 call->_override_symbolic_info = _override_symbolic_info; 3825 3826 // New call needs all inputs of old call. 3827 // Req... 3828 for (uint i = 0; i < req(); ++i) { 3829 // The expanded node does not need toc any more. 3830 // Add the inline cache constant here instead. This expresses the 3831 // register of the inline cache must be live at the call. 3832 // Else we would have to adapt JVMState by -1. 3833 if (i == mach_constant_base_node_input()) { 3834 call->add_req(loadConLNodes_IC._last); 3835 } else { 3836 call->add_req(in(i)); 3837 } 3838 } 3839 // ...as well as prec 3840 for (uint i = req(); i < len(); ++i) { 3841 call->add_prec(in(i)); 3842 } 3843 3844 // Remember nodes loading the inline cache into r19. 3845 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3846 call->_load_ic_node = loadConLNodes_IC._small; 3847 3848 // Operands for new nodes. 3849 call->_opnds[0] = _opnds[0]; 3850 call->_opnds[1] = _opnds[1]; 3851 3852 // Only the inline cache is associated with a register. 3853 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3854 3855 // Push new nodes. 3856 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3857 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3858 nodes->push(call); 3859 %} 3860 3861 // Compound version of call dynamic 3862 // Toc is only passed so that it can be used in ins_encode statement. 3863 // In the code we have to use $constanttablebase. 3864 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3865 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3866 MacroAssembler _masm(&cbuf); 3867 int start_offset = __ offset(); 3868 3869 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3870 #if 0 3871 int vtable_index = this->_vtable_index; 3872 if (_vtable_index < 0) { 3873 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3874 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3875 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3876 3877 // Virtual call relocation will point to ic load. 3878 address virtual_call_meta_addr = __ pc(); 3879 // Load a clear inline cache. 3880 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3881 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3882 if (!success) { 3883 ciEnv::current()->record_out_of_memory_failure(); 3884 return; 3885 } 3886 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3887 // to determine who we intended to call. 3888 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3889 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3890 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3891 "Fix constant in ret_addr_offset()"); 3892 } else { 3893 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3894 // Go thru the vtable. Get receiver klass. Receiver already 3895 // checked for non-null. If we'll go thru a C2I adapter, the 3896 // interpreter expects method in R19_method. 3897 3898 __ load_klass(R11_scratch1, R3); 3899 3900 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3901 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3902 __ li(R19_method, v_off); 3903 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3904 // NOTE: for vtable dispatches, the vtable entry will never be 3905 // null. However it may very well end up in handle_wrong_method 3906 // if the method is abstract for the particular class. 3907 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3908 // Call target. Either compiled code or C2I adapter. 3909 __ mtctr(R11_scratch1); 3910 __ bctrl(); 3911 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3912 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3913 } 3914 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3915 "Fix constant in ret_addr_offset()"); 3916 } 3917 #endif 3918 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3919 %} 3920 3921 // a runtime call 3922 enc_class enc_java_to_runtime_call (method meth) %{ 3923 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3924 3925 MacroAssembler _masm(&cbuf); 3926 const address start_pc = __ pc(); 3927 3928 #if defined(ABI_ELFv2) 3929 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3930 __ call_c(entry, relocInfo::runtime_call_type); 3931 #else 3932 // The function we're going to call. 3933 FunctionDescriptor fdtemp; 3934 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3935 3936 Register Rtoc = R12_scratch2; 3937 // Calculate the method's TOC. 3938 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3939 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3940 // pool entries; call_c_using_toc will optimize the call. 3941 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3942 if (!success) { 3943 ciEnv::current()->record_out_of_memory_failure(); 3944 return; 3945 } 3946 #endif 3947 3948 // Check the ret_addr_offset. 3949 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3950 "Fix constant in ret_addr_offset()"); 3951 %} 3952 3953 // Move to ctr for leaf call. 3954 // This enc_class is needed so that scheduler gets proper 3955 // input mapping for latency computation. 3956 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3957 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3958 MacroAssembler _masm(&cbuf); 3959 __ mtctr($src$$Register); 3960 %} 3961 3962 // Postalloc expand emitter for runtime leaf calls. 3963 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3964 loadConLNodesTuple loadConLNodes_Entry; 3965 #if defined(ABI_ELFv2) 3966 jlong entry_address = (jlong) this->entry_point(); 3967 assert(entry_address, "need address here"); 3968 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3969 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3970 #else 3971 // Get the struct that describes the function we are about to call. 3972 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3973 assert(fd, "need fd here"); 3974 jlong entry_address = (jlong) fd->entry(); 3975 // new nodes 3976 loadConLNodesTuple loadConLNodes_Env; 3977 loadConLNodesTuple loadConLNodes_Toc; 3978 3979 // Create nodes and operands for loading the entry point. 3980 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3981 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3982 3983 3984 // Create nodes and operands for loading the env pointer. 3985 if (fd->env() != NULL) { 3986 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3987 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3988 } else { 3989 loadConLNodes_Env._large_hi = NULL; 3990 loadConLNodes_Env._large_lo = NULL; 3991 loadConLNodes_Env._small = NULL; 3992 loadConLNodes_Env._last = new loadConL16Node(); 3993 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3994 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3995 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3996 } 3997 3998 // Create nodes and operands for loading the Toc point. 3999 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 4000 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 4001 #endif // ABI_ELFv2 4002 // mtctr node 4003 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 4004 4005 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 4006 mtctr->add_req(0, loadConLNodes_Entry._last); 4007 4008 mtctr->_opnds[0] = new iRegLdstOper(); 4009 mtctr->_opnds[1] = new iRegLdstOper(); 4010 4011 // call node 4012 MachCallLeafNode *call = new CallLeafDirectNode(); 4013 4014 call->_opnds[0] = _opnds[0]; 4015 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 4016 4017 // Make the new call node look like the old one. 4018 call->_name = _name; 4019 call->_tf = _tf; 4020 call->_entry_point = _entry_point; 4021 call->_cnt = _cnt; 4022 call->_argsize = _argsize; 4023 call->_oop_map = _oop_map; 4024 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 4025 call->_jvms = NULL; 4026 call->_jvmadj = _jvmadj; 4027 call->_in_rms = _in_rms; 4028 call->_nesting = _nesting; 4029 4030 4031 // New call needs all inputs of old call. 4032 // Req... 4033 for (uint i = 0; i < req(); ++i) { 4034 if (i != mach_constant_base_node_input()) { 4035 call->add_req(in(i)); 4036 } 4037 } 4038 4039 // These must be reqired edges, as the registers are live up to 4040 // the call. Else the constants are handled as kills. 4041 call->add_req(mtctr); 4042 #if !defined(ABI_ELFv2) 4043 call->add_req(loadConLNodes_Env._last); 4044 call->add_req(loadConLNodes_Toc._last); 4045 #endif 4046 4047 // ...as well as prec 4048 for (uint i = req(); i < len(); ++i) { 4049 call->add_prec(in(i)); 4050 } 4051 4052 // registers 4053 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 4054 4055 // Insert the new nodes. 4056 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 4057 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 4058 #if !defined(ABI_ELFv2) 4059 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 4060 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 4061 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 4062 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 4063 #endif 4064 nodes->push(mtctr); 4065 nodes->push(call); 4066 %} 4067 %} 4068 4069 //----------FRAME-------------------------------------------------------------- 4070 // Definition of frame structure and management information. 4071 4072 frame %{ 4073 // What direction does stack grow in (assumed to be same for native & Java). 4074 stack_direction(TOWARDS_LOW); 4075 4076 // These two registers define part of the calling convention between 4077 // compiled code and the interpreter. 4078 4079 // Inline Cache Register or method for I2C. 4080 inline_cache_reg(R19); // R19_method 4081 4082 // Method Oop Register when calling interpreter. 4083 interpreter_method_oop_reg(R19); // R19_method 4084 4085 // Optional: name the operand used by cisc-spilling to access 4086 // [stack_pointer + offset]. 4087 cisc_spilling_operand_name(indOffset); 4088 4089 // Number of stack slots consumed by a Monitor enter. 4090 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 4091 4092 // Compiled code's Frame Pointer. 4093 frame_pointer(R1); // R1_SP 4094 4095 // Interpreter stores its frame pointer in a register which is 4096 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 4097 // interpreted java to compiled java. 4098 // 4099 // R14_state holds pointer to caller's cInterpreter. 4100 interpreter_frame_pointer(R14); // R14_state 4101 4102 stack_alignment(frame::alignment_in_bytes); 4103 4104 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4105 4106 // Number of outgoing stack slots killed above the 4107 // out_preserve_stack_slots for calls to C. Supports the var-args 4108 // backing area for register parms. 4109 // 4110 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4111 4112 // The after-PROLOG location of the return address. Location of 4113 // return address specifies a type (REG or STACK) and a number 4114 // representing the register number (i.e. - use a register name) or 4115 // stack slot. 4116 // 4117 // A: Link register is stored in stack slot ... 4118 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4119 // J: Therefore, we make sure that the link register is also in R11_scratch1 4120 // at the end of the prolog. 4121 // B: We use R20, now. 4122 //return_addr(REG R20); 4123 4124 // G: After reading the comments made by all the luminaries on their 4125 // failure to tell the compiler where the return address really is, 4126 // I hardly dare to try myself. However, I'm convinced it's in slot 4127 // 4 what apparently works and saves us some spills. 4128 return_addr(STACK 4); 4129 4130 // This is the body of the function 4131 // 4132 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4133 // uint length, // length of array 4134 // bool is_outgoing) 4135 // 4136 // The `sig' array is to be updated. sig[j] represents the location 4137 // of the j-th argument, either a register or a stack slot. 4138 4139 // Comment taken from i486.ad: 4140 // Body of function which returns an integer array locating 4141 // arguments either in registers or in stack slots. Passed an array 4142 // of ideal registers called "sig" and a "length" count. Stack-slot 4143 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4144 // arguments for a CALLEE. Incoming stack arguments are 4145 // automatically biased by the preserve_stack_slots field above. 4146 calling_convention %{ 4147 // No difference between ingoing/outgoing. Just pass false. 4148 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4149 %} 4150 4151 // Comment taken from i486.ad: 4152 // Body of function which returns an integer array locating 4153 // arguments either in registers or in stack slots. Passed an array 4154 // of ideal registers called "sig" and a "length" count. Stack-slot 4155 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4156 // arguments for a CALLEE. Incoming stack arguments are 4157 // automatically biased by the preserve_stack_slots field above. 4158 c_calling_convention %{ 4159 // This is obviously always outgoing. 4160 // C argument in register AND stack slot. 4161 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4162 %} 4163 4164 // Location of native (C/C++) and interpreter return values. This 4165 // is specified to be the same as Java. In the 32-bit VM, long 4166 // values are actually returned from native calls in O0:O1 and 4167 // returned to the interpreter in I0:I1. The copying to and from 4168 // the register pairs is done by the appropriate call and epilog 4169 // opcodes. This simplifies the register allocator. 4170 c_return_value %{ 4171 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4172 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0), 4173 "only return normal values"); 4174 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4175 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4176 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4177 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4178 %} 4179 4180 // Location of compiled Java return values. Same as C 4181 return_value %{ 4182 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4183 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0), 4184 "only return normal values"); 4185 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4186 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4187 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4188 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4189 %} 4190 %} 4191 4192 4193 //----------ATTRIBUTES--------------------------------------------------------- 4194 4195 //----------Operand Attributes------------------------------------------------- 4196 op_attrib op_cost(1); // Required cost attribute. 4197 4198 //----------Instruction Attributes--------------------------------------------- 4199 4200 // Cost attribute. required. 4201 ins_attrib ins_cost(DEFAULT_COST); 4202 4203 // Is this instruction a non-matching short branch variant of some 4204 // long branch? Not required. 4205 ins_attrib ins_short_branch(0); 4206 4207 ins_attrib ins_is_TrapBasedCheckNode(true); 4208 4209 // Number of constants. 4210 // This instruction uses the given number of constants 4211 // (optional attribute). 4212 // This is needed to determine in time whether the constant pool will 4213 // exceed 4000 entries. Before postalloc_expand the overall number of constants 4214 // is determined. It's also used to compute the constant pool size 4215 // in Output(). 4216 ins_attrib ins_num_consts(0); 4217 4218 // Required alignment attribute (must be a power of 2) specifies the 4219 // alignment that some part of the instruction (not necessarily the 4220 // start) requires. If > 1, a compute_padding() function must be 4221 // provided for the instruction. 4222 ins_attrib ins_alignment(1); 4223 4224 // Enforce/prohibit rematerializations. 4225 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4226 // then rematerialization of that instruction is prohibited and the 4227 // instruction's value will be spilled if necessary. 4228 // Causes that MachNode::rematerialize() returns false. 4229 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 4230 // then rematerialization should be enforced and a copy of the instruction 4231 // should be inserted if possible; rematerialization is not guaranteed. 4232 // Note: this may result in rematerializations in front of every use. 4233 // Causes that MachNode::rematerialize() can return true. 4234 // (optional attribute) 4235 ins_attrib ins_cannot_rematerialize(false); 4236 ins_attrib ins_should_rematerialize(false); 4237 4238 // Instruction has variable size depending on alignment. 4239 ins_attrib ins_variable_size_depending_on_alignment(false); 4240 4241 // Instruction is a nop. 4242 ins_attrib ins_is_nop(false); 4243 4244 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4245 ins_attrib ins_use_mach_if_fast_lock_node(false); 4246 4247 // Field for the toc offset of a constant. 4248 // 4249 // This is needed if the toc offset is not encodable as an immediate in 4250 // the PPC load instruction. If so, the upper (hi) bits of the offset are 4251 // added to the toc, and from this a load with immediate is performed. 4252 // With postalloc expand, we get two nodes that require the same offset 4253 // but which don't know about each other. The offset is only known 4254 // when the constant is added to the constant pool during emitting. 4255 // It is generated in the 'hi'-node adding the upper bits, and saved 4256 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 4257 // the offset from there when it gets encoded. 4258 ins_attrib ins_field_const_toc_offset(0); 4259 ins_attrib ins_field_const_toc_offset_hi_node(0); 4260 4261 // A field that can hold the instructions offset in the code buffer. 4262 // Set in the nodes emitter. 4263 ins_attrib ins_field_cbuf_insts_offset(-1); 4264 4265 // Fields for referencing a call's load-IC-node. 4266 // If the toc offset can not be encoded as an immediate in a load, we 4267 // use two nodes. 4268 ins_attrib ins_field_load_ic_hi_node(0); 4269 ins_attrib ins_field_load_ic_node(0); 4270 4271 //----------OPERANDS----------------------------------------------------------- 4272 // Operand definitions must precede instruction definitions for correct 4273 // parsing in the ADLC because operands constitute user defined types 4274 // which are used in instruction definitions. 4275 // 4276 // Formats are generated automatically for constants and base registers. 4277 4278 operand vecX() %{ 4279 constraint(ALLOC_IN_RC(vs_reg)); 4280 match(VecX); 4281 4282 format %{ %} 4283 interface(REG_INTER); 4284 %} 4285 4286 //----------Simple Operands---------------------------------------------------- 4287 // Immediate Operands 4288 4289 // Integer Immediate: 32-bit 4290 operand immI() %{ 4291 match(ConI); 4292 op_cost(40); 4293 format %{ %} 4294 interface(CONST_INTER); 4295 %} 4296 4297 operand immI8() %{ 4298 predicate(Assembler::is_simm(n->get_int(), 8)); 4299 op_cost(0); 4300 match(ConI); 4301 format %{ %} 4302 interface(CONST_INTER); 4303 %} 4304 4305 // Integer Immediate: 16-bit 4306 operand immI16() %{ 4307 predicate(Assembler::is_simm(n->get_int(), 16)); 4308 op_cost(0); 4309 match(ConI); 4310 format %{ %} 4311 interface(CONST_INTER); 4312 %} 4313 4314 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4315 operand immIhi16() %{ 4316 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4317 match(ConI); 4318 op_cost(0); 4319 format %{ %} 4320 interface(CONST_INTER); 4321 %} 4322 4323 operand immInegpow2() %{ 4324 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 4325 match(ConI); 4326 op_cost(0); 4327 format %{ %} 4328 interface(CONST_INTER); 4329 %} 4330 4331 operand immIpow2minus1() %{ 4332 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 4333 match(ConI); 4334 op_cost(0); 4335 format %{ %} 4336 interface(CONST_INTER); 4337 %} 4338 4339 operand immIpowerOf2() %{ 4340 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 4341 match(ConI); 4342 op_cost(0); 4343 format %{ %} 4344 interface(CONST_INTER); 4345 %} 4346 4347 // Unsigned Integer Immediate: the values 0-31 4348 operand uimmI5() %{ 4349 predicate(Assembler::is_uimm(n->get_int(), 5)); 4350 match(ConI); 4351 op_cost(0); 4352 format %{ %} 4353 interface(CONST_INTER); 4354 %} 4355 4356 // Unsigned Integer Immediate: 6-bit 4357 operand uimmI6() %{ 4358 predicate(Assembler::is_uimm(n->get_int(), 6)); 4359 match(ConI); 4360 op_cost(0); 4361 format %{ %} 4362 interface(CONST_INTER); 4363 %} 4364 4365 // Unsigned Integer Immediate: 6-bit int, greater than 32 4366 operand uimmI6_ge32() %{ 4367 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4368 match(ConI); 4369 op_cost(0); 4370 format %{ %} 4371 interface(CONST_INTER); 4372 %} 4373 4374 // Unsigned Integer Immediate: 15-bit 4375 operand uimmI15() %{ 4376 predicate(Assembler::is_uimm(n->get_int(), 15)); 4377 match(ConI); 4378 op_cost(0); 4379 format %{ %} 4380 interface(CONST_INTER); 4381 %} 4382 4383 // Unsigned Integer Immediate: 16-bit 4384 operand uimmI16() %{ 4385 predicate(Assembler::is_uimm(n->get_int(), 16)); 4386 match(ConI); 4387 op_cost(0); 4388 format %{ %} 4389 interface(CONST_INTER); 4390 %} 4391 4392 // constant 'int 0'. 4393 operand immI_0() %{ 4394 predicate(n->get_int() == 0); 4395 match(ConI); 4396 op_cost(0); 4397 format %{ %} 4398 interface(CONST_INTER); 4399 %} 4400 4401 // constant 'int 1'. 4402 operand immI_1() %{ 4403 predicate(n->get_int() == 1); 4404 match(ConI); 4405 op_cost(0); 4406 format %{ %} 4407 interface(CONST_INTER); 4408 %} 4409 4410 // constant 'int -1'. 4411 operand immI_minus1() %{ 4412 predicate(n->get_int() == -1); 4413 match(ConI); 4414 op_cost(0); 4415 format %{ %} 4416 interface(CONST_INTER); 4417 %} 4418 4419 // int value 16. 4420 operand immI_16() %{ 4421 predicate(n->get_int() == 16); 4422 match(ConI); 4423 op_cost(0); 4424 format %{ %} 4425 interface(CONST_INTER); 4426 %} 4427 4428 // int value 24. 4429 operand immI_24() %{ 4430 predicate(n->get_int() == 24); 4431 match(ConI); 4432 op_cost(0); 4433 format %{ %} 4434 interface(CONST_INTER); 4435 %} 4436 4437 // Compressed oops constants 4438 // Pointer Immediate 4439 operand immN() %{ 4440 match(ConN); 4441 4442 op_cost(10); 4443 format %{ %} 4444 interface(CONST_INTER); 4445 %} 4446 4447 // NULL Pointer Immediate 4448 operand immN_0() %{ 4449 predicate(n->get_narrowcon() == 0); 4450 match(ConN); 4451 4452 op_cost(0); 4453 format %{ %} 4454 interface(CONST_INTER); 4455 %} 4456 4457 // Compressed klass constants 4458 operand immNKlass() %{ 4459 match(ConNKlass); 4460 4461 op_cost(0); 4462 format %{ %} 4463 interface(CONST_INTER); 4464 %} 4465 4466 // This operand can be used to avoid matching of an instruct 4467 // with chain rule. 4468 operand immNKlass_NM() %{ 4469 match(ConNKlass); 4470 predicate(false); 4471 op_cost(0); 4472 format %{ %} 4473 interface(CONST_INTER); 4474 %} 4475 4476 // Pointer Immediate: 64-bit 4477 operand immP() %{ 4478 match(ConP); 4479 op_cost(0); 4480 format %{ %} 4481 interface(CONST_INTER); 4482 %} 4483 4484 // Operand to avoid match of loadConP. 4485 // This operand can be used to avoid matching of an instruct 4486 // with chain rule. 4487 operand immP_NM() %{ 4488 match(ConP); 4489 predicate(false); 4490 op_cost(0); 4491 format %{ %} 4492 interface(CONST_INTER); 4493 %} 4494 4495 // costant 'pointer 0'. 4496 operand immP_0() %{ 4497 predicate(n->get_ptr() == 0); 4498 match(ConP); 4499 op_cost(0); 4500 format %{ %} 4501 interface(CONST_INTER); 4502 %} 4503 4504 // pointer 0x0 or 0x1 4505 operand immP_0or1() %{ 4506 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4507 match(ConP); 4508 op_cost(0); 4509 format %{ %} 4510 interface(CONST_INTER); 4511 %} 4512 4513 operand immL() %{ 4514 match(ConL); 4515 op_cost(40); 4516 format %{ %} 4517 interface(CONST_INTER); 4518 %} 4519 4520 operand immLmax30() %{ 4521 predicate((n->get_long() <= 30)); 4522 match(ConL); 4523 op_cost(0); 4524 format %{ %} 4525 interface(CONST_INTER); 4526 %} 4527 4528 // Long Immediate: 16-bit 4529 operand immL16() %{ 4530 predicate(Assembler::is_simm(n->get_long(), 16)); 4531 match(ConL); 4532 op_cost(0); 4533 format %{ %} 4534 interface(CONST_INTER); 4535 %} 4536 4537 // Long Immediate: 16-bit, 4-aligned 4538 operand immL16Alg4() %{ 4539 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4540 match(ConL); 4541 op_cost(0); 4542 format %{ %} 4543 interface(CONST_INTER); 4544 %} 4545 4546 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4547 operand immL32hi16() %{ 4548 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4549 match(ConL); 4550 op_cost(0); 4551 format %{ %} 4552 interface(CONST_INTER); 4553 %} 4554 4555 // Long Immediate: 32-bit 4556 operand immL32() %{ 4557 predicate(Assembler::is_simm(n->get_long(), 32)); 4558 match(ConL); 4559 op_cost(0); 4560 format %{ %} 4561 interface(CONST_INTER); 4562 %} 4563 4564 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4565 operand immLhighest16() %{ 4566 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4567 match(ConL); 4568 op_cost(0); 4569 format %{ %} 4570 interface(CONST_INTER); 4571 %} 4572 4573 operand immLnegpow2() %{ 4574 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4575 match(ConL); 4576 op_cost(0); 4577 format %{ %} 4578 interface(CONST_INTER); 4579 %} 4580 4581 operand immLpow2minus1() %{ 4582 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4583 (n->get_long() != (jlong)0xffffffffffffffffL)); 4584 match(ConL); 4585 op_cost(0); 4586 format %{ %} 4587 interface(CONST_INTER); 4588 %} 4589 4590 // constant 'long 0'. 4591 operand immL_0() %{ 4592 predicate(n->get_long() == 0L); 4593 match(ConL); 4594 op_cost(0); 4595 format %{ %} 4596 interface(CONST_INTER); 4597 %} 4598 4599 // constat ' long -1'. 4600 operand immL_minus1() %{ 4601 predicate(n->get_long() == -1L); 4602 match(ConL); 4603 op_cost(0); 4604 format %{ %} 4605 interface(CONST_INTER); 4606 %} 4607 4608 // Long Immediate: low 32-bit mask 4609 operand immL_32bits() %{ 4610 predicate(n->get_long() == 0xFFFFFFFFL); 4611 match(ConL); 4612 op_cost(0); 4613 format %{ %} 4614 interface(CONST_INTER); 4615 %} 4616 4617 // Unsigned Long Immediate: 16-bit 4618 operand uimmL16() %{ 4619 predicate(Assembler::is_uimm(n->get_long(), 16)); 4620 match(ConL); 4621 op_cost(0); 4622 format %{ %} 4623 interface(CONST_INTER); 4624 %} 4625 4626 // Float Immediate 4627 operand immF() %{ 4628 match(ConF); 4629 op_cost(40); 4630 format %{ %} 4631 interface(CONST_INTER); 4632 %} 4633 4634 // Float Immediate: +0.0f. 4635 operand immF_0() %{ 4636 predicate(jint_cast(n->getf()) == 0); 4637 match(ConF); 4638 4639 op_cost(0); 4640 format %{ %} 4641 interface(CONST_INTER); 4642 %} 4643 4644 // Double Immediate 4645 operand immD() %{ 4646 match(ConD); 4647 op_cost(40); 4648 format %{ %} 4649 interface(CONST_INTER); 4650 %} 4651 4652 // Double Immediate: +0.0d. 4653 operand immD_0() %{ 4654 predicate(jlong_cast(n->getd()) == 0); 4655 match(ConD); 4656 4657 op_cost(0); 4658 format %{ %} 4659 interface(CONST_INTER); 4660 %} 4661 4662 // Integer Register Operands 4663 // Integer Destination Register 4664 // See definition of reg_class bits32_reg_rw. 4665 operand iRegIdst() %{ 4666 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4667 match(RegI); 4668 match(rscratch1RegI); 4669 match(rscratch2RegI); 4670 match(rarg1RegI); 4671 match(rarg2RegI); 4672 match(rarg3RegI); 4673 match(rarg4RegI); 4674 format %{ %} 4675 interface(REG_INTER); 4676 %} 4677 4678 // Integer Source Register 4679 // See definition of reg_class bits32_reg_ro. 4680 operand iRegIsrc() %{ 4681 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4682 match(RegI); 4683 match(rscratch1RegI); 4684 match(rscratch2RegI); 4685 match(rarg1RegI); 4686 match(rarg2RegI); 4687 match(rarg3RegI); 4688 match(rarg4RegI); 4689 format %{ %} 4690 interface(REG_INTER); 4691 %} 4692 4693 operand rscratch1RegI() %{ 4694 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4695 match(iRegIdst); 4696 format %{ %} 4697 interface(REG_INTER); 4698 %} 4699 4700 operand rscratch2RegI() %{ 4701 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4702 match(iRegIdst); 4703 format %{ %} 4704 interface(REG_INTER); 4705 %} 4706 4707 operand rarg1RegI() %{ 4708 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4709 match(iRegIdst); 4710 format %{ %} 4711 interface(REG_INTER); 4712 %} 4713 4714 operand rarg2RegI() %{ 4715 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4716 match(iRegIdst); 4717 format %{ %} 4718 interface(REG_INTER); 4719 %} 4720 4721 operand rarg3RegI() %{ 4722 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4723 match(iRegIdst); 4724 format %{ %} 4725 interface(REG_INTER); 4726 %} 4727 4728 operand rarg4RegI() %{ 4729 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4730 match(iRegIdst); 4731 format %{ %} 4732 interface(REG_INTER); 4733 %} 4734 4735 operand rarg1RegL() %{ 4736 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4737 match(iRegLdst); 4738 format %{ %} 4739 interface(REG_INTER); 4740 %} 4741 4742 operand rarg2RegL() %{ 4743 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4744 match(iRegLdst); 4745 format %{ %} 4746 interface(REG_INTER); 4747 %} 4748 4749 operand rarg3RegL() %{ 4750 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4751 match(iRegLdst); 4752 format %{ %} 4753 interface(REG_INTER); 4754 %} 4755 4756 operand rarg4RegL() %{ 4757 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4758 match(iRegLdst); 4759 format %{ %} 4760 interface(REG_INTER); 4761 %} 4762 4763 // Pointer Destination Register 4764 // See definition of reg_class bits64_reg_rw. 4765 operand iRegPdst() %{ 4766 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4767 match(RegP); 4768 match(rscratch1RegP); 4769 match(rscratch2RegP); 4770 match(rarg1RegP); 4771 match(rarg2RegP); 4772 match(rarg3RegP); 4773 match(rarg4RegP); 4774 format %{ %} 4775 interface(REG_INTER); 4776 %} 4777 4778 // Pointer Destination Register 4779 // Operand not using r11 and r12 (killed in epilog). 4780 operand iRegPdstNoScratch() %{ 4781 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4782 match(RegP); 4783 match(rarg1RegP); 4784 match(rarg2RegP); 4785 match(rarg3RegP); 4786 match(rarg4RegP); 4787 format %{ %} 4788 interface(REG_INTER); 4789 %} 4790 4791 // Pointer Source Register 4792 // See definition of reg_class bits64_reg_ro. 4793 operand iRegPsrc() %{ 4794 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4795 match(RegP); 4796 match(iRegPdst); 4797 match(rscratch1RegP); 4798 match(rscratch2RegP); 4799 match(rarg1RegP); 4800 match(rarg2RegP); 4801 match(rarg3RegP); 4802 match(rarg4RegP); 4803 match(threadRegP); 4804 format %{ %} 4805 interface(REG_INTER); 4806 %} 4807 4808 // Thread operand. 4809 operand threadRegP() %{ 4810 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4811 match(iRegPdst); 4812 format %{ "R16" %} 4813 interface(REG_INTER); 4814 %} 4815 4816 operand rscratch1RegP() %{ 4817 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4818 match(iRegPdst); 4819 format %{ "R11" %} 4820 interface(REG_INTER); 4821 %} 4822 4823 operand rscratch2RegP() %{ 4824 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4825 match(iRegPdst); 4826 format %{ %} 4827 interface(REG_INTER); 4828 %} 4829 4830 operand rarg1RegP() %{ 4831 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4832 match(iRegPdst); 4833 format %{ %} 4834 interface(REG_INTER); 4835 %} 4836 4837 operand rarg2RegP() %{ 4838 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4839 match(iRegPdst); 4840 format %{ %} 4841 interface(REG_INTER); 4842 %} 4843 4844 operand rarg3RegP() %{ 4845 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4846 match(iRegPdst); 4847 format %{ %} 4848 interface(REG_INTER); 4849 %} 4850 4851 operand rarg4RegP() %{ 4852 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4853 match(iRegPdst); 4854 format %{ %} 4855 interface(REG_INTER); 4856 %} 4857 4858 operand iRegNsrc() %{ 4859 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4860 match(RegN); 4861 match(iRegNdst); 4862 4863 format %{ %} 4864 interface(REG_INTER); 4865 %} 4866 4867 operand iRegNdst() %{ 4868 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4869 match(RegN); 4870 4871 format %{ %} 4872 interface(REG_INTER); 4873 %} 4874 4875 // Long Destination Register 4876 // See definition of reg_class bits64_reg_rw. 4877 operand iRegLdst() %{ 4878 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4879 match(RegL); 4880 match(rscratch1RegL); 4881 match(rscratch2RegL); 4882 format %{ %} 4883 interface(REG_INTER); 4884 %} 4885 4886 // Long Source Register 4887 // See definition of reg_class bits64_reg_ro. 4888 operand iRegLsrc() %{ 4889 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4890 match(RegL); 4891 match(iRegLdst); 4892 match(rscratch1RegL); 4893 match(rscratch2RegL); 4894 format %{ %} 4895 interface(REG_INTER); 4896 %} 4897 4898 // Special operand for ConvL2I. 4899 operand iRegL2Isrc(iRegLsrc reg) %{ 4900 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4901 match(ConvL2I reg); 4902 format %{ "ConvL2I($reg)" %} 4903 interface(REG_INTER) 4904 %} 4905 4906 operand rscratch1RegL() %{ 4907 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4908 match(RegL); 4909 format %{ %} 4910 interface(REG_INTER); 4911 %} 4912 4913 operand rscratch2RegL() %{ 4914 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4915 match(RegL); 4916 format %{ %} 4917 interface(REG_INTER); 4918 %} 4919 4920 // Condition Code Flag Registers 4921 operand flagsReg() %{ 4922 constraint(ALLOC_IN_RC(int_flags)); 4923 match(RegFlags); 4924 format %{ %} 4925 interface(REG_INTER); 4926 %} 4927 4928 operand flagsRegSrc() %{ 4929 constraint(ALLOC_IN_RC(int_flags_ro)); 4930 match(RegFlags); 4931 match(flagsReg); 4932 match(flagsRegCR0); 4933 format %{ %} 4934 interface(REG_INTER); 4935 %} 4936 4937 // Condition Code Flag Register CR0 4938 operand flagsRegCR0() %{ 4939 constraint(ALLOC_IN_RC(int_flags_CR0)); 4940 match(RegFlags); 4941 format %{ "CR0" %} 4942 interface(REG_INTER); 4943 %} 4944 4945 operand flagsRegCR1() %{ 4946 constraint(ALLOC_IN_RC(int_flags_CR1)); 4947 match(RegFlags); 4948 format %{ "CR1" %} 4949 interface(REG_INTER); 4950 %} 4951 4952 operand flagsRegCR6() %{ 4953 constraint(ALLOC_IN_RC(int_flags_CR6)); 4954 match(RegFlags); 4955 format %{ "CR6" %} 4956 interface(REG_INTER); 4957 %} 4958 4959 operand regCTR() %{ 4960 constraint(ALLOC_IN_RC(ctr_reg)); 4961 // RegFlags should work. Introducing a RegSpecial type would cause a 4962 // lot of changes. 4963 match(RegFlags); 4964 format %{"SR_CTR" %} 4965 interface(REG_INTER); 4966 %} 4967 4968 operand regD() %{ 4969 constraint(ALLOC_IN_RC(dbl_reg)); 4970 match(RegD); 4971 format %{ %} 4972 interface(REG_INTER); 4973 %} 4974 4975 operand regF() %{ 4976 constraint(ALLOC_IN_RC(flt_reg)); 4977 match(RegF); 4978 format %{ %} 4979 interface(REG_INTER); 4980 %} 4981 4982 // Special Registers 4983 4984 // Method Register 4985 operand inline_cache_regP(iRegPdst reg) %{ 4986 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4987 match(reg); 4988 format %{ %} 4989 interface(REG_INTER); 4990 %} 4991 4992 operand compiler_method_oop_regP(iRegPdst reg) %{ 4993 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4994 match(reg); 4995 format %{ %} 4996 interface(REG_INTER); 4997 %} 4998 4999 operand interpreter_method_oop_regP(iRegPdst reg) %{ 5000 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 5001 match(reg); 5002 format %{ %} 5003 interface(REG_INTER); 5004 %} 5005 5006 // Operands to remove register moves in unscaled mode. 5007 // Match read/write registers with an EncodeP node if neither shift nor add are required. 5008 operand iRegP2N(iRegPsrc reg) %{ 5009 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0); 5010 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5011 match(EncodeP reg); 5012 format %{ "$reg" %} 5013 interface(REG_INTER) 5014 %} 5015 5016 operand iRegN2P(iRegNsrc reg) %{ 5017 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5018 constraint(ALLOC_IN_RC(bits32_reg_ro)); 5019 match(DecodeN reg); 5020 format %{ "$reg" %} 5021 interface(REG_INTER) 5022 %} 5023 5024 operand iRegN2P_klass(iRegNsrc reg) %{ 5025 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5026 constraint(ALLOC_IN_RC(bits32_reg_ro)); 5027 match(DecodeNKlass reg); 5028 format %{ "$reg" %} 5029 interface(REG_INTER) 5030 %} 5031 5032 //----------Complex Operands--------------------------------------------------- 5033 // Indirect Memory Reference 5034 operand indirect(iRegPsrc reg) %{ 5035 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5036 match(reg); 5037 op_cost(100); 5038 format %{ "[$reg]" %} 5039 interface(MEMORY_INTER) %{ 5040 base($reg); 5041 index(0x0); 5042 scale(0x0); 5043 disp(0x0); 5044 %} 5045 %} 5046 5047 // Indirect with Offset 5048 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 5049 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5050 match(AddP reg offset); 5051 op_cost(100); 5052 format %{ "[$reg + $offset]" %} 5053 interface(MEMORY_INTER) %{ 5054 base($reg); 5055 index(0x0); 5056 scale(0x0); 5057 disp($offset); 5058 %} 5059 %} 5060 5061 // Indirect with 4-aligned Offset 5062 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 5063 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5064 match(AddP reg offset); 5065 op_cost(100); 5066 format %{ "[$reg + $offset]" %} 5067 interface(MEMORY_INTER) %{ 5068 base($reg); 5069 index(0x0); 5070 scale(0x0); 5071 disp($offset); 5072 %} 5073 %} 5074 5075 //----------Complex Operands for Compressed OOPs------------------------------- 5076 // Compressed OOPs with narrow_oop_shift == 0. 5077 5078 // Indirect Memory Reference, compressed OOP 5079 operand indirectNarrow(iRegNsrc reg) %{ 5080 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5081 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5082 match(DecodeN reg); 5083 op_cost(100); 5084 format %{ "[$reg]" %} 5085 interface(MEMORY_INTER) %{ 5086 base($reg); 5087 index(0x0); 5088 scale(0x0); 5089 disp(0x0); 5090 %} 5091 %} 5092 5093 operand indirectNarrow_klass(iRegNsrc reg) %{ 5094 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5095 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5096 match(DecodeNKlass reg); 5097 op_cost(100); 5098 format %{ "[$reg]" %} 5099 interface(MEMORY_INTER) %{ 5100 base($reg); 5101 index(0x0); 5102 scale(0x0); 5103 disp(0x0); 5104 %} 5105 %} 5106 5107 // Indirect with Offset, compressed OOP 5108 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 5109 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5110 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5111 match(AddP (DecodeN reg) offset); 5112 op_cost(100); 5113 format %{ "[$reg + $offset]" %} 5114 interface(MEMORY_INTER) %{ 5115 base($reg); 5116 index(0x0); 5117 scale(0x0); 5118 disp($offset); 5119 %} 5120 %} 5121 5122 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5123 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5124 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5125 match(AddP (DecodeNKlass reg) offset); 5126 op_cost(100); 5127 format %{ "[$reg + $offset]" %} 5128 interface(MEMORY_INTER) %{ 5129 base($reg); 5130 index(0x0); 5131 scale(0x0); 5132 disp($offset); 5133 %} 5134 %} 5135 5136 // Indirect with 4-aligned Offset, compressed OOP 5137 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 5138 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5139 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5140 match(AddP (DecodeN reg) offset); 5141 op_cost(100); 5142 format %{ "[$reg + $offset]" %} 5143 interface(MEMORY_INTER) %{ 5144 base($reg); 5145 index(0x0); 5146 scale(0x0); 5147 disp($offset); 5148 %} 5149 %} 5150 5151 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5152 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5153 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5154 match(AddP (DecodeNKlass reg) offset); 5155 op_cost(100); 5156 format %{ "[$reg + $offset]" %} 5157 interface(MEMORY_INTER) %{ 5158 base($reg); 5159 index(0x0); 5160 scale(0x0); 5161 disp($offset); 5162 %} 5163 %} 5164 5165 //----------Special Memory Operands-------------------------------------------- 5166 // Stack Slot Operand 5167 // 5168 // This operand is used for loading and storing temporary values on 5169 // the stack where a match requires a value to flow through memory. 5170 operand stackSlotI(sRegI reg) %{ 5171 constraint(ALLOC_IN_RC(stack_slots)); 5172 op_cost(100); 5173 //match(RegI); 5174 format %{ "[sp+$reg]" %} 5175 interface(MEMORY_INTER) %{ 5176 base(0x1); // R1_SP 5177 index(0x0); 5178 scale(0x0); 5179 disp($reg); // Stack Offset 5180 %} 5181 %} 5182 5183 operand stackSlotL(sRegL reg) %{ 5184 constraint(ALLOC_IN_RC(stack_slots)); 5185 op_cost(100); 5186 //match(RegL); 5187 format %{ "[sp+$reg]" %} 5188 interface(MEMORY_INTER) %{ 5189 base(0x1); // R1_SP 5190 index(0x0); 5191 scale(0x0); 5192 disp($reg); // Stack Offset 5193 %} 5194 %} 5195 5196 operand stackSlotP(sRegP reg) %{ 5197 constraint(ALLOC_IN_RC(stack_slots)); 5198 op_cost(100); 5199 //match(RegP); 5200 format %{ "[sp+$reg]" %} 5201 interface(MEMORY_INTER) %{ 5202 base(0x1); // R1_SP 5203 index(0x0); 5204 scale(0x0); 5205 disp($reg); // Stack Offset 5206 %} 5207 %} 5208 5209 operand stackSlotF(sRegF reg) %{ 5210 constraint(ALLOC_IN_RC(stack_slots)); 5211 op_cost(100); 5212 //match(RegF); 5213 format %{ "[sp+$reg]" %} 5214 interface(MEMORY_INTER) %{ 5215 base(0x1); // R1_SP 5216 index(0x0); 5217 scale(0x0); 5218 disp($reg); // Stack Offset 5219 %} 5220 %} 5221 5222 operand stackSlotD(sRegD reg) %{ 5223 constraint(ALLOC_IN_RC(stack_slots)); 5224 op_cost(100); 5225 //match(RegD); 5226 format %{ "[sp+$reg]" %} 5227 interface(MEMORY_INTER) %{ 5228 base(0x1); // R1_SP 5229 index(0x0); 5230 scale(0x0); 5231 disp($reg); // Stack Offset 5232 %} 5233 %} 5234 5235 // Operands for expressing Control Flow 5236 // NOTE: Label is a predefined operand which should not be redefined in 5237 // the AD file. It is generically handled within the ADLC. 5238 5239 //----------Conditional Branch Operands---------------------------------------- 5240 // Comparison Op 5241 // 5242 // This is the operation of the comparison, and is limited to the 5243 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5244 // (!=). 5245 // 5246 // Other attributes of the comparison, such as unsignedness, are specified 5247 // by the comparison instruction that sets a condition code flags register. 5248 // That result is represented by a flags operand whose subtype is appropriate 5249 // to the unsignedness (etc.) of the comparison. 5250 // 5251 // Later, the instruction which matches both the Comparison Op (a Bool) and 5252 // the flags (produced by the Cmp) specifies the coding of the comparison op 5253 // by matching a specific subtype of Bool operand below. 5254 5255 // When used for floating point comparisons: unordered same as less. 5256 operand cmpOp() %{ 5257 match(Bool); 5258 format %{ "" %} 5259 interface(COND_INTER) %{ 5260 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5261 // BO & BI 5262 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5263 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5264 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5265 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5266 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5267 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5268 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5269 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5270 %} 5271 %} 5272 5273 //----------OPERAND CLASSES---------------------------------------------------- 5274 // Operand Classes are groups of operands that are used to simplify 5275 // instruction definitions by not requiring the AD writer to specify 5276 // seperate instructions for every form of operand when the 5277 // instruction accepts multiple operand types with the same basic 5278 // encoding and format. The classic case of this is memory operands. 5279 // Indirect is not included since its use is limited to Compare & Swap. 5280 5281 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5282 // Memory operand where offsets are 4-aligned. Required for ld, std. 5283 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5284 opclass indirectMemory(indirect, indirectNarrow); 5285 5286 // Special opclass for I and ConvL2I. 5287 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5288 5289 // Operand classes to match encode and decode. iRegN_P2N is only used 5290 // for storeN. I have never seen an encode node elsewhere. 5291 opclass iRegN_P2N(iRegNsrc, iRegP2N); 5292 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5293 5294 //----------PIPELINE----------------------------------------------------------- 5295 5296 pipeline %{ 5297 5298 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5299 // J. Res. & Dev., No. 1, Jan. 2002. 5300 5301 //----------ATTRIBUTES--------------------------------------------------------- 5302 attributes %{ 5303 5304 // Power4 instructions are of fixed length. 5305 fixed_size_instructions; 5306 5307 // TODO: if `bundle' means number of instructions fetched 5308 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5309 // max instructions issued per cycle, this is 5. 5310 max_instructions_per_bundle = 8; 5311 5312 // A Power4 instruction is 4 bytes long. 5313 instruction_unit_size = 4; 5314 5315 // The Power4 processor fetches 64 bytes... 5316 instruction_fetch_unit_size = 64; 5317 5318 // ...in one line 5319 instruction_fetch_units = 1 5320 5321 // Unused, list one so that array generated by adlc is not empty. 5322 // Aix compiler chokes if _nop_count = 0. 5323 nops(fxNop); 5324 %} 5325 5326 //----------RESOURCES---------------------------------------------------------- 5327 // Resources are the functional units available to the machine 5328 resources( 5329 PPC_BR, // branch unit 5330 PPC_CR, // condition unit 5331 PPC_FX1, // integer arithmetic unit 1 5332 PPC_FX2, // integer arithmetic unit 2 5333 PPC_LDST1, // load/store unit 1 5334 PPC_LDST2, // load/store unit 2 5335 PPC_FP1, // float arithmetic unit 1 5336 PPC_FP2, // float arithmetic unit 2 5337 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5338 PPC_FX = PPC_FX1 | PPC_FX2, 5339 PPC_FP = PPC_FP1 | PPC_FP2 5340 ); 5341 5342 //----------PIPELINE DESCRIPTION----------------------------------------------- 5343 // Pipeline Description specifies the stages in the machine's pipeline 5344 pipe_desc( 5345 // Power4 longest pipeline path 5346 PPC_IF, // instruction fetch 5347 PPC_IC, 5348 //PPC_BP, // branch prediction 5349 PPC_D0, // decode 5350 PPC_D1, // decode 5351 PPC_D2, // decode 5352 PPC_D3, // decode 5353 PPC_Xfer1, 5354 PPC_GD, // group definition 5355 PPC_MP, // map 5356 PPC_ISS, // issue 5357 PPC_RF, // resource fetch 5358 PPC_EX1, // execute (all units) 5359 PPC_EX2, // execute (FP, LDST) 5360 PPC_EX3, // execute (FP, LDST) 5361 PPC_EX4, // execute (FP) 5362 PPC_EX5, // execute (FP) 5363 PPC_EX6, // execute (FP) 5364 PPC_WB, // write back 5365 PPC_Xfer2, 5366 PPC_CP 5367 ); 5368 5369 //----------PIPELINE CLASSES--------------------------------------------------- 5370 // Pipeline Classes describe the stages in which input and output are 5371 // referenced by the hardware pipeline. 5372 5373 // Simple pipeline classes. 5374 5375 // Default pipeline class. 5376 pipe_class pipe_class_default() %{ 5377 single_instruction; 5378 fixed_latency(2); 5379 %} 5380 5381 // Pipeline class for empty instructions. 5382 pipe_class pipe_class_empty() %{ 5383 single_instruction; 5384 fixed_latency(0); 5385 %} 5386 5387 // Pipeline class for compares. 5388 pipe_class pipe_class_compare() %{ 5389 single_instruction; 5390 fixed_latency(16); 5391 %} 5392 5393 // Pipeline class for traps. 5394 pipe_class pipe_class_trap() %{ 5395 single_instruction; 5396 fixed_latency(100); 5397 %} 5398 5399 // Pipeline class for memory operations. 5400 pipe_class pipe_class_memory() %{ 5401 single_instruction; 5402 fixed_latency(16); 5403 %} 5404 5405 // Pipeline class for call. 5406 pipe_class pipe_class_call() %{ 5407 single_instruction; 5408 fixed_latency(100); 5409 %} 5410 5411 // Define the class for the Nop node. 5412 define %{ 5413 MachNop = pipe_class_default; 5414 %} 5415 5416 %} 5417 5418 //----------INSTRUCTIONS------------------------------------------------------- 5419 5420 // Naming of instructions: 5421 // opA_operB / opA_operB_operC: 5422 // Operation 'op' with one or two source operands 'oper'. Result 5423 // type is A, source operand types are B and C. 5424 // Iff A == B == C, B and C are left out. 5425 // 5426 // The instructions are ordered according to the following scheme: 5427 // - loads 5428 // - load constants 5429 // - prefetch 5430 // - store 5431 // - encode/decode 5432 // - membar 5433 // - conditional moves 5434 // - compare & swap 5435 // - arithmetic and logic operations 5436 // * int: Add, Sub, Mul, Div, Mod 5437 // * int: lShift, arShift, urShift, rot 5438 // * float: Add, Sub, Mul, Div 5439 // * and, or, xor ... 5440 // - register moves: float <-> int, reg <-> stack, repl 5441 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5442 // - conv (low level type cast requiring bit changes (sign extend etc) 5443 // - compares, range & zero checks. 5444 // - branches 5445 // - complex operations, intrinsics, min, max, replicate 5446 // - lock 5447 // - Calls 5448 // 5449 // If there are similar instructions with different types they are sorted: 5450 // int before float 5451 // small before big 5452 // signed before unsigned 5453 // e.g., loadS before loadUS before loadI before loadF. 5454 5455 5456 //----------Load/Store Instructions-------------------------------------------- 5457 5458 //----------Load Instructions-------------------------------------------------- 5459 5460 // Converts byte to int. 5461 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5462 // reuses the 'amount' operand, but adlc expects that operand specification 5463 // and operands in match rule are equivalent. 5464 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5465 effect(DEF dst, USE src); 5466 format %{ "EXTSB $dst, $src \t// byte->int" %} 5467 size(4); 5468 ins_encode %{ 5469 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5470 __ extsb($dst$$Register, $src$$Register); 5471 %} 5472 ins_pipe(pipe_class_default); 5473 %} 5474 5475 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5476 // match-rule, false predicate 5477 match(Set dst (LoadB mem)); 5478 predicate(false); 5479 5480 format %{ "LBZ $dst, $mem" %} 5481 size(4); 5482 ins_encode( enc_lbz(dst, mem) ); 5483 ins_pipe(pipe_class_memory); 5484 %} 5485 5486 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5487 // match-rule, false predicate 5488 match(Set dst (LoadB mem)); 5489 predicate(false); 5490 5491 format %{ "LBZ $dst, $mem\n\t" 5492 "TWI $dst\n\t" 5493 "ISYNC" %} 5494 size(12); 5495 ins_encode( enc_lbz_ac(dst, mem) ); 5496 ins_pipe(pipe_class_memory); 5497 %} 5498 5499 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5500 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5501 match(Set dst (LoadB mem)); 5502 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5503 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5504 expand %{ 5505 iRegIdst tmp; 5506 loadUB_indirect(tmp, mem); 5507 convB2I_reg_2(dst, tmp); 5508 %} 5509 %} 5510 5511 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5512 match(Set dst (LoadB mem)); 5513 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5514 expand %{ 5515 iRegIdst tmp; 5516 loadUB_indirect_ac(tmp, mem); 5517 convB2I_reg_2(dst, tmp); 5518 %} 5519 %} 5520 5521 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5522 // match-rule, false predicate 5523 match(Set dst (LoadB mem)); 5524 predicate(false); 5525 5526 format %{ "LBZ $dst, $mem" %} 5527 size(4); 5528 ins_encode( enc_lbz(dst, mem) ); 5529 ins_pipe(pipe_class_memory); 5530 %} 5531 5532 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5533 // match-rule, false predicate 5534 match(Set dst (LoadB mem)); 5535 predicate(false); 5536 5537 format %{ "LBZ $dst, $mem\n\t" 5538 "TWI $dst\n\t" 5539 "ISYNC" %} 5540 size(12); 5541 ins_encode( enc_lbz_ac(dst, mem) ); 5542 ins_pipe(pipe_class_memory); 5543 %} 5544 5545 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5546 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5547 match(Set dst (LoadB mem)); 5548 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5549 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5550 5551 expand %{ 5552 iRegIdst tmp; 5553 loadUB_indOffset16(tmp, mem); 5554 convB2I_reg_2(dst, tmp); 5555 %} 5556 %} 5557 5558 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5559 match(Set dst (LoadB mem)); 5560 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5561 5562 expand %{ 5563 iRegIdst tmp; 5564 loadUB_indOffset16_ac(tmp, mem); 5565 convB2I_reg_2(dst, tmp); 5566 %} 5567 %} 5568 5569 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5570 instruct loadUB(iRegIdst dst, memory mem) %{ 5571 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5572 match(Set dst (LoadUB mem)); 5573 ins_cost(MEMORY_REF_COST); 5574 5575 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5576 size(4); 5577 ins_encode( enc_lbz(dst, mem) ); 5578 ins_pipe(pipe_class_memory); 5579 %} 5580 5581 // Load Unsigned Byte (8bit UNsigned) acquire. 5582 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5583 match(Set dst (LoadUB mem)); 5584 ins_cost(3*MEMORY_REF_COST); 5585 5586 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5587 "TWI $dst\n\t" 5588 "ISYNC" %} 5589 size(12); 5590 ins_encode( enc_lbz_ac(dst, mem) ); 5591 ins_pipe(pipe_class_memory); 5592 %} 5593 5594 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5595 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5596 match(Set dst (ConvI2L (LoadUB mem))); 5597 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5598 ins_cost(MEMORY_REF_COST); 5599 5600 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5601 size(4); 5602 ins_encode( enc_lbz(dst, mem) ); 5603 ins_pipe(pipe_class_memory); 5604 %} 5605 5606 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5607 match(Set dst (ConvI2L (LoadUB mem))); 5608 ins_cost(3*MEMORY_REF_COST); 5609 5610 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5611 "TWI $dst\n\t" 5612 "ISYNC" %} 5613 size(12); 5614 ins_encode( enc_lbz_ac(dst, mem) ); 5615 ins_pipe(pipe_class_memory); 5616 %} 5617 5618 // Load Short (16bit signed) 5619 instruct loadS(iRegIdst dst, memory mem) %{ 5620 match(Set dst (LoadS mem)); 5621 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5622 ins_cost(MEMORY_REF_COST); 5623 5624 format %{ "LHA $dst, $mem" %} 5625 size(4); 5626 ins_encode %{ 5627 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5628 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5629 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5630 %} 5631 ins_pipe(pipe_class_memory); 5632 %} 5633 5634 // Load Short (16bit signed) acquire. 5635 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5636 match(Set dst (LoadS mem)); 5637 ins_cost(3*MEMORY_REF_COST); 5638 5639 format %{ "LHA $dst, $mem\t acquire\n\t" 5640 "TWI $dst\n\t" 5641 "ISYNC" %} 5642 size(12); 5643 ins_encode %{ 5644 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5645 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5646 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5647 __ twi_0($dst$$Register); 5648 __ isync(); 5649 %} 5650 ins_pipe(pipe_class_memory); 5651 %} 5652 5653 // Load Char (16bit unsigned) 5654 instruct loadUS(iRegIdst dst, memory mem) %{ 5655 match(Set dst (LoadUS mem)); 5656 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5657 ins_cost(MEMORY_REF_COST); 5658 5659 format %{ "LHZ $dst, $mem" %} 5660 size(4); 5661 ins_encode( enc_lhz(dst, mem) ); 5662 ins_pipe(pipe_class_memory); 5663 %} 5664 5665 // Load Char (16bit unsigned) acquire. 5666 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5667 match(Set dst (LoadUS mem)); 5668 ins_cost(3*MEMORY_REF_COST); 5669 5670 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5671 "TWI $dst\n\t" 5672 "ISYNC" %} 5673 size(12); 5674 ins_encode( enc_lhz_ac(dst, mem) ); 5675 ins_pipe(pipe_class_memory); 5676 %} 5677 5678 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5679 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5680 match(Set dst (ConvI2L (LoadUS mem))); 5681 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5682 ins_cost(MEMORY_REF_COST); 5683 5684 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5685 size(4); 5686 ins_encode( enc_lhz(dst, mem) ); 5687 ins_pipe(pipe_class_memory); 5688 %} 5689 5690 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5691 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5692 match(Set dst (ConvI2L (LoadUS mem))); 5693 ins_cost(3*MEMORY_REF_COST); 5694 5695 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5696 "TWI $dst\n\t" 5697 "ISYNC" %} 5698 size(12); 5699 ins_encode( enc_lhz_ac(dst, mem) ); 5700 ins_pipe(pipe_class_memory); 5701 %} 5702 5703 // Load Integer. 5704 instruct loadI(iRegIdst dst, memory mem) %{ 5705 match(Set dst (LoadI mem)); 5706 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5707 ins_cost(MEMORY_REF_COST); 5708 5709 format %{ "LWZ $dst, $mem" %} 5710 size(4); 5711 ins_encode( enc_lwz(dst, mem) ); 5712 ins_pipe(pipe_class_memory); 5713 %} 5714 5715 // Load Integer acquire. 5716 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5717 match(Set dst (LoadI mem)); 5718 ins_cost(3*MEMORY_REF_COST); 5719 5720 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5721 "TWI $dst\n\t" 5722 "ISYNC" %} 5723 size(12); 5724 ins_encode( enc_lwz_ac(dst, mem) ); 5725 ins_pipe(pipe_class_memory); 5726 %} 5727 5728 // Match loading integer and casting it to unsigned int in 5729 // long register. 5730 // LoadI + ConvI2L + AndL 0xffffffff. 5731 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5732 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5733 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5734 ins_cost(MEMORY_REF_COST); 5735 5736 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5737 size(4); 5738 ins_encode( enc_lwz(dst, mem) ); 5739 ins_pipe(pipe_class_memory); 5740 %} 5741 5742 // Match loading integer and casting it to long. 5743 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5744 match(Set dst (ConvI2L (LoadI mem))); 5745 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5746 ins_cost(MEMORY_REF_COST); 5747 5748 format %{ "LWA $dst, $mem \t// loadI2L" %} 5749 size(4); 5750 ins_encode %{ 5751 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5752 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5753 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5754 %} 5755 ins_pipe(pipe_class_memory); 5756 %} 5757 5758 // Match loading integer and casting it to long - acquire. 5759 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5760 match(Set dst (ConvI2L (LoadI mem))); 5761 ins_cost(3*MEMORY_REF_COST); 5762 5763 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5764 "TWI $dst\n\t" 5765 "ISYNC" %} 5766 size(12); 5767 ins_encode %{ 5768 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5769 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5770 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5771 __ twi_0($dst$$Register); 5772 __ isync(); 5773 %} 5774 ins_pipe(pipe_class_memory); 5775 %} 5776 5777 // Load Long - aligned 5778 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5779 match(Set dst (LoadL mem)); 5780 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5781 ins_cost(MEMORY_REF_COST); 5782 5783 format %{ "LD $dst, $mem \t// long" %} 5784 size(4); 5785 ins_encode( enc_ld(dst, mem) ); 5786 ins_pipe(pipe_class_memory); 5787 %} 5788 5789 // Load Long - aligned acquire. 5790 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5791 match(Set dst (LoadL mem)); 5792 ins_cost(3*MEMORY_REF_COST); 5793 5794 format %{ "LD $dst, $mem \t// long acquire\n\t" 5795 "TWI $dst\n\t" 5796 "ISYNC" %} 5797 size(12); 5798 ins_encode( enc_ld_ac(dst, mem) ); 5799 ins_pipe(pipe_class_memory); 5800 %} 5801 5802 // Load Long - UNaligned 5803 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5804 match(Set dst (LoadL_unaligned mem)); 5805 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5806 ins_cost(MEMORY_REF_COST); 5807 5808 format %{ "LD $dst, $mem \t// unaligned long" %} 5809 size(4); 5810 ins_encode( enc_ld(dst, mem) ); 5811 ins_pipe(pipe_class_memory); 5812 %} 5813 5814 // Load nodes for superwords 5815 5816 // Load Aligned Packed Byte 5817 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5818 predicate(n->as_LoadVector()->memory_size() == 8); 5819 match(Set dst (LoadVector mem)); 5820 ins_cost(MEMORY_REF_COST); 5821 5822 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5823 size(4); 5824 ins_encode( enc_ld(dst, mem) ); 5825 ins_pipe(pipe_class_memory); 5826 %} 5827 5828 // Load Aligned Packed Byte 5829 instruct loadV16(vecX dst, indirect mem) %{ 5830 predicate(n->as_LoadVector()->memory_size() == 16); 5831 match(Set dst (LoadVector mem)); 5832 ins_cost(MEMORY_REF_COST); 5833 5834 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5835 size(4); 5836 ins_encode %{ 5837 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5838 %} 5839 ins_pipe(pipe_class_default); 5840 %} 5841 5842 // Load Range, range = array length (=jint) 5843 instruct loadRange(iRegIdst dst, memory mem) %{ 5844 match(Set dst (LoadRange mem)); 5845 ins_cost(MEMORY_REF_COST); 5846 5847 format %{ "LWZ $dst, $mem \t// range" %} 5848 size(4); 5849 ins_encode( enc_lwz(dst, mem) ); 5850 ins_pipe(pipe_class_memory); 5851 %} 5852 5853 // Load Compressed Pointer 5854 instruct loadN(iRegNdst dst, memory mem) %{ 5855 match(Set dst (LoadN mem)); 5856 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5857 ins_cost(MEMORY_REF_COST); 5858 5859 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5860 size(4); 5861 ins_encode( enc_lwz(dst, mem) ); 5862 ins_pipe(pipe_class_memory); 5863 %} 5864 5865 // Load Compressed Pointer acquire. 5866 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5867 match(Set dst (LoadN mem)); 5868 ins_cost(3*MEMORY_REF_COST); 5869 5870 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5871 "TWI $dst\n\t" 5872 "ISYNC" %} 5873 size(12); 5874 ins_encode( enc_lwz_ac(dst, mem) ); 5875 ins_pipe(pipe_class_memory); 5876 %} 5877 5878 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5879 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5880 match(Set dst (DecodeN (LoadN mem))); 5881 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0); 5882 ins_cost(MEMORY_REF_COST); 5883 5884 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5885 size(4); 5886 ins_encode( enc_lwz(dst, mem) ); 5887 ins_pipe(pipe_class_memory); 5888 %} 5889 5890 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5891 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5892 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0 && 5893 _kids[0]->_leaf->as_Load()->is_unordered()); 5894 ins_cost(MEMORY_REF_COST); 5895 5896 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5897 size(4); 5898 ins_encode( enc_lwz(dst, mem) ); 5899 ins_pipe(pipe_class_memory); 5900 %} 5901 5902 // Load Pointer 5903 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5904 match(Set dst (LoadP mem)); 5905 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5906 ins_cost(MEMORY_REF_COST); 5907 5908 format %{ "LD $dst, $mem \t// ptr" %} 5909 size(4); 5910 ins_encode( enc_ld(dst, mem) ); 5911 ins_pipe(pipe_class_memory); 5912 %} 5913 5914 // Load Pointer acquire. 5915 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5916 match(Set dst (LoadP mem)); 5917 ins_cost(3*MEMORY_REF_COST); 5918 5919 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5920 "TWI $dst\n\t" 5921 "ISYNC" %} 5922 size(12); 5923 ins_encode( enc_ld_ac(dst, mem) ); 5924 ins_pipe(pipe_class_memory); 5925 %} 5926 5927 // LoadP + CastP2L 5928 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5929 match(Set dst (CastP2X (LoadP mem))); 5930 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5931 ins_cost(MEMORY_REF_COST); 5932 5933 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5934 size(4); 5935 ins_encode( enc_ld(dst, mem) ); 5936 ins_pipe(pipe_class_memory); 5937 %} 5938 5939 // Load compressed klass pointer. 5940 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5941 match(Set dst (LoadNKlass mem)); 5942 ins_cost(MEMORY_REF_COST); 5943 5944 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5945 size(4); 5946 ins_encode( enc_lwz(dst, mem) ); 5947 ins_pipe(pipe_class_memory); 5948 %} 5949 5950 // Load Klass Pointer 5951 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5952 match(Set dst (LoadKlass mem)); 5953 ins_cost(MEMORY_REF_COST); 5954 5955 format %{ "LD $dst, $mem \t// klass ptr" %} 5956 size(4); 5957 ins_encode( enc_ld(dst, mem) ); 5958 ins_pipe(pipe_class_memory); 5959 %} 5960 5961 // Load Float 5962 instruct loadF(regF dst, memory mem) %{ 5963 match(Set dst (LoadF mem)); 5964 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5965 ins_cost(MEMORY_REF_COST); 5966 5967 format %{ "LFS $dst, $mem" %} 5968 size(4); 5969 ins_encode %{ 5970 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5971 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5972 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5973 %} 5974 ins_pipe(pipe_class_memory); 5975 %} 5976 5977 // Load Float acquire. 5978 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5979 match(Set dst (LoadF mem)); 5980 effect(TEMP cr0); 5981 ins_cost(3*MEMORY_REF_COST); 5982 5983 format %{ "LFS $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 __ lfs($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 - aligned 6003 instruct loadD(regD dst, memory mem) %{ 6004 match(Set dst (LoadD mem)); 6005 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 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 // Load Double - aligned acquire. 6015 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 6016 match(Set dst (LoadD mem)); 6017 effect(TEMP cr0); 6018 ins_cost(3*MEMORY_REF_COST); 6019 6020 format %{ "LFD $dst, $mem \t// acquire\n\t" 6021 "FCMPU cr0, $dst, $dst\n\t" 6022 "BNE cr0, next\n" 6023 "next:\n\t" 6024 "ISYNC" %} 6025 size(16); 6026 ins_encode %{ 6027 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6028 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6029 Label next; 6030 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 6031 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 6032 __ bne(CCR0, next); 6033 __ bind(next); 6034 __ isync(); 6035 %} 6036 ins_pipe(pipe_class_memory); 6037 %} 6038 6039 // Load Double - UNaligned 6040 instruct loadD_unaligned(regD dst, memory mem) %{ 6041 match(Set dst (LoadD_unaligned mem)); 6042 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 6043 ins_cost(MEMORY_REF_COST); 6044 6045 format %{ "LFD $dst, $mem" %} 6046 size(4); 6047 ins_encode( enc_lfd(dst, mem) ); 6048 ins_pipe(pipe_class_memory); 6049 %} 6050 6051 //----------Constants-------------------------------------------------------- 6052 6053 // Load MachConstantTableBase: add hi offset to global toc. 6054 // TODO: Handle hidden register r29 in bundler! 6055 instruct loadToc_hi(iRegLdst dst) %{ 6056 effect(DEF dst); 6057 ins_cost(DEFAULT_COST); 6058 6059 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 6060 size(4); 6061 ins_encode %{ 6062 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6063 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 6064 %} 6065 ins_pipe(pipe_class_default); 6066 %} 6067 6068 // Load MachConstantTableBase: add lo offset to global toc. 6069 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 6070 effect(DEF dst, USE src); 6071 ins_cost(DEFAULT_COST); 6072 6073 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 6074 size(4); 6075 ins_encode %{ 6076 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6077 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 6078 %} 6079 ins_pipe(pipe_class_default); 6080 %} 6081 6082 // Load 16-bit integer constant 0xssss???? 6083 instruct loadConI16(iRegIdst dst, immI16 src) %{ 6084 match(Set dst src); 6085 6086 format %{ "LI $dst, $src" %} 6087 size(4); 6088 ins_encode %{ 6089 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6090 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6091 %} 6092 ins_pipe(pipe_class_default); 6093 %} 6094 6095 // Load integer constant 0x????0000 6096 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 6097 match(Set dst src); 6098 ins_cost(DEFAULT_COST); 6099 6100 format %{ "LIS $dst, $src.hi" %} 6101 size(4); 6102 ins_encode %{ 6103 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6104 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 6105 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6106 %} 6107 ins_pipe(pipe_class_default); 6108 %} 6109 6110 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 6111 // and sign extended), this adds the low 16 bits. 6112 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6113 // no match-rule, false predicate 6114 effect(DEF dst, USE src1, USE src2); 6115 predicate(false); 6116 6117 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6118 size(4); 6119 ins_encode %{ 6120 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6121 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6122 %} 6123 ins_pipe(pipe_class_default); 6124 %} 6125 6126 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6127 match(Set dst src); 6128 ins_cost(DEFAULT_COST*2); 6129 6130 expand %{ 6131 // Would like to use $src$$constant. 6132 immI16 srcLo %{ _opnds[1]->constant() %} 6133 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6134 immIhi16 srcHi %{ _opnds[1]->constant() %} 6135 iRegIdst tmpI; 6136 loadConIhi16(tmpI, srcHi); 6137 loadConI32_lo16(dst, tmpI, srcLo); 6138 %} 6139 %} 6140 6141 // No constant pool entries required. 6142 instruct loadConL16(iRegLdst dst, immL16 src) %{ 6143 match(Set dst src); 6144 6145 format %{ "LI $dst, $src \t// long" %} 6146 size(4); 6147 ins_encode %{ 6148 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6149 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6150 %} 6151 ins_pipe(pipe_class_default); 6152 %} 6153 6154 // Load long constant 0xssssssss????0000 6155 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6156 match(Set dst src); 6157 ins_cost(DEFAULT_COST); 6158 6159 format %{ "LIS $dst, $src.hi \t// long" %} 6160 size(4); 6161 ins_encode %{ 6162 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6163 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6164 %} 6165 ins_pipe(pipe_class_default); 6166 %} 6167 6168 // To load a 32 bit constant: merge lower 16 bits into already loaded 6169 // high 16 bits. 6170 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6171 // no match-rule, false predicate 6172 effect(DEF dst, USE src1, USE src2); 6173 predicate(false); 6174 6175 format %{ "ORI $dst, $src1, $src2.lo" %} 6176 size(4); 6177 ins_encode %{ 6178 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6179 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6180 %} 6181 ins_pipe(pipe_class_default); 6182 %} 6183 6184 // Load 32-bit long constant 6185 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6186 match(Set dst src); 6187 ins_cost(DEFAULT_COST*2); 6188 6189 expand %{ 6190 // Would like to use $src$$constant. 6191 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6192 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6193 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6194 iRegLdst tmpL; 6195 loadConL32hi16(tmpL, srcHi); 6196 loadConL32_lo16(dst, tmpL, srcLo); 6197 %} 6198 %} 6199 6200 // Load long constant 0x????000000000000. 6201 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6202 match(Set dst src); 6203 ins_cost(DEFAULT_COST); 6204 6205 expand %{ 6206 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6207 immI shift32 %{ 32 %} 6208 iRegLdst tmpL; 6209 loadConL32hi16(tmpL, srcHi); 6210 lshiftL_regL_immI(dst, tmpL, shift32); 6211 %} 6212 %} 6213 6214 // Expand node for constant pool load: small offset. 6215 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6216 effect(DEF dst, USE src, USE toc); 6217 ins_cost(MEMORY_REF_COST); 6218 6219 ins_num_consts(1); 6220 // Needed so that CallDynamicJavaDirect can compute the address of this 6221 // instruction for relocation. 6222 ins_field_cbuf_insts_offset(int); 6223 6224 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6225 size(4); 6226 ins_encode( enc_load_long_constL(dst, src, toc) ); 6227 ins_pipe(pipe_class_memory); 6228 %} 6229 6230 // Expand node for constant pool load: large offset. 6231 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6232 effect(DEF dst, USE src, USE toc); 6233 predicate(false); 6234 6235 ins_num_consts(1); 6236 ins_field_const_toc_offset(int); 6237 // Needed so that CallDynamicJavaDirect can compute the address of this 6238 // instruction for relocation. 6239 ins_field_cbuf_insts_offset(int); 6240 6241 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6242 size(4); 6243 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6244 ins_pipe(pipe_class_default); 6245 %} 6246 6247 // Expand node for constant pool load: large offset. 6248 // No constant pool entries required. 6249 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6250 effect(DEF dst, USE src, USE base); 6251 predicate(false); 6252 6253 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6254 6255 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6256 size(4); 6257 ins_encode %{ 6258 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6259 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6260 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6261 %} 6262 ins_pipe(pipe_class_memory); 6263 %} 6264 6265 // Load long constant from constant table. Expand in case of 6266 // offset > 16 bit is needed. 6267 // Adlc adds toc node MachConstantTableBase. 6268 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6269 match(Set dst src); 6270 ins_cost(MEMORY_REF_COST); 6271 6272 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6273 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6274 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6275 %} 6276 6277 // Load NULL as compressed oop. 6278 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6279 match(Set dst src); 6280 ins_cost(DEFAULT_COST); 6281 6282 format %{ "LI $dst, $src \t// compressed ptr" %} 6283 size(4); 6284 ins_encode %{ 6285 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6286 __ li($dst$$Register, 0); 6287 %} 6288 ins_pipe(pipe_class_default); 6289 %} 6290 6291 // Load hi part of compressed oop constant. 6292 instruct loadConN_hi(iRegNdst dst, immN src) %{ 6293 effect(DEF dst, USE src); 6294 ins_cost(DEFAULT_COST); 6295 6296 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6297 size(4); 6298 ins_encode %{ 6299 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6300 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6301 %} 6302 ins_pipe(pipe_class_default); 6303 %} 6304 6305 // Add lo part of compressed oop constant to already loaded hi part. 6306 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6307 effect(DEF dst, USE src1, USE src2); 6308 ins_cost(DEFAULT_COST); 6309 6310 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6311 size(4); 6312 ins_encode %{ 6313 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6314 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6315 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6316 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6317 __ relocate(rspec, 1); 6318 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6319 %} 6320 ins_pipe(pipe_class_default); 6321 %} 6322 6323 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6324 effect(DEF dst, USE src, USE shift, USE mask_begin); 6325 6326 size(4); 6327 ins_encode %{ 6328 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6329 %} 6330 ins_pipe(pipe_class_default); 6331 %} 6332 6333 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6334 // leaving the upper 32 bits with sign-extension bits. 6335 // This clears these bits: dst = src & 0xFFFFFFFF. 6336 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6337 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6338 effect(DEF dst, USE src); 6339 predicate(false); 6340 6341 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6342 size(4); 6343 ins_encode %{ 6344 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6345 __ clrldi($dst$$Register, $src$$Register, 0x20); 6346 %} 6347 ins_pipe(pipe_class_default); 6348 %} 6349 6350 // Optimize DecodeN for disjoint base. 6351 // Load base of compressed oops into a register 6352 instruct loadBase(iRegLdst dst) %{ 6353 effect(DEF dst); 6354 6355 format %{ "LoadConst $dst, heapbase" %} 6356 ins_encode %{ 6357 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6358 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0); 6359 %} 6360 ins_pipe(pipe_class_default); 6361 %} 6362 6363 // Loading ConN must be postalloc expanded so that edges between 6364 // the nodes are safe. They may not interfere with a safepoint. 6365 // GL TODO: This needs three instructions: better put this into the constant pool. 6366 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6367 match(Set dst src); 6368 ins_cost(DEFAULT_COST*2); 6369 6370 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6371 postalloc_expand %{ 6372 MachNode *m1 = new loadConN_hiNode(); 6373 MachNode *m2 = new loadConN_loNode(); 6374 MachNode *m3 = new clearMs32bNode(); 6375 m1->add_req(NULL); 6376 m2->add_req(NULL, m1); 6377 m3->add_req(NULL, m2); 6378 m1->_opnds[0] = op_dst; 6379 m1->_opnds[1] = op_src; 6380 m2->_opnds[0] = op_dst; 6381 m2->_opnds[1] = op_dst; 6382 m2->_opnds[2] = op_src; 6383 m3->_opnds[0] = op_dst; 6384 m3->_opnds[1] = op_dst; 6385 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6386 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6387 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6388 nodes->push(m1); 6389 nodes->push(m2); 6390 nodes->push(m3); 6391 %} 6392 %} 6393 6394 // We have seen a safepoint between the hi and lo parts, and this node was handled 6395 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6396 // not a narrow oop. 6397 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6398 match(Set dst src); 6399 effect(DEF dst, USE src); 6400 ins_cost(DEFAULT_COST); 6401 6402 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6403 size(4); 6404 ins_encode %{ 6405 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6406 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant); 6407 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6408 %} 6409 ins_pipe(pipe_class_default); 6410 %} 6411 6412 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6413 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6414 match(Set dst src1); 6415 effect(TEMP src2); 6416 ins_cost(DEFAULT_COST); 6417 6418 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6419 size(4); 6420 ins_encode %{ 6421 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6422 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6423 %} 6424 ins_pipe(pipe_class_default); 6425 %} 6426 6427 // This needs a match rule so that build_oop_map knows this is 6428 // not a narrow oop. 6429 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6430 match(Set dst src1); 6431 effect(TEMP src2); 6432 ins_cost(DEFAULT_COST); 6433 6434 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6435 size(4); 6436 ins_encode %{ 6437 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6438 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src1$$constant); 6439 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6440 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6441 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6442 6443 __ relocate(rspec, 1); 6444 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6445 %} 6446 ins_pipe(pipe_class_default); 6447 %} 6448 6449 // Loading ConNKlass must be postalloc expanded so that edges between 6450 // the nodes are safe. They may not interfere with a safepoint. 6451 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6452 match(Set dst src); 6453 ins_cost(DEFAULT_COST*2); 6454 6455 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6456 postalloc_expand %{ 6457 // Load high bits into register. Sign extended. 6458 MachNode *m1 = new loadConNKlass_hiNode(); 6459 m1->add_req(NULL); 6460 m1->_opnds[0] = op_dst; 6461 m1->_opnds[1] = op_src; 6462 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6463 nodes->push(m1); 6464 6465 MachNode *m2 = m1; 6466 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) { 6467 // Value might be 1-extended. Mask out these bits. 6468 m2 = new loadConNKlass_maskNode(); 6469 m2->add_req(NULL, m1); 6470 m2->_opnds[0] = op_dst; 6471 m2->_opnds[1] = op_src; 6472 m2->_opnds[2] = op_dst; 6473 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6474 nodes->push(m2); 6475 } 6476 6477 MachNode *m3 = new loadConNKlass_loNode(); 6478 m3->add_req(NULL, m2); 6479 m3->_opnds[0] = op_dst; 6480 m3->_opnds[1] = op_src; 6481 m3->_opnds[2] = op_dst; 6482 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6483 nodes->push(m3); 6484 %} 6485 %} 6486 6487 // 0x1 is used in object initialization (initial object header). 6488 // No constant pool entries required. 6489 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6490 match(Set dst src); 6491 6492 format %{ "LI $dst, $src \t// ptr" %} 6493 size(4); 6494 ins_encode %{ 6495 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6496 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6497 %} 6498 ins_pipe(pipe_class_default); 6499 %} 6500 6501 // Expand node for constant pool load: small offset. 6502 // The match rule is needed to generate the correct bottom_type(), 6503 // however this node should never match. The use of predicate is not 6504 // possible since ADLC forbids predicates for chain rules. The higher 6505 // costs do not prevent matching in this case. For that reason the 6506 // operand immP_NM with predicate(false) is used. 6507 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6508 match(Set dst src); 6509 effect(TEMP toc); 6510 6511 ins_num_consts(1); 6512 6513 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6514 size(4); 6515 ins_encode( enc_load_long_constP(dst, src, toc) ); 6516 ins_pipe(pipe_class_memory); 6517 %} 6518 6519 // Expand node for constant pool load: large offset. 6520 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6521 effect(DEF dst, USE src, USE toc); 6522 predicate(false); 6523 6524 ins_num_consts(1); 6525 ins_field_const_toc_offset(int); 6526 6527 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6528 size(4); 6529 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6530 ins_pipe(pipe_class_default); 6531 %} 6532 6533 // Expand node for constant pool load: large offset. 6534 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6535 match(Set dst src); 6536 effect(TEMP base); 6537 6538 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6539 6540 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6541 size(4); 6542 ins_encode %{ 6543 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6544 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6545 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6546 %} 6547 ins_pipe(pipe_class_memory); 6548 %} 6549 6550 // Load pointer constant from constant table. Expand in case an 6551 // offset > 16 bit is needed. 6552 // Adlc adds toc node MachConstantTableBase. 6553 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6554 match(Set dst src); 6555 ins_cost(MEMORY_REF_COST); 6556 6557 // This rule does not use "expand" because then 6558 // the result type is not known to be an Oop. An ADLC 6559 // enhancement will be needed to make that work - not worth it! 6560 6561 // If this instruction rematerializes, it prolongs the live range 6562 // of the toc node, causing illegal graphs. 6563 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6564 ins_cannot_rematerialize(true); 6565 6566 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6567 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6568 %} 6569 6570 // Expand node for constant pool load: small offset. 6571 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6572 effect(DEF dst, USE src, USE toc); 6573 ins_cost(MEMORY_REF_COST); 6574 6575 ins_num_consts(1); 6576 6577 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6578 size(4); 6579 ins_encode %{ 6580 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6581 address float_address = __ float_constant($src$$constant); 6582 if (float_address == NULL) { 6583 ciEnv::current()->record_out_of_memory_failure(); 6584 return; 6585 } 6586 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6587 %} 6588 ins_pipe(pipe_class_memory); 6589 %} 6590 6591 // Expand node for constant pool load: large offset. 6592 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6593 effect(DEF dst, USE src, USE toc); 6594 ins_cost(MEMORY_REF_COST); 6595 6596 ins_num_consts(1); 6597 6598 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6599 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6600 "ADDIS $toc, $toc, -offset_hi"%} 6601 size(12); 6602 ins_encode %{ 6603 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6604 FloatRegister Rdst = $dst$$FloatRegister; 6605 Register Rtoc = $toc$$Register; 6606 address float_address = __ float_constant($src$$constant); 6607 if (float_address == NULL) { 6608 ciEnv::current()->record_out_of_memory_failure(); 6609 return; 6610 } 6611 int offset = __ offset_to_method_toc(float_address); 6612 int hi = (offset + (1<<15))>>16; 6613 int lo = offset - hi * (1<<16); 6614 6615 __ addis(Rtoc, Rtoc, hi); 6616 __ lfs(Rdst, lo, Rtoc); 6617 __ addis(Rtoc, Rtoc, -hi); 6618 %} 6619 ins_pipe(pipe_class_memory); 6620 %} 6621 6622 // Adlc adds toc node MachConstantTableBase. 6623 instruct loadConF_Ex(regF dst, immF src) %{ 6624 match(Set dst src); 6625 ins_cost(MEMORY_REF_COST); 6626 6627 // See loadConP. 6628 ins_cannot_rematerialize(true); 6629 6630 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6631 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6632 %} 6633 6634 // Expand node for constant pool load: small offset. 6635 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6636 effect(DEF dst, USE src, USE toc); 6637 ins_cost(MEMORY_REF_COST); 6638 6639 ins_num_consts(1); 6640 6641 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6642 size(4); 6643 ins_encode %{ 6644 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6645 address float_address = __ double_constant($src$$constant); 6646 if (float_address == NULL) { 6647 ciEnv::current()->record_out_of_memory_failure(); 6648 return; 6649 } 6650 int offset = __ offset_to_method_toc(float_address); 6651 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6652 %} 6653 ins_pipe(pipe_class_memory); 6654 %} 6655 6656 // Expand node for constant pool load: large offset. 6657 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6658 effect(DEF dst, USE src, USE toc); 6659 ins_cost(MEMORY_REF_COST); 6660 6661 ins_num_consts(1); 6662 6663 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6664 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6665 "ADDIS $toc, $toc, -offset_hi" %} 6666 size(12); 6667 ins_encode %{ 6668 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6669 FloatRegister Rdst = $dst$$FloatRegister; 6670 Register Rtoc = $toc$$Register; 6671 address float_address = __ double_constant($src$$constant); 6672 if (float_address == NULL) { 6673 ciEnv::current()->record_out_of_memory_failure(); 6674 return; 6675 } 6676 int offset = __ offset_to_method_toc(float_address); 6677 int hi = (offset + (1<<15))>>16; 6678 int lo = offset - hi * (1<<16); 6679 6680 __ addis(Rtoc, Rtoc, hi); 6681 __ lfd(Rdst, lo, Rtoc); 6682 __ addis(Rtoc, Rtoc, -hi); 6683 %} 6684 ins_pipe(pipe_class_memory); 6685 %} 6686 6687 // Adlc adds toc node MachConstantTableBase. 6688 instruct loadConD_Ex(regD dst, immD src) %{ 6689 match(Set dst src); 6690 ins_cost(MEMORY_REF_COST); 6691 6692 // See loadConP. 6693 ins_cannot_rematerialize(true); 6694 6695 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6696 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6697 %} 6698 6699 // Prefetch instructions. 6700 // Must be safe to execute with invalid address (cannot fault). 6701 6702 // Special prefetch versions which use the dcbz instruction. 6703 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6704 match(PrefetchAllocation (AddP mem src)); 6705 predicate(AllocatePrefetchStyle == 3); 6706 ins_cost(MEMORY_REF_COST); 6707 6708 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6709 size(4); 6710 ins_encode %{ 6711 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6712 __ dcbz($src$$Register, $mem$$base$$Register); 6713 %} 6714 ins_pipe(pipe_class_memory); 6715 %} 6716 6717 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6718 match(PrefetchAllocation mem); 6719 predicate(AllocatePrefetchStyle == 3); 6720 ins_cost(MEMORY_REF_COST); 6721 6722 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6723 size(4); 6724 ins_encode %{ 6725 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6726 __ dcbz($mem$$base$$Register); 6727 %} 6728 ins_pipe(pipe_class_memory); 6729 %} 6730 6731 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6732 match(PrefetchAllocation (AddP mem src)); 6733 predicate(AllocatePrefetchStyle != 3); 6734 ins_cost(MEMORY_REF_COST); 6735 6736 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6737 size(4); 6738 ins_encode %{ 6739 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6740 __ dcbtst($src$$Register, $mem$$base$$Register); 6741 %} 6742 ins_pipe(pipe_class_memory); 6743 %} 6744 6745 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6746 match(PrefetchAllocation mem); 6747 predicate(AllocatePrefetchStyle != 3); 6748 ins_cost(MEMORY_REF_COST); 6749 6750 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6751 size(4); 6752 ins_encode %{ 6753 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6754 __ dcbtst($mem$$base$$Register); 6755 %} 6756 ins_pipe(pipe_class_memory); 6757 %} 6758 6759 //----------Store Instructions------------------------------------------------- 6760 6761 // Store Byte 6762 instruct storeB(memory mem, iRegIsrc src) %{ 6763 match(Set mem (StoreB mem src)); 6764 ins_cost(MEMORY_REF_COST); 6765 6766 format %{ "STB $src, $mem \t// byte" %} 6767 size(4); 6768 ins_encode %{ 6769 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6770 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6771 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6772 %} 6773 ins_pipe(pipe_class_memory); 6774 %} 6775 6776 // Store Char/Short 6777 instruct storeC(memory mem, iRegIsrc src) %{ 6778 match(Set mem (StoreC mem src)); 6779 ins_cost(MEMORY_REF_COST); 6780 6781 format %{ "STH $src, $mem \t// short" %} 6782 size(4); 6783 ins_encode %{ 6784 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6785 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6786 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6787 %} 6788 ins_pipe(pipe_class_memory); 6789 %} 6790 6791 // Store Integer 6792 instruct storeI(memory mem, iRegIsrc src) %{ 6793 match(Set mem (StoreI mem src)); 6794 ins_cost(MEMORY_REF_COST); 6795 6796 format %{ "STW $src, $mem" %} 6797 size(4); 6798 ins_encode( enc_stw(src, mem) ); 6799 ins_pipe(pipe_class_memory); 6800 %} 6801 6802 // ConvL2I + StoreI. 6803 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6804 match(Set mem (StoreI mem (ConvL2I src))); 6805 ins_cost(MEMORY_REF_COST); 6806 6807 format %{ "STW l2i($src), $mem" %} 6808 size(4); 6809 ins_encode( enc_stw(src, mem) ); 6810 ins_pipe(pipe_class_memory); 6811 %} 6812 6813 // Store Long 6814 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6815 match(Set mem (StoreL mem src)); 6816 ins_cost(MEMORY_REF_COST); 6817 6818 format %{ "STD $src, $mem \t// long" %} 6819 size(4); 6820 ins_encode( enc_std(src, mem) ); 6821 ins_pipe(pipe_class_memory); 6822 %} 6823 6824 // Store super word nodes. 6825 6826 // Store Aligned Packed Byte long register to memory 6827 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6828 predicate(n->as_StoreVector()->memory_size() == 8); 6829 match(Set mem (StoreVector mem src)); 6830 ins_cost(MEMORY_REF_COST); 6831 6832 format %{ "STD $mem, $src \t// packed8B" %} 6833 size(4); 6834 ins_encode( enc_std(src, mem) ); 6835 ins_pipe(pipe_class_memory); 6836 %} 6837 6838 // Store Packed Byte long register to memory 6839 instruct storeV16(indirect mem, vecX src) %{ 6840 predicate(n->as_StoreVector()->memory_size() == 16); 6841 match(Set mem (StoreVector mem src)); 6842 ins_cost(MEMORY_REF_COST); 6843 6844 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6845 size(4); 6846 ins_encode %{ 6847 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6848 %} 6849 ins_pipe(pipe_class_default); 6850 %} 6851 6852 // Store Compressed Oop 6853 instruct storeN(memory dst, iRegN_P2N src) %{ 6854 match(Set dst (StoreN dst src)); 6855 ins_cost(MEMORY_REF_COST); 6856 6857 format %{ "STW $src, $dst \t// compressed oop" %} 6858 size(4); 6859 ins_encode( enc_stw(src, dst) ); 6860 ins_pipe(pipe_class_memory); 6861 %} 6862 6863 // Store Compressed KLass 6864 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6865 match(Set dst (StoreNKlass dst src)); 6866 ins_cost(MEMORY_REF_COST); 6867 6868 format %{ "STW $src, $dst \t// compressed klass" %} 6869 size(4); 6870 ins_encode( enc_stw(src, dst) ); 6871 ins_pipe(pipe_class_memory); 6872 %} 6873 6874 // Store Pointer 6875 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6876 match(Set dst (StoreP dst src)); 6877 ins_cost(MEMORY_REF_COST); 6878 6879 format %{ "STD $src, $dst \t// ptr" %} 6880 size(4); 6881 ins_encode( enc_std(src, dst) ); 6882 ins_pipe(pipe_class_memory); 6883 %} 6884 6885 // Store Float 6886 instruct storeF(memory mem, regF src) %{ 6887 match(Set mem (StoreF mem src)); 6888 ins_cost(MEMORY_REF_COST); 6889 6890 format %{ "STFS $src, $mem" %} 6891 size(4); 6892 ins_encode( enc_stfs(src, mem) ); 6893 ins_pipe(pipe_class_memory); 6894 %} 6895 6896 // Store Double 6897 instruct storeD(memory mem, regD src) %{ 6898 match(Set mem (StoreD mem src)); 6899 ins_cost(MEMORY_REF_COST); 6900 6901 format %{ "STFD $src, $mem" %} 6902 size(4); 6903 ins_encode( enc_stfd(src, mem) ); 6904 ins_pipe(pipe_class_memory); 6905 %} 6906 6907 //----------Store Instructions With Zeros-------------------------------------- 6908 6909 // Card-mark for CMS garbage collection. 6910 // This cardmark does an optimization so that it must not always 6911 // do a releasing store. For this, it gets the address of 6912 // CMSCollectorCardTableBarrierSetBSExt::_requires_release as input. 6913 // (Using releaseFieldAddr in the match rule is a hack.) 6914 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6915 match(Set mem (StoreCM mem releaseFieldAddr)); 6916 effect(TEMP crx); 6917 predicate(false); 6918 ins_cost(MEMORY_REF_COST); 6919 6920 // See loadConP. 6921 ins_cannot_rematerialize(true); 6922 6923 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6924 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6925 ins_pipe(pipe_class_memory); 6926 %} 6927 6928 // Card-mark for CMS garbage collection. 6929 // This cardmark does an optimization so that it must not always 6930 // do a releasing store. For this, it needs the constant address of 6931 // CMSCollectorCardTableBarrierSetBSExt::_requires_release. 6932 // This constant address is split off here by expand so we can use 6933 // adlc / matcher functionality to load it from the constant section. 6934 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6935 match(Set mem (StoreCM mem zero)); 6936 predicate(UseConcMarkSweepGC); 6937 6938 expand %{ 6939 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableBarrierSetBSExt::requires_release_address() */ %} 6940 iRegLdst releaseFieldAddress; 6941 flagsReg crx; 6942 loadConL_Ex(releaseFieldAddress, baseImm); 6943 storeCM_CMS(mem, releaseFieldAddress, crx); 6944 %} 6945 %} 6946 6947 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6948 match(Set mem (StoreCM mem zero)); 6949 predicate(UseG1GC); 6950 ins_cost(MEMORY_REF_COST); 6951 6952 ins_cannot_rematerialize(true); 6953 6954 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6955 size(8); 6956 ins_encode %{ 6957 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6958 __ li(R0, 0); 6959 //__ release(); // G1: oops are allowed to get visible after dirty marking 6960 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6961 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6962 %} 6963 ins_pipe(pipe_class_memory); 6964 %} 6965 6966 // Convert oop pointer into compressed form. 6967 6968 // Nodes for postalloc expand. 6969 6970 // Shift node for expand. 6971 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6972 // The match rule is needed to make it a 'MachTypeNode'! 6973 match(Set dst (EncodeP src)); 6974 predicate(false); 6975 6976 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6977 size(4); 6978 ins_encode %{ 6979 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6980 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 6981 %} 6982 ins_pipe(pipe_class_default); 6983 %} 6984 6985 // Add node for expand. 6986 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6987 // The match rule is needed to make it a 'MachTypeNode'! 6988 match(Set dst (EncodeP src)); 6989 predicate(false); 6990 6991 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6992 ins_encode %{ 6993 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6994 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 6995 %} 6996 ins_pipe(pipe_class_default); 6997 %} 6998 6999 // Conditional sub base. 7000 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7001 // The match rule is needed to make it a 'MachTypeNode'! 7002 match(Set dst (EncodeP (Binary crx src1))); 7003 predicate(false); 7004 7005 format %{ "BEQ $crx, done\n\t" 7006 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 7007 "done:" %} 7008 ins_encode %{ 7009 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7010 Label done; 7011 __ beq($crx$$CondRegister, done); 7012 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0); 7013 __ bind(done); 7014 %} 7015 ins_pipe(pipe_class_default); 7016 %} 7017 7018 // Power 7 can use isel instruction 7019 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7020 // The match rule is needed to make it a 'MachTypeNode'! 7021 match(Set dst (EncodeP (Binary crx src1))); 7022 predicate(false); 7023 7024 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 7025 size(4); 7026 ins_encode %{ 7027 // This is a Power7 instruction for which no machine description exists. 7028 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7029 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7030 %} 7031 ins_pipe(pipe_class_default); 7032 %} 7033 7034 // Disjoint narrow oop base. 7035 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7036 match(Set dst (EncodeP src)); 7037 predicate(CompressedOops::base_disjoint()); 7038 7039 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7040 size(4); 7041 ins_encode %{ 7042 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7043 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32); 7044 %} 7045 ins_pipe(pipe_class_default); 7046 %} 7047 7048 // shift != 0, base != 0 7049 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 7050 match(Set dst (EncodeP src)); 7051 effect(TEMP crx); 7052 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 7053 CompressedOops::shift() != 0 && 7054 CompressedOops::base_overlaps()); 7055 7056 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 7057 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 7058 %} 7059 7060 // shift != 0, base != 0 7061 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 7062 match(Set dst (EncodeP src)); 7063 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 7064 CompressedOops::shift() != 0 && 7065 CompressedOops::base_overlaps()); 7066 7067 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 7068 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 7069 %} 7070 7071 // shift != 0, base == 0 7072 // TODO: This is the same as encodeP_shift. Merge! 7073 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 7074 match(Set dst (EncodeP src)); 7075 predicate(CompressedOops::shift() != 0 && 7076 CompressedOops::base() ==0); 7077 7078 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 7079 size(4); 7080 ins_encode %{ 7081 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7082 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 7083 %} 7084 ins_pipe(pipe_class_default); 7085 %} 7086 7087 // Compressed OOPs with narrow_oop_shift == 0. 7088 // shift == 0, base == 0 7089 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 7090 match(Set dst (EncodeP src)); 7091 predicate(CompressedOops::shift() == 0); 7092 7093 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 7094 // variable size, 0 or 4. 7095 ins_encode %{ 7096 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7097 __ mr_if_needed($dst$$Register, $src$$Register); 7098 %} 7099 ins_pipe(pipe_class_default); 7100 %} 7101 7102 // Decode nodes. 7103 7104 // Shift node for expand. 7105 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 7106 // The match rule is needed to make it a 'MachTypeNode'! 7107 match(Set dst (DecodeN src)); 7108 predicate(false); 7109 7110 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 7111 size(4); 7112 ins_encode %{ 7113 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7114 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 7115 %} 7116 ins_pipe(pipe_class_default); 7117 %} 7118 7119 // Add node for expand. 7120 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7121 // The match rule is needed to make it a 'MachTypeNode'! 7122 match(Set dst (DecodeN src)); 7123 predicate(false); 7124 7125 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7126 ins_encode %{ 7127 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7128 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 7129 %} 7130 ins_pipe(pipe_class_default); 7131 %} 7132 7133 // conditianal add base for expand 7134 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7135 // The match rule is needed to make it a 'MachTypeNode'! 7136 // NOTICE that the rule is nonsense - we just have to make sure that: 7137 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7138 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7139 match(Set dst (DecodeN (Binary crx src))); 7140 predicate(false); 7141 7142 format %{ "BEQ $crx, done\n\t" 7143 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7144 "done:" %} 7145 ins_encode %{ 7146 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7147 Label done; 7148 __ beq($crx$$CondRegister, done); 7149 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 7150 __ bind(done); 7151 %} 7152 ins_pipe(pipe_class_default); 7153 %} 7154 7155 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7156 // The match rule is needed to make it a 'MachTypeNode'! 7157 // NOTICE that the rule is nonsense - we just have to make sure that: 7158 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7159 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7160 match(Set dst (DecodeN (Binary crx src1))); 7161 predicate(false); 7162 7163 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7164 size(4); 7165 ins_encode %{ 7166 // This is a Power7 instruction for which no machine description exists. 7167 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7168 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7169 %} 7170 ins_pipe(pipe_class_default); 7171 %} 7172 7173 // shift != 0, base != 0 7174 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7175 match(Set dst (DecodeN src)); 7176 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7177 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7178 CompressedOops::shift() != 0 && 7179 CompressedOops::base() != 0); 7180 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7181 effect(TEMP crx); 7182 7183 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7184 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7185 %} 7186 7187 // shift != 0, base == 0 7188 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7189 match(Set dst (DecodeN src)); 7190 predicate(CompressedOops::shift() != 0 && 7191 CompressedOops::base() == 0); 7192 7193 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7194 size(4); 7195 ins_encode %{ 7196 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7197 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 7198 %} 7199 ins_pipe(pipe_class_default); 7200 %} 7201 7202 // Optimize DecodeN for disjoint base. 7203 // Shift narrow oop and or it into register that already contains the heap base. 7204 // Base == dst must hold, and is assured by construction in postaloc_expand. 7205 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7206 match(Set dst (DecodeN src)); 7207 effect(TEMP base); 7208 predicate(false); 7209 7210 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7211 size(4); 7212 ins_encode %{ 7213 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7214 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift()); 7215 %} 7216 ins_pipe(pipe_class_default); 7217 %} 7218 7219 // Optimize DecodeN for disjoint base. 7220 // This node requires only one cycle on the critical path. 7221 // We must postalloc_expand as we can not express use_def effects where 7222 // the used register is L and the def'ed register P. 7223 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7224 match(Set dst (DecodeN src)); 7225 effect(TEMP_DEF dst); 7226 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7227 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7228 CompressedOops::base_disjoint()); 7229 ins_cost(DEFAULT_COST); 7230 7231 format %{ "MOV $dst, heapbase \t\n" 7232 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7233 postalloc_expand %{ 7234 loadBaseNode *n1 = new loadBaseNode(); 7235 n1->add_req(NULL); 7236 n1->_opnds[0] = op_dst; 7237 7238 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7239 n2->add_req(n_region, n_src, n1); 7240 n2->_opnds[0] = op_dst; 7241 n2->_opnds[1] = op_src; 7242 n2->_opnds[2] = op_dst; 7243 n2->_bottom_type = _bottom_type; 7244 7245 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7246 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7247 7248 nodes->push(n1); 7249 nodes->push(n2); 7250 %} 7251 %} 7252 7253 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7254 match(Set dst (DecodeN src)); 7255 effect(TEMP_DEF dst, TEMP crx); 7256 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7257 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7258 CompressedOops::base_disjoint() && VM_Version::has_isel()); 7259 ins_cost(3 * DEFAULT_COST); 7260 7261 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7262 postalloc_expand %{ 7263 loadBaseNode *n1 = new loadBaseNode(); 7264 n1->add_req(NULL); 7265 n1->_opnds[0] = op_dst; 7266 7267 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7268 n_compare->add_req(n_region, n_src); 7269 n_compare->_opnds[0] = op_crx; 7270 n_compare->_opnds[1] = op_src; 7271 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7272 7273 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7274 n2->add_req(n_region, n_src, n1); 7275 n2->_opnds[0] = op_dst; 7276 n2->_opnds[1] = op_src; 7277 n2->_opnds[2] = op_dst; 7278 n2->_bottom_type = _bottom_type; 7279 7280 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7281 n_cond_set->add_req(n_region, n_compare, n2); 7282 n_cond_set->_opnds[0] = op_dst; 7283 n_cond_set->_opnds[1] = op_crx; 7284 n_cond_set->_opnds[2] = op_dst; 7285 n_cond_set->_bottom_type = _bottom_type; 7286 7287 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7288 ra_->set_oop(n_cond_set, true); 7289 7290 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7291 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7292 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7293 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7294 7295 nodes->push(n1); 7296 nodes->push(n_compare); 7297 nodes->push(n2); 7298 nodes->push(n_cond_set); 7299 %} 7300 %} 7301 7302 // src != 0, shift != 0, base != 0 7303 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7304 match(Set dst (DecodeN src)); 7305 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7306 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7307 CompressedOops::shift() != 0 && 7308 CompressedOops::base() != 0); 7309 ins_cost(2 * DEFAULT_COST); 7310 7311 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7312 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7313 %} 7314 7315 // Compressed OOPs with narrow_oop_shift == 0. 7316 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7317 match(Set dst (DecodeN src)); 7318 predicate(CompressedOops::shift() == 0); 7319 ins_cost(DEFAULT_COST); 7320 7321 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7322 // variable size, 0 or 4. 7323 ins_encode %{ 7324 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7325 __ mr_if_needed($dst$$Register, $src$$Register); 7326 %} 7327 ins_pipe(pipe_class_default); 7328 %} 7329 7330 // Convert compressed oop into int for vectors alignment masking. 7331 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7332 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7333 predicate(CompressedOops::shift() == 0); 7334 ins_cost(DEFAULT_COST); 7335 7336 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7337 // variable size, 0 or 4. 7338 ins_encode %{ 7339 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7340 __ mr_if_needed($dst$$Register, $src$$Register); 7341 %} 7342 ins_pipe(pipe_class_default); 7343 %} 7344 7345 // Convert klass pointer into compressed form. 7346 7347 // Nodes for postalloc expand. 7348 7349 // Shift node for expand. 7350 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7351 // The match rule is needed to make it a 'MachTypeNode'! 7352 match(Set dst (EncodePKlass src)); 7353 predicate(false); 7354 7355 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7356 size(4); 7357 ins_encode %{ 7358 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7359 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 7360 %} 7361 ins_pipe(pipe_class_default); 7362 %} 7363 7364 // Add node for expand. 7365 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7366 // The match rule is needed to make it a 'MachTypeNode'! 7367 match(Set dst (EncodePKlass (Binary base src))); 7368 predicate(false); 7369 7370 format %{ "SUB $dst, $base, $src \t// encode" %} 7371 size(4); 7372 ins_encode %{ 7373 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7374 __ subf($dst$$Register, $base$$Register, $src$$Register); 7375 %} 7376 ins_pipe(pipe_class_default); 7377 %} 7378 7379 // Disjoint narrow oop base. 7380 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7381 match(Set dst (EncodePKlass src)); 7382 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/); 7383 7384 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7385 size(4); 7386 ins_encode %{ 7387 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7388 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32); 7389 %} 7390 ins_pipe(pipe_class_default); 7391 %} 7392 7393 // shift != 0, base != 0 7394 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7395 match(Set dst (EncodePKlass (Binary base src))); 7396 predicate(false); 7397 7398 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7399 postalloc_expand %{ 7400 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7401 n1->add_req(n_region, n_base, n_src); 7402 n1->_opnds[0] = op_dst; 7403 n1->_opnds[1] = op_base; 7404 n1->_opnds[2] = op_src; 7405 n1->_bottom_type = _bottom_type; 7406 7407 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7408 n2->add_req(n_region, n1); 7409 n2->_opnds[0] = op_dst; 7410 n2->_opnds[1] = op_dst; 7411 n2->_bottom_type = _bottom_type; 7412 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7413 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7414 7415 nodes->push(n1); 7416 nodes->push(n2); 7417 %} 7418 %} 7419 7420 // shift != 0, base != 0 7421 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7422 match(Set dst (EncodePKlass src)); 7423 //predicate(CompressedKlassPointers::shift() != 0 && 7424 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/); 7425 7426 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7427 ins_cost(DEFAULT_COST*2); // Don't count constant. 7428 expand %{ 7429 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %} 7430 iRegLdst base; 7431 loadConL_Ex(base, baseImm); 7432 encodePKlass_not_null_Ex(dst, base, src); 7433 %} 7434 %} 7435 7436 // Decode nodes. 7437 7438 // Shift node for expand. 7439 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7440 // The match rule is needed to make it a 'MachTypeNode'! 7441 match(Set dst (DecodeNKlass src)); 7442 predicate(false); 7443 7444 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7445 size(4); 7446 ins_encode %{ 7447 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7448 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 7449 %} 7450 ins_pipe(pipe_class_default); 7451 %} 7452 7453 // Add node for expand. 7454 7455 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7456 // The match rule is needed to make it a 'MachTypeNode'! 7457 match(Set dst (DecodeNKlass (Binary base src))); 7458 predicate(false); 7459 7460 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7461 size(4); 7462 ins_encode %{ 7463 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7464 __ add($dst$$Register, $base$$Register, $src$$Register); 7465 %} 7466 ins_pipe(pipe_class_default); 7467 %} 7468 7469 // src != 0, shift != 0, base != 0 7470 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7471 match(Set dst (DecodeNKlass (Binary base src))); 7472 //effect(kill src); // We need a register for the immediate result after shifting. 7473 predicate(false); 7474 7475 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7476 postalloc_expand %{ 7477 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7478 n1->add_req(n_region, n_base, n_src); 7479 n1->_opnds[0] = op_dst; 7480 n1->_opnds[1] = op_base; 7481 n1->_opnds[2] = op_src; 7482 n1->_bottom_type = _bottom_type; 7483 7484 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7485 n2->add_req(n_region, n1); 7486 n2->_opnds[0] = op_dst; 7487 n2->_opnds[1] = op_dst; 7488 n2->_bottom_type = _bottom_type; 7489 7490 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7491 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7492 7493 nodes->push(n1); 7494 nodes->push(n2); 7495 %} 7496 %} 7497 7498 // src != 0, shift != 0, base != 0 7499 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7500 match(Set dst (DecodeNKlass src)); 7501 // predicate(CompressedKlassPointers::shift() != 0 && 7502 // CompressedKlassPointers::base() != 0); 7503 7504 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7505 7506 ins_cost(DEFAULT_COST*2); // Don't count constant. 7507 expand %{ 7508 // We add first, then we shift. Like this, we can get along with one register less. 7509 // But we have to load the base pre-shifted. 7510 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %} 7511 iRegLdst base; 7512 loadConL_Ex(base, baseImm); 7513 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7514 %} 7515 %} 7516 7517 //----------MemBar Instructions----------------------------------------------- 7518 // Memory barrier flavors 7519 7520 instruct membar_acquire() %{ 7521 match(LoadFence); 7522 ins_cost(4*MEMORY_REF_COST); 7523 7524 format %{ "MEMBAR-acquire" %} 7525 size(4); 7526 ins_encode %{ 7527 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7528 __ acquire(); 7529 %} 7530 ins_pipe(pipe_class_default); 7531 %} 7532 7533 instruct unnecessary_membar_acquire() %{ 7534 match(MemBarAcquire); 7535 ins_cost(0); 7536 7537 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7538 size(0); 7539 ins_encode( /*empty*/ ); 7540 ins_pipe(pipe_class_default); 7541 %} 7542 7543 instruct membar_acquire_lock() %{ 7544 match(MemBarAcquireLock); 7545 ins_cost(0); 7546 7547 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7548 size(0); 7549 ins_encode( /*empty*/ ); 7550 ins_pipe(pipe_class_default); 7551 %} 7552 7553 instruct membar_release() %{ 7554 match(MemBarRelease); 7555 match(StoreFence); 7556 ins_cost(4*MEMORY_REF_COST); 7557 7558 format %{ "MEMBAR-release" %} 7559 size(4); 7560 ins_encode %{ 7561 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7562 __ release(); 7563 %} 7564 ins_pipe(pipe_class_default); 7565 %} 7566 7567 instruct membar_storestore() %{ 7568 match(MemBarStoreStore); 7569 ins_cost(4*MEMORY_REF_COST); 7570 7571 format %{ "MEMBAR-store-store" %} 7572 size(4); 7573 ins_encode %{ 7574 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7575 __ membar(Assembler::StoreStore); 7576 %} 7577 ins_pipe(pipe_class_default); 7578 %} 7579 7580 instruct membar_release_lock() %{ 7581 match(MemBarReleaseLock); 7582 ins_cost(0); 7583 7584 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7585 size(0); 7586 ins_encode( /*empty*/ ); 7587 ins_pipe(pipe_class_default); 7588 %} 7589 7590 instruct membar_volatile() %{ 7591 match(MemBarVolatile); 7592 ins_cost(4*MEMORY_REF_COST); 7593 7594 format %{ "MEMBAR-volatile" %} 7595 size(4); 7596 ins_encode %{ 7597 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7598 __ fence(); 7599 %} 7600 ins_pipe(pipe_class_default); 7601 %} 7602 7603 // This optimization is wrong on PPC. The following pattern is not supported: 7604 // MemBarVolatile 7605 // ^ ^ 7606 // | | 7607 // CtrlProj MemProj 7608 // ^ ^ 7609 // | | 7610 // | Load 7611 // | 7612 // MemBarVolatile 7613 // 7614 // The first MemBarVolatile could get optimized out! According to 7615 // Vladimir, this pattern can not occur on Oracle platforms. 7616 // However, it does occur on PPC64 (because of membars in 7617 // inline_unsafe_load_store). 7618 // 7619 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7620 // Don't forget to look at the implementation of post_store_load_barrier again, 7621 // we did other fixes in that method. 7622 //instruct unnecessary_membar_volatile() %{ 7623 // match(MemBarVolatile); 7624 // predicate(Matcher::post_store_load_barrier(n)); 7625 // ins_cost(0); 7626 // 7627 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7628 // size(0); 7629 // ins_encode( /*empty*/ ); 7630 // ins_pipe(pipe_class_default); 7631 //%} 7632 7633 instruct membar_CPUOrder() %{ 7634 match(MemBarCPUOrder); 7635 ins_cost(0); 7636 7637 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7638 size(0); 7639 ins_encode( /*empty*/ ); 7640 ins_pipe(pipe_class_default); 7641 %} 7642 7643 //----------Conditional Move--------------------------------------------------- 7644 7645 // Cmove using isel. 7646 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7647 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7648 predicate(VM_Version::has_isel()); 7649 ins_cost(DEFAULT_COST); 7650 7651 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7652 size(4); 7653 ins_encode %{ 7654 // This is a Power7 instruction for which no machine description 7655 // exists. Anyways, the scheduler should be off on Power7. 7656 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7657 int cc = $cmp$$cmpcode; 7658 __ isel($dst$$Register, $crx$$CondRegister, 7659 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7660 %} 7661 ins_pipe(pipe_class_default); 7662 %} 7663 7664 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7665 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7666 predicate(!VM_Version::has_isel()); 7667 ins_cost(DEFAULT_COST+BRANCH_COST); 7668 7669 ins_variable_size_depending_on_alignment(true); 7670 7671 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7672 // Worst case is branch + move + stop, no stop without scheduler 7673 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7674 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7675 ins_pipe(pipe_class_default); 7676 %} 7677 7678 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7679 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7680 ins_cost(DEFAULT_COST+BRANCH_COST); 7681 7682 ins_variable_size_depending_on_alignment(true); 7683 7684 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7685 // Worst case is branch + move + stop, no stop without scheduler 7686 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7687 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7688 ins_pipe(pipe_class_default); 7689 %} 7690 7691 // Cmove using isel. 7692 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7693 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7694 predicate(VM_Version::has_isel()); 7695 ins_cost(DEFAULT_COST); 7696 7697 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7698 size(4); 7699 ins_encode %{ 7700 // This is a Power7 instruction for which no machine description 7701 // exists. Anyways, the scheduler should be off on Power7. 7702 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7703 int cc = $cmp$$cmpcode; 7704 __ isel($dst$$Register, $crx$$CondRegister, 7705 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7706 %} 7707 ins_pipe(pipe_class_default); 7708 %} 7709 7710 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7711 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7712 predicate(!VM_Version::has_isel()); 7713 ins_cost(DEFAULT_COST+BRANCH_COST); 7714 7715 ins_variable_size_depending_on_alignment(true); 7716 7717 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7718 // Worst case is branch + move + stop, no stop without scheduler. 7719 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7720 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7721 ins_pipe(pipe_class_default); 7722 %} 7723 7724 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7725 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7726 ins_cost(DEFAULT_COST+BRANCH_COST); 7727 7728 ins_variable_size_depending_on_alignment(true); 7729 7730 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7731 // Worst case is branch + move + stop, no stop without scheduler. 7732 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7733 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7734 ins_pipe(pipe_class_default); 7735 %} 7736 7737 // Cmove using isel. 7738 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7739 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7740 predicate(VM_Version::has_isel()); 7741 ins_cost(DEFAULT_COST); 7742 7743 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7744 size(4); 7745 ins_encode %{ 7746 // This is a Power7 instruction for which no machine description 7747 // exists. Anyways, the scheduler should be off on Power7. 7748 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7749 int cc = $cmp$$cmpcode; 7750 __ isel($dst$$Register, $crx$$CondRegister, 7751 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7752 %} 7753 ins_pipe(pipe_class_default); 7754 %} 7755 7756 // Conditional move for RegN. Only cmov(reg, reg). 7757 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7758 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7759 predicate(!VM_Version::has_isel()); 7760 ins_cost(DEFAULT_COST+BRANCH_COST); 7761 7762 ins_variable_size_depending_on_alignment(true); 7763 7764 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7765 // Worst case is branch + move + stop, no stop without scheduler. 7766 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7767 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7768 ins_pipe(pipe_class_default); 7769 %} 7770 7771 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7772 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7773 ins_cost(DEFAULT_COST+BRANCH_COST); 7774 7775 ins_variable_size_depending_on_alignment(true); 7776 7777 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7778 // Worst case is branch + move + stop, no stop without scheduler. 7779 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7780 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7781 ins_pipe(pipe_class_default); 7782 %} 7783 7784 // Cmove using isel. 7785 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7786 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7787 predicate(VM_Version::has_isel()); 7788 ins_cost(DEFAULT_COST); 7789 7790 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7791 size(4); 7792 ins_encode %{ 7793 // This is a Power7 instruction for which no machine description 7794 // exists. Anyways, the scheduler should be off on Power7. 7795 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7796 int cc = $cmp$$cmpcode; 7797 __ isel($dst$$Register, $crx$$CondRegister, 7798 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7799 %} 7800 ins_pipe(pipe_class_default); 7801 %} 7802 7803 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7804 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7805 predicate(!VM_Version::has_isel()); 7806 ins_cost(DEFAULT_COST+BRANCH_COST); 7807 7808 ins_variable_size_depending_on_alignment(true); 7809 7810 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7811 // Worst case is branch + move + stop, no stop without scheduler. 7812 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7813 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7814 ins_pipe(pipe_class_default); 7815 %} 7816 7817 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7818 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7819 ins_cost(DEFAULT_COST+BRANCH_COST); 7820 7821 ins_variable_size_depending_on_alignment(true); 7822 7823 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7824 // Worst case is branch + move + stop, no stop without scheduler. 7825 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7826 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7827 ins_pipe(pipe_class_default); 7828 %} 7829 7830 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7831 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7832 ins_cost(DEFAULT_COST+BRANCH_COST); 7833 7834 ins_variable_size_depending_on_alignment(true); 7835 7836 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7837 // Worst case is branch + move + stop, no stop without scheduler. 7838 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7839 ins_encode %{ 7840 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7841 Label done; 7842 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7843 // Branch if not (cmp crx). 7844 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7845 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7846 // TODO PPC port __ endgroup_if_needed(_size == 12); 7847 __ bind(done); 7848 %} 7849 ins_pipe(pipe_class_default); 7850 %} 7851 7852 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7853 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7854 ins_cost(DEFAULT_COST+BRANCH_COST); 7855 7856 ins_variable_size_depending_on_alignment(true); 7857 7858 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7859 // Worst case is branch + move + stop, no stop without scheduler. 7860 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7861 ins_encode %{ 7862 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7863 Label done; 7864 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7865 // Branch if not (cmp crx). 7866 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7867 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7868 // TODO PPC port __ endgroup_if_needed(_size == 12); 7869 __ bind(done); 7870 %} 7871 ins_pipe(pipe_class_default); 7872 %} 7873 7874 //----------Conditional_store-------------------------------------------------- 7875 // Conditional-store of the updated heap-top. 7876 // Used during allocation of the shared heap. 7877 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7878 7879 // As compareAndSwapL, but return flag register instead of boolean value in 7880 // int register. 7881 // Used by sun/misc/AtomicLongCSImpl.java. 7882 // Mem_ptr must be a memory operand, else this node does not get 7883 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7884 // can be rematerialized which leads to errors. 7885 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7886 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7887 effect(TEMP cr0); 7888 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7889 ins_encode %{ 7890 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7891 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7892 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7893 noreg, NULL, true); 7894 %} 7895 ins_pipe(pipe_class_default); 7896 %} 7897 7898 // As compareAndSwapP, but return flag register instead of boolean value in 7899 // int register. 7900 // This instruction is matched if UseTLAB is off. 7901 // Mem_ptr must be a memory operand, else this node does not get 7902 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7903 // can be rematerialized which leads to errors. 7904 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7905 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7906 ins_cost(2*MEMORY_REF_COST); 7907 7908 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7909 ins_encode %{ 7910 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7911 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7912 %} 7913 ins_pipe(pipe_class_memory); 7914 %} 7915 7916 // Implement LoadPLocked. Must be ordered against changes of the memory location 7917 // by storePConditional. 7918 // Don't know whether this is ever used. 7919 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7920 match(Set dst (LoadPLocked mem)); 7921 ins_cost(2*MEMORY_REF_COST); 7922 7923 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7924 size(4); 7925 ins_encode %{ 7926 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7927 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7928 %} 7929 ins_pipe(pipe_class_memory); 7930 %} 7931 7932 //----------Compare-And-Swap--------------------------------------------------- 7933 7934 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7935 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7936 // matched. 7937 7938 // Strong versions: 7939 7940 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7941 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7942 predicate(VM_Version::has_lqarx()); 7943 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7944 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7945 ins_encode %{ 7946 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7947 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7948 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7949 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7950 $res$$Register, true); 7951 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 7952 __ isync(); 7953 } else { 7954 __ sync(); 7955 } 7956 %} 7957 ins_pipe(pipe_class_default); 7958 %} 7959 7960 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7961 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7962 predicate(!VM_Version::has_lqarx()); 7963 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7964 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7965 ins_encode %{ 7966 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7967 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7968 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7969 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7970 $res$$Register, true); 7971 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 7972 __ isync(); 7973 } else { 7974 __ sync(); 7975 } 7976 %} 7977 ins_pipe(pipe_class_default); 7978 %} 7979 7980 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7981 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7982 predicate(VM_Version::has_lqarx()); 7983 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7984 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7985 ins_encode %{ 7986 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7987 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7988 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7989 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7990 $res$$Register, true); 7991 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 7992 __ isync(); 7993 } else { 7994 __ sync(); 7995 } 7996 %} 7997 ins_pipe(pipe_class_default); 7998 %} 7999 8000 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8001 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 8002 predicate(!VM_Version::has_lqarx()); 8003 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8004 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8005 ins_encode %{ 8006 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8007 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8008 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8009 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8010 $res$$Register, true); 8011 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8012 __ isync(); 8013 } else { 8014 __ sync(); 8015 } 8016 %} 8017 ins_pipe(pipe_class_default); 8018 %} 8019 8020 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8021 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 8022 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8023 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8024 ins_encode %{ 8025 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8026 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8027 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8028 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8029 $res$$Register, true); 8030 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8031 __ isync(); 8032 } else { 8033 __ sync(); 8034 } 8035 %} 8036 ins_pipe(pipe_class_default); 8037 %} 8038 8039 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8040 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 8041 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8042 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8043 ins_encode %{ 8044 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8045 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8046 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8047 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8048 $res$$Register, true); 8049 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8050 __ isync(); 8051 } else { 8052 __ sync(); 8053 } 8054 %} 8055 ins_pipe(pipe_class_default); 8056 %} 8057 8058 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8059 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 8060 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8061 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8062 ins_encode %{ 8063 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8064 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8065 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8066 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8067 $res$$Register, NULL, true); 8068 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8069 __ isync(); 8070 } else { 8071 __ sync(); 8072 } 8073 %} 8074 ins_pipe(pipe_class_default); 8075 %} 8076 8077 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8078 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 8079 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8080 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8081 ins_encode %{ 8082 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8083 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8084 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8085 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8086 $res$$Register, NULL, true); 8087 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8088 __ isync(); 8089 } else { 8090 __ sync(); 8091 } 8092 %} 8093 ins_pipe(pipe_class_default); 8094 %} 8095 8096 // Weak versions: 8097 8098 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8099 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8100 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8101 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8102 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8103 ins_encode %{ 8104 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8105 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8106 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8107 MacroAssembler::MemBarNone, 8108 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8109 %} 8110 ins_pipe(pipe_class_default); 8111 %} 8112 8113 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8114 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8115 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8116 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8117 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8118 ins_encode %{ 8119 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8120 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8121 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8122 MacroAssembler::MemBarNone, 8123 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8124 %} 8125 ins_pipe(pipe_class_default); 8126 %} 8127 8128 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8129 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8130 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8131 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8132 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8133 ins_encode %{ 8134 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8135 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8136 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8137 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8138 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8139 %} 8140 ins_pipe(pipe_class_default); 8141 %} 8142 8143 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8144 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8145 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8146 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8147 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8148 ins_encode %{ 8149 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8150 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8151 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8152 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8153 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8154 %} 8155 ins_pipe(pipe_class_default); 8156 %} 8157 8158 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8159 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8160 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8161 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8162 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8163 ins_encode %{ 8164 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8165 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8166 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8167 MacroAssembler::MemBarNone, 8168 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8169 %} 8170 ins_pipe(pipe_class_default); 8171 %} 8172 8173 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8174 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8175 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8176 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8177 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8178 ins_encode %{ 8179 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8180 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8181 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8182 MacroAssembler::MemBarNone, 8183 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8184 %} 8185 ins_pipe(pipe_class_default); 8186 %} 8187 8188 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8189 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8190 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8191 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8192 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8193 ins_encode %{ 8194 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8195 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8196 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8197 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8198 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8199 %} 8200 ins_pipe(pipe_class_default); 8201 %} 8202 8203 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8204 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8205 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8206 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8207 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8208 ins_encode %{ 8209 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8210 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8211 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8212 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8213 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8214 %} 8215 ins_pipe(pipe_class_default); 8216 %} 8217 8218 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8219 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8220 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8221 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8222 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8223 ins_encode %{ 8224 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8225 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8226 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8227 MacroAssembler::MemBarNone, 8228 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8229 %} 8230 ins_pipe(pipe_class_default); 8231 %} 8232 8233 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8234 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8235 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8236 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8237 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8238 ins_encode %{ 8239 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8240 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8241 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8242 // value is never passed to caller. 8243 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8244 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8245 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8246 %} 8247 ins_pipe(pipe_class_default); 8248 %} 8249 8250 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8251 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8252 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8253 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8254 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8255 ins_encode %{ 8256 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8257 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8258 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8259 MacroAssembler::MemBarNone, 8260 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8261 %} 8262 ins_pipe(pipe_class_default); 8263 %} 8264 8265 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8266 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8267 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8268 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8269 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8270 ins_encode %{ 8271 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8272 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8273 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8274 // value is never passed to caller. 8275 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8276 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8277 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8278 %} 8279 ins_pipe(pipe_class_default); 8280 %} 8281 8282 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8283 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8284 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8285 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8286 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8287 ins_encode %{ 8288 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8289 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8290 // value is never passed to caller. 8291 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8292 MacroAssembler::MemBarNone, 8293 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8294 %} 8295 ins_pipe(pipe_class_default); 8296 %} 8297 8298 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8299 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8300 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8301 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8302 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 8303 ins_encode %{ 8304 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8305 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8306 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8307 // value is never passed to caller. 8308 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8309 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8310 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8311 %} 8312 ins_pipe(pipe_class_default); 8313 %} 8314 8315 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8316 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8317 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8318 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8319 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8320 ins_encode %{ 8321 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8322 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8323 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8324 MacroAssembler::MemBarNone, 8325 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8326 %} 8327 ins_pipe(pipe_class_default); 8328 %} 8329 8330 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8331 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8332 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8333 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8334 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8335 ins_encode %{ 8336 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8337 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8338 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8339 // value is never passed to caller. 8340 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8341 SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8342 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8343 %} 8344 ins_pipe(pipe_class_default); 8345 %} 8346 8347 // CompareAndExchange 8348 8349 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8350 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8351 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8352 effect(TEMP_DEF res, TEMP cr0); 8353 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8354 ins_encode %{ 8355 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8356 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8357 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8358 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8359 noreg, true); 8360 %} 8361 ins_pipe(pipe_class_default); 8362 %} 8363 8364 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8365 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8366 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8367 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8368 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8369 ins_encode %{ 8370 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8371 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8372 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8373 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8374 noreg, true); 8375 %} 8376 ins_pipe(pipe_class_default); 8377 %} 8378 8379 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8380 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8381 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8382 effect(TEMP_DEF res, TEMP cr0); 8383 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8384 ins_encode %{ 8385 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8386 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8387 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8388 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8389 noreg, true); 8390 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8391 __ isync(); 8392 } else { 8393 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8394 __ sync(); 8395 } 8396 %} 8397 ins_pipe(pipe_class_default); 8398 %} 8399 8400 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8401 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8402 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8403 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8404 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8405 ins_encode %{ 8406 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8407 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8408 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8409 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8410 noreg, true); 8411 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8412 __ isync(); 8413 } else { 8414 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8415 __ sync(); 8416 } 8417 %} 8418 ins_pipe(pipe_class_default); 8419 %} 8420 8421 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8422 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8423 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8424 effect(TEMP_DEF res, TEMP cr0); 8425 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8426 ins_encode %{ 8427 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8428 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8429 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8430 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8431 noreg, true); 8432 %} 8433 ins_pipe(pipe_class_default); 8434 %} 8435 8436 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8437 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8438 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8439 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8440 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8441 ins_encode %{ 8442 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8443 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8444 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8445 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8446 noreg, true); 8447 %} 8448 ins_pipe(pipe_class_default); 8449 %} 8450 8451 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8452 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8453 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8454 effect(TEMP_DEF res, TEMP cr0); 8455 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8456 ins_encode %{ 8457 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8458 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8459 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8460 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8461 noreg, true); 8462 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8463 __ isync(); 8464 } else { 8465 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8466 __ sync(); 8467 } 8468 %} 8469 ins_pipe(pipe_class_default); 8470 %} 8471 8472 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8473 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8474 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8475 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8476 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8477 ins_encode %{ 8478 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8479 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8480 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8481 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8482 noreg, true); 8483 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8484 __ isync(); 8485 } else { 8486 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8487 __ sync(); 8488 } 8489 %} 8490 ins_pipe(pipe_class_default); 8491 %} 8492 8493 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8494 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8495 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8496 effect(TEMP_DEF res, TEMP cr0); 8497 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8498 ins_encode %{ 8499 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8500 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8501 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8502 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8503 noreg, true); 8504 %} 8505 ins_pipe(pipe_class_default); 8506 %} 8507 8508 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8509 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8510 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8511 effect(TEMP_DEF res, TEMP cr0); 8512 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8513 ins_encode %{ 8514 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8515 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8516 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8517 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8518 noreg, true); 8519 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8520 __ isync(); 8521 } else { 8522 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8523 __ sync(); 8524 } 8525 %} 8526 ins_pipe(pipe_class_default); 8527 %} 8528 8529 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8530 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8531 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8532 effect(TEMP_DEF res, TEMP cr0); 8533 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8534 ins_encode %{ 8535 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8536 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8537 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8538 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8539 noreg, true); 8540 %} 8541 ins_pipe(pipe_class_default); 8542 %} 8543 8544 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8545 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8546 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8547 effect(TEMP_DEF res, TEMP cr0); 8548 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8549 ins_encode %{ 8550 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8551 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8552 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8553 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8554 noreg, true); 8555 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8556 __ isync(); 8557 } else { 8558 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8559 __ sync(); 8560 } 8561 %} 8562 ins_pipe(pipe_class_default); 8563 %} 8564 8565 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8566 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8567 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8568 effect(TEMP_DEF res, TEMP cr0); 8569 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8570 ins_encode %{ 8571 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8572 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8573 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8574 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8575 noreg, NULL, true); 8576 %} 8577 ins_pipe(pipe_class_default); 8578 %} 8579 8580 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8581 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8582 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8583 effect(TEMP_DEF res, TEMP cr0); 8584 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8585 ins_encode %{ 8586 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8587 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8588 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8589 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8590 noreg, NULL, true); 8591 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8592 __ isync(); 8593 } else { 8594 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8595 __ sync(); 8596 } 8597 %} 8598 ins_pipe(pipe_class_default); 8599 %} 8600 8601 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8602 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8603 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8604 effect(TEMP_DEF res, TEMP cr0); 8605 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8606 ins_encode %{ 8607 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8608 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8609 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8610 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8611 noreg, NULL, true); 8612 %} 8613 ins_pipe(pipe_class_default); 8614 %} 8615 8616 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8617 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8618 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8619 effect(TEMP_DEF res, TEMP cr0); 8620 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8621 ins_encode %{ 8622 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8623 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8624 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8625 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8626 noreg, NULL, true); 8627 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8628 __ isync(); 8629 } else { 8630 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8631 __ sync(); 8632 } 8633 %} 8634 ins_pipe(pipe_class_default); 8635 %} 8636 8637 // Special RMW 8638 8639 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8640 match(Set res (GetAndAddB mem_ptr src)); 8641 predicate(VM_Version::has_lqarx()); 8642 effect(TEMP_DEF res, TEMP cr0); 8643 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8644 ins_encode %{ 8645 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8646 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8647 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8648 __ isync(); 8649 } else { 8650 __ sync(); 8651 } 8652 %} 8653 ins_pipe(pipe_class_default); 8654 %} 8655 8656 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8657 match(Set res (GetAndAddB mem_ptr src)); 8658 predicate(!VM_Version::has_lqarx()); 8659 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8660 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8661 ins_encode %{ 8662 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8663 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8664 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8665 __ isync(); 8666 } else { 8667 __ sync(); 8668 } 8669 %} 8670 ins_pipe(pipe_class_default); 8671 %} 8672 8673 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8674 match(Set res (GetAndAddS mem_ptr src)); 8675 predicate(VM_Version::has_lqarx()); 8676 effect(TEMP_DEF res, TEMP cr0); 8677 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8678 ins_encode %{ 8679 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8680 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8681 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8682 __ isync(); 8683 } else { 8684 __ sync(); 8685 } 8686 %} 8687 ins_pipe(pipe_class_default); 8688 %} 8689 8690 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8691 match(Set res (GetAndAddS mem_ptr src)); 8692 predicate(!VM_Version::has_lqarx()); 8693 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8694 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8695 ins_encode %{ 8696 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8697 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8698 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8699 __ isync(); 8700 } else { 8701 __ sync(); 8702 } 8703 %} 8704 ins_pipe(pipe_class_default); 8705 %} 8706 8707 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8708 match(Set res (GetAndAddI mem_ptr src)); 8709 effect(TEMP_DEF res, TEMP cr0); 8710 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8711 ins_encode %{ 8712 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8713 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8714 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8715 __ isync(); 8716 } else { 8717 __ sync(); 8718 } 8719 %} 8720 ins_pipe(pipe_class_default); 8721 %} 8722 8723 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8724 match(Set res (GetAndAddL mem_ptr src)); 8725 effect(TEMP_DEF res, TEMP cr0); 8726 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8727 ins_encode %{ 8728 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8729 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8730 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8731 __ isync(); 8732 } else { 8733 __ sync(); 8734 } 8735 %} 8736 ins_pipe(pipe_class_default); 8737 %} 8738 8739 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8740 match(Set res (GetAndSetB mem_ptr src)); 8741 predicate(VM_Version::has_lqarx()); 8742 effect(TEMP_DEF res, TEMP cr0); 8743 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8744 ins_encode %{ 8745 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8746 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8747 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8748 __ isync(); 8749 } else { 8750 __ sync(); 8751 } 8752 %} 8753 ins_pipe(pipe_class_default); 8754 %} 8755 8756 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8757 match(Set res (GetAndSetB mem_ptr src)); 8758 predicate(!VM_Version::has_lqarx()); 8759 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8760 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8761 ins_encode %{ 8762 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8763 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8764 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8765 __ isync(); 8766 } else { 8767 __ sync(); 8768 } 8769 %} 8770 ins_pipe(pipe_class_default); 8771 %} 8772 8773 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8774 match(Set res (GetAndSetS mem_ptr src)); 8775 predicate(VM_Version::has_lqarx()); 8776 effect(TEMP_DEF res, TEMP cr0); 8777 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8778 ins_encode %{ 8779 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8780 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8781 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8782 __ isync(); 8783 } else { 8784 __ sync(); 8785 } 8786 %} 8787 ins_pipe(pipe_class_default); 8788 %} 8789 8790 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8791 match(Set res (GetAndSetS mem_ptr src)); 8792 predicate(!VM_Version::has_lqarx()); 8793 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8794 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8795 ins_encode %{ 8796 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8797 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8798 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8799 __ isync(); 8800 } else { 8801 __ sync(); 8802 } 8803 %} 8804 ins_pipe(pipe_class_default); 8805 %} 8806 8807 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8808 match(Set res (GetAndSetI mem_ptr src)); 8809 effect(TEMP_DEF res, TEMP cr0); 8810 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8811 ins_encode %{ 8812 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8813 MacroAssembler::cmpxchgx_hint_atomic_update()); 8814 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8815 __ isync(); 8816 } else { 8817 __ sync(); 8818 } 8819 %} 8820 ins_pipe(pipe_class_default); 8821 %} 8822 8823 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8824 match(Set res (GetAndSetL mem_ptr src)); 8825 effect(TEMP_DEF res, TEMP cr0); 8826 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8827 ins_encode %{ 8828 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8829 MacroAssembler::cmpxchgx_hint_atomic_update()); 8830 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8831 __ isync(); 8832 } else { 8833 __ sync(); 8834 } 8835 %} 8836 ins_pipe(pipe_class_default); 8837 %} 8838 8839 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8840 match(Set res (GetAndSetP mem_ptr src)); 8841 effect(TEMP_DEF res, TEMP cr0); 8842 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8843 ins_encode %{ 8844 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8845 MacroAssembler::cmpxchgx_hint_atomic_update()); 8846 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8847 __ isync(); 8848 } else { 8849 __ sync(); 8850 } 8851 %} 8852 ins_pipe(pipe_class_default); 8853 %} 8854 8855 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8856 match(Set res (GetAndSetN mem_ptr src)); 8857 effect(TEMP_DEF res, TEMP cr0); 8858 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8859 ins_encode %{ 8860 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8861 MacroAssembler::cmpxchgx_hint_atomic_update()); 8862 if (SUPPORT_IRIW_FOR_NOT_MULTI_COPY_ATOMIC_CPU) { 8863 __ isync(); 8864 } else { 8865 __ sync(); 8866 } 8867 %} 8868 ins_pipe(pipe_class_default); 8869 %} 8870 8871 //----------Arithmetic Instructions-------------------------------------------- 8872 // Addition Instructions 8873 8874 // Register Addition 8875 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8876 match(Set dst (AddI src1 src2)); 8877 format %{ "ADD $dst, $src1, $src2" %} 8878 size(4); 8879 ins_encode %{ 8880 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8881 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8882 %} 8883 ins_pipe(pipe_class_default); 8884 %} 8885 8886 // Expand does not work with above instruct. (??) 8887 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8888 // no match-rule 8889 effect(DEF dst, USE src1, USE src2); 8890 format %{ "ADD $dst, $src1, $src2" %} 8891 size(4); 8892 ins_encode %{ 8893 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8894 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8895 %} 8896 ins_pipe(pipe_class_default); 8897 %} 8898 8899 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8900 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8901 ins_cost(DEFAULT_COST*3); 8902 8903 expand %{ 8904 // FIXME: we should do this in the ideal world. 8905 iRegIdst tmp1; 8906 iRegIdst tmp2; 8907 addI_reg_reg(tmp1, src1, src2); 8908 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8909 addI_reg_reg(dst, tmp1, tmp2); 8910 %} 8911 %} 8912 8913 // Immediate Addition 8914 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8915 match(Set dst (AddI src1 src2)); 8916 format %{ "ADDI $dst, $src1, $src2" %} 8917 size(4); 8918 ins_encode %{ 8919 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8920 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8921 %} 8922 ins_pipe(pipe_class_default); 8923 %} 8924 8925 // Immediate Addition with 16-bit shifted operand 8926 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8927 match(Set dst (AddI src1 src2)); 8928 format %{ "ADDIS $dst, $src1, $src2" %} 8929 size(4); 8930 ins_encode %{ 8931 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8932 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8933 %} 8934 ins_pipe(pipe_class_default); 8935 %} 8936 8937 // Long Addition 8938 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8939 match(Set dst (AddL src1 src2)); 8940 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8941 size(4); 8942 ins_encode %{ 8943 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8944 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8945 %} 8946 ins_pipe(pipe_class_default); 8947 %} 8948 8949 // Expand does not work with above instruct. (??) 8950 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8951 // no match-rule 8952 effect(DEF dst, USE src1, USE src2); 8953 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8954 size(4); 8955 ins_encode %{ 8956 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8957 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8958 %} 8959 ins_pipe(pipe_class_default); 8960 %} 8961 8962 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8963 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8964 ins_cost(DEFAULT_COST*3); 8965 8966 expand %{ 8967 // FIXME: we should do this in the ideal world. 8968 iRegLdst tmp1; 8969 iRegLdst tmp2; 8970 addL_reg_reg(tmp1, src1, src2); 8971 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8972 addL_reg_reg(dst, tmp1, tmp2); 8973 %} 8974 %} 8975 8976 // AddL + ConvL2I. 8977 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8978 match(Set dst (ConvL2I (AddL src1 src2))); 8979 8980 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8981 size(4); 8982 ins_encode %{ 8983 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8984 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8985 %} 8986 ins_pipe(pipe_class_default); 8987 %} 8988 8989 // No constant pool entries required. 8990 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8991 match(Set dst (AddL src1 src2)); 8992 8993 format %{ "ADDI $dst, $src1, $src2" %} 8994 size(4); 8995 ins_encode %{ 8996 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8997 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8998 %} 8999 ins_pipe(pipe_class_default); 9000 %} 9001 9002 // Long Immediate Addition with 16-bit shifted operand. 9003 // No constant pool entries required. 9004 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 9005 match(Set dst (AddL src1 src2)); 9006 9007 format %{ "ADDIS $dst, $src1, $src2" %} 9008 size(4); 9009 ins_encode %{ 9010 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 9011 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 9012 %} 9013 ins_pipe(pipe_class_default); 9014 %} 9015 9016 // Pointer Register Addition 9017 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 9018 match(Set dst (AddP src1 src2)); 9019 format %{ "ADD $dst, $src1, $src2" %} 9020 size(4); 9021 ins_encode %{ 9022 // TODO: PPC port $archOpcode(ppc64Opcode_add); 9023 __ add($dst$$Register, $src1$$Register, $src2$$Register); 9024 %} 9025 ins_pipe(pipe_class_default); 9026 %} 9027 9028 // Pointer Immediate Addition 9029 // No constant pool entries required. 9030 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 9031 match(Set dst (AddP src1 src2)); 9032 9033 format %{ "ADDI $dst, $src1, $src2" %} 9034 size(4); 9035 ins_encode %{ 9036 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 9037 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 9038 %} 9039 ins_pipe(pipe_class_default); 9040 %} 9041 9042 // Pointer Immediate Addition with 16-bit shifted operand. 9043 // No constant pool entries required. 9044 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 9045 match(Set dst (AddP src1 src2)); 9046 9047 format %{ "ADDIS $dst, $src1, $src2" %} 9048 size(4); 9049 ins_encode %{ 9050 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 9051 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 9052 %} 9053 ins_pipe(pipe_class_default); 9054 %} 9055 9056 //--------------------- 9057 // Subtraction Instructions 9058 9059 // Register Subtraction 9060 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9061 match(Set dst (SubI src1 src2)); 9062 format %{ "SUBF $dst, $src2, $src1" %} 9063 size(4); 9064 ins_encode %{ 9065 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9066 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9067 %} 9068 ins_pipe(pipe_class_default); 9069 %} 9070 9071 // Immediate Subtraction 9072 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 9073 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 9074 9075 // SubI from constant (using subfic). 9076 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 9077 match(Set dst (SubI src1 src2)); 9078 format %{ "SUBI $dst, $src1, $src2" %} 9079 9080 size(4); 9081 ins_encode %{ 9082 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 9083 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 9084 %} 9085 ins_pipe(pipe_class_default); 9086 %} 9087 9088 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 9089 // positive integers and 0xF...F for negative ones. 9090 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 9091 // no match-rule, false predicate 9092 effect(DEF dst, USE src); 9093 predicate(false); 9094 9095 format %{ "SRAWI $dst, $src, #31" %} 9096 size(4); 9097 ins_encode %{ 9098 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9099 __ srawi($dst$$Register, $src$$Register, 0x1f); 9100 %} 9101 ins_pipe(pipe_class_default); 9102 %} 9103 9104 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 9105 match(Set dst (AbsI src)); 9106 ins_cost(DEFAULT_COST*3); 9107 9108 expand %{ 9109 iRegIdst tmp1; 9110 iRegIdst tmp2; 9111 signmask32I_regI(tmp1, src); 9112 xorI_reg_reg(tmp2, tmp1, src); 9113 subI_reg_reg(dst, tmp2, tmp1); 9114 %} 9115 %} 9116 9117 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9118 match(Set dst (SubI zero src2)); 9119 format %{ "NEG $dst, $src2" %} 9120 size(4); 9121 ins_encode %{ 9122 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9123 __ neg($dst$$Register, $src2$$Register); 9124 %} 9125 ins_pipe(pipe_class_default); 9126 %} 9127 9128 // Long subtraction 9129 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9130 match(Set dst (SubL src1 src2)); 9131 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9132 size(4); 9133 ins_encode %{ 9134 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9135 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9136 %} 9137 ins_pipe(pipe_class_default); 9138 %} 9139 9140 // SubL + convL2I. 9141 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9142 match(Set dst (ConvL2I (SubL src1 src2))); 9143 9144 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9145 size(4); 9146 ins_encode %{ 9147 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9148 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9149 %} 9150 ins_pipe(pipe_class_default); 9151 %} 9152 9153 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9154 // positive longs and 0xF...F for negative ones. 9155 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9156 // no match-rule, false predicate 9157 effect(DEF dst, USE src); 9158 predicate(false); 9159 9160 format %{ "SRADI $dst, $src, #63" %} 9161 size(4); 9162 ins_encode %{ 9163 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9164 __ sradi($dst$$Register, $src$$Register, 0x3f); 9165 %} 9166 ins_pipe(pipe_class_default); 9167 %} 9168 9169 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9170 // positive longs and 0xF...F for negative ones. 9171 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9172 // no match-rule, false predicate 9173 effect(DEF dst, USE src); 9174 predicate(false); 9175 9176 format %{ "SRADI $dst, $src, #63" %} 9177 size(4); 9178 ins_encode %{ 9179 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9180 __ sradi($dst$$Register, $src$$Register, 0x3f); 9181 %} 9182 ins_pipe(pipe_class_default); 9183 %} 9184 9185 // Long negation 9186 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9187 match(Set dst (SubL zero src2)); 9188 format %{ "NEG $dst, $src2 \t// long" %} 9189 size(4); 9190 ins_encode %{ 9191 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9192 __ neg($dst$$Register, $src2$$Register); 9193 %} 9194 ins_pipe(pipe_class_default); 9195 %} 9196 9197 // NegL + ConvL2I. 9198 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9199 match(Set dst (ConvL2I (SubL zero src2))); 9200 9201 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9202 size(4); 9203 ins_encode %{ 9204 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9205 __ neg($dst$$Register, $src2$$Register); 9206 %} 9207 ins_pipe(pipe_class_default); 9208 %} 9209 9210 // Multiplication Instructions 9211 // Integer Multiplication 9212 9213 // Register Multiplication 9214 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9215 match(Set dst (MulI src1 src2)); 9216 ins_cost(DEFAULT_COST); 9217 9218 format %{ "MULLW $dst, $src1, $src2" %} 9219 size(4); 9220 ins_encode %{ 9221 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9222 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9223 %} 9224 ins_pipe(pipe_class_default); 9225 %} 9226 9227 // Immediate Multiplication 9228 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9229 match(Set dst (MulI src1 src2)); 9230 ins_cost(DEFAULT_COST); 9231 9232 format %{ "MULLI $dst, $src1, $src2" %} 9233 size(4); 9234 ins_encode %{ 9235 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9236 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9237 %} 9238 ins_pipe(pipe_class_default); 9239 %} 9240 9241 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9242 match(Set dst (MulL src1 src2)); 9243 ins_cost(DEFAULT_COST); 9244 9245 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9246 size(4); 9247 ins_encode %{ 9248 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9249 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9250 %} 9251 ins_pipe(pipe_class_default); 9252 %} 9253 9254 // Multiply high for optimized long division by constant. 9255 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9256 match(Set dst (MulHiL src1 src2)); 9257 ins_cost(DEFAULT_COST); 9258 9259 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9260 size(4); 9261 ins_encode %{ 9262 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9263 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9264 %} 9265 ins_pipe(pipe_class_default); 9266 %} 9267 9268 // Immediate Multiplication 9269 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9270 match(Set dst (MulL src1 src2)); 9271 ins_cost(DEFAULT_COST); 9272 9273 format %{ "MULLI $dst, $src1, $src2" %} 9274 size(4); 9275 ins_encode %{ 9276 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9277 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9278 %} 9279 ins_pipe(pipe_class_default); 9280 %} 9281 9282 // Integer Division with Immediate -1: Negate. 9283 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9284 match(Set dst (DivI src1 src2)); 9285 ins_cost(DEFAULT_COST); 9286 9287 format %{ "NEG $dst, $src1 \t// /-1" %} 9288 size(4); 9289 ins_encode %{ 9290 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9291 __ neg($dst$$Register, $src1$$Register); 9292 %} 9293 ins_pipe(pipe_class_default); 9294 %} 9295 9296 // Integer Division with constant, but not -1. 9297 // We should be able to improve this by checking the type of src2. 9298 // It might well be that src2 is known to be positive. 9299 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9300 match(Set dst (DivI src1 src2)); 9301 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9302 ins_cost(2*DEFAULT_COST); 9303 9304 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9305 size(4); 9306 ins_encode %{ 9307 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9308 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9309 %} 9310 ins_pipe(pipe_class_default); 9311 %} 9312 9313 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9314 effect(USE_DEF dst, USE src1, USE crx); 9315 predicate(false); 9316 9317 ins_variable_size_depending_on_alignment(true); 9318 9319 format %{ "CMOVE $dst, neg($src1), $crx" %} 9320 // Worst case is branch + move + stop, no stop without scheduler. 9321 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9322 ins_encode %{ 9323 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9324 Label done; 9325 __ bne($crx$$CondRegister, done); 9326 __ neg($dst$$Register, $src1$$Register); 9327 // TODO PPC port __ endgroup_if_needed(_size == 12); 9328 __ bind(done); 9329 %} 9330 ins_pipe(pipe_class_default); 9331 %} 9332 9333 // Integer Division with Registers not containing constants. 9334 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9335 match(Set dst (DivI src1 src2)); 9336 ins_cost(10*DEFAULT_COST); 9337 9338 expand %{ 9339 immI16 imm %{ (int)-1 %} 9340 flagsReg tmp1; 9341 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9342 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9343 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9344 %} 9345 %} 9346 9347 // Long Division with Immediate -1: Negate. 9348 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9349 match(Set dst (DivL src1 src2)); 9350 ins_cost(DEFAULT_COST); 9351 9352 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9353 size(4); 9354 ins_encode %{ 9355 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9356 __ neg($dst$$Register, $src1$$Register); 9357 %} 9358 ins_pipe(pipe_class_default); 9359 %} 9360 9361 // Long Division with constant, but not -1. 9362 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9363 match(Set dst (DivL src1 src2)); 9364 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9365 ins_cost(2*DEFAULT_COST); 9366 9367 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9368 size(4); 9369 ins_encode %{ 9370 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9371 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9372 %} 9373 ins_pipe(pipe_class_default); 9374 %} 9375 9376 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9377 effect(USE_DEF dst, USE src1, USE crx); 9378 predicate(false); 9379 9380 ins_variable_size_depending_on_alignment(true); 9381 9382 format %{ "CMOVE $dst, neg($src1), $crx" %} 9383 // Worst case is branch + move + stop, no stop without scheduler. 9384 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9385 ins_encode %{ 9386 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9387 Label done; 9388 __ bne($crx$$CondRegister, done); 9389 __ neg($dst$$Register, $src1$$Register); 9390 // TODO PPC port __ endgroup_if_needed(_size == 12); 9391 __ bind(done); 9392 %} 9393 ins_pipe(pipe_class_default); 9394 %} 9395 9396 // Long Division with Registers not containing constants. 9397 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9398 match(Set dst (DivL src1 src2)); 9399 ins_cost(10*DEFAULT_COST); 9400 9401 expand %{ 9402 immL16 imm %{ (int)-1 %} 9403 flagsReg tmp1; 9404 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9405 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9406 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9407 %} 9408 %} 9409 9410 // Integer Remainder with registers. 9411 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9412 match(Set dst (ModI src1 src2)); 9413 ins_cost(10*DEFAULT_COST); 9414 9415 expand %{ 9416 immI16 imm %{ (int)-1 %} 9417 flagsReg tmp1; 9418 iRegIdst tmp2; 9419 iRegIdst tmp3; 9420 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9421 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9422 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9423 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9424 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9425 %} 9426 %} 9427 9428 // Long Remainder with registers 9429 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9430 match(Set dst (ModL src1 src2)); 9431 ins_cost(10*DEFAULT_COST); 9432 9433 expand %{ 9434 immL16 imm %{ (int)-1 %} 9435 flagsReg tmp1; 9436 iRegLdst tmp2; 9437 iRegLdst tmp3; 9438 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9439 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9440 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9441 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9442 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9443 %} 9444 %} 9445 9446 // Integer Shift Instructions 9447 9448 // Register Shift Left 9449 9450 // Clear all but the lowest #mask bits. 9451 // Used to normalize shift amounts in registers. 9452 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9453 // no match-rule, false predicate 9454 effect(DEF dst, USE src, USE mask); 9455 predicate(false); 9456 9457 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9458 size(4); 9459 ins_encode %{ 9460 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9461 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9462 %} 9463 ins_pipe(pipe_class_default); 9464 %} 9465 9466 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9467 // no match-rule, false predicate 9468 effect(DEF dst, USE src1, USE src2); 9469 predicate(false); 9470 9471 format %{ "SLW $dst, $src1, $src2" %} 9472 size(4); 9473 ins_encode %{ 9474 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9475 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9476 %} 9477 ins_pipe(pipe_class_default); 9478 %} 9479 9480 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9481 match(Set dst (LShiftI src1 src2)); 9482 ins_cost(DEFAULT_COST*2); 9483 expand %{ 9484 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9485 iRegIdst tmpI; 9486 maskI_reg_imm(tmpI, src2, mask); 9487 lShiftI_reg_reg(dst, src1, tmpI); 9488 %} 9489 %} 9490 9491 // Register Shift Left Immediate 9492 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9493 match(Set dst (LShiftI src1 src2)); 9494 9495 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9496 size(4); 9497 ins_encode %{ 9498 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9499 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9500 %} 9501 ins_pipe(pipe_class_default); 9502 %} 9503 9504 // AndI with negpow2-constant + LShiftI 9505 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9506 match(Set dst (LShiftI (AndI src1 src2) src3)); 9507 predicate(UseRotateAndMaskInstructionsPPC64); 9508 9509 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9510 size(4); 9511 ins_encode %{ 9512 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9513 long src2 = $src2$$constant; 9514 long src3 = $src3$$constant; 9515 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9516 if (maskbits >= 32) { 9517 __ li($dst$$Register, 0); // addi 9518 } else { 9519 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9520 } 9521 %} 9522 ins_pipe(pipe_class_default); 9523 %} 9524 9525 // RShiftI + AndI with negpow2-constant + LShiftI 9526 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9527 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9528 predicate(UseRotateAndMaskInstructionsPPC64); 9529 9530 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9531 size(4); 9532 ins_encode %{ 9533 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9534 long src2 = $src2$$constant; 9535 long src3 = $src3$$constant; 9536 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9537 if (maskbits >= 32) { 9538 __ li($dst$$Register, 0); // addi 9539 } else { 9540 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9541 } 9542 %} 9543 ins_pipe(pipe_class_default); 9544 %} 9545 9546 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9547 // no match-rule, false predicate 9548 effect(DEF dst, USE src1, USE src2); 9549 predicate(false); 9550 9551 format %{ "SLD $dst, $src1, $src2" %} 9552 size(4); 9553 ins_encode %{ 9554 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9555 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9556 %} 9557 ins_pipe(pipe_class_default); 9558 %} 9559 9560 // Register Shift Left 9561 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9562 match(Set dst (LShiftL src1 src2)); 9563 ins_cost(DEFAULT_COST*2); 9564 expand %{ 9565 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9566 iRegIdst tmpI; 9567 maskI_reg_imm(tmpI, src2, mask); 9568 lShiftL_regL_regI(dst, src1, tmpI); 9569 %} 9570 %} 9571 9572 // Register Shift Left Immediate 9573 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9574 match(Set dst (LShiftL src1 src2)); 9575 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9576 size(4); 9577 ins_encode %{ 9578 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9579 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9580 %} 9581 ins_pipe(pipe_class_default); 9582 %} 9583 9584 // If we shift more than 32 bits, we need not convert I2L. 9585 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9586 match(Set dst (LShiftL (ConvI2L src1) src2)); 9587 ins_cost(DEFAULT_COST); 9588 9589 size(4); 9590 format %{ "SLDI $dst, i2l($src1), $src2" %} 9591 ins_encode %{ 9592 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9593 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9594 %} 9595 ins_pipe(pipe_class_default); 9596 %} 9597 9598 // Shift a postivie int to the left. 9599 // Clrlsldi clears the upper 32 bits and shifts. 9600 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9601 match(Set dst (LShiftL (ConvI2L src1) src2)); 9602 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9603 9604 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9605 size(4); 9606 ins_encode %{ 9607 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9608 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9609 %} 9610 ins_pipe(pipe_class_default); 9611 %} 9612 9613 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9614 // no match-rule, false predicate 9615 effect(DEF dst, USE src1, USE src2); 9616 predicate(false); 9617 9618 format %{ "SRAW $dst, $src1, $src2" %} 9619 size(4); 9620 ins_encode %{ 9621 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9622 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9623 %} 9624 ins_pipe(pipe_class_default); 9625 %} 9626 9627 // Register Arithmetic Shift Right 9628 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9629 match(Set dst (RShiftI src1 src2)); 9630 ins_cost(DEFAULT_COST*2); 9631 expand %{ 9632 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9633 iRegIdst tmpI; 9634 maskI_reg_imm(tmpI, src2, mask); 9635 arShiftI_reg_reg(dst, src1, tmpI); 9636 %} 9637 %} 9638 9639 // Register Arithmetic Shift Right Immediate 9640 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9641 match(Set dst (RShiftI src1 src2)); 9642 9643 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9644 size(4); 9645 ins_encode %{ 9646 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9647 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9648 %} 9649 ins_pipe(pipe_class_default); 9650 %} 9651 9652 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9653 // no match-rule, false predicate 9654 effect(DEF dst, USE src1, USE src2); 9655 predicate(false); 9656 9657 format %{ "SRAD $dst, $src1, $src2" %} 9658 size(4); 9659 ins_encode %{ 9660 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9661 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9662 %} 9663 ins_pipe(pipe_class_default); 9664 %} 9665 9666 // Register Shift Right Arithmetic Long 9667 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9668 match(Set dst (RShiftL src1 src2)); 9669 ins_cost(DEFAULT_COST*2); 9670 9671 expand %{ 9672 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9673 iRegIdst tmpI; 9674 maskI_reg_imm(tmpI, src2, mask); 9675 arShiftL_regL_regI(dst, src1, tmpI); 9676 %} 9677 %} 9678 9679 // Register Shift Right Immediate 9680 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9681 match(Set dst (RShiftL src1 src2)); 9682 9683 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9684 size(4); 9685 ins_encode %{ 9686 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9687 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9688 %} 9689 ins_pipe(pipe_class_default); 9690 %} 9691 9692 // RShiftL + ConvL2I 9693 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9694 match(Set dst (ConvL2I (RShiftL src1 src2))); 9695 9696 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9697 size(4); 9698 ins_encode %{ 9699 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9700 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9701 %} 9702 ins_pipe(pipe_class_default); 9703 %} 9704 9705 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9706 // no match-rule, false predicate 9707 effect(DEF dst, USE src1, USE src2); 9708 predicate(false); 9709 9710 format %{ "SRW $dst, $src1, $src2" %} 9711 size(4); 9712 ins_encode %{ 9713 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9714 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9715 %} 9716 ins_pipe(pipe_class_default); 9717 %} 9718 9719 // Register Shift Right 9720 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9721 match(Set dst (URShiftI src1 src2)); 9722 ins_cost(DEFAULT_COST*2); 9723 9724 expand %{ 9725 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9726 iRegIdst tmpI; 9727 maskI_reg_imm(tmpI, src2, mask); 9728 urShiftI_reg_reg(dst, src1, tmpI); 9729 %} 9730 %} 9731 9732 // Register Shift Right Immediate 9733 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9734 match(Set dst (URShiftI src1 src2)); 9735 9736 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9737 size(4); 9738 ins_encode %{ 9739 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9740 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9741 %} 9742 ins_pipe(pipe_class_default); 9743 %} 9744 9745 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9746 // no match-rule, false predicate 9747 effect(DEF dst, USE src1, USE src2); 9748 predicate(false); 9749 9750 format %{ "SRD $dst, $src1, $src2" %} 9751 size(4); 9752 ins_encode %{ 9753 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9754 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9755 %} 9756 ins_pipe(pipe_class_default); 9757 %} 9758 9759 // Register Shift Right 9760 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9761 match(Set dst (URShiftL src1 src2)); 9762 ins_cost(DEFAULT_COST*2); 9763 9764 expand %{ 9765 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9766 iRegIdst tmpI; 9767 maskI_reg_imm(tmpI, src2, mask); 9768 urShiftL_regL_regI(dst, src1, tmpI); 9769 %} 9770 %} 9771 9772 // Register Shift Right Immediate 9773 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9774 match(Set dst (URShiftL src1 src2)); 9775 9776 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9777 size(4); 9778 ins_encode %{ 9779 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9780 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9781 %} 9782 ins_pipe(pipe_class_default); 9783 %} 9784 9785 // URShiftL + ConvL2I. 9786 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9787 match(Set dst (ConvL2I (URShiftL src1 src2))); 9788 9789 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9790 size(4); 9791 ins_encode %{ 9792 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9793 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9794 %} 9795 ins_pipe(pipe_class_default); 9796 %} 9797 9798 // Register Shift Right Immediate with a CastP2X 9799 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9800 match(Set dst (URShiftL (CastP2X src1) src2)); 9801 9802 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9803 size(4); 9804 ins_encode %{ 9805 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9806 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9807 %} 9808 ins_pipe(pipe_class_default); 9809 %} 9810 9811 // Bitfield Extract: URShiftI + AndI 9812 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9813 match(Set dst (AndI (URShiftI src1 src2) src3)); 9814 9815 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9816 size(4); 9817 ins_encode %{ 9818 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9819 int rshift = ($src2$$constant) & 0x1f; 9820 int length = log2_long(((jlong) $src3$$constant) + 1); 9821 if (rshift + length > 32) { 9822 // if necessary, adjust mask to omit rotated bits. 9823 length = 32 - rshift; 9824 } 9825 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9826 %} 9827 ins_pipe(pipe_class_default); 9828 %} 9829 9830 // Bitfield Extract: URShiftL + AndL 9831 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9832 match(Set dst (AndL (URShiftL src1 src2) src3)); 9833 9834 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9835 size(4); 9836 ins_encode %{ 9837 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9838 int rshift = ($src2$$constant) & 0x3f; 9839 int length = log2_long(((jlong) $src3$$constant) + 1); 9840 if (rshift + length > 64) { 9841 // if necessary, adjust mask to omit rotated bits. 9842 length = 64 - rshift; 9843 } 9844 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9845 %} 9846 ins_pipe(pipe_class_default); 9847 %} 9848 9849 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9850 match(Set dst (ConvL2I (ConvI2L src))); 9851 9852 format %{ "EXTSW $dst, $src \t// int->int" %} 9853 size(4); 9854 ins_encode %{ 9855 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9856 __ extsw($dst$$Register, $src$$Register); 9857 %} 9858 ins_pipe(pipe_class_default); 9859 %} 9860 9861 //----------Rotate Instructions------------------------------------------------ 9862 9863 // Rotate Left by 8-bit immediate 9864 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9865 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9866 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9867 9868 format %{ "ROTLWI $dst, $src, $lshift" %} 9869 size(4); 9870 ins_encode %{ 9871 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9872 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9873 %} 9874 ins_pipe(pipe_class_default); 9875 %} 9876 9877 // Rotate Right by 8-bit immediate 9878 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9879 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9880 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9881 9882 format %{ "ROTRWI $dst, $rshift" %} 9883 size(4); 9884 ins_encode %{ 9885 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9886 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9887 %} 9888 ins_pipe(pipe_class_default); 9889 %} 9890 9891 //----------Floating Point Arithmetic Instructions----------------------------- 9892 9893 // Add float single precision 9894 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9895 match(Set dst (AddF src1 src2)); 9896 9897 format %{ "FADDS $dst, $src1, $src2" %} 9898 size(4); 9899 ins_encode %{ 9900 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9901 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9902 %} 9903 ins_pipe(pipe_class_default); 9904 %} 9905 9906 // Add float double precision 9907 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9908 match(Set dst (AddD src1 src2)); 9909 9910 format %{ "FADD $dst, $src1, $src2" %} 9911 size(4); 9912 ins_encode %{ 9913 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9914 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9915 %} 9916 ins_pipe(pipe_class_default); 9917 %} 9918 9919 // Sub float single precision 9920 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9921 match(Set dst (SubF src1 src2)); 9922 9923 format %{ "FSUBS $dst, $src1, $src2" %} 9924 size(4); 9925 ins_encode %{ 9926 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9927 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9928 %} 9929 ins_pipe(pipe_class_default); 9930 %} 9931 9932 // Sub float double precision 9933 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9934 match(Set dst (SubD src1 src2)); 9935 format %{ "FSUB $dst, $src1, $src2" %} 9936 size(4); 9937 ins_encode %{ 9938 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9939 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9940 %} 9941 ins_pipe(pipe_class_default); 9942 %} 9943 9944 // Mul float single precision 9945 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9946 match(Set dst (MulF src1 src2)); 9947 format %{ "FMULS $dst, $src1, $src2" %} 9948 size(4); 9949 ins_encode %{ 9950 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9951 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9952 %} 9953 ins_pipe(pipe_class_default); 9954 %} 9955 9956 // Mul float double precision 9957 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9958 match(Set dst (MulD src1 src2)); 9959 format %{ "FMUL $dst, $src1, $src2" %} 9960 size(4); 9961 ins_encode %{ 9962 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9963 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9964 %} 9965 ins_pipe(pipe_class_default); 9966 %} 9967 9968 // Div float single precision 9969 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9970 match(Set dst (DivF src1 src2)); 9971 format %{ "FDIVS $dst, $src1, $src2" %} 9972 size(4); 9973 ins_encode %{ 9974 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9975 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9976 %} 9977 ins_pipe(pipe_class_default); 9978 %} 9979 9980 // Div float double precision 9981 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9982 match(Set dst (DivD src1 src2)); 9983 format %{ "FDIV $dst, $src1, $src2" %} 9984 size(4); 9985 ins_encode %{ 9986 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9987 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9988 %} 9989 ins_pipe(pipe_class_default); 9990 %} 9991 9992 // Absolute float single precision 9993 instruct absF_reg(regF dst, regF src) %{ 9994 match(Set dst (AbsF src)); 9995 format %{ "FABS $dst, $src \t// float" %} 9996 size(4); 9997 ins_encode %{ 9998 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9999 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 10000 %} 10001 ins_pipe(pipe_class_default); 10002 %} 10003 10004 // Absolute float double precision 10005 instruct absD_reg(regD dst, regD src) %{ 10006 match(Set dst (AbsD src)); 10007 format %{ "FABS $dst, $src \t// double" %} 10008 size(4); 10009 ins_encode %{ 10010 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 10011 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 10012 %} 10013 ins_pipe(pipe_class_default); 10014 %} 10015 10016 instruct negF_reg(regF dst, regF src) %{ 10017 match(Set dst (NegF src)); 10018 format %{ "FNEG $dst, $src \t// float" %} 10019 size(4); 10020 ins_encode %{ 10021 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 10022 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 10023 %} 10024 ins_pipe(pipe_class_default); 10025 %} 10026 10027 instruct negD_reg(regD dst, regD src) %{ 10028 match(Set dst (NegD src)); 10029 format %{ "FNEG $dst, $src \t// double" %} 10030 size(4); 10031 ins_encode %{ 10032 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 10033 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 10034 %} 10035 ins_pipe(pipe_class_default); 10036 %} 10037 10038 // AbsF + NegF. 10039 instruct negF_absF_reg(regF dst, regF src) %{ 10040 match(Set dst (NegF (AbsF src))); 10041 format %{ "FNABS $dst, $src \t// float" %} 10042 size(4); 10043 ins_encode %{ 10044 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10045 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10046 %} 10047 ins_pipe(pipe_class_default); 10048 %} 10049 10050 // AbsD + NegD. 10051 instruct negD_absD_reg(regD dst, regD src) %{ 10052 match(Set dst (NegD (AbsD src))); 10053 format %{ "FNABS $dst, $src \t// double" %} 10054 size(4); 10055 ins_encode %{ 10056 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10057 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10058 %} 10059 ins_pipe(pipe_class_default); 10060 %} 10061 10062 // VM_Version::has_fsqrt() decides if this node will be used. 10063 // Sqrt float double precision 10064 instruct sqrtD_reg(regD dst, regD src) %{ 10065 match(Set dst (SqrtD src)); 10066 format %{ "FSQRT $dst, $src" %} 10067 size(4); 10068 ins_encode %{ 10069 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 10070 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 10071 %} 10072 ins_pipe(pipe_class_default); 10073 %} 10074 10075 // Single-precision sqrt. 10076 instruct sqrtF_reg(regF dst, regF src) %{ 10077 match(Set dst (SqrtF src)); 10078 predicate(VM_Version::has_fsqrts()); 10079 ins_cost(DEFAULT_COST); 10080 10081 format %{ "FSQRTS $dst, $src" %} 10082 size(4); 10083 ins_encode %{ 10084 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 10085 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 10086 %} 10087 ins_pipe(pipe_class_default); 10088 %} 10089 10090 instruct roundDouble_nop(regD dst) %{ 10091 match(Set dst (RoundDouble dst)); 10092 ins_cost(0); 10093 10094 format %{ " -- \t// RoundDouble not needed - empty" %} 10095 size(0); 10096 // PPC results are already "rounded" (i.e., normal-format IEEE). 10097 ins_encode( /*empty*/ ); 10098 ins_pipe(pipe_class_default); 10099 %} 10100 10101 instruct roundFloat_nop(regF dst) %{ 10102 match(Set dst (RoundFloat dst)); 10103 ins_cost(0); 10104 10105 format %{ " -- \t// RoundFloat not needed - empty" %} 10106 size(0); 10107 // PPC results are already "rounded" (i.e., normal-format IEEE). 10108 ins_encode( /*empty*/ ); 10109 ins_pipe(pipe_class_default); 10110 %} 10111 10112 10113 // Multiply-Accumulate 10114 // src1 * src2 + src3 10115 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10116 match(Set dst (FmaF src3 (Binary src1 src2))); 10117 10118 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10119 size(4); 10120 ins_encode %{ 10121 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10122 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10123 %} 10124 ins_pipe(pipe_class_default); 10125 %} 10126 10127 // src1 * src2 + src3 10128 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10129 match(Set dst (FmaD src3 (Binary src1 src2))); 10130 10131 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10132 size(4); 10133 ins_encode %{ 10134 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10135 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10136 %} 10137 ins_pipe(pipe_class_default); 10138 %} 10139 10140 // -src1 * src2 + src3 = -(src1*src2-src3) 10141 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10142 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10143 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10144 10145 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10146 size(4); 10147 ins_encode %{ 10148 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10149 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10150 %} 10151 ins_pipe(pipe_class_default); 10152 %} 10153 10154 // -src1 * src2 + src3 = -(src1*src2-src3) 10155 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10156 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10157 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10158 10159 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10160 size(4); 10161 ins_encode %{ 10162 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10163 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10164 %} 10165 ins_pipe(pipe_class_default); 10166 %} 10167 10168 // -src1 * src2 - src3 = -(src1*src2+src3) 10169 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10170 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10171 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10172 10173 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10174 size(4); 10175 ins_encode %{ 10176 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10177 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10178 %} 10179 ins_pipe(pipe_class_default); 10180 %} 10181 10182 // -src1 * src2 - src3 = -(src1*src2+src3) 10183 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10184 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10185 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10186 10187 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10188 size(4); 10189 ins_encode %{ 10190 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10191 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10192 %} 10193 ins_pipe(pipe_class_default); 10194 %} 10195 10196 // src1 * src2 - src3 10197 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10198 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10199 10200 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10201 size(4); 10202 ins_encode %{ 10203 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10204 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10205 %} 10206 ins_pipe(pipe_class_default); 10207 %} 10208 10209 // src1 * src2 - src3 10210 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10211 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10212 10213 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10214 size(4); 10215 ins_encode %{ 10216 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10217 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10218 %} 10219 ins_pipe(pipe_class_default); 10220 %} 10221 10222 10223 //----------Logical Instructions----------------------------------------------- 10224 10225 // And Instructions 10226 10227 // Register And 10228 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10229 match(Set dst (AndI src1 src2)); 10230 format %{ "AND $dst, $src1, $src2" %} 10231 size(4); 10232 ins_encode %{ 10233 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10234 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10235 %} 10236 ins_pipe(pipe_class_default); 10237 %} 10238 10239 // Left shifted Immediate And 10240 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10241 match(Set dst (AndI src1 src2)); 10242 effect(KILL cr0); 10243 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10244 size(4); 10245 ins_encode %{ 10246 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10247 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10248 %} 10249 ins_pipe(pipe_class_default); 10250 %} 10251 10252 // Immediate And 10253 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10254 match(Set dst (AndI src1 src2)); 10255 effect(KILL cr0); 10256 10257 format %{ "ANDI $dst, $src1, $src2" %} 10258 size(4); 10259 ins_encode %{ 10260 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10261 // FIXME: avoid andi_ ? 10262 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10263 %} 10264 ins_pipe(pipe_class_default); 10265 %} 10266 10267 // Immediate And where the immediate is a negative power of 2. 10268 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10269 match(Set dst (AndI src1 src2)); 10270 format %{ "ANDWI $dst, $src1, $src2" %} 10271 size(4); 10272 ins_encode %{ 10273 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10274 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10275 %} 10276 ins_pipe(pipe_class_default); 10277 %} 10278 10279 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10280 match(Set dst (AndI src1 src2)); 10281 format %{ "ANDWI $dst, $src1, $src2" %} 10282 size(4); 10283 ins_encode %{ 10284 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10285 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10286 %} 10287 ins_pipe(pipe_class_default); 10288 %} 10289 10290 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10291 match(Set dst (AndI src1 src2)); 10292 predicate(UseRotateAndMaskInstructionsPPC64); 10293 format %{ "ANDWI $dst, $src1, $src2" %} 10294 size(4); 10295 ins_encode %{ 10296 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10297 __ rlwinm($dst$$Register, $src1$$Register, 0, 10298 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10299 %} 10300 ins_pipe(pipe_class_default); 10301 %} 10302 10303 // Register And Long 10304 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10305 match(Set dst (AndL src1 src2)); 10306 ins_cost(DEFAULT_COST); 10307 10308 format %{ "AND $dst, $src1, $src2 \t// long" %} 10309 size(4); 10310 ins_encode %{ 10311 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10312 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10313 %} 10314 ins_pipe(pipe_class_default); 10315 %} 10316 10317 // Immediate And long 10318 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10319 match(Set dst (AndL src1 src2)); 10320 effect(KILL cr0); 10321 10322 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10323 size(4); 10324 ins_encode %{ 10325 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10326 // FIXME: avoid andi_ ? 10327 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10328 %} 10329 ins_pipe(pipe_class_default); 10330 %} 10331 10332 // Immediate And Long where the immediate is a negative power of 2. 10333 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10334 match(Set dst (AndL src1 src2)); 10335 format %{ "ANDDI $dst, $src1, $src2" %} 10336 size(4); 10337 ins_encode %{ 10338 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10339 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10340 %} 10341 ins_pipe(pipe_class_default); 10342 %} 10343 10344 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10345 match(Set dst (AndL src1 src2)); 10346 format %{ "ANDDI $dst, $src1, $src2" %} 10347 size(4); 10348 ins_encode %{ 10349 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10350 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10351 %} 10352 ins_pipe(pipe_class_default); 10353 %} 10354 10355 // AndL + ConvL2I. 10356 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10357 match(Set dst (ConvL2I (AndL src1 src2))); 10358 ins_cost(DEFAULT_COST); 10359 10360 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10361 size(4); 10362 ins_encode %{ 10363 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10364 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10365 %} 10366 ins_pipe(pipe_class_default); 10367 %} 10368 10369 // Or Instructions 10370 10371 // Register Or 10372 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10373 match(Set dst (OrI src1 src2)); 10374 format %{ "OR $dst, $src1, $src2" %} 10375 size(4); 10376 ins_encode %{ 10377 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10378 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10379 %} 10380 ins_pipe(pipe_class_default); 10381 %} 10382 10383 // Expand does not work with above instruct. (??) 10384 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10385 // no match-rule 10386 effect(DEF dst, USE src1, USE src2); 10387 format %{ "OR $dst, $src1, $src2" %} 10388 size(4); 10389 ins_encode %{ 10390 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10391 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10392 %} 10393 ins_pipe(pipe_class_default); 10394 %} 10395 10396 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10397 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10398 ins_cost(DEFAULT_COST*3); 10399 10400 expand %{ 10401 // FIXME: we should do this in the ideal world. 10402 iRegIdst tmp1; 10403 iRegIdst tmp2; 10404 orI_reg_reg(tmp1, src1, src2); 10405 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10406 orI_reg_reg(dst, tmp1, tmp2); 10407 %} 10408 %} 10409 10410 // Immediate Or 10411 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10412 match(Set dst (OrI src1 src2)); 10413 format %{ "ORI $dst, $src1, $src2" %} 10414 size(4); 10415 ins_encode %{ 10416 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10417 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10418 %} 10419 ins_pipe(pipe_class_default); 10420 %} 10421 10422 // Register Or Long 10423 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10424 match(Set dst (OrL src1 src2)); 10425 ins_cost(DEFAULT_COST); 10426 10427 size(4); 10428 format %{ "OR $dst, $src1, $src2 \t// long" %} 10429 ins_encode %{ 10430 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10431 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10432 %} 10433 ins_pipe(pipe_class_default); 10434 %} 10435 10436 // OrL + ConvL2I. 10437 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10438 match(Set dst (ConvL2I (OrL src1 src2))); 10439 ins_cost(DEFAULT_COST); 10440 10441 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10442 size(4); 10443 ins_encode %{ 10444 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10445 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10446 %} 10447 ins_pipe(pipe_class_default); 10448 %} 10449 10450 // Immediate Or long 10451 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10452 match(Set dst (OrL src1 con)); 10453 ins_cost(DEFAULT_COST); 10454 10455 format %{ "ORI $dst, $src1, $con \t// long" %} 10456 size(4); 10457 ins_encode %{ 10458 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10459 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10460 %} 10461 ins_pipe(pipe_class_default); 10462 %} 10463 10464 // Xor Instructions 10465 10466 // Register Xor 10467 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10468 match(Set dst (XorI src1 src2)); 10469 format %{ "XOR $dst, $src1, $src2" %} 10470 size(4); 10471 ins_encode %{ 10472 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10473 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10474 %} 10475 ins_pipe(pipe_class_default); 10476 %} 10477 10478 // Expand does not work with above instruct. (??) 10479 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10480 // no match-rule 10481 effect(DEF dst, USE src1, USE src2); 10482 format %{ "XOR $dst, $src1, $src2" %} 10483 size(4); 10484 ins_encode %{ 10485 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10486 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10487 %} 10488 ins_pipe(pipe_class_default); 10489 %} 10490 10491 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10492 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10493 ins_cost(DEFAULT_COST*3); 10494 10495 expand %{ 10496 // FIXME: we should do this in the ideal world. 10497 iRegIdst tmp1; 10498 iRegIdst tmp2; 10499 xorI_reg_reg(tmp1, src1, src2); 10500 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10501 xorI_reg_reg(dst, tmp1, tmp2); 10502 %} 10503 %} 10504 10505 // Immediate Xor 10506 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10507 match(Set dst (XorI src1 src2)); 10508 format %{ "XORI $dst, $src1, $src2" %} 10509 size(4); 10510 ins_encode %{ 10511 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10512 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10513 %} 10514 ins_pipe(pipe_class_default); 10515 %} 10516 10517 // Register Xor Long 10518 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10519 match(Set dst (XorL src1 src2)); 10520 ins_cost(DEFAULT_COST); 10521 10522 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10523 size(4); 10524 ins_encode %{ 10525 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10526 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10527 %} 10528 ins_pipe(pipe_class_default); 10529 %} 10530 10531 // XorL + ConvL2I. 10532 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10533 match(Set dst (ConvL2I (XorL src1 src2))); 10534 ins_cost(DEFAULT_COST); 10535 10536 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10537 size(4); 10538 ins_encode %{ 10539 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10540 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10541 %} 10542 ins_pipe(pipe_class_default); 10543 %} 10544 10545 // Immediate Xor Long 10546 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10547 match(Set dst (XorL src1 src2)); 10548 ins_cost(DEFAULT_COST); 10549 10550 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10551 size(4); 10552 ins_encode %{ 10553 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10554 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10555 %} 10556 ins_pipe(pipe_class_default); 10557 %} 10558 10559 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10560 match(Set dst (XorI src1 src2)); 10561 ins_cost(DEFAULT_COST); 10562 10563 format %{ "NOT $dst, $src1 ($src2)" %} 10564 size(4); 10565 ins_encode %{ 10566 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10567 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10568 %} 10569 ins_pipe(pipe_class_default); 10570 %} 10571 10572 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10573 match(Set dst (XorL src1 src2)); 10574 ins_cost(DEFAULT_COST); 10575 10576 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10577 size(4); 10578 ins_encode %{ 10579 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10580 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10581 %} 10582 ins_pipe(pipe_class_default); 10583 %} 10584 10585 // And-complement 10586 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10587 match(Set dst (AndI (XorI src1 src2) src3)); 10588 ins_cost(DEFAULT_COST); 10589 10590 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10591 size(4); 10592 ins_encode( enc_andc(dst, src3, src1) ); 10593 ins_pipe(pipe_class_default); 10594 %} 10595 10596 // And-complement 10597 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10598 // no match-rule, false predicate 10599 effect(DEF dst, USE src1, USE src2); 10600 predicate(false); 10601 10602 format %{ "ANDC $dst, $src1, $src2" %} 10603 size(4); 10604 ins_encode %{ 10605 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10606 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10607 %} 10608 ins_pipe(pipe_class_default); 10609 %} 10610 10611 //----------Moves between int/long and float/double---------------------------- 10612 // 10613 // The following rules move values from int/long registers/stack-locations 10614 // to float/double registers/stack-locations and vice versa, without doing any 10615 // conversions. These rules are used to implement the bit-conversion methods 10616 // of java.lang.Float etc., e.g. 10617 // int floatToIntBits(float value) 10618 // float intBitsToFloat(int bits) 10619 // 10620 // Notes on the implementation on ppc64: 10621 // For Power7 and earlier, the rules are limited to those which move between a 10622 // register and a stack-location, because we always have to go through memory 10623 // when moving between a float register and an integer register. 10624 // This restriction is removed in Power8 with the introduction of the mtfprd 10625 // and mffprd instructions. 10626 10627 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10628 match(Set dst (MoveL2D src)); 10629 predicate(VM_Version::has_mtfprd()); 10630 10631 format %{ "MTFPRD $dst, $src" %} 10632 size(4); 10633 ins_encode %{ 10634 __ mtfprd($dst$$FloatRegister, $src$$Register); 10635 %} 10636 ins_pipe(pipe_class_default); 10637 %} 10638 10639 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10640 // no match-rule, false predicate 10641 effect(DEF dst, USE src); 10642 predicate(false); 10643 10644 format %{ "MTFPRWA $dst, $src" %} 10645 size(4); 10646 ins_encode %{ 10647 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10648 %} 10649 ins_pipe(pipe_class_default); 10650 %} 10651 10652 //---------- Chain stack slots between similar types -------- 10653 10654 // These are needed so that the rules below can match. 10655 10656 // Load integer from stack slot 10657 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10658 match(Set dst src); 10659 ins_cost(MEMORY_REF_COST); 10660 10661 format %{ "LWZ $dst, $src" %} 10662 size(4); 10663 ins_encode( enc_lwz(dst, src) ); 10664 ins_pipe(pipe_class_memory); 10665 %} 10666 10667 // Store integer to stack slot 10668 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10669 match(Set dst src); 10670 ins_cost(MEMORY_REF_COST); 10671 10672 format %{ "STW $src, $dst \t// stk" %} 10673 size(4); 10674 ins_encode( enc_stw(src, dst) ); // rs=rt 10675 ins_pipe(pipe_class_memory); 10676 %} 10677 10678 // Load long from stack slot 10679 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10680 match(Set dst src); 10681 ins_cost(MEMORY_REF_COST); 10682 10683 format %{ "LD $dst, $src \t// long" %} 10684 size(4); 10685 ins_encode( enc_ld(dst, src) ); 10686 ins_pipe(pipe_class_memory); 10687 %} 10688 10689 // Store long to stack slot 10690 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10691 match(Set dst src); 10692 ins_cost(MEMORY_REF_COST); 10693 10694 format %{ "STD $src, $dst \t// long" %} 10695 size(4); 10696 ins_encode( enc_std(src, dst) ); // rs=rt 10697 ins_pipe(pipe_class_memory); 10698 %} 10699 10700 //----------Moves between int and float 10701 10702 // Move float value from float stack-location to integer register. 10703 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10704 match(Set dst (MoveF2I src)); 10705 ins_cost(MEMORY_REF_COST); 10706 10707 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10708 size(4); 10709 ins_encode( enc_lwz(dst, src) ); 10710 ins_pipe(pipe_class_memory); 10711 %} 10712 10713 // Move float value from float register to integer stack-location. 10714 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10715 match(Set dst (MoveF2I src)); 10716 ins_cost(MEMORY_REF_COST); 10717 10718 format %{ "STFS $src, $dst \t// MoveF2I" %} 10719 size(4); 10720 ins_encode( enc_stfs(src, dst) ); 10721 ins_pipe(pipe_class_memory); 10722 %} 10723 10724 // Move integer value from integer stack-location to float register. 10725 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10726 match(Set dst (MoveI2F src)); 10727 ins_cost(MEMORY_REF_COST); 10728 10729 format %{ "LFS $dst, $src \t// MoveI2F" %} 10730 size(4); 10731 ins_encode %{ 10732 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10733 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10734 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10735 %} 10736 ins_pipe(pipe_class_memory); 10737 %} 10738 10739 // Move integer value from integer register to float stack-location. 10740 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10741 match(Set dst (MoveI2F src)); 10742 ins_cost(MEMORY_REF_COST); 10743 10744 format %{ "STW $src, $dst \t// MoveI2F" %} 10745 size(4); 10746 ins_encode( enc_stw(src, dst) ); 10747 ins_pipe(pipe_class_memory); 10748 %} 10749 10750 //----------Moves between long and float 10751 10752 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10753 // no match-rule, false predicate 10754 effect(DEF dst, USE src); 10755 predicate(false); 10756 10757 format %{ "storeD $src, $dst \t// STACK" %} 10758 size(4); 10759 ins_encode( enc_stfd(src, dst) ); 10760 ins_pipe(pipe_class_default); 10761 %} 10762 10763 //----------Moves between long and double 10764 10765 // Move double value from double stack-location to long register. 10766 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10767 match(Set dst (MoveD2L src)); 10768 ins_cost(MEMORY_REF_COST); 10769 size(4); 10770 format %{ "LD $dst, $src \t// MoveD2L" %} 10771 ins_encode( enc_ld(dst, src) ); 10772 ins_pipe(pipe_class_memory); 10773 %} 10774 10775 // Move double value from double register to long stack-location. 10776 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10777 match(Set dst (MoveD2L src)); 10778 effect(DEF dst, USE src); 10779 ins_cost(MEMORY_REF_COST); 10780 10781 format %{ "STFD $src, $dst \t// MoveD2L" %} 10782 size(4); 10783 ins_encode( enc_stfd(src, dst) ); 10784 ins_pipe(pipe_class_memory); 10785 %} 10786 10787 // Move long value from long stack-location to double register. 10788 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10789 match(Set dst (MoveL2D src)); 10790 ins_cost(MEMORY_REF_COST); 10791 10792 format %{ "LFD $dst, $src \t// MoveL2D" %} 10793 size(4); 10794 ins_encode( enc_lfd(dst, src) ); 10795 ins_pipe(pipe_class_memory); 10796 %} 10797 10798 // Move long value from long register to double stack-location. 10799 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10800 match(Set dst (MoveL2D src)); 10801 ins_cost(MEMORY_REF_COST); 10802 10803 format %{ "STD $src, $dst \t// MoveL2D" %} 10804 size(4); 10805 ins_encode( enc_std(src, dst) ); 10806 ins_pipe(pipe_class_memory); 10807 %} 10808 10809 //----------Register Move Instructions----------------------------------------- 10810 10811 // Replicate for Superword 10812 10813 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10814 predicate(false); 10815 effect(DEF dst, USE src); 10816 10817 format %{ "MR $dst, $src \t// replicate " %} 10818 // variable size, 0 or 4. 10819 ins_encode %{ 10820 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10821 __ mr_if_needed($dst$$Register, $src$$Register); 10822 %} 10823 ins_pipe(pipe_class_default); 10824 %} 10825 10826 //----------Cast instructions (Java-level type cast)--------------------------- 10827 10828 // Cast Long to Pointer for unsafe natives. 10829 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10830 match(Set dst (CastX2P src)); 10831 10832 format %{ "MR $dst, $src \t// Long->Ptr" %} 10833 // variable size, 0 or 4. 10834 ins_encode %{ 10835 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10836 __ mr_if_needed($dst$$Register, $src$$Register); 10837 %} 10838 ins_pipe(pipe_class_default); 10839 %} 10840 10841 // Cast Pointer to Long for unsafe natives. 10842 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10843 match(Set dst (CastP2X src)); 10844 10845 format %{ "MR $dst, $src \t// Ptr->Long" %} 10846 // variable size, 0 or 4. 10847 ins_encode %{ 10848 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10849 __ mr_if_needed($dst$$Register, $src$$Register); 10850 %} 10851 ins_pipe(pipe_class_default); 10852 %} 10853 10854 instruct castPP(iRegPdst dst) %{ 10855 match(Set dst (CastPP dst)); 10856 format %{ " -- \t// castPP of $dst" %} 10857 size(0); 10858 ins_encode( /*empty*/ ); 10859 ins_pipe(pipe_class_default); 10860 %} 10861 10862 instruct castII(iRegIdst dst) %{ 10863 match(Set dst (CastII dst)); 10864 format %{ " -- \t// castII of $dst" %} 10865 size(0); 10866 ins_encode( /*empty*/ ); 10867 ins_pipe(pipe_class_default); 10868 %} 10869 10870 instruct checkCastPP(iRegPdst dst) %{ 10871 match(Set dst (CheckCastPP dst)); 10872 format %{ " -- \t// checkcastPP of $dst" %} 10873 size(0); 10874 ins_encode( /*empty*/ ); 10875 ins_pipe(pipe_class_default); 10876 %} 10877 10878 //----------Convert instructions----------------------------------------------- 10879 10880 // Convert to boolean. 10881 10882 // int_to_bool(src) : { 1 if src != 0 10883 // { 0 else 10884 // 10885 // strategy: 10886 // 1) Count leading zeros of 32 bit-value src, 10887 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10888 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10889 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10890 10891 // convI2Bool 10892 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10893 match(Set dst (Conv2B src)); 10894 predicate(UseCountLeadingZerosInstructionsPPC64); 10895 ins_cost(DEFAULT_COST); 10896 10897 expand %{ 10898 immI shiftAmount %{ 0x5 %} 10899 uimmI16 mask %{ 0x1 %} 10900 iRegIdst tmp1; 10901 iRegIdst tmp2; 10902 countLeadingZerosI(tmp1, src); 10903 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10904 xorI_reg_uimm16(dst, tmp2, mask); 10905 %} 10906 %} 10907 10908 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10909 match(Set dst (Conv2B src)); 10910 effect(TEMP crx); 10911 predicate(!UseCountLeadingZerosInstructionsPPC64); 10912 ins_cost(DEFAULT_COST); 10913 10914 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10915 "LI $dst, #0\n\t" 10916 "BEQ $crx, done\n\t" 10917 "LI $dst, #1\n" 10918 "done:" %} 10919 size(16); 10920 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10921 ins_pipe(pipe_class_compare); 10922 %} 10923 10924 // ConvI2B + XorI 10925 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10926 match(Set dst (XorI (Conv2B src) mask)); 10927 predicate(UseCountLeadingZerosInstructionsPPC64); 10928 ins_cost(DEFAULT_COST); 10929 10930 expand %{ 10931 immI shiftAmount %{ 0x5 %} 10932 iRegIdst tmp1; 10933 countLeadingZerosI(tmp1, src); 10934 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10935 %} 10936 %} 10937 10938 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10939 match(Set dst (XorI (Conv2B src) mask)); 10940 effect(TEMP crx); 10941 predicate(!UseCountLeadingZerosInstructionsPPC64); 10942 ins_cost(DEFAULT_COST); 10943 10944 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10945 "LI $dst, #1\n\t" 10946 "BEQ $crx, done\n\t" 10947 "LI $dst, #0\n" 10948 "done:" %} 10949 size(16); 10950 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10951 ins_pipe(pipe_class_compare); 10952 %} 10953 10954 // AndI 0b0..010..0 + ConvI2B 10955 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10956 match(Set dst (Conv2B (AndI src mask))); 10957 predicate(UseRotateAndMaskInstructionsPPC64); 10958 ins_cost(DEFAULT_COST); 10959 10960 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10961 size(4); 10962 ins_encode %{ 10963 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10964 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10965 %} 10966 ins_pipe(pipe_class_default); 10967 %} 10968 10969 // Convert pointer to boolean. 10970 // 10971 // ptr_to_bool(src) : { 1 if src != 0 10972 // { 0 else 10973 // 10974 // strategy: 10975 // 1) Count leading zeros of 64 bit-value src, 10976 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10977 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10978 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10979 10980 // ConvP2B 10981 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10982 match(Set dst (Conv2B src)); 10983 predicate(UseCountLeadingZerosInstructionsPPC64); 10984 ins_cost(DEFAULT_COST); 10985 10986 expand %{ 10987 immI shiftAmount %{ 0x6 %} 10988 uimmI16 mask %{ 0x1 %} 10989 iRegIdst tmp1; 10990 iRegIdst tmp2; 10991 countLeadingZerosP(tmp1, src); 10992 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10993 xorI_reg_uimm16(dst, tmp2, mask); 10994 %} 10995 %} 10996 10997 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10998 match(Set dst (Conv2B src)); 10999 effect(TEMP crx); 11000 predicate(!UseCountLeadingZerosInstructionsPPC64); 11001 ins_cost(DEFAULT_COST); 11002 11003 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 11004 "LI $dst, #0\n\t" 11005 "BEQ $crx, done\n\t" 11006 "LI $dst, #1\n" 11007 "done:" %} 11008 size(16); 11009 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 11010 ins_pipe(pipe_class_compare); 11011 %} 11012 11013 // ConvP2B + XorI 11014 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 11015 match(Set dst (XorI (Conv2B src) mask)); 11016 predicate(UseCountLeadingZerosInstructionsPPC64); 11017 ins_cost(DEFAULT_COST); 11018 11019 expand %{ 11020 immI shiftAmount %{ 0x6 %} 11021 iRegIdst tmp1; 11022 countLeadingZerosP(tmp1, src); 11023 urShiftI_reg_imm(dst, tmp1, shiftAmount); 11024 %} 11025 %} 11026 11027 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 11028 match(Set dst (XorI (Conv2B src) mask)); 11029 effect(TEMP crx); 11030 predicate(!UseCountLeadingZerosInstructionsPPC64); 11031 ins_cost(DEFAULT_COST); 11032 11033 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 11034 "LI $dst, #1\n\t" 11035 "BEQ $crx, done\n\t" 11036 "LI $dst, #0\n" 11037 "done:" %} 11038 size(16); 11039 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 11040 ins_pipe(pipe_class_compare); 11041 %} 11042 11043 // if src1 < src2, return -1 else return 0 11044 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 11045 match(Set dst (CmpLTMask src1 src2)); 11046 ins_cost(DEFAULT_COST*4); 11047 11048 expand %{ 11049 iRegLdst src1s; 11050 iRegLdst src2s; 11051 iRegLdst diff; 11052 convI2L_reg(src1s, src1); // Ensure proper sign extension. 11053 convI2L_reg(src2s, src2); // Ensure proper sign extension. 11054 subL_reg_reg(diff, src1s, src2s); 11055 // Need to consider >=33 bit result, therefore we need signmaskL. 11056 signmask64I_regL(dst, diff); 11057 %} 11058 %} 11059 11060 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 11061 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 11062 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 11063 size(4); 11064 ins_encode %{ 11065 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 11066 __ srawi($dst$$Register, $src1$$Register, 0x1f); 11067 %} 11068 ins_pipe(pipe_class_default); 11069 %} 11070 11071 //----------Arithmetic Conversion Instructions--------------------------------- 11072 11073 // Convert to Byte -- nop 11074 // Convert to Short -- nop 11075 11076 // Convert to Int 11077 11078 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 11079 match(Set dst (RShiftI (LShiftI src amount) amount)); 11080 format %{ "EXTSB $dst, $src \t// byte->int" %} 11081 size(4); 11082 ins_encode %{ 11083 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 11084 __ extsb($dst$$Register, $src$$Register); 11085 %} 11086 ins_pipe(pipe_class_default); 11087 %} 11088 11089 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 11090 effect(DEF dst, USE src); 11091 11092 size(4); 11093 ins_encode %{ 11094 __ extsh($dst$$Register, $src$$Register); 11095 %} 11096 ins_pipe(pipe_class_default); 11097 %} 11098 11099 // LShiftI 16 + RShiftI 16 converts short to int. 11100 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 11101 match(Set dst (RShiftI (LShiftI src amount) amount)); 11102 format %{ "EXTSH $dst, $src \t// short->int" %} 11103 size(4); 11104 ins_encode %{ 11105 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 11106 __ extsh($dst$$Register, $src$$Register); 11107 %} 11108 ins_pipe(pipe_class_default); 11109 %} 11110 11111 // ConvL2I + ConvI2L: Sign extend int in long register. 11112 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11113 match(Set dst (ConvI2L (ConvL2I src))); 11114 11115 format %{ "EXTSW $dst, $src \t// long->long" %} 11116 size(4); 11117 ins_encode %{ 11118 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11119 __ extsw($dst$$Register, $src$$Register); 11120 %} 11121 ins_pipe(pipe_class_default); 11122 %} 11123 11124 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11125 match(Set dst (ConvL2I src)); 11126 format %{ "MR $dst, $src \t// long->int" %} 11127 // variable size, 0 or 4 11128 ins_encode %{ 11129 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11130 __ mr_if_needed($dst$$Register, $src$$Register); 11131 %} 11132 ins_pipe(pipe_class_default); 11133 %} 11134 11135 instruct convD2IRaw_regD(regD dst, regD src) %{ 11136 // no match-rule, false predicate 11137 effect(DEF dst, USE src); 11138 predicate(false); 11139 11140 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11141 size(4); 11142 ins_encode %{ 11143 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11144 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11145 %} 11146 ins_pipe(pipe_class_default); 11147 %} 11148 11149 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 11150 // no match-rule, false predicate 11151 effect(DEF dst, USE crx, USE src); 11152 predicate(false); 11153 11154 ins_variable_size_depending_on_alignment(true); 11155 11156 format %{ "cmovI $crx, $dst, $src" %} 11157 // Worst case is branch + move + stop, no stop without scheduler. 11158 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11159 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11160 ins_pipe(pipe_class_default); 11161 %} 11162 11163 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11164 // no match-rule, false predicate 11165 effect(DEF dst, USE crx, USE src); 11166 predicate(false); 11167 11168 ins_variable_size_depending_on_alignment(true); 11169 11170 format %{ "cmovI $crx, $dst, $src" %} 11171 // Worst case is branch + move + stop, no stop without scheduler. 11172 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11173 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11174 ins_pipe(pipe_class_default); 11175 %} 11176 11177 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11178 // no match-rule, false predicate 11179 effect(DEF dst, USE crx, USE mem); 11180 predicate(false); 11181 11182 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11183 postalloc_expand %{ 11184 // 11185 // replaces 11186 // 11187 // region dst crx mem 11188 // \ | | / 11189 // dst=cmovI_bso_stackSlotL_conLvalue0 11190 // 11191 // with 11192 // 11193 // region dst 11194 // \ / 11195 // dst=loadConI16(0) 11196 // | 11197 // ^ region dst crx mem 11198 // | \ | | / 11199 // dst=cmovI_bso_stackSlotL 11200 // 11201 11202 // Create new nodes. 11203 MachNode *m1 = new loadConI16Node(); 11204 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11205 11206 // inputs for new nodes 11207 m1->add_req(n_region); 11208 m2->add_req(n_region, n_crx, n_mem); 11209 11210 // precedences for new nodes 11211 m2->add_prec(m1); 11212 11213 // operands for new nodes 11214 m1->_opnds[0] = op_dst; 11215 m1->_opnds[1] = new immI16Oper(0); 11216 11217 m2->_opnds[0] = op_dst; 11218 m2->_opnds[1] = op_crx; 11219 m2->_opnds[2] = op_mem; 11220 11221 // registers for new nodes 11222 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11223 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11224 11225 // Insert new nodes. 11226 nodes->push(m1); 11227 nodes->push(m2); 11228 %} 11229 %} 11230 11231 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11232 // no match-rule, false predicate 11233 effect(DEF dst, USE crx, USE src); 11234 predicate(false); 11235 11236 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11237 postalloc_expand %{ 11238 // 11239 // replaces 11240 // 11241 // region dst crx src 11242 // \ | | / 11243 // dst=cmovI_bso_reg_conLvalue0 11244 // 11245 // with 11246 // 11247 // region dst 11248 // \ / 11249 // dst=loadConI16(0) 11250 // | 11251 // ^ region dst crx src 11252 // | \ | | / 11253 // dst=cmovI_bso_reg 11254 // 11255 11256 // Create new nodes. 11257 MachNode *m1 = new loadConI16Node(); 11258 MachNode *m2 = new cmovI_bso_regNode(); 11259 11260 // inputs for new nodes 11261 m1->add_req(n_region); 11262 m2->add_req(n_region, n_crx, n_src); 11263 11264 // precedences for new nodes 11265 m2->add_prec(m1); 11266 11267 // operands for new nodes 11268 m1->_opnds[0] = op_dst; 11269 m1->_opnds[1] = new immI16Oper(0); 11270 11271 m2->_opnds[0] = op_dst; 11272 m2->_opnds[1] = op_crx; 11273 m2->_opnds[2] = op_src; 11274 11275 // registers for new nodes 11276 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11277 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11278 11279 // Insert new nodes. 11280 nodes->push(m1); 11281 nodes->push(m2); 11282 %} 11283 %} 11284 11285 // Double to Int conversion, NaN is mapped to 0. 11286 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11287 match(Set dst (ConvD2I src)); 11288 predicate(!VM_Version::has_mtfprd()); 11289 ins_cost(DEFAULT_COST); 11290 11291 expand %{ 11292 regD tmpD; 11293 stackSlotL tmpS; 11294 flagsReg crx; 11295 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11296 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11297 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11298 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11299 %} 11300 %} 11301 11302 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11303 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11304 match(Set dst (ConvD2I src)); 11305 predicate(VM_Version::has_mtfprd()); 11306 ins_cost(DEFAULT_COST); 11307 11308 expand %{ 11309 regD tmpD; 11310 flagsReg crx; 11311 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11312 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11313 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11314 %} 11315 %} 11316 11317 instruct convF2IRaw_regF(regF dst, regF src) %{ 11318 // no match-rule, false predicate 11319 effect(DEF dst, USE src); 11320 predicate(false); 11321 11322 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11323 size(4); 11324 ins_encode %{ 11325 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11326 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11327 %} 11328 ins_pipe(pipe_class_default); 11329 %} 11330 11331 // Float to Int conversion, NaN is mapped to 0. 11332 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11333 match(Set dst (ConvF2I src)); 11334 predicate(!VM_Version::has_mtfprd()); 11335 ins_cost(DEFAULT_COST); 11336 11337 expand %{ 11338 regF tmpF; 11339 stackSlotL tmpS; 11340 flagsReg crx; 11341 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11342 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11343 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11344 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11345 %} 11346 %} 11347 11348 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11349 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11350 match(Set dst (ConvF2I src)); 11351 predicate(VM_Version::has_mtfprd()); 11352 ins_cost(DEFAULT_COST); 11353 11354 expand %{ 11355 regF tmpF; 11356 flagsReg crx; 11357 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11358 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11359 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11360 %} 11361 %} 11362 11363 // Convert to Long 11364 11365 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11366 match(Set dst (ConvI2L src)); 11367 format %{ "EXTSW $dst, $src \t// int->long" %} 11368 size(4); 11369 ins_encode %{ 11370 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11371 __ extsw($dst$$Register, $src$$Register); 11372 %} 11373 ins_pipe(pipe_class_default); 11374 %} 11375 11376 // Zero-extend: convert unsigned int to long (convUI2L). 11377 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11378 match(Set dst (AndL (ConvI2L src) mask)); 11379 ins_cost(DEFAULT_COST); 11380 11381 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11382 size(4); 11383 ins_encode %{ 11384 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11385 __ clrldi($dst$$Register, $src$$Register, 32); 11386 %} 11387 ins_pipe(pipe_class_default); 11388 %} 11389 11390 // Zero-extend: convert unsigned int to long in long register. 11391 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11392 match(Set dst (AndL src mask)); 11393 ins_cost(DEFAULT_COST); 11394 11395 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11396 size(4); 11397 ins_encode %{ 11398 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11399 __ clrldi($dst$$Register, $src$$Register, 32); 11400 %} 11401 ins_pipe(pipe_class_default); 11402 %} 11403 11404 instruct convF2LRaw_regF(regF dst, regF src) %{ 11405 // no match-rule, false predicate 11406 effect(DEF dst, USE src); 11407 predicate(false); 11408 11409 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11410 size(4); 11411 ins_encode %{ 11412 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11413 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11414 %} 11415 ins_pipe(pipe_class_default); 11416 %} 11417 11418 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 11419 // no match-rule, false predicate 11420 effect(DEF dst, USE crx, USE src); 11421 predicate(false); 11422 11423 ins_variable_size_depending_on_alignment(true); 11424 11425 format %{ "cmovL $crx, $dst, $src" %} 11426 // Worst case is branch + move + stop, no stop without scheduler. 11427 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11428 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11429 ins_pipe(pipe_class_default); 11430 %} 11431 11432 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11433 // no match-rule, false predicate 11434 effect(DEF dst, USE crx, USE src); 11435 predicate(false); 11436 11437 ins_variable_size_depending_on_alignment(true); 11438 11439 format %{ "cmovL $crx, $dst, $src" %} 11440 // Worst case is branch + move + stop, no stop without scheduler. 11441 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11442 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11443 ins_pipe(pipe_class_default); 11444 %} 11445 11446 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11447 // no match-rule, false predicate 11448 effect(DEF dst, USE crx, USE mem); 11449 predicate(false); 11450 11451 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11452 postalloc_expand %{ 11453 // 11454 // replaces 11455 // 11456 // region dst crx mem 11457 // \ | | / 11458 // dst=cmovL_bso_stackSlotL_conLvalue0 11459 // 11460 // with 11461 // 11462 // region dst 11463 // \ / 11464 // dst=loadConL16(0) 11465 // | 11466 // ^ region dst crx mem 11467 // | \ | | / 11468 // dst=cmovL_bso_stackSlotL 11469 // 11470 11471 // Create new nodes. 11472 MachNode *m1 = new loadConL16Node(); 11473 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11474 11475 // inputs for new nodes 11476 m1->add_req(n_region); 11477 m2->add_req(n_region, n_crx, n_mem); 11478 m2->add_prec(m1); 11479 11480 // operands for new nodes 11481 m1->_opnds[0] = op_dst; 11482 m1->_opnds[1] = new immL16Oper(0); 11483 m2->_opnds[0] = op_dst; 11484 m2->_opnds[1] = op_crx; 11485 m2->_opnds[2] = op_mem; 11486 11487 // registers for new nodes 11488 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11489 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11490 11491 // Insert new nodes. 11492 nodes->push(m1); 11493 nodes->push(m2); 11494 %} 11495 %} 11496 11497 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11498 // no match-rule, false predicate 11499 effect(DEF dst, USE crx, USE src); 11500 predicate(false); 11501 11502 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11503 postalloc_expand %{ 11504 // 11505 // replaces 11506 // 11507 // region dst crx src 11508 // \ | | / 11509 // dst=cmovL_bso_reg_conLvalue0 11510 // 11511 // with 11512 // 11513 // region dst 11514 // \ / 11515 // dst=loadConL16(0) 11516 // | 11517 // ^ region dst crx src 11518 // | \ | | / 11519 // dst=cmovL_bso_reg 11520 // 11521 11522 // Create new nodes. 11523 MachNode *m1 = new loadConL16Node(); 11524 MachNode *m2 = new cmovL_bso_regNode(); 11525 11526 // inputs for new nodes 11527 m1->add_req(n_region); 11528 m2->add_req(n_region, n_crx, n_src); 11529 m2->add_prec(m1); 11530 11531 // operands for new nodes 11532 m1->_opnds[0] = op_dst; 11533 m1->_opnds[1] = new immL16Oper(0); 11534 m2->_opnds[0] = op_dst; 11535 m2->_opnds[1] = op_crx; 11536 m2->_opnds[2] = op_src; 11537 11538 // registers for new nodes 11539 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11540 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11541 11542 // Insert new nodes. 11543 nodes->push(m1); 11544 nodes->push(m2); 11545 %} 11546 %} 11547 11548 // Float to Long conversion, NaN is mapped to 0. 11549 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11550 match(Set dst (ConvF2L src)); 11551 predicate(!VM_Version::has_mtfprd()); 11552 ins_cost(DEFAULT_COST); 11553 11554 expand %{ 11555 regF tmpF; 11556 stackSlotL tmpS; 11557 flagsReg crx; 11558 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11559 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11560 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11561 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11562 %} 11563 %} 11564 11565 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11566 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11567 match(Set dst (ConvF2L src)); 11568 predicate(VM_Version::has_mtfprd()); 11569 ins_cost(DEFAULT_COST); 11570 11571 expand %{ 11572 regF tmpF; 11573 flagsReg crx; 11574 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11575 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11576 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11577 %} 11578 %} 11579 11580 instruct convD2LRaw_regD(regD dst, regD src) %{ 11581 // no match-rule, false predicate 11582 effect(DEF dst, USE src); 11583 predicate(false); 11584 11585 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11586 size(4); 11587 ins_encode %{ 11588 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11589 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11590 %} 11591 ins_pipe(pipe_class_default); 11592 %} 11593 11594 // Double to Long conversion, NaN is mapped to 0. 11595 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11596 match(Set dst (ConvD2L src)); 11597 predicate(!VM_Version::has_mtfprd()); 11598 ins_cost(DEFAULT_COST); 11599 11600 expand %{ 11601 regD tmpD; 11602 stackSlotL tmpS; 11603 flagsReg crx; 11604 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11605 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11606 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11607 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11608 %} 11609 %} 11610 11611 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11612 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11613 match(Set dst (ConvD2L src)); 11614 predicate(VM_Version::has_mtfprd()); 11615 ins_cost(DEFAULT_COST); 11616 11617 expand %{ 11618 regD tmpD; 11619 flagsReg crx; 11620 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11621 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11622 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11623 %} 11624 %} 11625 11626 // Convert to Float 11627 11628 // Placed here as needed in expand. 11629 instruct convL2DRaw_regD(regD dst, regD src) %{ 11630 // no match-rule, false predicate 11631 effect(DEF dst, USE src); 11632 predicate(false); 11633 11634 format %{ "FCFID $dst, $src \t// convL2D" %} 11635 size(4); 11636 ins_encode %{ 11637 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11638 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11639 %} 11640 ins_pipe(pipe_class_default); 11641 %} 11642 11643 // Placed here as needed in expand. 11644 instruct convD2F_reg(regF dst, regD src) %{ 11645 match(Set dst (ConvD2F src)); 11646 format %{ "FRSP $dst, $src \t// convD2F" %} 11647 size(4); 11648 ins_encode %{ 11649 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11650 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11651 %} 11652 ins_pipe(pipe_class_default); 11653 %} 11654 11655 // Integer to Float conversion. 11656 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11657 match(Set dst (ConvI2F src)); 11658 predicate(!VM_Version::has_fcfids()); 11659 ins_cost(DEFAULT_COST); 11660 11661 expand %{ 11662 iRegLdst tmpL; 11663 stackSlotL tmpS; 11664 regD tmpD; 11665 regD tmpD2; 11666 convI2L_reg(tmpL, src); // Sign-extension int to long. 11667 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11668 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11669 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11670 convD2F_reg(dst, tmpD2); // Convert double to float. 11671 %} 11672 %} 11673 11674 instruct convL2FRaw_regF(regF dst, regD src) %{ 11675 // no match-rule, false predicate 11676 effect(DEF dst, USE src); 11677 predicate(false); 11678 11679 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11680 size(4); 11681 ins_encode %{ 11682 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11683 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11684 %} 11685 ins_pipe(pipe_class_default); 11686 %} 11687 11688 // Integer to Float conversion. Special version for Power7. 11689 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11690 match(Set dst (ConvI2F src)); 11691 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11692 ins_cost(DEFAULT_COST); 11693 11694 expand %{ 11695 iRegLdst tmpL; 11696 stackSlotL tmpS; 11697 regD tmpD; 11698 convI2L_reg(tmpL, src); // Sign-extension int to long. 11699 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11700 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11701 convL2FRaw_regF(dst, tmpD); // Convert to float. 11702 %} 11703 %} 11704 11705 // Integer to Float conversion. Special version for Power8. 11706 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11707 match(Set dst (ConvI2F src)); 11708 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11709 ins_cost(DEFAULT_COST); 11710 11711 expand %{ 11712 regD tmpD; 11713 moveI2D_reg(tmpD, src); 11714 convL2FRaw_regF(dst, tmpD); // Convert to float. 11715 %} 11716 %} 11717 11718 // L2F to avoid runtime call. 11719 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11720 match(Set dst (ConvL2F src)); 11721 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11722 ins_cost(DEFAULT_COST); 11723 11724 expand %{ 11725 stackSlotL tmpS; 11726 regD tmpD; 11727 regL_to_stkL(tmpS, src); // Store long to stack. 11728 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11729 convL2FRaw_regF(dst, tmpD); // Convert to float. 11730 %} 11731 %} 11732 11733 // L2F to avoid runtime call. Special version for Power8. 11734 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11735 match(Set dst (ConvL2F src)); 11736 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11737 ins_cost(DEFAULT_COST); 11738 11739 expand %{ 11740 regD tmpD; 11741 moveL2D_reg(tmpD, src); 11742 convL2FRaw_regF(dst, tmpD); // Convert to float. 11743 %} 11744 %} 11745 11746 // Moved up as used in expand. 11747 //instruct convD2F_reg(regF dst, regD src) %{%} 11748 11749 // Convert to Double 11750 11751 // Integer to Double conversion. 11752 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11753 match(Set dst (ConvI2D src)); 11754 predicate(!VM_Version::has_mtfprd()); 11755 ins_cost(DEFAULT_COST); 11756 11757 expand %{ 11758 iRegLdst tmpL; 11759 stackSlotL tmpS; 11760 regD tmpD; 11761 convI2L_reg(tmpL, src); // Sign-extension int to long. 11762 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11763 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11764 convL2DRaw_regD(dst, tmpD); // Convert to double. 11765 %} 11766 %} 11767 11768 // Integer to Double conversion. Special version for Power8. 11769 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11770 match(Set dst (ConvI2D src)); 11771 predicate(VM_Version::has_mtfprd()); 11772 ins_cost(DEFAULT_COST); 11773 11774 expand %{ 11775 regD tmpD; 11776 moveI2D_reg(tmpD, src); 11777 convL2DRaw_regD(dst, tmpD); // Convert to double. 11778 %} 11779 %} 11780 11781 // Long to Double conversion 11782 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11783 match(Set dst (ConvL2D src)); 11784 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11785 11786 expand %{ 11787 regD tmpD; 11788 moveL2D_stack_reg(tmpD, src); 11789 convL2DRaw_regD(dst, tmpD); 11790 %} 11791 %} 11792 11793 // Long to Double conversion. Special version for Power8. 11794 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11795 match(Set dst (ConvL2D src)); 11796 predicate(VM_Version::has_mtfprd()); 11797 ins_cost(DEFAULT_COST); 11798 11799 expand %{ 11800 regD tmpD; 11801 moveL2D_reg(tmpD, src); 11802 convL2DRaw_regD(dst, tmpD); // Convert to double. 11803 %} 11804 %} 11805 11806 instruct convF2D_reg(regD dst, regF src) %{ 11807 match(Set dst (ConvF2D src)); 11808 format %{ "FMR $dst, $src \t// float->double" %} 11809 // variable size, 0 or 4 11810 ins_encode %{ 11811 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11812 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11813 %} 11814 ins_pipe(pipe_class_default); 11815 %} 11816 11817 //----------Control Flow Instructions------------------------------------------ 11818 // Compare Instructions 11819 11820 // Compare Integers 11821 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11822 match(Set crx (CmpI src1 src2)); 11823 size(4); 11824 format %{ "CMPW $crx, $src1, $src2" %} 11825 ins_encode %{ 11826 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11827 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11828 %} 11829 ins_pipe(pipe_class_compare); 11830 %} 11831 11832 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11833 match(Set crx (CmpI src1 src2)); 11834 format %{ "CMPWI $crx, $src1, $src2" %} 11835 size(4); 11836 ins_encode %{ 11837 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11838 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11839 %} 11840 ins_pipe(pipe_class_compare); 11841 %} 11842 11843 // (src1 & src2) == 0? 11844 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11845 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11846 // r0 is killed 11847 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11848 size(4); 11849 ins_encode %{ 11850 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11851 __ andi_(R0, $src1$$Register, $src2$$constant); 11852 %} 11853 ins_pipe(pipe_class_compare); 11854 %} 11855 11856 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11857 match(Set crx (CmpL src1 src2)); 11858 format %{ "CMPD $crx, $src1, $src2" %} 11859 size(4); 11860 ins_encode %{ 11861 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11862 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11863 %} 11864 ins_pipe(pipe_class_compare); 11865 %} 11866 11867 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11868 match(Set crx (CmpL src1 src2)); 11869 format %{ "CMPDI $crx, $src1, $src2" %} 11870 size(4); 11871 ins_encode %{ 11872 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11873 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11874 %} 11875 ins_pipe(pipe_class_compare); 11876 %} 11877 11878 // Added CmpUL for LoopPredicate. 11879 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11880 match(Set crx (CmpUL src1 src2)); 11881 format %{ "CMPLD $crx, $src1, $src2" %} 11882 size(4); 11883 ins_encode %{ 11884 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11885 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11886 %} 11887 ins_pipe(pipe_class_compare); 11888 %} 11889 11890 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11891 match(Set crx (CmpUL src1 src2)); 11892 format %{ "CMPLDI $crx, $src1, $src2" %} 11893 size(4); 11894 ins_encode %{ 11895 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11896 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11897 %} 11898 ins_pipe(pipe_class_compare); 11899 %} 11900 11901 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11902 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11903 // r0 is killed 11904 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11905 size(4); 11906 ins_encode %{ 11907 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11908 __ and_(R0, $src1$$Register, $src2$$Register); 11909 %} 11910 ins_pipe(pipe_class_compare); 11911 %} 11912 11913 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11914 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11915 // r0 is killed 11916 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11917 size(4); 11918 ins_encode %{ 11919 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11920 __ andi_(R0, $src1$$Register, $src2$$constant); 11921 %} 11922 ins_pipe(pipe_class_compare); 11923 %} 11924 11925 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11926 // no match-rule, false predicate 11927 effect(DEF dst, USE crx); 11928 predicate(false); 11929 11930 ins_variable_size_depending_on_alignment(true); 11931 11932 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11933 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11934 size((false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16)); 11935 ins_encode %{ 11936 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11937 Label done; 11938 // li(Rdst, 0); // equal -> 0 11939 __ beq($crx$$CondRegister, done); 11940 __ li($dst$$Register, 1); // greater -> +1 11941 __ bgt($crx$$CondRegister, done); 11942 __ li($dst$$Register, -1); // unordered or less -> -1 11943 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11944 __ bind(done); 11945 %} 11946 ins_pipe(pipe_class_compare); 11947 %} 11948 11949 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11950 // no match-rule, false predicate 11951 effect(DEF dst, USE crx); 11952 predicate(false); 11953 11954 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11955 postalloc_expand %{ 11956 // 11957 // replaces 11958 // 11959 // region crx 11960 // \ | 11961 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11962 // 11963 // with 11964 // 11965 // region 11966 // \ 11967 // dst=loadConI16(0) 11968 // | 11969 // ^ region crx 11970 // | \ | 11971 // dst=cmovI_conIvalueMinus1_conIvalue1 11972 // 11973 11974 // Create new nodes. 11975 MachNode *m1 = new loadConI16Node(); 11976 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11977 11978 // inputs for new nodes 11979 m1->add_req(n_region); 11980 m2->add_req(n_region, n_crx); 11981 m2->add_prec(m1); 11982 11983 // operands for new nodes 11984 m1->_opnds[0] = op_dst; 11985 m1->_opnds[1] = new immI16Oper(0); 11986 m2->_opnds[0] = op_dst; 11987 m2->_opnds[1] = op_crx; 11988 11989 // registers for new nodes 11990 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11991 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11992 11993 // Insert new nodes. 11994 nodes->push(m1); 11995 nodes->push(m2); 11996 %} 11997 %} 11998 11999 // Manifest a CmpL3 result in an integer register. Very painful. 12000 // This is the test to avoid. 12001 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 12002 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 12003 match(Set dst (CmpL3 src1 src2)); 12004 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12005 12006 expand %{ 12007 flagsReg tmp1; 12008 cmpL_reg_reg(tmp1, src1, src2); 12009 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12010 %} 12011 %} 12012 12013 // Implicit range checks. 12014 // A range check in the ideal world has one of the following shapes: 12015 // - (If le (CmpU length index)), (IfTrue throw exception) 12016 // - (If lt (CmpU index length)), (IfFalse throw exception) 12017 // 12018 // Match range check 'If le (CmpU length index)'. 12019 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 12020 match(If cmp (CmpU src_length index)); 12021 effect(USE labl); 12022 predicate(TrapBasedRangeChecks && 12023 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 12024 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 12025 (Matcher::branches_to_uncommon_trap(_leaf))); 12026 12027 ins_is_TrapBasedCheckNode(true); 12028 12029 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 12030 size(4); 12031 ins_encode %{ 12032 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12033 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 12034 __ trap_range_check_le($src_length$$Register, $index$$constant); 12035 } else { 12036 // Both successors are uncommon traps, probability is 0. 12037 // Node got flipped during fixup flow. 12038 assert($cmp$$cmpcode == 0x9, "must be greater"); 12039 __ trap_range_check_g($src_length$$Register, $index$$constant); 12040 } 12041 %} 12042 ins_pipe(pipe_class_trap); 12043 %} 12044 12045 // Match range check 'If lt (CmpU index length)'. 12046 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 12047 match(If cmp (CmpU src_index src_length)); 12048 effect(USE labl); 12049 predicate(TrapBasedRangeChecks && 12050 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12051 _leaf->as_If()->_prob >= PROB_ALWAYS && 12052 (Matcher::branches_to_uncommon_trap(_leaf))); 12053 12054 ins_is_TrapBasedCheckNode(true); 12055 12056 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 12057 size(4); 12058 ins_encode %{ 12059 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 12060 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12061 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 12062 } else { 12063 // Both successors are uncommon traps, probability is 0. 12064 // Node got flipped during fixup flow. 12065 assert($cmp$$cmpcode == 0x8, "must be less"); 12066 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 12067 } 12068 %} 12069 ins_pipe(pipe_class_trap); 12070 %} 12071 12072 // Match range check 'If lt (CmpU index length)'. 12073 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 12074 match(If cmp (CmpU src_index length)); 12075 effect(USE labl); 12076 predicate(TrapBasedRangeChecks && 12077 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12078 _leaf->as_If()->_prob >= PROB_ALWAYS && 12079 (Matcher::branches_to_uncommon_trap(_leaf))); 12080 12081 ins_is_TrapBasedCheckNode(true); 12082 12083 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 12084 size(4); 12085 ins_encode %{ 12086 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12087 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12088 __ trap_range_check_ge($src_index$$Register, $length$$constant); 12089 } else { 12090 // Both successors are uncommon traps, probability is 0. 12091 // Node got flipped during fixup flow. 12092 assert($cmp$$cmpcode == 0x8, "must be less"); 12093 __ trap_range_check_l($src_index$$Register, $length$$constant); 12094 } 12095 %} 12096 ins_pipe(pipe_class_trap); 12097 %} 12098 12099 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 12100 match(Set crx (CmpU src1 src2)); 12101 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 12102 size(4); 12103 ins_encode %{ 12104 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12105 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12106 %} 12107 ins_pipe(pipe_class_compare); 12108 %} 12109 12110 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 12111 match(Set crx (CmpU src1 src2)); 12112 size(4); 12113 format %{ "CMPLWI $crx, $src1, $src2" %} 12114 ins_encode %{ 12115 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12116 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12117 %} 12118 ins_pipe(pipe_class_compare); 12119 %} 12120 12121 // Implicit zero checks (more implicit null checks). 12122 // No constant pool entries required. 12123 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12124 match(If cmp (CmpN value zero)); 12125 effect(USE labl); 12126 predicate(TrapBasedNullChecks && 12127 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12128 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12129 Matcher::branches_to_uncommon_trap(_leaf)); 12130 ins_cost(1); 12131 12132 ins_is_TrapBasedCheckNode(true); 12133 12134 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12135 size(4); 12136 ins_encode %{ 12137 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12138 if ($cmp$$cmpcode == 0xA) { 12139 __ trap_null_check($value$$Register); 12140 } else { 12141 // Both successors are uncommon traps, probability is 0. 12142 // Node got flipped during fixup flow. 12143 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12144 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12145 } 12146 %} 12147 ins_pipe(pipe_class_trap); 12148 %} 12149 12150 // Compare narrow oops. 12151 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12152 match(Set crx (CmpN src1 src2)); 12153 12154 size(4); 12155 ins_cost(2); 12156 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12157 ins_encode %{ 12158 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12159 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12160 %} 12161 ins_pipe(pipe_class_compare); 12162 %} 12163 12164 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12165 match(Set crx (CmpN src1 src2)); 12166 // Make this more expensive than zeroCheckN_iReg_imm0. 12167 ins_cost(2); 12168 12169 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12170 size(4); 12171 ins_encode %{ 12172 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12173 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12174 %} 12175 ins_pipe(pipe_class_compare); 12176 %} 12177 12178 // Implicit zero checks (more implicit null checks). 12179 // No constant pool entries required. 12180 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12181 match(If cmp (CmpP value zero)); 12182 effect(USE labl); 12183 predicate(TrapBasedNullChecks && 12184 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12185 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12186 Matcher::branches_to_uncommon_trap(_leaf)); 12187 ins_cost(1); // Should not be cheaper than zeroCheckN. 12188 12189 ins_is_TrapBasedCheckNode(true); 12190 12191 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12192 size(4); 12193 ins_encode %{ 12194 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12195 if ($cmp$$cmpcode == 0xA) { 12196 __ trap_null_check($value$$Register); 12197 } else { 12198 // Both successors are uncommon traps, probability is 0. 12199 // Node got flipped during fixup flow. 12200 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12201 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12202 } 12203 %} 12204 ins_pipe(pipe_class_trap); 12205 %} 12206 12207 // Compare Pointers 12208 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12209 match(Set crx (CmpP src1 src2)); 12210 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12211 size(4); 12212 ins_encode %{ 12213 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12214 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12215 %} 12216 ins_pipe(pipe_class_compare); 12217 %} 12218 12219 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12220 match(Set crx (CmpP src1 src2)); 12221 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12222 size(4); 12223 ins_encode %{ 12224 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12225 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12226 %} 12227 ins_pipe(pipe_class_compare); 12228 %} 12229 12230 // Used in postalloc expand. 12231 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12232 // This match rule prevents reordering of node before a safepoint. 12233 // This only makes sense if this instructions is used exclusively 12234 // for the expansion of EncodeP! 12235 match(Set crx (CmpP src1 src2)); 12236 predicate(false); 12237 12238 format %{ "CMPDI $crx, $src1, $src2" %} 12239 size(4); 12240 ins_encode %{ 12241 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12242 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12243 %} 12244 ins_pipe(pipe_class_compare); 12245 %} 12246 12247 //----------Float Compares---------------------------------------------------- 12248 12249 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12250 // Needs matchrule, see cmpDUnordered. 12251 match(Set crx (CmpF src1 src2)); 12252 // no match-rule, false predicate 12253 predicate(false); 12254 12255 format %{ "cmpFUrd $crx, $src1, $src2" %} 12256 size(4); 12257 ins_encode %{ 12258 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12259 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12260 %} 12261 ins_pipe(pipe_class_default); 12262 %} 12263 12264 instruct cmov_bns_less(flagsReg crx) %{ 12265 // no match-rule, false predicate 12266 effect(DEF crx); 12267 predicate(false); 12268 12269 ins_variable_size_depending_on_alignment(true); 12270 12271 format %{ "cmov $crx" %} 12272 // Worst case is branch + move + stop, no stop without scheduler. 12273 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12)); 12274 ins_encode %{ 12275 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12276 Label done; 12277 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12278 __ li(R0, 0); 12279 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12280 // TODO PPC port __ endgroup_if_needed(_size == 16); 12281 __ bind(done); 12282 %} 12283 ins_pipe(pipe_class_default); 12284 %} 12285 12286 // Compare floating, generate condition code. 12287 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12288 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12289 // 12290 // The following code sequence occurs a lot in mpegaudio: 12291 // 12292 // block BXX: 12293 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12294 // cmpFUrd CCR6, F11, F9 12295 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12296 // cmov CCR6 12297 // 8: instruct branchConSched: 12298 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12299 match(Set crx (CmpF src1 src2)); 12300 ins_cost(DEFAULT_COST+BRANCH_COST); 12301 12302 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12303 postalloc_expand %{ 12304 // 12305 // replaces 12306 // 12307 // region src1 src2 12308 // \ | | 12309 // crx=cmpF_reg_reg 12310 // 12311 // with 12312 // 12313 // region src1 src2 12314 // \ | | 12315 // crx=cmpFUnordered_reg_reg 12316 // | 12317 // ^ region 12318 // | \ 12319 // crx=cmov_bns_less 12320 // 12321 12322 // Create new nodes. 12323 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12324 MachNode *m2 = new cmov_bns_lessNode(); 12325 12326 // inputs for new nodes 12327 m1->add_req(n_region, n_src1, n_src2); 12328 m2->add_req(n_region); 12329 m2->add_prec(m1); 12330 12331 // operands for new nodes 12332 m1->_opnds[0] = op_crx; 12333 m1->_opnds[1] = op_src1; 12334 m1->_opnds[2] = op_src2; 12335 m2->_opnds[0] = op_crx; 12336 12337 // registers for new nodes 12338 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12339 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12340 12341 // Insert new nodes. 12342 nodes->push(m1); 12343 nodes->push(m2); 12344 %} 12345 %} 12346 12347 // Compare float, generate -1,0,1 12348 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12349 match(Set dst (CmpF3 src1 src2)); 12350 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12351 12352 expand %{ 12353 flagsReg tmp1; 12354 cmpFUnordered_reg_reg(tmp1, src1, src2); 12355 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12356 %} 12357 %} 12358 12359 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12360 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12361 // node right before the conditional move using it. 12362 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12363 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12364 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12365 // conditional move was supposed to be spilled. 12366 match(Set crx (CmpD src1 src2)); 12367 // False predicate, shall not be matched. 12368 predicate(false); 12369 12370 format %{ "cmpFUrd $crx, $src1, $src2" %} 12371 size(4); 12372 ins_encode %{ 12373 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12374 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12375 %} 12376 ins_pipe(pipe_class_default); 12377 %} 12378 12379 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12380 match(Set crx (CmpD src1 src2)); 12381 ins_cost(DEFAULT_COST+BRANCH_COST); 12382 12383 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12384 postalloc_expand %{ 12385 // 12386 // replaces 12387 // 12388 // region src1 src2 12389 // \ | | 12390 // crx=cmpD_reg_reg 12391 // 12392 // with 12393 // 12394 // region src1 src2 12395 // \ | | 12396 // crx=cmpDUnordered_reg_reg 12397 // | 12398 // ^ region 12399 // | \ 12400 // crx=cmov_bns_less 12401 // 12402 12403 // create new nodes 12404 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12405 MachNode *m2 = new cmov_bns_lessNode(); 12406 12407 // inputs for new nodes 12408 m1->add_req(n_region, n_src1, n_src2); 12409 m2->add_req(n_region); 12410 m2->add_prec(m1); 12411 12412 // operands for new nodes 12413 m1->_opnds[0] = op_crx; 12414 m1->_opnds[1] = op_src1; 12415 m1->_opnds[2] = op_src2; 12416 m2->_opnds[0] = op_crx; 12417 12418 // registers for new nodes 12419 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12420 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12421 12422 // Insert new nodes. 12423 nodes->push(m1); 12424 nodes->push(m2); 12425 %} 12426 %} 12427 12428 // Compare double, generate -1,0,1 12429 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12430 match(Set dst (CmpD3 src1 src2)); 12431 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12432 12433 expand %{ 12434 flagsReg tmp1; 12435 cmpDUnordered_reg_reg(tmp1, src1, src2); 12436 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12437 %} 12438 %} 12439 12440 // Compare char 12441 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12442 match(Set dst (Digit src1)); 12443 effect(TEMP src2, TEMP crx); 12444 ins_cost(3 * DEFAULT_COST); 12445 12446 format %{ "LI $src2, 0x3930\n\t" 12447 "CMPRB $crx, 0, $src1, $src2\n\t" 12448 "SETB $dst, $crx" %} 12449 size(12); 12450 ins_encode %{ 12451 // 0x30: 0, 0x39: 9 12452 __ li($src2$$Register, 0x3930); 12453 // compare src1 with ranges 0x30 to 0x39 12454 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12455 __ setb($dst$$Register, $crx$$CondRegister); 12456 %} 12457 ins_pipe(pipe_class_default); 12458 %} 12459 12460 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12461 match(Set dst (LowerCase src1)); 12462 effect(TEMP src2, TEMP crx); 12463 ins_cost(12 * DEFAULT_COST); 12464 12465 format %{ "LI $src2, 0x7A61\n\t" 12466 "CMPRB $crx, 0, $src1, $src2\n\t" 12467 "BGT $crx, done\n\t" 12468 "LIS $src2, (signed short)0xF6DF\n\t" 12469 "ORI $src2, $src2, 0xFFF8\n\t" 12470 "CMPRB $crx, 1, $src1, $src2\n\t" 12471 "BGT $crx, done\n\t" 12472 "LIS $src2, (signed short)0xAAB5\n\t" 12473 "ORI $src2, $src2, 0xBABA\n\t" 12474 "INSRDI $src2, $src2, 32, 0\n\t" 12475 "CMPEQB $crx, 1, $src1, $src2\n" 12476 "done:\n\t" 12477 "SETB $dst, $crx" %} 12478 12479 size(48); 12480 ins_encode %{ 12481 Label done; 12482 // 0x61: a, 0x7A: z 12483 __ li($src2$$Register, 0x7A61); 12484 // compare src1 with ranges 0x61 to 0x7A 12485 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12486 __ bgt($crx$$CondRegister, done); 12487 12488 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case 12489 __ lis($src2$$Register, (signed short)0xF6DF); 12490 __ ori($src2$$Register, $src2$$Register, 0xFFF8); 12491 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF 12492 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12493 __ bgt($crx$$CondRegister, done); 12494 12495 // 0xAA: feminine ordinal indicator 12496 // 0xB5: micro sign 12497 // 0xBA: masculine ordinal indicator 12498 __ lis($src2$$Register, (signed short)0xAAB5); 12499 __ ori($src2$$Register, $src2$$Register, 0xBABA); 12500 __ insrdi($src2$$Register, $src2$$Register, 32, 0); 12501 // compare src1 with 0xAA, 0xB5, and 0xBA 12502 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register); 12503 12504 __ bind(done); 12505 __ setb($dst$$Register, $crx$$CondRegister); 12506 %} 12507 ins_pipe(pipe_class_default); 12508 %} 12509 12510 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12511 match(Set dst (UpperCase src1)); 12512 effect(TEMP src2, TEMP crx); 12513 ins_cost(7 * DEFAULT_COST); 12514 12515 format %{ "LI $src2, 0x5A41\n\t" 12516 "CMPRB $crx, 0, $src1, $src2\n\t" 12517 "BGT $crx, done\n\t" 12518 "LIS $src2, (signed short)0xD6C0\n\t" 12519 "ORI $src2, $src2, 0xDED8\n\t" 12520 "CMPRB $crx, 1, $src1, $src2\n" 12521 "done:\n\t" 12522 "SETB $dst, $crx" %} 12523 12524 size(28); 12525 ins_encode %{ 12526 Label done; 12527 // 0x41: A, 0x5A: Z 12528 __ li($src2$$Register, 0x5A41); 12529 // compare src1 with a range 0x41 to 0x5A 12530 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12531 __ bgt($crx$$CondRegister, done); 12532 12533 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case 12534 __ lis($src2$$Register, (signed short)0xD6C0); 12535 __ ori($src2$$Register, $src2$$Register, 0xDED8); 12536 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE 12537 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12538 12539 __ bind(done); 12540 __ setb($dst$$Register, $crx$$CondRegister); 12541 %} 12542 ins_pipe(pipe_class_default); 12543 %} 12544 12545 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12546 match(Set dst (Whitespace src1)); 12547 effect(TEMP src2, TEMP crx); 12548 ins_cost(4 * DEFAULT_COST); 12549 12550 format %{ "LI $src2, 0x0D09\n\t" 12551 "ADDIS $src2, 0x201C\n\t" 12552 "CMPRB $crx, 1, $src1, $src2\n\t" 12553 "SETB $dst, $crx" %} 12554 size(16); 12555 ins_encode %{ 12556 // 0x09 to 0x0D, 0x1C to 0x20 12557 __ li($src2$$Register, 0x0D09); 12558 __ addis($src2$$Register, $src2$$Register, 0x0201C); 12559 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20 12560 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12561 __ setb($dst$$Register, $crx$$CondRegister); 12562 %} 12563 ins_pipe(pipe_class_default); 12564 %} 12565 12566 //----------Branches--------------------------------------------------------- 12567 // Jump 12568 12569 // Direct Branch. 12570 instruct branch(label labl) %{ 12571 match(Goto); 12572 effect(USE labl); 12573 ins_cost(BRANCH_COST); 12574 12575 format %{ "B $labl" %} 12576 size(4); 12577 ins_encode %{ 12578 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12579 Label d; // dummy 12580 __ bind(d); 12581 Label* p = $labl$$label; 12582 // `p' is `NULL' when this encoding class is used only to 12583 // determine the size of the encoded instruction. 12584 Label& l = (NULL == p)? d : *(p); 12585 __ b(l); 12586 %} 12587 ins_pipe(pipe_class_default); 12588 %} 12589 12590 // Conditional Near Branch 12591 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12592 // Same match rule as `branchConFar'. 12593 match(If cmp crx); 12594 effect(USE lbl); 12595 ins_cost(BRANCH_COST); 12596 12597 // If set to 1 this indicates that the current instruction is a 12598 // short variant of a long branch. This avoids using this 12599 // instruction in first-pass matching. It will then only be used in 12600 // the `Shorten_branches' pass. 12601 ins_short_branch(1); 12602 12603 format %{ "B$cmp $crx, $lbl" %} 12604 size(4); 12605 ins_encode( enc_bc(crx, cmp, lbl) ); 12606 ins_pipe(pipe_class_default); 12607 %} 12608 12609 // This is for cases when the ppc64 `bc' instruction does not 12610 // reach far enough. So we emit a far branch here, which is more 12611 // expensive. 12612 // 12613 // Conditional Far Branch 12614 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12615 // Same match rule as `branchCon'. 12616 match(If cmp crx); 12617 effect(USE crx, USE lbl); 12618 predicate(!false /* TODO: PPC port HB_Schedule*/); 12619 // Higher cost than `branchCon'. 12620 ins_cost(5*BRANCH_COST); 12621 12622 // This is not a short variant of a branch, but the long variant. 12623 ins_short_branch(0); 12624 12625 format %{ "B_FAR$cmp $crx, $lbl" %} 12626 size(8); 12627 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12628 ins_pipe(pipe_class_default); 12629 %} 12630 12631 // Conditional Branch used with Power6 scheduler (can be far or short). 12632 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12633 // Same match rule as `branchCon'. 12634 match(If cmp crx); 12635 effect(USE crx, USE lbl); 12636 predicate(false /* TODO: PPC port HB_Schedule*/); 12637 // Higher cost than `branchCon'. 12638 ins_cost(5*BRANCH_COST); 12639 12640 // Actually size doesn't depend on alignment but on shortening. 12641 ins_variable_size_depending_on_alignment(true); 12642 // long variant. 12643 ins_short_branch(0); 12644 12645 format %{ "B_FAR$cmp $crx, $lbl" %} 12646 size(8); // worst case 12647 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12648 ins_pipe(pipe_class_default); 12649 %} 12650 12651 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12652 match(CountedLoopEnd cmp crx); 12653 effect(USE labl); 12654 ins_cost(BRANCH_COST); 12655 12656 // short variant. 12657 ins_short_branch(1); 12658 12659 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12660 size(4); 12661 ins_encode( enc_bc(crx, cmp, labl) ); 12662 ins_pipe(pipe_class_default); 12663 %} 12664 12665 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12666 match(CountedLoopEnd cmp crx); 12667 effect(USE labl); 12668 predicate(!false /* TODO: PPC port HB_Schedule */); 12669 ins_cost(BRANCH_COST); 12670 12671 // Long variant. 12672 ins_short_branch(0); 12673 12674 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12675 size(8); 12676 ins_encode( enc_bc_far(crx, cmp, labl) ); 12677 ins_pipe(pipe_class_default); 12678 %} 12679 12680 // Conditional Branch used with Power6 scheduler (can be far or short). 12681 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12682 match(CountedLoopEnd cmp crx); 12683 effect(USE labl); 12684 predicate(false /* TODO: PPC port HB_Schedule */); 12685 // Higher cost than `branchCon'. 12686 ins_cost(5*BRANCH_COST); 12687 12688 // Actually size doesn't depend on alignment but on shortening. 12689 ins_variable_size_depending_on_alignment(true); 12690 // Long variant. 12691 ins_short_branch(0); 12692 12693 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12694 size(8); // worst case 12695 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12696 ins_pipe(pipe_class_default); 12697 %} 12698 12699 // ============================================================================ 12700 // Java runtime operations, intrinsics and other complex operations. 12701 12702 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12703 // array for an instance of the superklass. Set a hidden internal cache on a 12704 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12705 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12706 // 12707 // GL TODO: Improve this. 12708 // - result should not be a TEMP 12709 // - Add match rule as on sparc avoiding additional Cmp. 12710 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12711 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12712 match(Set result (PartialSubtypeCheck subklass superklass)); 12713 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12714 ins_cost(DEFAULT_COST*10); 12715 12716 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12717 ins_encode %{ 12718 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12719 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12720 $tmp_klass$$Register, NULL, $result$$Register); 12721 %} 12722 ins_pipe(pipe_class_default); 12723 %} 12724 12725 // inlined locking and unlocking 12726 12727 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12728 match(Set crx (FastLock oop box)); 12729 effect(TEMP tmp1, TEMP tmp2); 12730 predicate(!Compile::current()->use_rtm()); 12731 12732 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12733 ins_encode %{ 12734 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12735 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12736 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12737 UseBiasedLocking && !UseOptoBiasInlining); 12738 // If locking was successfull, crx should indicate 'EQ'. 12739 // The compiler generates a branch to the runtime call to 12740 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12741 %} 12742 ins_pipe(pipe_class_compare); 12743 %} 12744 12745 // Separate version for TM. Use bound register for box to enable USE_KILL. 12746 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12747 match(Set crx (FastLock oop box)); 12748 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12749 predicate(Compile::current()->use_rtm()); 12750 12751 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12752 ins_encode %{ 12753 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12754 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12755 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12756 /*Biased Locking*/ false, 12757 _rtm_counters, _stack_rtm_counters, 12758 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12759 /*TM*/ true, ra_->C->profile_rtm()); 12760 // If locking was successfull, crx should indicate 'EQ'. 12761 // The compiler generates a branch to the runtime call to 12762 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12763 %} 12764 ins_pipe(pipe_class_compare); 12765 %} 12766 12767 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12768 match(Set crx (FastUnlock oop box)); 12769 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12770 predicate(!Compile::current()->use_rtm()); 12771 12772 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12773 ins_encode %{ 12774 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12775 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12776 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12777 UseBiasedLocking && !UseOptoBiasInlining, 12778 false); 12779 // If unlocking was successfull, crx should indicate 'EQ'. 12780 // The compiler generates a branch to the runtime call to 12781 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12782 %} 12783 ins_pipe(pipe_class_compare); 12784 %} 12785 12786 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12787 match(Set crx (FastUnlock oop box)); 12788 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12789 predicate(Compile::current()->use_rtm()); 12790 12791 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12792 ins_encode %{ 12793 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12794 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12795 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12796 /*Biased Locking*/ false, /*TM*/ true); 12797 // If unlocking was successfull, crx should indicate 'EQ'. 12798 // The compiler generates a branch to the runtime call to 12799 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12800 %} 12801 ins_pipe(pipe_class_compare); 12802 %} 12803 12804 // Align address. 12805 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12806 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12807 12808 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12809 size(4); 12810 ins_encode %{ 12811 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12812 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12813 %} 12814 ins_pipe(pipe_class_default); 12815 %} 12816 12817 // Array size computation. 12818 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12819 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12820 12821 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12822 size(4); 12823 ins_encode %{ 12824 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12825 __ subf($dst$$Register, $start$$Register, $end$$Register); 12826 %} 12827 ins_pipe(pipe_class_default); 12828 %} 12829 12830 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12831 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12832 match(Set dummy (ClearArray cnt base)); 12833 effect(USE_KILL base, KILL ctr); 12834 ins_cost(2 * MEMORY_REF_COST); 12835 12836 format %{ "ClearArray $cnt, $base" %} 12837 ins_encode %{ 12838 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12839 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12840 %} 12841 ins_pipe(pipe_class_default); 12842 %} 12843 12844 // Clear-array with constant large array length. 12845 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12846 match(Set dummy (ClearArray cnt base)); 12847 effect(USE_KILL base, TEMP tmp, KILL ctr); 12848 ins_cost(3 * MEMORY_REF_COST); 12849 12850 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12851 ins_encode %{ 12852 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12853 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12854 %} 12855 ins_pipe(pipe_class_default); 12856 %} 12857 12858 // Clear-array with dynamic array length. 12859 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12860 match(Set dummy (ClearArray cnt base)); 12861 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12862 ins_cost(4 * MEMORY_REF_COST); 12863 12864 format %{ "ClearArray $cnt, $base" %} 12865 ins_encode %{ 12866 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12867 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12868 %} 12869 ins_pipe(pipe_class_default); 12870 %} 12871 12872 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12873 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12874 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12875 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12876 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12877 ins_cost(300); 12878 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12879 ins_encode %{ 12880 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12881 __ string_compare($str1$$Register, $str2$$Register, 12882 $cnt1$$Register, $cnt2$$Register, 12883 $tmp$$Register, 12884 $result$$Register, StrIntrinsicNode::LL); 12885 %} 12886 ins_pipe(pipe_class_default); 12887 %} 12888 12889 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12890 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12891 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12892 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12893 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12894 ins_cost(300); 12895 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12896 ins_encode %{ 12897 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12898 __ string_compare($str1$$Register, $str2$$Register, 12899 $cnt1$$Register, $cnt2$$Register, 12900 $tmp$$Register, 12901 $result$$Register, StrIntrinsicNode::UU); 12902 %} 12903 ins_pipe(pipe_class_default); 12904 %} 12905 12906 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12907 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12908 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12909 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12910 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12911 ins_cost(300); 12912 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12913 ins_encode %{ 12914 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12915 __ string_compare($str1$$Register, $str2$$Register, 12916 $cnt1$$Register, $cnt2$$Register, 12917 $tmp$$Register, 12918 $result$$Register, StrIntrinsicNode::LU); 12919 %} 12920 ins_pipe(pipe_class_default); 12921 %} 12922 12923 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12924 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12925 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12926 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12927 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12928 ins_cost(300); 12929 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12930 ins_encode %{ 12931 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12932 __ string_compare($str2$$Register, $str1$$Register, 12933 $cnt2$$Register, $cnt1$$Register, 12934 $tmp$$Register, 12935 $result$$Register, StrIntrinsicNode::UL); 12936 %} 12937 ins_pipe(pipe_class_default); 12938 %} 12939 12940 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12941 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12942 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12943 match(Set result (StrEquals (Binary str1 str2) cnt)); 12944 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12945 ins_cost(300); 12946 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12947 ins_encode %{ 12948 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12949 __ array_equals(false, $str1$$Register, $str2$$Register, 12950 $cnt$$Register, $tmp$$Register, 12951 $result$$Register, true /* byte */); 12952 %} 12953 ins_pipe(pipe_class_default); 12954 %} 12955 12956 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12957 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12958 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12959 match(Set result (StrEquals (Binary str1 str2) cnt)); 12960 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12961 ins_cost(300); 12962 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12963 ins_encode %{ 12964 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12965 __ array_equals(false, $str1$$Register, $str2$$Register, 12966 $cnt$$Register, $tmp$$Register, 12967 $result$$Register, false /* byte */); 12968 %} 12969 ins_pipe(pipe_class_default); 12970 %} 12971 12972 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12973 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12974 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12975 match(Set result (AryEq ary1 ary2)); 12976 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12977 ins_cost(300); 12978 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12979 ins_encode %{ 12980 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12981 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12982 $tmp1$$Register, $tmp2$$Register, 12983 $result$$Register, true /* byte */); 12984 %} 12985 ins_pipe(pipe_class_default); 12986 %} 12987 12988 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12989 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12990 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12991 match(Set result (AryEq ary1 ary2)); 12992 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12993 ins_cost(300); 12994 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12995 ins_encode %{ 12996 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12997 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12998 $tmp1$$Register, $tmp2$$Register, 12999 $result$$Register, false /* byte */); 13000 %} 13001 ins_pipe(pipe_class_default); 13002 %} 13003 13004 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13005 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13006 iRegIdst tmp1, iRegIdst tmp2, 13007 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13008 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13009 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13010 // Required for EA: check if it is still a type_array. 13011 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13012 ins_cost(150); 13013 13014 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13015 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13016 13017 ins_encode %{ 13018 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13019 immPOper *needleOper = (immPOper *)$needleImm; 13020 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13021 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13022 jchar chr; 13023 #ifdef VM_LITTLE_ENDIAN 13024 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 13025 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 13026 #else 13027 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 13028 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 13029 #endif 13030 __ string_indexof_char($result$$Register, 13031 $haystack$$Register, $haycnt$$Register, 13032 R0, chr, 13033 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13034 %} 13035 ins_pipe(pipe_class_compare); 13036 %} 13037 13038 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13039 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13040 iRegIdst tmp1, iRegIdst tmp2, 13041 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13042 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13043 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13044 // Required for EA: check if it is still a type_array. 13045 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13046 ins_cost(150); 13047 13048 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13049 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13050 13051 ins_encode %{ 13052 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13053 immPOper *needleOper = (immPOper *)$needleImm; 13054 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13055 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13056 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13057 __ string_indexof_char($result$$Register, 13058 $haystack$$Register, $haycnt$$Register, 13059 R0, chr, 13060 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13061 %} 13062 ins_pipe(pipe_class_compare); 13063 %} 13064 13065 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13066 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13067 iRegIdst tmp1, iRegIdst tmp2, 13068 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13069 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13070 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13071 // Required for EA: check if it is still a type_array. 13072 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13073 ins_cost(150); 13074 13075 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13076 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13077 13078 ins_encode %{ 13079 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13080 immPOper *needleOper = (immPOper *)$needleImm; 13081 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13082 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13083 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13084 __ string_indexof_char($result$$Register, 13085 $haystack$$Register, $haycnt$$Register, 13086 R0, chr, 13087 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13088 %} 13089 ins_pipe(pipe_class_compare); 13090 %} 13091 13092 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13093 rscratch2RegP needle, immI_1 needlecntImm, 13094 iRegIdst tmp1, iRegIdst tmp2, 13095 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13096 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13097 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13098 // Required for EA: check if it is still a type_array. 13099 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13100 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13101 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13102 ins_cost(180); 13103 13104 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13105 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13106 ins_encode %{ 13107 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13108 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13109 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13110 guarantee(needle_values, "sanity"); 13111 jchar chr; 13112 #ifdef VM_LITTLE_ENDIAN 13113 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 13114 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 13115 #else 13116 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 13117 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 13118 #endif 13119 __ string_indexof_char($result$$Register, 13120 $haystack$$Register, $haycnt$$Register, 13121 R0, chr, 13122 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13123 %} 13124 ins_pipe(pipe_class_compare); 13125 %} 13126 13127 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13128 rscratch2RegP needle, immI_1 needlecntImm, 13129 iRegIdst tmp1, iRegIdst tmp2, 13130 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13131 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13132 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13133 // Required for EA: check if it is still a type_array. 13134 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13135 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13136 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13137 ins_cost(180); 13138 13139 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13140 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13141 ins_encode %{ 13142 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13143 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13144 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13145 guarantee(needle_values, "sanity"); 13146 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13147 __ string_indexof_char($result$$Register, 13148 $haystack$$Register, $haycnt$$Register, 13149 R0, chr, 13150 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13151 %} 13152 ins_pipe(pipe_class_compare); 13153 %} 13154 13155 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13156 rscratch2RegP needle, immI_1 needlecntImm, 13157 iRegIdst tmp1, iRegIdst tmp2, 13158 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13159 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13160 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13161 // Required for EA: check if it is still a type_array. 13162 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13163 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13164 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13165 ins_cost(180); 13166 13167 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13168 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13169 ins_encode %{ 13170 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13171 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13172 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13173 guarantee(needle_values, "sanity"); 13174 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13175 __ string_indexof_char($result$$Register, 13176 $haystack$$Register, $haycnt$$Register, 13177 R0, chr, 13178 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13179 %} 13180 ins_pipe(pipe_class_compare); 13181 %} 13182 13183 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13184 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 13185 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13186 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 13187 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13188 ins_cost(180); 13189 13190 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 13191 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13192 ins_encode %{ 13193 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13194 __ string_indexof_char($result$$Register, 13195 $haystack$$Register, $haycnt$$Register, 13196 $ch$$Register, 0 /* this is not used if the character is already in a register */, 13197 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13198 %} 13199 ins_pipe(pipe_class_compare); 13200 %} 13201 13202 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13203 iRegPsrc needle, uimmI15 needlecntImm, 13204 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13205 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13206 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13207 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13208 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13209 // Required for EA: check if it is still a type_array. 13210 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13211 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13212 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13213 ins_cost(250); 13214 13215 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13216 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13217 ins_encode %{ 13218 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13219 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13220 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13221 13222 __ string_indexof($result$$Register, 13223 $haystack$$Register, $haycnt$$Register, 13224 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13225 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13226 %} 13227 ins_pipe(pipe_class_compare); 13228 %} 13229 13230 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13231 iRegPsrc needle, uimmI15 needlecntImm, 13232 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13233 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13234 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13235 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13236 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13237 // Required for EA: check if it is still a type_array. 13238 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13239 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13240 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13241 ins_cost(250); 13242 13243 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13244 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13245 ins_encode %{ 13246 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13247 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13248 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13249 13250 __ string_indexof($result$$Register, 13251 $haystack$$Register, $haycnt$$Register, 13252 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13253 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13254 %} 13255 ins_pipe(pipe_class_compare); 13256 %} 13257 13258 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13259 iRegPsrc needle, uimmI15 needlecntImm, 13260 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13261 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13262 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13263 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13264 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13265 // Required for EA: check if it is still a type_array. 13266 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13267 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13268 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13269 ins_cost(250); 13270 13271 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13272 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13273 ins_encode %{ 13274 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13275 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13276 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13277 13278 __ string_indexof($result$$Register, 13279 $haystack$$Register, $haycnt$$Register, 13280 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13281 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13282 %} 13283 ins_pipe(pipe_class_compare); 13284 %} 13285 13286 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13287 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13288 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13289 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13290 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13291 TEMP_DEF result, 13292 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13293 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13294 ins_cost(300); 13295 13296 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13297 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13298 ins_encode %{ 13299 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13300 __ string_indexof($result$$Register, 13301 $haystack$$Register, $haycnt$$Register, 13302 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13303 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13304 %} 13305 ins_pipe(pipe_class_compare); 13306 %} 13307 13308 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13309 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13310 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13311 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13312 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13313 TEMP_DEF result, 13314 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13315 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13316 ins_cost(300); 13317 13318 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13319 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13320 ins_encode %{ 13321 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13322 __ string_indexof($result$$Register, 13323 $haystack$$Register, $haycnt$$Register, 13324 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13325 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13326 %} 13327 ins_pipe(pipe_class_compare); 13328 %} 13329 13330 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13331 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13332 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13333 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13334 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13335 TEMP_DEF result, 13336 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13337 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13338 ins_cost(300); 13339 13340 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13341 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13342 ins_encode %{ 13343 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13344 __ string_indexof($result$$Register, 13345 $haystack$$Register, $haycnt$$Register, 13346 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13347 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13348 %} 13349 ins_pipe(pipe_class_compare); 13350 %} 13351 13352 // char[] to byte[] compression 13353 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13354 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13355 match(Set result (StrCompressedCopy src (Binary dst len))); 13356 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13357 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13358 ins_cost(300); 13359 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13360 ins_encode %{ 13361 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13362 Label Lskip, Ldone; 13363 __ li($result$$Register, 0); 13364 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13365 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13366 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13367 __ beq(CCR0, Lskip); 13368 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13369 __ bind(Lskip); 13370 __ mr($result$$Register, $len$$Register); 13371 __ bind(Ldone); 13372 %} 13373 ins_pipe(pipe_class_default); 13374 %} 13375 13376 // byte[] to char[] inflation 13377 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13378 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13379 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13380 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13381 ins_cost(300); 13382 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13383 ins_encode %{ 13384 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13385 Label Ldone; 13386 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13387 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13388 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13389 __ beq(CCR0, Ldone); 13390 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13391 __ bind(Ldone); 13392 %} 13393 ins_pipe(pipe_class_default); 13394 %} 13395 13396 // StringCoding.java intrinsics 13397 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13398 regCTR ctr, flagsRegCR0 cr0) 13399 %{ 13400 match(Set result (HasNegatives ary1 len)); 13401 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13402 ins_cost(300); 13403 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13404 ins_encode %{ 13405 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13406 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13407 $tmp1$$Register, $tmp2$$Register); 13408 %} 13409 ins_pipe(pipe_class_default); 13410 %} 13411 13412 // encode char[] to byte[] in ISO_8859_1 13413 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13414 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13415 match(Set result (EncodeISOArray src (Binary dst len))); 13416 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13417 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13418 ins_cost(300); 13419 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13420 ins_encode %{ 13421 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13422 Label Lslow, Lfailure1, Lfailure2, Ldone; 13423 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13424 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13425 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13426 __ beq(CCR0, Ldone); 13427 __ bind(Lslow); 13428 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13429 __ li($result$$Register, 0); 13430 __ b(Ldone); 13431 13432 __ bind(Lfailure1); 13433 __ mr($result$$Register, $len$$Register); 13434 __ mfctr($tmp1$$Register); 13435 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13436 __ beq(CCR0, Ldone); 13437 __ b(Lslow); 13438 13439 __ bind(Lfailure2); 13440 __ mfctr($result$$Register); // Remaining characters. 13441 13442 __ bind(Ldone); 13443 __ subf($result$$Register, $result$$Register, $len$$Register); 13444 %} 13445 ins_pipe(pipe_class_default); 13446 %} 13447 13448 13449 //---------- Min/Max Instructions --------------------------------------------- 13450 13451 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13452 match(Set dst (MinI src1 src2)); 13453 ins_cost(DEFAULT_COST*6); 13454 13455 expand %{ 13456 iRegLdst src1s; 13457 iRegLdst src2s; 13458 iRegLdst diff; 13459 iRegLdst sm; 13460 iRegLdst doz; // difference or zero 13461 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13462 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13463 subL_reg_reg(diff, src2s, src1s); 13464 // Need to consider >=33 bit result, therefore we need signmaskL. 13465 signmask64L_regL(sm, diff); 13466 andL_reg_reg(doz, diff, sm); // <=0 13467 addI_regL_regL(dst, doz, src1s); 13468 %} 13469 %} 13470 13471 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13472 match(Set dst (MinI src1 src2)); 13473 effect(KILL cr0); 13474 predicate(VM_Version::has_isel()); 13475 ins_cost(DEFAULT_COST*2); 13476 13477 ins_encode %{ 13478 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13479 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13480 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13481 %} 13482 ins_pipe(pipe_class_default); 13483 %} 13484 13485 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13486 match(Set dst (MaxI src1 src2)); 13487 ins_cost(DEFAULT_COST*6); 13488 13489 expand %{ 13490 iRegLdst src1s; 13491 iRegLdst src2s; 13492 iRegLdst diff; 13493 iRegLdst sm; 13494 iRegLdst doz; // difference or zero 13495 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13496 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13497 subL_reg_reg(diff, src2s, src1s); 13498 // Need to consider >=33 bit result, therefore we need signmaskL. 13499 signmask64L_regL(sm, diff); 13500 andcL_reg_reg(doz, diff, sm); // >=0 13501 addI_regL_regL(dst, doz, src1s); 13502 %} 13503 %} 13504 13505 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13506 match(Set dst (MaxI src1 src2)); 13507 effect(KILL cr0); 13508 predicate(VM_Version::has_isel()); 13509 ins_cost(DEFAULT_COST*2); 13510 13511 ins_encode %{ 13512 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13513 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13514 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13515 %} 13516 ins_pipe(pipe_class_default); 13517 %} 13518 13519 //---------- Population Count Instructions ------------------------------------ 13520 13521 // Popcnt for Power7. 13522 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13523 match(Set dst (PopCountI src)); 13524 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13525 ins_cost(DEFAULT_COST); 13526 13527 format %{ "POPCNTW $dst, $src" %} 13528 size(4); 13529 ins_encode %{ 13530 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13531 __ popcntw($dst$$Register, $src$$Register); 13532 %} 13533 ins_pipe(pipe_class_default); 13534 %} 13535 13536 // Popcnt for Power7. 13537 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13538 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13539 match(Set dst (PopCountL src)); 13540 ins_cost(DEFAULT_COST); 13541 13542 format %{ "POPCNTD $dst, $src" %} 13543 size(4); 13544 ins_encode %{ 13545 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13546 __ popcntd($dst$$Register, $src$$Register); 13547 %} 13548 ins_pipe(pipe_class_default); 13549 %} 13550 13551 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13552 match(Set dst (CountLeadingZerosI src)); 13553 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13554 ins_cost(DEFAULT_COST); 13555 13556 format %{ "CNTLZW $dst, $src" %} 13557 size(4); 13558 ins_encode %{ 13559 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13560 __ cntlzw($dst$$Register, $src$$Register); 13561 %} 13562 ins_pipe(pipe_class_default); 13563 %} 13564 13565 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13566 match(Set dst (CountLeadingZerosL src)); 13567 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13568 ins_cost(DEFAULT_COST); 13569 13570 format %{ "CNTLZD $dst, $src" %} 13571 size(4); 13572 ins_encode %{ 13573 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13574 __ cntlzd($dst$$Register, $src$$Register); 13575 %} 13576 ins_pipe(pipe_class_default); 13577 %} 13578 13579 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13580 // no match-rule, false predicate 13581 effect(DEF dst, USE src); 13582 predicate(false); 13583 13584 format %{ "CNTLZD $dst, $src" %} 13585 size(4); 13586 ins_encode %{ 13587 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13588 __ cntlzd($dst$$Register, $src$$Register); 13589 %} 13590 ins_pipe(pipe_class_default); 13591 %} 13592 13593 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13594 match(Set dst (CountTrailingZerosI src)); 13595 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13596 ins_cost(DEFAULT_COST); 13597 13598 expand %{ 13599 immI16 imm1 %{ (int)-1 %} 13600 immI16 imm2 %{ (int)32 %} 13601 immI_minus1 m1 %{ -1 %} 13602 iRegIdst tmpI1; 13603 iRegIdst tmpI2; 13604 iRegIdst tmpI3; 13605 addI_reg_imm16(tmpI1, src, imm1); 13606 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13607 countLeadingZerosI(tmpI3, tmpI2); 13608 subI_imm16_reg(dst, imm2, tmpI3); 13609 %} 13610 %} 13611 13612 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{ 13613 match(Set dst (CountTrailingZerosI src)); 13614 predicate(UseCountTrailingZerosInstructionsPPC64); 13615 ins_cost(DEFAULT_COST); 13616 13617 format %{ "CNTTZW $dst, $src" %} 13618 size(4); 13619 ins_encode %{ 13620 __ cnttzw($dst$$Register, $src$$Register); 13621 %} 13622 ins_pipe(pipe_class_default); 13623 %} 13624 13625 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13626 match(Set dst (CountTrailingZerosL src)); 13627 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13628 ins_cost(DEFAULT_COST); 13629 13630 expand %{ 13631 immL16 imm1 %{ (long)-1 %} 13632 immI16 imm2 %{ (int)64 %} 13633 iRegLdst tmpL1; 13634 iRegLdst tmpL2; 13635 iRegIdst tmpL3; 13636 addL_reg_imm16(tmpL1, src, imm1); 13637 andcL_reg_reg(tmpL2, tmpL1, src); 13638 countLeadingZerosL(tmpL3, tmpL2); 13639 subI_imm16_reg(dst, imm2, tmpL3); 13640 %} 13641 %} 13642 13643 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{ 13644 match(Set dst (CountTrailingZerosL src)); 13645 predicate(UseCountTrailingZerosInstructionsPPC64); 13646 ins_cost(DEFAULT_COST); 13647 13648 format %{ "CNTTZD $dst, $src" %} 13649 size(4); 13650 ins_encode %{ 13651 __ cnttzd($dst$$Register, $src$$Register); 13652 %} 13653 ins_pipe(pipe_class_default); 13654 %} 13655 13656 // Expand nodes for byte_reverse_int. 13657 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13658 effect(DEF dst, USE src, USE pos, USE shift); 13659 predicate(false); 13660 13661 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13662 size(4); 13663 ins_encode %{ 13664 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13665 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13666 %} 13667 ins_pipe(pipe_class_default); 13668 %} 13669 13670 // As insrwi_a, but with USE_DEF. 13671 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13672 effect(USE_DEF dst, USE src, USE pos, USE shift); 13673 predicate(false); 13674 13675 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13676 size(4); 13677 ins_encode %{ 13678 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13679 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13680 %} 13681 ins_pipe(pipe_class_default); 13682 %} 13683 13684 // Just slightly faster than java implementation. 13685 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13686 match(Set dst (ReverseBytesI src)); 13687 ins_cost(7*DEFAULT_COST); 13688 13689 expand %{ 13690 immI16 imm24 %{ (int) 24 %} 13691 immI16 imm16 %{ (int) 16 %} 13692 immI16 imm8 %{ (int) 8 %} 13693 immI16 imm4 %{ (int) 4 %} 13694 immI16 imm0 %{ (int) 0 %} 13695 iRegLdst tmpI1; 13696 iRegLdst tmpI2; 13697 iRegLdst tmpI3; 13698 13699 urShiftI_reg_imm(tmpI1, src, imm24); 13700 insrwi_a(dst, tmpI1, imm24, imm8); 13701 urShiftI_reg_imm(tmpI2, src, imm16); 13702 insrwi(dst, tmpI2, imm8, imm16); 13703 urShiftI_reg_imm(tmpI3, src, imm8); 13704 insrwi(dst, tmpI3, imm8, imm8); 13705 insrwi(dst, src, imm0, imm8); 13706 %} 13707 %} 13708 13709 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13710 match(Set dst (ReverseBytesL src)); 13711 ins_cost(15*DEFAULT_COST); 13712 13713 expand %{ 13714 immI16 imm56 %{ (int) 56 %} 13715 immI16 imm48 %{ (int) 48 %} 13716 immI16 imm40 %{ (int) 40 %} 13717 immI16 imm32 %{ (int) 32 %} 13718 immI16 imm24 %{ (int) 24 %} 13719 immI16 imm16 %{ (int) 16 %} 13720 immI16 imm8 %{ (int) 8 %} 13721 immI16 imm0 %{ (int) 0 %} 13722 iRegLdst tmpL1; 13723 iRegLdst tmpL2; 13724 iRegLdst tmpL3; 13725 iRegLdst tmpL4; 13726 iRegLdst tmpL5; 13727 iRegLdst tmpL6; 13728 13729 // src : |a|b|c|d|e|f|g|h| 13730 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13731 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13732 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13733 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13734 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13735 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13736 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13737 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13738 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13739 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13740 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13741 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13742 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13743 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13744 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13745 %} 13746 %} 13747 13748 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13749 match(Set dst (ReverseBytesUS src)); 13750 ins_cost(2*DEFAULT_COST); 13751 13752 expand %{ 13753 immI16 imm16 %{ (int) 16 %} 13754 immI16 imm8 %{ (int) 8 %} 13755 13756 urShiftI_reg_imm(dst, src, imm8); 13757 insrwi(dst, src, imm16, imm8); 13758 %} 13759 %} 13760 13761 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13762 match(Set dst (ReverseBytesS src)); 13763 ins_cost(3*DEFAULT_COST); 13764 13765 expand %{ 13766 immI16 imm16 %{ (int) 16 %} 13767 immI16 imm8 %{ (int) 8 %} 13768 iRegLdst tmpI1; 13769 13770 urShiftI_reg_imm(tmpI1, src, imm8); 13771 insrwi(tmpI1, src, imm16, imm8); 13772 extsh(dst, tmpI1); 13773 %} 13774 %} 13775 13776 // Load Integer reversed byte order 13777 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13778 match(Set dst (ReverseBytesI (LoadI mem))); 13779 ins_cost(MEMORY_REF_COST); 13780 13781 size(4); 13782 ins_encode %{ 13783 __ lwbrx($dst$$Register, $mem$$Register); 13784 %} 13785 ins_pipe(pipe_class_default); 13786 %} 13787 13788 // Load Long - aligned and reversed 13789 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13790 match(Set dst (ReverseBytesL (LoadL mem))); 13791 predicate(VM_Version::has_ldbrx()); 13792 ins_cost(MEMORY_REF_COST); 13793 13794 size(4); 13795 ins_encode %{ 13796 __ ldbrx($dst$$Register, $mem$$Register); 13797 %} 13798 ins_pipe(pipe_class_default); 13799 %} 13800 13801 // Load unsigned short / char reversed byte order 13802 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13803 match(Set dst (ReverseBytesUS (LoadUS mem))); 13804 ins_cost(MEMORY_REF_COST); 13805 13806 size(4); 13807 ins_encode %{ 13808 __ lhbrx($dst$$Register, $mem$$Register); 13809 %} 13810 ins_pipe(pipe_class_default); 13811 %} 13812 13813 // Load short reversed byte order 13814 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13815 match(Set dst (ReverseBytesS (LoadS mem))); 13816 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13817 13818 size(8); 13819 ins_encode %{ 13820 __ lhbrx($dst$$Register, $mem$$Register); 13821 __ extsh($dst$$Register, $dst$$Register); 13822 %} 13823 ins_pipe(pipe_class_default); 13824 %} 13825 13826 // Store Integer reversed byte order 13827 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13828 match(Set mem (StoreI mem (ReverseBytesI src))); 13829 ins_cost(MEMORY_REF_COST); 13830 13831 size(4); 13832 ins_encode %{ 13833 __ stwbrx($src$$Register, $mem$$Register); 13834 %} 13835 ins_pipe(pipe_class_default); 13836 %} 13837 13838 // Store Long reversed byte order 13839 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13840 match(Set mem (StoreL mem (ReverseBytesL src))); 13841 predicate(VM_Version::has_stdbrx()); 13842 ins_cost(MEMORY_REF_COST); 13843 13844 size(4); 13845 ins_encode %{ 13846 __ stdbrx($src$$Register, $mem$$Register); 13847 %} 13848 ins_pipe(pipe_class_default); 13849 %} 13850 13851 // Store unsigned short / char reversed byte order 13852 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13853 match(Set mem (StoreC mem (ReverseBytesUS src))); 13854 ins_cost(MEMORY_REF_COST); 13855 13856 size(4); 13857 ins_encode %{ 13858 __ sthbrx($src$$Register, $mem$$Register); 13859 %} 13860 ins_pipe(pipe_class_default); 13861 %} 13862 13863 // Store short reversed byte order 13864 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13865 match(Set mem (StoreC mem (ReverseBytesS src))); 13866 ins_cost(MEMORY_REF_COST); 13867 13868 size(4); 13869 ins_encode %{ 13870 __ sthbrx($src$$Register, $mem$$Register); 13871 %} 13872 ins_pipe(pipe_class_default); 13873 %} 13874 13875 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13876 effect(DEF temp1, USE src); 13877 13878 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %} 13879 size(4); 13880 ins_encode %{ 13881 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13882 %} 13883 ins_pipe(pipe_class_default); 13884 %} 13885 13886 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13887 effect(DEF dst, USE src, USE imm1); 13888 13889 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %} 13890 size(4); 13891 ins_encode %{ 13892 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13893 %} 13894 ins_pipe(pipe_class_default); 13895 %} 13896 13897 instruct xscvdpspn_regF(vecX dst, regF src) %{ 13898 effect(DEF dst, USE src); 13899 13900 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %} 13901 size(4); 13902 ins_encode %{ 13903 __ xscvdpspn($dst$$VectorSRegister, $src$$FloatRegister->to_vsr()); 13904 %} 13905 ins_pipe(pipe_class_default); 13906 %} 13907 13908 //---------- Replicate Vector Instructions ------------------------------------ 13909 13910 // Insrdi does replicate if src == dst. 13911 instruct repl32(iRegLdst dst) %{ 13912 predicate(false); 13913 effect(USE_DEF dst); 13914 13915 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13916 size(4); 13917 ins_encode %{ 13918 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13919 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13920 %} 13921 ins_pipe(pipe_class_default); 13922 %} 13923 13924 // Insrdi does replicate if src == dst. 13925 instruct repl48(iRegLdst dst) %{ 13926 predicate(false); 13927 effect(USE_DEF dst); 13928 13929 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13930 size(4); 13931 ins_encode %{ 13932 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13933 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13934 %} 13935 ins_pipe(pipe_class_default); 13936 %} 13937 13938 // Insrdi does replicate if src == dst. 13939 instruct repl56(iRegLdst dst) %{ 13940 predicate(false); 13941 effect(USE_DEF dst); 13942 13943 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13944 size(4); 13945 ins_encode %{ 13946 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13947 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 13948 %} 13949 ins_pipe(pipe_class_default); 13950 %} 13951 13952 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13953 match(Set dst (ReplicateB src)); 13954 predicate(n->as_Vector()->length() == 8); 13955 expand %{ 13956 moveReg(dst, src); 13957 repl56(dst); 13958 repl48(dst); 13959 repl32(dst); 13960 %} 13961 %} 13962 13963 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 13964 match(Set dst (ReplicateB zero)); 13965 predicate(n->as_Vector()->length() == 8); 13966 format %{ "LI $dst, #0 \t// replicate8B" %} 13967 size(4); 13968 ins_encode %{ 13969 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13970 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13971 %} 13972 ins_pipe(pipe_class_default); 13973 %} 13974 13975 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13976 match(Set dst (ReplicateB src)); 13977 predicate(n->as_Vector()->length() == 8); 13978 format %{ "LI $dst, #-1 \t// replicate8B" %} 13979 size(4); 13980 ins_encode %{ 13981 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13982 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13983 %} 13984 ins_pipe(pipe_class_default); 13985 %} 13986 13987 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 13988 match(Set dst (ReplicateB src)); 13989 predicate(n->as_Vector()->length() == 16); 13990 13991 expand %{ 13992 iRegLdst tmpL; 13993 vecX tmpV; 13994 immI8 imm1 %{ (int) 1 %} 13995 moveReg(tmpL, src); 13996 repl56(tmpL); 13997 repl48(tmpL); 13998 mtvsrwz(tmpV, tmpL); 13999 xxspltw(dst, tmpV, imm1); 14000 %} 14001 %} 14002 14003 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 14004 match(Set dst (ReplicateB zero)); 14005 predicate(n->as_Vector()->length() == 16); 14006 14007 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 14008 size(4); 14009 ins_encode %{ 14010 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14011 %} 14012 ins_pipe(pipe_class_default); 14013 %} 14014 14015 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 14016 match(Set dst (ReplicateB src)); 14017 predicate(n->as_Vector()->length() == 16); 14018 14019 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14020 size(4); 14021 ins_encode %{ 14022 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14023 %} 14024 ins_pipe(pipe_class_default); 14025 %} 14026 14027 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14028 match(Set dst (ReplicateS src)); 14029 predicate(n->as_Vector()->length() == 4); 14030 expand %{ 14031 moveReg(dst, src); 14032 repl48(dst); 14033 repl32(dst); 14034 %} 14035 %} 14036 14037 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 14038 match(Set dst (ReplicateS zero)); 14039 predicate(n->as_Vector()->length() == 4); 14040 format %{ "LI $dst, #0 \t// replicate4S" %} 14041 size(4); 14042 ins_encode %{ 14043 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14044 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14045 %} 14046 ins_pipe(pipe_class_default); 14047 %} 14048 14049 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14050 match(Set dst (ReplicateS src)); 14051 predicate(n->as_Vector()->length() == 4); 14052 format %{ "LI $dst, -1 \t// replicate4S" %} 14053 size(4); 14054 ins_encode %{ 14055 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14056 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14057 %} 14058 ins_pipe(pipe_class_default); 14059 %} 14060 14061 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 14062 match(Set dst (ReplicateS src)); 14063 predicate(n->as_Vector()->length() == 8); 14064 14065 expand %{ 14066 iRegLdst tmpL; 14067 vecX tmpV; 14068 immI8 zero %{ (int) 0 %} 14069 moveReg(tmpL, src); 14070 repl48(tmpL); 14071 repl32(tmpL); 14072 mtvsrd(tmpV, tmpL); 14073 xxpermdi(dst, tmpV, tmpV, zero); 14074 %} 14075 %} 14076 14077 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 14078 match(Set dst (ReplicateS zero)); 14079 predicate(n->as_Vector()->length() == 8); 14080 14081 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 14082 size(4); 14083 ins_encode %{ 14084 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14085 %} 14086 ins_pipe(pipe_class_default); 14087 %} 14088 14089 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 14090 match(Set dst (ReplicateS src)); 14091 predicate(n->as_Vector()->length() == 8); 14092 14093 format %{ "XXLEQV $dst, $src \t// replicate8S" %} 14094 size(4); 14095 ins_encode %{ 14096 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14097 %} 14098 ins_pipe(pipe_class_default); 14099 %} 14100 14101 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14102 match(Set dst (ReplicateI src)); 14103 predicate(n->as_Vector()->length() == 2); 14104 ins_cost(2 * DEFAULT_COST); 14105 expand %{ 14106 moveReg(dst, src); 14107 repl32(dst); 14108 %} 14109 %} 14110 14111 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 14112 match(Set dst (ReplicateI zero)); 14113 predicate(n->as_Vector()->length() == 2); 14114 format %{ "LI $dst, #0 \t// replicate2I" %} 14115 size(4); 14116 ins_encode %{ 14117 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14118 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14119 %} 14120 ins_pipe(pipe_class_default); 14121 %} 14122 14123 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14124 match(Set dst (ReplicateI src)); 14125 predicate(n->as_Vector()->length() == 2); 14126 format %{ "LI $dst, -1 \t// replicate2I" %} 14127 size(4); 14128 ins_encode %{ 14129 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14130 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14131 %} 14132 ins_pipe(pipe_class_default); 14133 %} 14134 14135 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 14136 match(Set dst (ReplicateI src)); 14137 predicate(n->as_Vector()->length() == 4); 14138 ins_cost(2 * DEFAULT_COST); 14139 14140 expand %{ 14141 iRegLdst tmpL; 14142 vecX tmpV; 14143 immI8 zero %{ (int) 0 %} 14144 moveReg(tmpL, src); 14145 repl32(tmpL); 14146 mtvsrd(tmpV, tmpL); 14147 xxpermdi(dst, tmpV, tmpV, zero); 14148 %} 14149 %} 14150 14151 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 14152 match(Set dst (ReplicateI zero)); 14153 predicate(n->as_Vector()->length() == 4); 14154 14155 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 14156 size(4); 14157 ins_encode %{ 14158 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14159 %} 14160 ins_pipe(pipe_class_default); 14161 %} 14162 14163 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 14164 match(Set dst (ReplicateI src)); 14165 predicate(n->as_Vector()->length() == 4); 14166 14167 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 14168 size(4); 14169 ins_encode %{ 14170 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14171 %} 14172 ins_pipe(pipe_class_default); 14173 %} 14174 14175 // Move float to int register via stack, replicate. 14176 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 14177 match(Set dst (ReplicateF src)); 14178 predicate(n->as_Vector()->length() == 2); 14179 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14180 expand %{ 14181 stackSlotL tmpS; 14182 iRegIdst tmpI; 14183 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14184 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14185 moveReg(dst, tmpI); // Move int to long reg. 14186 repl32(dst); // Replicate bitpattern. 14187 %} 14188 %} 14189 14190 // Replicate scalar constant to packed float values in Double register 14191 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 14192 match(Set dst (ReplicateF src)); 14193 predicate(n->as_Vector()->length() == 2); 14194 ins_cost(5 * DEFAULT_COST); 14195 14196 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 14197 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 14198 %} 14199 14200 // Replicate scalar zero constant to packed float values in Double register 14201 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 14202 match(Set dst (ReplicateF zero)); 14203 predicate(n->as_Vector()->length() == 2); 14204 14205 format %{ "LI $dst, #0 \t// replicate2F" %} 14206 ins_encode %{ 14207 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14208 __ li($dst$$Register, 0x0); 14209 %} 14210 ins_pipe(pipe_class_default); 14211 %} 14212 14213 14214 //----------Vector Arithmetic Instructions-------------------------------------- 14215 14216 // Vector Addition Instructions 14217 14218 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{ 14219 match(Set dst (AddVB src1 src2)); 14220 predicate(n->as_Vector()->length() == 16); 14221 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %} 14222 size(4); 14223 ins_encode %{ 14224 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14225 %} 14226 ins_pipe(pipe_class_default); 14227 %} 14228 14229 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{ 14230 match(Set dst (AddVS src1 src2)); 14231 predicate(n->as_Vector()->length() == 8); 14232 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %} 14233 size(4); 14234 ins_encode %{ 14235 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14236 %} 14237 ins_pipe(pipe_class_default); 14238 %} 14239 14240 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{ 14241 match(Set dst (AddVI src1 src2)); 14242 predicate(n->as_Vector()->length() == 4); 14243 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %} 14244 size(4); 14245 ins_encode %{ 14246 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14247 %} 14248 ins_pipe(pipe_class_default); 14249 %} 14250 14251 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{ 14252 match(Set dst (AddVF src1 src2)); 14253 predicate(n->as_Vector()->length() == 4); 14254 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %} 14255 size(4); 14256 ins_encode %{ 14257 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14258 %} 14259 ins_pipe(pipe_class_default); 14260 %} 14261 14262 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{ 14263 match(Set dst (AddVL src1 src2)); 14264 predicate(n->as_Vector()->length() == 2); 14265 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %} 14266 size(4); 14267 ins_encode %{ 14268 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14269 %} 14270 ins_pipe(pipe_class_default); 14271 %} 14272 14273 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{ 14274 match(Set dst (AddVD src1 src2)); 14275 predicate(n->as_Vector()->length() == 2); 14276 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %} 14277 size(4); 14278 ins_encode %{ 14279 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14280 %} 14281 ins_pipe(pipe_class_default); 14282 %} 14283 14284 // Vector Subtraction Instructions 14285 14286 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{ 14287 match(Set dst (SubVB src1 src2)); 14288 predicate(n->as_Vector()->length() == 16); 14289 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %} 14290 size(4); 14291 ins_encode %{ 14292 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14293 %} 14294 ins_pipe(pipe_class_default); 14295 %} 14296 14297 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{ 14298 match(Set dst (SubVS src1 src2)); 14299 predicate(n->as_Vector()->length() == 8); 14300 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %} 14301 size(4); 14302 ins_encode %{ 14303 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14304 %} 14305 ins_pipe(pipe_class_default); 14306 %} 14307 14308 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{ 14309 match(Set dst (SubVI src1 src2)); 14310 predicate(n->as_Vector()->length() == 4); 14311 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %} 14312 size(4); 14313 ins_encode %{ 14314 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14315 %} 14316 ins_pipe(pipe_class_default); 14317 %} 14318 14319 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{ 14320 match(Set dst (SubVF src1 src2)); 14321 predicate(n->as_Vector()->length() == 4); 14322 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %} 14323 size(4); 14324 ins_encode %{ 14325 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14326 %} 14327 ins_pipe(pipe_class_default); 14328 %} 14329 14330 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{ 14331 match(Set dst (SubVL src1 src2)); 14332 predicate(n->as_Vector()->length() == 2); 14333 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %} 14334 size(4); 14335 ins_encode %{ 14336 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14337 %} 14338 ins_pipe(pipe_class_default); 14339 %} 14340 14341 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{ 14342 match(Set dst (SubVD src1 src2)); 14343 predicate(n->as_Vector()->length() == 2); 14344 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %} 14345 size(4); 14346 ins_encode %{ 14347 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14348 %} 14349 ins_pipe(pipe_class_default); 14350 %} 14351 14352 // Vector Multiplication Instructions 14353 14354 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 14355 match(Set dst (MulVS src1 src2)); 14356 predicate(n->as_Vector()->length() == 8); 14357 effect(TEMP tmp); 14358 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %} 14359 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %} 14360 size(8); 14361 ins_encode %{ 14362 __ vspltish($tmp$$VectorSRegister->to_vr(), 0); 14363 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr()); 14364 %} 14365 ins_pipe(pipe_class_default); 14366 %} 14367 14368 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{ 14369 match(Set dst (MulVI src1 src2)); 14370 predicate(n->as_Vector()->length() == 4); 14371 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %} 14372 size(4); 14373 ins_encode %{ 14374 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14375 %} 14376 ins_pipe(pipe_class_default); 14377 %} 14378 14379 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{ 14380 match(Set dst (MulVF src1 src2)); 14381 predicate(n->as_Vector()->length() == 4); 14382 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %} 14383 size(4); 14384 ins_encode %{ 14385 __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14386 %} 14387 ins_pipe(pipe_class_default); 14388 %} 14389 14390 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{ 14391 match(Set dst (MulVD src1 src2)); 14392 predicate(n->as_Vector()->length() == 2); 14393 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %} 14394 size(4); 14395 ins_encode %{ 14396 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14397 %} 14398 ins_pipe(pipe_class_default); 14399 %} 14400 14401 // Vector Division Instructions 14402 14403 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{ 14404 match(Set dst (DivVF src1 src2)); 14405 predicate(n->as_Vector()->length() == 4); 14406 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %} 14407 size(4); 14408 ins_encode %{ 14409 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14410 %} 14411 ins_pipe(pipe_class_default); 14412 %} 14413 14414 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ 14415 match(Set dst (DivVD src1 src2)); 14416 predicate(n->as_Vector()->length() == 2); 14417 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %} 14418 size(4); 14419 ins_encode %{ 14420 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14421 %} 14422 ins_pipe(pipe_class_default); 14423 %} 14424 14425 // Vector Absolute Instructions 14426 14427 instruct vabs4F_reg(vecX dst, vecX src) %{ 14428 match(Set dst (AbsVF src)); 14429 predicate(n->as_Vector()->length() == 4); 14430 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %} 14431 size(4); 14432 ins_encode %{ 14433 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister); 14434 %} 14435 ins_pipe(pipe_class_default); 14436 %} 14437 14438 instruct vabs2D_reg(vecX dst, vecX src) %{ 14439 match(Set dst (AbsVD src)); 14440 predicate(n->as_Vector()->length() == 2); 14441 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %} 14442 size(4); 14443 ins_encode %{ 14444 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister); 14445 %} 14446 ins_pipe(pipe_class_default); 14447 %} 14448 14449 // Vector Negate Instructions 14450 14451 instruct vneg4F_reg(vecX dst, vecX src) %{ 14452 match(Set dst (NegVF src)); 14453 predicate(n->as_Vector()->length() == 4); 14454 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %} 14455 size(4); 14456 ins_encode %{ 14457 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister); 14458 %} 14459 ins_pipe(pipe_class_default); 14460 %} 14461 14462 instruct vneg2D_reg(vecX dst, vecX src) %{ 14463 match(Set dst (NegVD src)); 14464 predicate(n->as_Vector()->length() == 2); 14465 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %} 14466 size(4); 14467 ins_encode %{ 14468 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister); 14469 %} 14470 ins_pipe(pipe_class_default); 14471 %} 14472 14473 // Vector Square Root Instructions 14474 14475 instruct vsqrt4F_reg(vecX dst, vecX src) %{ 14476 match(Set dst (SqrtVF src)); 14477 predicate(n->as_Vector()->length() == 4); 14478 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %} 14479 size(4); 14480 ins_encode %{ 14481 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister); 14482 %} 14483 ins_pipe(pipe_class_default); 14484 %} 14485 14486 instruct vsqrt2D_reg(vecX dst, vecX src) %{ 14487 match(Set dst (SqrtVD src)); 14488 predicate(n->as_Vector()->length() == 2); 14489 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %} 14490 size(4); 14491 ins_encode %{ 14492 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister); 14493 %} 14494 ins_pipe(pipe_class_default); 14495 %} 14496 14497 // Vector Population Count Instructions 14498 14499 instruct vpopcnt4I_reg(vecX dst, vecX src) %{ 14500 match(Set dst (PopCountVI src)); 14501 predicate(n->as_Vector()->length() == 4); 14502 format %{ "VPOPCNTW $dst,$src\t// pop count packed4I" %} 14503 size(4); 14504 ins_encode %{ 14505 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14506 %} 14507 ins_pipe(pipe_class_default); 14508 %} 14509 14510 // --------------------------------- FMA -------------------------------------- 14511 // dst + src1 * src2 14512 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{ 14513 match(Set dst (FmaVF dst (Binary src1 src2))); 14514 predicate(n->as_Vector()->length() == 4); 14515 14516 format %{ "XVMADDASP $dst, $src1, $src2" %} 14517 14518 size(4); 14519 ins_encode %{ 14520 __ xvmaddasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14521 %} 14522 ins_pipe(pipe_class_default); 14523 %} 14524 14525 // dst - src1 * src2 14526 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{ 14527 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 14528 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 14529 predicate(n->as_Vector()->length() == 4); 14530 14531 format %{ "XVNMSUBASP $dst, $src1, $src2" %} 14532 14533 size(4); 14534 ins_encode %{ 14535 __ xvnmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14536 %} 14537 ins_pipe(pipe_class_default); 14538 %} 14539 14540 // - dst + src1 * src2 14541 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{ 14542 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2))); 14543 predicate(n->as_Vector()->length() == 4); 14544 14545 format %{ "XVMSUBASP $dst, $src1, $src2" %} 14546 14547 size(4); 14548 ins_encode %{ 14549 __ xvmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14550 %} 14551 ins_pipe(pipe_class_default); 14552 %} 14553 14554 // dst + src1 * src2 14555 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{ 14556 match(Set dst (FmaVD dst (Binary src1 src2))); 14557 predicate(n->as_Vector()->length() == 2); 14558 14559 format %{ "XVMADDADP $dst, $src1, $src2" %} 14560 14561 size(4); 14562 ins_encode %{ 14563 __ xvmaddadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14564 %} 14565 ins_pipe(pipe_class_default); 14566 %} 14567 14568 // dst - src1 * src2 14569 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{ 14570 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 14571 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 14572 predicate(n->as_Vector()->length() == 2); 14573 14574 format %{ "XVNMSUBADP $dst, $src1, $src2" %} 14575 14576 size(4); 14577 ins_encode %{ 14578 __ xvnmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14579 %} 14580 ins_pipe(pipe_class_default); 14581 %} 14582 14583 // - dst + src1 * src2 14584 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{ 14585 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2))); 14586 predicate(n->as_Vector()->length() == 2); 14587 14588 format %{ "XVMSUBADP $dst, $src1, $src2" %} 14589 14590 size(4); 14591 ins_encode %{ 14592 __ xvmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14593 %} 14594 ins_pipe(pipe_class_default); 14595 %} 14596 14597 //----------Overflow Math Instructions----------------------------------------- 14598 14599 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 14600 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14601 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14602 14603 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14604 match(Set cr0 (OverflowAddL op1 op2)); 14605 14606 format %{ "add_ $op1, $op2\t# overflow check long" %} 14607 ins_encode %{ 14608 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14609 __ li(R0, 0); 14610 __ mtxer(R0); // clear XER.SO 14611 __ addo_(R0, $op1$$Register, $op2$$Register); 14612 %} 14613 ins_pipe(pipe_class_default); 14614 %} 14615 14616 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14617 match(Set cr0 (OverflowSubL op1 op2)); 14618 14619 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14620 ins_encode %{ 14621 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14622 __ li(R0, 0); 14623 __ mtxer(R0); // clear XER.SO 14624 __ subfo_(R0, $op2$$Register, $op1$$Register); 14625 %} 14626 ins_pipe(pipe_class_default); 14627 %} 14628 14629 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14630 match(Set cr0 (OverflowSubL zero op2)); 14631 14632 format %{ "nego_ R0, $op2\t# overflow check long" %} 14633 ins_encode %{ 14634 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14635 __ li(R0, 0); 14636 __ mtxer(R0); // clear XER.SO 14637 __ nego_(R0, $op2$$Register); 14638 %} 14639 ins_pipe(pipe_class_default); 14640 %} 14641 14642 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14643 match(Set cr0 (OverflowMulL op1 op2)); 14644 14645 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14646 ins_encode %{ 14647 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14648 __ li(R0, 0); 14649 __ mtxer(R0); // clear XER.SO 14650 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14651 %} 14652 ins_pipe(pipe_class_default); 14653 %} 14654 14655 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14656 match(Set dst (ReplicateF src)); 14657 predicate(n->as_Vector()->length() == 4); 14658 ins_cost(DEFAULT_COST); 14659 expand %{ 14660 vecX tmpV; 14661 immI8 zero %{ (int) 0 %} 14662 14663 xscvdpspn_regF(tmpV, src); 14664 xxspltw(dst, tmpV, zero); 14665 %} 14666 %} 14667 14668 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14669 match(Set dst (ReplicateF src)); 14670 predicate(n->as_Vector()->length() == 4); 14671 effect(TEMP tmp); 14672 ins_cost(10 * DEFAULT_COST); 14673 14674 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14675 %} 14676 14677 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14678 match(Set dst (ReplicateF zero)); 14679 predicate(n->as_Vector()->length() == 4); 14680 14681 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14682 ins_encode %{ 14683 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14684 %} 14685 ins_pipe(pipe_class_default); 14686 %} 14687 14688 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14689 match(Set dst (ReplicateD src)); 14690 predicate(n->as_Vector()->length() == 2); 14691 14692 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %} 14693 size(4); 14694 ins_encode %{ 14695 __ xxpermdi($dst$$VectorSRegister, $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0); 14696 %} 14697 ins_pipe(pipe_class_default); 14698 %} 14699 14700 instruct repl2D_immD0(vecX dst, immD_0 zero) %{ 14701 match(Set dst (ReplicateD zero)); 14702 predicate(n->as_Vector()->length() == 2); 14703 14704 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14705 size(4); 14706 ins_encode %{ 14707 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14708 %} 14709 ins_pipe(pipe_class_default); 14710 %} 14711 14712 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14713 predicate(false); 14714 effect(DEF dst, USE src); 14715 14716 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %} 14717 size(4); 14718 ins_encode %{ 14719 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14720 %} 14721 ins_pipe(pipe_class_default); 14722 %} 14723 14724 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14725 effect(DEF dst, USE src, USE zero); 14726 14727 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %} 14728 size(4); 14729 ins_encode %{ 14730 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14731 %} 14732 ins_pipe(pipe_class_default); 14733 %} 14734 14735 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14736 effect(DEF dst, USE src1, USE src2, USE zero); 14737 14738 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %} 14739 size(4); 14740 ins_encode %{ 14741 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14742 %} 14743 ins_pipe(pipe_class_default); 14744 %} 14745 14746 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14747 match(Set dst (ReplicateL src)); 14748 predicate(n->as_Vector()->length() == 2); 14749 expand %{ 14750 vecX tmpV; 14751 immI8 zero %{ (int) 0 %} 14752 mtvsrd(tmpV, src); 14753 xxpermdi(dst, tmpV, tmpV, zero); 14754 %} 14755 %} 14756 14757 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14758 match(Set dst (ReplicateL zero)); 14759 predicate(n->as_Vector()->length() == 2); 14760 14761 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14762 size(4); 14763 ins_encode %{ 14764 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14765 %} 14766 ins_pipe(pipe_class_default); 14767 %} 14768 14769 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14770 match(Set dst (ReplicateL src)); 14771 predicate(n->as_Vector()->length() == 2); 14772 14773 format %{ "XXLEQV $dst, $src \t// replicate2L" %} 14774 size(4); 14775 ins_encode %{ 14776 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14777 %} 14778 ins_pipe(pipe_class_default); 14779 %} 14780 14781 // ============================================================================ 14782 // Safepoint Instruction 14783 14784 instruct safePoint_poll(iRegPdst poll) %{ 14785 match(SafePoint poll); 14786 14787 // It caused problems to add the effect that r0 is killed, but this 14788 // effect no longer needs to be mentioned, since r0 is not contained 14789 // in a reg_class. 14790 14791 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14792 size(4); 14793 ins_encode( enc_poll(0x0, poll) ); 14794 ins_pipe(pipe_class_default); 14795 %} 14796 14797 // ============================================================================ 14798 // Call Instructions 14799 14800 // Call Java Static Instruction 14801 14802 // Schedulable version of call static node. 14803 instruct CallStaticJavaDirect(method meth) %{ 14804 match(CallStaticJava); 14805 effect(USE meth); 14806 ins_cost(CALL_COST); 14807 14808 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14809 14810 format %{ "CALL,static $meth \t// ==> " %} 14811 size(4); 14812 ins_encode( enc_java_static_call(meth) ); 14813 ins_pipe(pipe_class_call); 14814 %} 14815 14816 // Call Java Dynamic Instruction 14817 14818 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14819 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14820 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14821 // The call destination must still be placed in the constant pool. 14822 instruct CallDynamicJavaDirectSched(method meth) %{ 14823 match(CallDynamicJava); // To get all the data fields we need ... 14824 effect(USE meth); 14825 predicate(false); // ... but never match. 14826 14827 ins_field_load_ic_hi_node(loadConL_hiNode*); 14828 ins_field_load_ic_node(loadConLNode*); 14829 ins_num_consts(1 /* 1 patchable constant: call destination */); 14830 14831 format %{ "BL \t// dynamic $meth ==> " %} 14832 size(4); 14833 ins_encode( enc_java_dynamic_call_sched(meth) ); 14834 ins_pipe(pipe_class_call); 14835 %} 14836 14837 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14838 // We use postalloc expanded calls if we use inline caches 14839 // and do not update method data. 14840 // 14841 // This instruction has two constants: inline cache (IC) and call destination. 14842 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14843 // one constant. 14844 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14845 match(CallDynamicJava); 14846 effect(USE meth); 14847 predicate(UseInlineCaches); 14848 ins_cost(CALL_COST); 14849 14850 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14851 14852 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14853 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14854 %} 14855 14856 // Compound version of call dynamic java 14857 // We use postalloc expanded calls if we use inline caches 14858 // and do not update method data. 14859 instruct CallDynamicJavaDirect(method meth) %{ 14860 match(CallDynamicJava); 14861 effect(USE meth); 14862 predicate(!UseInlineCaches); 14863 ins_cost(CALL_COST); 14864 14865 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14866 ins_num_consts(4); 14867 14868 format %{ "CALL,dynamic $meth \t// ==> " %} 14869 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14870 ins_pipe(pipe_class_call); 14871 %} 14872 14873 // Call Runtime Instruction 14874 14875 instruct CallRuntimeDirect(method meth) %{ 14876 match(CallRuntime); 14877 effect(USE meth); 14878 ins_cost(CALL_COST); 14879 14880 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14881 // env for callee, C-toc. 14882 ins_num_consts(3); 14883 14884 format %{ "CALL,runtime" %} 14885 ins_encode( enc_java_to_runtime_call(meth) ); 14886 ins_pipe(pipe_class_call); 14887 %} 14888 14889 // Call Leaf 14890 14891 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14892 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14893 effect(DEF dst, USE src); 14894 14895 ins_num_consts(1); 14896 14897 format %{ "MTCTR $src" %} 14898 size(4); 14899 ins_encode( enc_leaf_call_mtctr(src) ); 14900 ins_pipe(pipe_class_default); 14901 %} 14902 14903 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 14904 instruct CallLeafDirect(method meth) %{ 14905 match(CallLeaf); // To get the data all the data fields we need ... 14906 effect(USE meth); 14907 predicate(false); // but never match. 14908 14909 format %{ "BCTRL \t// leaf call $meth ==> " %} 14910 size(4); 14911 ins_encode %{ 14912 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 14913 __ bctrl(); 14914 %} 14915 ins_pipe(pipe_class_call); 14916 %} 14917 14918 // postalloc expand of CallLeafDirect. 14919 // Load adress to call from TOC, then bl to it. 14920 instruct CallLeafDirect_Ex(method meth) %{ 14921 match(CallLeaf); 14922 effect(USE meth); 14923 ins_cost(CALL_COST); 14924 14925 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14926 // env for callee, C-toc. 14927 ins_num_consts(3); 14928 14929 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14930 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14931 %} 14932 14933 // Call runtime without safepoint - same as CallLeaf. 14934 // postalloc expand of CallLeafNoFPDirect. 14935 // Load adress to call from TOC, then bl to it. 14936 instruct CallLeafNoFPDirect_Ex(method meth) %{ 14937 match(CallLeafNoFP); 14938 effect(USE meth); 14939 ins_cost(CALL_COST); 14940 14941 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14942 // env for callee, C-toc. 14943 ins_num_consts(3); 14944 14945 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14946 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14947 %} 14948 14949 // Tail Call; Jump from runtime stub to Java code. 14950 // Also known as an 'interprocedural jump'. 14951 // Target of jump will eventually return to caller. 14952 // TailJump below removes the return address. 14953 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 14954 match(TailCall jump_target method_oop); 14955 ins_cost(CALL_COST); 14956 14957 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 14958 "BCTR \t// tail call" %} 14959 size(8); 14960 ins_encode %{ 14961 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14962 __ mtctr($jump_target$$Register); 14963 __ bctr(); 14964 %} 14965 ins_pipe(pipe_class_call); 14966 %} 14967 14968 // Return Instruction 14969 instruct Ret() %{ 14970 match(Return); 14971 format %{ "BLR \t// branch to link register" %} 14972 size(4); 14973 ins_encode %{ 14974 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 14975 // LR is restored in MachEpilogNode. Just do the RET here. 14976 __ blr(); 14977 %} 14978 ins_pipe(pipe_class_default); 14979 %} 14980 14981 // Tail Jump; remove the return address; jump to target. 14982 // TailCall above leaves the return address around. 14983 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14984 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14985 // "restore" before this instruction (in Epilogue), we need to materialize it 14986 // in %i0. 14987 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14988 match(TailJump jump_target ex_oop); 14989 ins_cost(CALL_COST); 14990 14991 format %{ "LD R4_ARG2 = LR\n\t" 14992 "MTCTR $jump_target\n\t" 14993 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14994 size(12); 14995 ins_encode %{ 14996 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14997 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 14998 __ mtctr($jump_target$$Register); 14999 __ bctr(); 15000 %} 15001 ins_pipe(pipe_class_call); 15002 %} 15003 15004 // Create exception oop: created by stack-crawling runtime code. 15005 // Created exception is now available to this handler, and is setup 15006 // just prior to jumping to this handler. No code emitted. 15007 instruct CreateException(rarg1RegP ex_oop) %{ 15008 match(Set ex_oop (CreateEx)); 15009 ins_cost(0); 15010 15011 format %{ " -- \t// exception oop; no code emitted" %} 15012 size(0); 15013 ins_encode( /*empty*/ ); 15014 ins_pipe(pipe_class_default); 15015 %} 15016 15017 // Rethrow exception: The exception oop will come in the first 15018 // argument position. Then JUMP (not call) to the rethrow stub code. 15019 instruct RethrowException() %{ 15020 match(Rethrow); 15021 ins_cost(CALL_COST); 15022 15023 format %{ "Jmp rethrow_stub" %} 15024 ins_encode %{ 15025 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 15026 cbuf.set_insts_mark(); 15027 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 15028 %} 15029 ins_pipe(pipe_class_call); 15030 %} 15031 15032 // Die now. 15033 instruct ShouldNotReachHere() %{ 15034 match(Halt); 15035 ins_cost(CALL_COST); 15036 15037 format %{ "ShouldNotReachHere" %} 15038 size(4); 15039 ins_encode %{ 15040 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 15041 __ trap_should_not_reach_here(); 15042 %} 15043 ins_pipe(pipe_class_default); 15044 %} 15045 15046 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 15047 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 15048 // Get a DEF on threadRegP, no costs, no encoding, use 15049 // 'ins_should_rematerialize(true)' to avoid spilling. 15050 instruct tlsLoadP(threadRegP dst) %{ 15051 match(Set dst (ThreadLocal)); 15052 ins_cost(0); 15053 15054 ins_should_rematerialize(true); 15055 15056 format %{ " -- \t// $dst=Thread::current(), empty" %} 15057 size(0); 15058 ins_encode( /*empty*/ ); 15059 ins_pipe(pipe_class_empty); 15060 %} 15061 15062 //---Some PPC specific nodes--------------------------------------------------- 15063 15064 // Stop a group. 15065 instruct endGroup() %{ 15066 ins_cost(0); 15067 15068 ins_is_nop(true); 15069 15070 format %{ "End Bundle (ori r1, r1, 0)" %} 15071 size(4); 15072 ins_encode %{ 15073 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 15074 __ endgroup(); 15075 %} 15076 ins_pipe(pipe_class_default); 15077 %} 15078 15079 // Nop instructions 15080 15081 instruct fxNop() %{ 15082 ins_cost(0); 15083 15084 ins_is_nop(true); 15085 15086 format %{ "fxNop" %} 15087 size(4); 15088 ins_encode %{ 15089 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15090 __ nop(); 15091 %} 15092 ins_pipe(pipe_class_default); 15093 %} 15094 15095 instruct fpNop0() %{ 15096 ins_cost(0); 15097 15098 ins_is_nop(true); 15099 15100 format %{ "fpNop0" %} 15101 size(4); 15102 ins_encode %{ 15103 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15104 __ fpnop0(); 15105 %} 15106 ins_pipe(pipe_class_default); 15107 %} 15108 15109 instruct fpNop1() %{ 15110 ins_cost(0); 15111 15112 ins_is_nop(true); 15113 15114 format %{ "fpNop1" %} 15115 size(4); 15116 ins_encode %{ 15117 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15118 __ fpnop1(); 15119 %} 15120 ins_pipe(pipe_class_default); 15121 %} 15122 15123 instruct brNop0() %{ 15124 ins_cost(0); 15125 size(4); 15126 format %{ "brNop0" %} 15127 ins_encode %{ 15128 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15129 __ brnop0(); 15130 %} 15131 ins_is_nop(true); 15132 ins_pipe(pipe_class_default); 15133 %} 15134 15135 instruct brNop1() %{ 15136 ins_cost(0); 15137 15138 ins_is_nop(true); 15139 15140 format %{ "brNop1" %} 15141 size(4); 15142 ins_encode %{ 15143 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15144 __ brnop1(); 15145 %} 15146 ins_pipe(pipe_class_default); 15147 %} 15148 15149 instruct brNop2() %{ 15150 ins_cost(0); 15151 15152 ins_is_nop(true); 15153 15154 format %{ "brNop2" %} 15155 size(4); 15156 ins_encode %{ 15157 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15158 __ brnop2(); 15159 %} 15160 ins_pipe(pipe_class_default); 15161 %} 15162 15163 //----------PEEPHOLE RULES----------------------------------------------------- 15164 // These must follow all instruction definitions as they use the names 15165 // defined in the instructions definitions. 15166 // 15167 // peepmatch ( root_instr_name [preceeding_instruction]* ); 15168 // 15169 // peepconstraint %{ 15170 // (instruction_number.operand_name relational_op instruction_number.operand_name 15171 // [, ...] ); 15172 // // instruction numbers are zero-based using left to right order in peepmatch 15173 // 15174 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 15175 // // provide an instruction_number.operand_name for each operand that appears 15176 // // in the replacement instruction's match rule 15177 // 15178 // ---------VM FLAGS--------------------------------------------------------- 15179 // 15180 // All peephole optimizations can be turned off using -XX:-OptoPeephole 15181 // 15182 // Each peephole rule is given an identifying number starting with zero and 15183 // increasing by one in the order seen by the parser. An individual peephole 15184 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 15185 // on the command-line. 15186 // 15187 // ---------CURRENT LIMITATIONS---------------------------------------------- 15188 // 15189 // Only match adjacent instructions in same basic block 15190 // Only equality constraints 15191 // Only constraints between operands, not (0.dest_reg == EAX_enc) 15192 // Only one replacement instruction 15193 // 15194 // ---------EXAMPLE---------------------------------------------------------- 15195 // 15196 // // pertinent parts of existing instructions in architecture description 15197 // instruct movI(eRegI dst, eRegI src) %{ 15198 // match(Set dst (CopyI src)); 15199 // %} 15200 // 15201 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 15202 // match(Set dst (AddI dst src)); 15203 // effect(KILL cr); 15204 // %} 15205 // 15206 // // Change (inc mov) to lea 15207 // peephole %{ 15208 // // increment preceeded by register-register move 15209 // peepmatch ( incI_eReg movI ); 15210 // // require that the destination register of the increment 15211 // // match the destination register of the move 15212 // peepconstraint ( 0.dst == 1.dst ); 15213 // // construct a replacement instruction that sets 15214 // // the destination to ( move's source register + one ) 15215 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15216 // %} 15217 // 15218 // Implementation no longer uses movX instructions since 15219 // machine-independent system no longer uses CopyX nodes. 15220 // 15221 // peephole %{ 15222 // peepmatch ( incI_eReg movI ); 15223 // peepconstraint ( 0.dst == 1.dst ); 15224 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15225 // %} 15226 // 15227 // peephole %{ 15228 // peepmatch ( decI_eReg movI ); 15229 // peepconstraint ( 0.dst == 1.dst ); 15230 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15231 // %} 15232 // 15233 // peephole %{ 15234 // peepmatch ( addI_eReg_imm movI ); 15235 // peepconstraint ( 0.dst == 1.dst ); 15236 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15237 // %} 15238 // 15239 // peephole %{ 15240 // peepmatch ( addP_eReg_imm movP ); 15241 // peepconstraint ( 0.dst == 1.dst ); 15242 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 15243 // %} 15244 15245 // // Change load of spilled value to only a spill 15246 // instruct storeI(memory mem, eRegI src) %{ 15247 // match(Set mem (StoreI mem src)); 15248 // %} 15249 // 15250 // instruct loadI(eRegI dst, memory mem) %{ 15251 // match(Set dst (LoadI mem)); 15252 // %} 15253 // 15254 peephole %{ 15255 peepmatch ( loadI storeI ); 15256 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15257 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 15258 %} 15259 15260 peephole %{ 15261 peepmatch ( loadL storeL ); 15262 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15263 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 15264 %} 15265 15266 peephole %{ 15267 peepmatch ( loadP storeP ); 15268 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 15269 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 15270 %} 15271 15272 //----------SMARTSPILL RULES--------------------------------------------------- 15273 // These must follow all instruction definitions as they use the names 15274 // defined in the instructions definitions.