1 // 2 // Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2018 SAP SE. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // 27 // PPC64 Architecture Description File 28 // 29 30 //----------REGISTER DEFINITION BLOCK------------------------------------------ 31 // This information is used by the matcher and the register allocator to 32 // describe individual registers and classes of registers within the target 33 // architecture. 34 register %{ 35 //----------Architecture Description Register Definitions---------------------- 36 // General Registers 37 // "reg_def" name (register save type, C convention save type, 38 // ideal register type, encoding); 39 // 40 // Register Save Types: 41 // 42 // NS = No-Save: The register allocator assumes that these registers 43 // can be used without saving upon entry to the method, & 44 // that they do not need to be saved at call sites. 45 // 46 // SOC = Save-On-Call: The register allocator assumes that these registers 47 // can be used without saving upon entry to the method, 48 // but that they must be saved at call sites. 49 // These are called "volatiles" on ppc. 50 // 51 // SOE = Save-On-Entry: The register allocator assumes that these registers 52 // must be saved before using them upon entry to the 53 // method, but they do not need to be saved at call 54 // sites. 55 // These are called "nonvolatiles" on ppc. 56 // 57 // AS = Always-Save: The register allocator assumes that these registers 58 // must be saved before using them upon entry to the 59 // method, & that they must be saved at call sites. 60 // 61 // Ideal Register Type is used to determine how to save & restore a 62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 64 // 65 // The encoding number is the actual bit-pattern placed into the opcodes. 66 // 67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI 68 // Supplement Version 1.7 as of 2003-10-29. 69 // 70 // For each 64-bit register we must define two registers: the register 71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half', 72 // e.g. R3_H, which is needed by the allocator, but is not used 73 // for stores, loads, etc. 74 75 // ---------------------------- 76 // Integer/Long Registers 77 // ---------------------------- 78 79 // PPC64 has 32 64-bit integer registers. 80 81 // types: v = volatile, nv = non-volatile, s = system 82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs 83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() ); 84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP 85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() ); 86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC 87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() ); 88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret 89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() ); 90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2 91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() ); 92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3 93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() ); 94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4 95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() ); 96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5 97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() ); 98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6 99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() ); 100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7 101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() ); 102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8 103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next()); 104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch 105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next()); 106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch 107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next()); 108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id 109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next()); 110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv 111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next()); 112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv 113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next()); 114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv 115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next()); 116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv 117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next()); 118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv 119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next()); 120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv 121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next()); 122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv 123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next()); 124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv 125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next()); 126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv 127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next()); 128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv 129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next()); 130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv 131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next()); 132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv 133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next()); 134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv 135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next()); 136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv 137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next()); 138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv 139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next()); 140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv 141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next()); 142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv 143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next()); 144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv 145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next()); 146 147 148 // ---------------------------- 149 // Float/Double Registers 150 // ---------------------------- 151 152 // Double Registers 153 // The rules of ADL require that double registers be defined in pairs. 154 // Each pair must be two 32-bit values, but not necessarily a pair of 155 // single float registers. In each pair, ADLC-assigned register numbers 156 // must be adjacent, with the lower number even. Finally, when the 157 // CPU stores such a register pair to memory, the word associated with 158 // the lower ADLC-assigned number must be stored to the lower address. 159 160 // PPC64 has 32 64-bit floating-point registers. Each can store a single 161 // or double precision floating-point value. 162 163 // types: v = volatile, nv = non-volatile, s = system 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch 165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret 167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2 169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3 171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4 173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5 175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6 177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7 179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8 181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9 183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10 185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next()); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11 187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next()); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12 189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next()); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13 191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next()); 192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv 193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next()); 194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv 195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next()); 196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv 197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next()); 198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv 199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next()); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv 201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next()); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv 203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next()); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv 205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next()); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv 207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next()); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv 209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next()); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv 211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next()); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv 213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next()); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv 215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next()); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv 217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next()); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv 219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next()); 220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv 221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next()); 222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv 223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next()); 224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv 225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next()); 226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv 227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next()); 228 229 // ---------------------------- 230 // Special Registers 231 // ---------------------------- 232 233 // Condition Codes Flag Registers 234 235 // PPC64 has 8 condition code "registers" which are all contained 236 // in the CR register. 237 238 // types: v = volatile, nv = non-volatile, s = system 239 reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v 240 reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v 241 reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv 242 reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv 243 reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv 244 reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v 245 reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v 246 reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg()); // v 247 248 // Special registers of PPC64 249 250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v 251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v 252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v 253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v 254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v 255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v 256 257 // ---------------------------- 258 // Vector-Scalar Registers 259 // ---------------------------- 260 reg_def VSR0 ( SOC, SOC, Op_VecX, 0, NULL); 261 reg_def VSR1 ( SOC, SOC, Op_VecX, 1, NULL); 262 reg_def VSR2 ( SOC, SOC, Op_VecX, 2, NULL); 263 reg_def VSR3 ( SOC, SOC, Op_VecX, 3, NULL); 264 reg_def VSR4 ( SOC, SOC, Op_VecX, 4, NULL); 265 reg_def VSR5 ( SOC, SOC, Op_VecX, 5, NULL); 266 reg_def VSR6 ( SOC, SOC, Op_VecX, 6, NULL); 267 reg_def VSR7 ( SOC, SOC, Op_VecX, 7, NULL); 268 reg_def VSR8 ( SOC, SOC, Op_VecX, 8, NULL); 269 reg_def VSR9 ( SOC, SOC, Op_VecX, 9, NULL); 270 reg_def VSR10 ( SOC, SOC, Op_VecX, 10, NULL); 271 reg_def VSR11 ( SOC, SOC, Op_VecX, 11, NULL); 272 reg_def VSR12 ( SOC, SOC, Op_VecX, 12, NULL); 273 reg_def VSR13 ( SOC, SOC, Op_VecX, 13, NULL); 274 reg_def VSR14 ( SOC, SOC, Op_VecX, 14, NULL); 275 reg_def VSR15 ( SOC, SOC, Op_VecX, 15, NULL); 276 reg_def VSR16 ( SOC, SOC, Op_VecX, 16, NULL); 277 reg_def VSR17 ( SOC, SOC, Op_VecX, 17, NULL); 278 reg_def VSR18 ( SOC, SOC, Op_VecX, 18, NULL); 279 reg_def VSR19 ( SOC, SOC, Op_VecX, 19, NULL); 280 reg_def VSR20 ( SOC, SOC, Op_VecX, 20, NULL); 281 reg_def VSR21 ( SOC, SOC, Op_VecX, 21, NULL); 282 reg_def VSR22 ( SOC, SOC, Op_VecX, 22, NULL); 283 reg_def VSR23 ( SOC, SOC, Op_VecX, 23, NULL); 284 reg_def VSR24 ( SOC, SOC, Op_VecX, 24, NULL); 285 reg_def VSR25 ( SOC, SOC, Op_VecX, 25, NULL); 286 reg_def VSR26 ( SOC, SOC, Op_VecX, 26, NULL); 287 reg_def VSR27 ( SOC, SOC, Op_VecX, 27, NULL); 288 reg_def VSR28 ( SOC, SOC, Op_VecX, 28, NULL); 289 reg_def VSR29 ( SOC, SOC, Op_VecX, 29, NULL); 290 reg_def VSR30 ( SOC, SOC, Op_VecX, 30, NULL); 291 reg_def VSR31 ( SOC, SOC, Op_VecX, 31, NULL); 292 reg_def VSR32 ( SOC, SOC, Op_VecX, 32, NULL); 293 reg_def VSR33 ( SOC, SOC, Op_VecX, 33, NULL); 294 reg_def VSR34 ( SOC, SOC, Op_VecX, 34, NULL); 295 reg_def VSR35 ( SOC, SOC, Op_VecX, 35, NULL); 296 reg_def VSR36 ( SOC, SOC, Op_VecX, 36, NULL); 297 reg_def VSR37 ( SOC, SOC, Op_VecX, 37, NULL); 298 reg_def VSR38 ( SOC, SOC, Op_VecX, 38, NULL); 299 reg_def VSR39 ( SOC, SOC, Op_VecX, 39, NULL); 300 reg_def VSR40 ( SOC, SOC, Op_VecX, 40, NULL); 301 reg_def VSR41 ( SOC, SOC, Op_VecX, 41, NULL); 302 reg_def VSR42 ( SOC, SOC, Op_VecX, 42, NULL); 303 reg_def VSR43 ( SOC, SOC, Op_VecX, 43, NULL); 304 reg_def VSR44 ( SOC, SOC, Op_VecX, 44, NULL); 305 reg_def VSR45 ( SOC, SOC, Op_VecX, 45, NULL); 306 reg_def VSR46 ( SOC, SOC, Op_VecX, 46, NULL); 307 reg_def VSR47 ( SOC, SOC, Op_VecX, 47, NULL); 308 reg_def VSR48 ( SOC, SOC, Op_VecX, 48, NULL); 309 reg_def VSR49 ( SOC, SOC, Op_VecX, 49, NULL); 310 reg_def VSR50 ( SOC, SOC, Op_VecX, 50, NULL); 311 reg_def VSR51 ( SOC, SOC, Op_VecX, 51, NULL); 312 reg_def VSR52 ( SOC, SOC, Op_VecX, 52, NULL); 313 reg_def VSR53 ( SOC, SOC, Op_VecX, 53, NULL); 314 reg_def VSR54 ( SOC, SOC, Op_VecX, 54, NULL); 315 reg_def VSR55 ( SOC, SOC, Op_VecX, 55, NULL); 316 reg_def VSR56 ( SOC, SOC, Op_VecX, 56, NULL); 317 reg_def VSR57 ( SOC, SOC, Op_VecX, 57, NULL); 318 reg_def VSR58 ( SOC, SOC, Op_VecX, 58, NULL); 319 reg_def VSR59 ( SOC, SOC, Op_VecX, 59, NULL); 320 reg_def VSR60 ( SOC, SOC, Op_VecX, 60, NULL); 321 reg_def VSR61 ( SOC, SOC, Op_VecX, 61, NULL); 322 reg_def VSR62 ( SOC, SOC, Op_VecX, 62, NULL); 323 reg_def VSR63 ( SOC, SOC, Op_VecX, 63, NULL); 324 325 // ---------------------------- 326 // Specify priority of register selection within phases of register 327 // allocation. Highest priority is first. A useful heuristic is to 328 // give registers a low priority when they are required by machine 329 // instructions, like EAX and EDX on I486, and choose no-save registers 330 // before save-on-call, & save-on-call before save-on-entry. Registers 331 // which participate in fixed calling sequences should come last. 332 // Registers which are used as pairs must fall on an even boundary. 333 334 // It's worth about 1% on SPEC geomean to get this right. 335 336 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 337 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 338 // R3_num. Therefore, R3_num may not be (and in reality is not) 339 // the same as R3->encoding()! Furthermore, we cannot make any 340 // assumptions on ordering, e.g. R3_num may be less than R2_num. 341 // Additionally, the function 342 // static enum RC rc_class(OptoReg::Name reg ) 343 // maps a given <register>_num value to its chunk type (except for flags) 344 // and its current implementation relies on chunk0 and chunk1 having a 345 // size of 64 each. 346 347 // If you change this allocation class, please have a look at the 348 // default values for the parameters RoundRobinIntegerRegIntervalStart 349 // and RoundRobinFloatRegIntervalStart 350 351 alloc_class chunk0 ( 352 // Chunk0 contains *all* 64 integer registers halves. 353 354 // "non-volatile" registers 355 R14, R14_H, 356 R15, R15_H, 357 R17, R17_H, 358 R18, R18_H, 359 R19, R19_H, 360 R20, R20_H, 361 R21, R21_H, 362 R22, R22_H, 363 R23, R23_H, 364 R24, R24_H, 365 R25, R25_H, 366 R26, R26_H, 367 R27, R27_H, 368 R28, R28_H, 369 R29, R29_H, 370 R30, R30_H, 371 R31, R31_H, 372 373 // scratch/special registers 374 R11, R11_H, 375 R12, R12_H, 376 377 // argument registers 378 R10, R10_H, 379 R9, R9_H, 380 R8, R8_H, 381 R7, R7_H, 382 R6, R6_H, 383 R5, R5_H, 384 R4, R4_H, 385 R3, R3_H, 386 387 // special registers, not available for allocation 388 R16, R16_H, // R16_thread 389 R13, R13_H, // system thread id 390 R2, R2_H, // may be used for TOC 391 R1, R1_H, // SP 392 R0, R0_H // R0 (scratch) 393 ); 394 395 // If you change this allocation class, please have a look at the 396 // default values for the parameters RoundRobinIntegerRegIntervalStart 397 // and RoundRobinFloatRegIntervalStart 398 399 alloc_class chunk1 ( 400 // Chunk1 contains *all* 64 floating-point registers halves. 401 402 // scratch register 403 F0, F0_H, 404 405 // argument registers 406 F13, F13_H, 407 F12, F12_H, 408 F11, F11_H, 409 F10, F10_H, 410 F9, F9_H, 411 F8, F8_H, 412 F7, F7_H, 413 F6, F6_H, 414 F5, F5_H, 415 F4, F4_H, 416 F3, F3_H, 417 F2, F2_H, 418 F1, F1_H, 419 420 // non-volatile registers 421 F14, F14_H, 422 F15, F15_H, 423 F16, F16_H, 424 F17, F17_H, 425 F18, F18_H, 426 F19, F19_H, 427 F20, F20_H, 428 F21, F21_H, 429 F22, F22_H, 430 F23, F23_H, 431 F24, F24_H, 432 F25, F25_H, 433 F26, F26_H, 434 F27, F27_H, 435 F28, F28_H, 436 F29, F29_H, 437 F30, F30_H, 438 F31, F31_H 439 ); 440 441 alloc_class chunk2 ( 442 // Chunk2 contains *all* 8 condition code registers. 443 444 CCR0, 445 CCR1, 446 CCR2, 447 CCR3, 448 CCR4, 449 CCR5, 450 CCR6, 451 CCR7 452 ); 453 454 alloc_class chunk3 ( 455 VSR0, 456 VSR1, 457 VSR2, 458 VSR3, 459 VSR4, 460 VSR5, 461 VSR6, 462 VSR7, 463 VSR8, 464 VSR9, 465 VSR10, 466 VSR11, 467 VSR12, 468 VSR13, 469 VSR14, 470 VSR15, 471 VSR16, 472 VSR17, 473 VSR18, 474 VSR19, 475 VSR20, 476 VSR21, 477 VSR22, 478 VSR23, 479 VSR24, 480 VSR25, 481 VSR26, 482 VSR27, 483 VSR28, 484 VSR29, 485 VSR30, 486 VSR31, 487 VSR32, 488 VSR33, 489 VSR34, 490 VSR35, 491 VSR36, 492 VSR37, 493 VSR38, 494 VSR39, 495 VSR40, 496 VSR41, 497 VSR42, 498 VSR43, 499 VSR44, 500 VSR45, 501 VSR46, 502 VSR47, 503 VSR48, 504 VSR49, 505 VSR50, 506 VSR51, 507 VSR52, 508 VSR53, 509 VSR54, 510 VSR55, 511 VSR56, 512 VSR57, 513 VSR58, 514 VSR59, 515 VSR60, 516 VSR61, 517 VSR62, 518 VSR63 519 ); 520 521 alloc_class chunk4 ( 522 // special registers 523 // These registers are not allocated, but used for nodes generated by postalloc expand. 524 SR_XER, 525 SR_LR, 526 SR_CTR, 527 SR_VRSAVE, 528 SR_SPEFSCR, 529 SR_PPR 530 ); 531 532 //-------Architecture Description Register Classes----------------------- 533 534 // Several register classes are automatically defined based upon 535 // information in this architecture description. 536 537 // 1) reg_class inline_cache_reg ( as defined in frame section ) 538 // 2) reg_class compiler_method_oop_reg ( as defined in frame section ) 539 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 540 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 541 // 542 543 // ---------------------------- 544 // 32 Bit Register Classes 545 // ---------------------------- 546 547 // We specify registers twice, once as read/write, and once read-only. 548 // We use the read-only registers for source operands. With this, we 549 // can include preset read only registers in this class, as a hard-coded 550 // '0'-register. (We used to simulate this on ppc.) 551 552 // 32 bit registers that can be read and written i.e. these registers 553 // can be dest (or src) of normal instructions. 554 reg_class bits32_reg_rw( 555 /*R0*/ // R0 556 /*R1*/ // SP 557 R2, // TOC 558 R3, 559 R4, 560 R5, 561 R6, 562 R7, 563 R8, 564 R9, 565 R10, 566 R11, 567 R12, 568 /*R13*/ // system thread id 569 R14, 570 R15, 571 /*R16*/ // R16_thread 572 R17, 573 R18, 574 R19, 575 R20, 576 R21, 577 R22, 578 R23, 579 R24, 580 R25, 581 R26, 582 R27, 583 R28, 584 /*R29,*/ // global TOC 585 R30, 586 R31 587 ); 588 589 // 32 bit registers that can only be read i.e. these registers can 590 // only be src of all instructions. 591 reg_class bits32_reg_ro( 592 /*R0*/ // R0 593 /*R1*/ // SP 594 R2 // TOC 595 R3, 596 R4, 597 R5, 598 R6, 599 R7, 600 R8, 601 R9, 602 R10, 603 R11, 604 R12, 605 /*R13*/ // system thread id 606 R14, 607 R15, 608 /*R16*/ // R16_thread 609 R17, 610 R18, 611 R19, 612 R20, 613 R21, 614 R22, 615 R23, 616 R24, 617 R25, 618 R26, 619 R27, 620 R28, 621 /*R29,*/ 622 R30, 623 R31 624 ); 625 626 reg_class rscratch1_bits32_reg(R11); 627 reg_class rscratch2_bits32_reg(R12); 628 reg_class rarg1_bits32_reg(R3); 629 reg_class rarg2_bits32_reg(R4); 630 reg_class rarg3_bits32_reg(R5); 631 reg_class rarg4_bits32_reg(R6); 632 633 // ---------------------------- 634 // 64 Bit Register Classes 635 // ---------------------------- 636 // 64-bit build means 64-bit pointers means hi/lo pairs 637 638 reg_class rscratch1_bits64_reg(R11_H, R11); 639 reg_class rscratch2_bits64_reg(R12_H, R12); 640 reg_class rarg1_bits64_reg(R3_H, R3); 641 reg_class rarg2_bits64_reg(R4_H, R4); 642 reg_class rarg3_bits64_reg(R5_H, R5); 643 reg_class rarg4_bits64_reg(R6_H, R6); 644 // Thread register, 'written' by tlsLoadP, see there. 645 reg_class thread_bits64_reg(R16_H, R16); 646 647 reg_class r19_bits64_reg(R19_H, R19); 648 649 // 64 bit registers that can be read and written i.e. these registers 650 // can be dest (or src) of normal instructions. 651 reg_class bits64_reg_rw( 652 /*R0_H, R0*/ // R0 653 /*R1_H, R1*/ // SP 654 R2_H, R2, // TOC 655 R3_H, R3, 656 R4_H, R4, 657 R5_H, R5, 658 R6_H, R6, 659 R7_H, R7, 660 R8_H, R8, 661 R9_H, R9, 662 R10_H, R10, 663 R11_H, R11, 664 R12_H, R12, 665 /*R13_H, R13*/ // system thread id 666 R14_H, R14, 667 R15_H, R15, 668 /*R16_H, R16*/ // R16_thread 669 R17_H, R17, 670 R18_H, R18, 671 R19_H, R19, 672 R20_H, R20, 673 R21_H, R21, 674 R22_H, R22, 675 R23_H, R23, 676 R24_H, R24, 677 R25_H, R25, 678 R26_H, R26, 679 R27_H, R27, 680 R28_H, R28, 681 /*R29_H, R29,*/ 682 R30_H, R30, 683 R31_H, R31 684 ); 685 686 // 64 bit registers used excluding r2, r11 and r12 687 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses 688 // r2, r11 and r12 internally. 689 reg_class bits64_reg_leaf_call( 690 /*R0_H, R0*/ // R0 691 /*R1_H, R1*/ // SP 692 /*R2_H, R2*/ // TOC 693 R3_H, R3, 694 R4_H, R4, 695 R5_H, R5, 696 R6_H, R6, 697 R7_H, R7, 698 R8_H, R8, 699 R9_H, R9, 700 R10_H, R10, 701 /*R11_H, R11*/ 702 /*R12_H, R12*/ 703 /*R13_H, R13*/ // system thread id 704 R14_H, R14, 705 R15_H, R15, 706 /*R16_H, R16*/ // R16_thread 707 R17_H, R17, 708 R18_H, R18, 709 R19_H, R19, 710 R20_H, R20, 711 R21_H, R21, 712 R22_H, R22, 713 R23_H, R23, 714 R24_H, R24, 715 R25_H, R25, 716 R26_H, R26, 717 R27_H, R27, 718 R28_H, R28, 719 /*R29_H, R29,*/ 720 R30_H, R30, 721 R31_H, R31 722 ); 723 724 // Used to hold the TOC to avoid collisions with expanded DynamicCall 725 // which uses r19 as inline cache internally and expanded LeafCall which uses 726 // r2, r11 and r12 internally. 727 reg_class bits64_constant_table_base( 728 /*R0_H, R0*/ // R0 729 /*R1_H, R1*/ // SP 730 /*R2_H, R2*/ // TOC 731 R3_H, R3, 732 R4_H, R4, 733 R5_H, R5, 734 R6_H, R6, 735 R7_H, R7, 736 R8_H, R8, 737 R9_H, R9, 738 R10_H, R10, 739 /*R11_H, R11*/ 740 /*R12_H, R12*/ 741 /*R13_H, R13*/ // system thread id 742 R14_H, R14, 743 R15_H, R15, 744 /*R16_H, R16*/ // R16_thread 745 R17_H, R17, 746 R18_H, R18, 747 /*R19_H, R19*/ 748 R20_H, R20, 749 R21_H, R21, 750 R22_H, R22, 751 R23_H, R23, 752 R24_H, R24, 753 R25_H, R25, 754 R26_H, R26, 755 R27_H, R27, 756 R28_H, R28, 757 /*R29_H, R29,*/ 758 R30_H, R30, 759 R31_H, R31 760 ); 761 762 // 64 bit registers that can only be read i.e. these registers can 763 // only be src of all instructions. 764 reg_class bits64_reg_ro( 765 /*R0_H, R0*/ // R0 766 R1_H, R1, 767 R2_H, R2, // TOC 768 R3_H, R3, 769 R4_H, R4, 770 R5_H, R5, 771 R6_H, R6, 772 R7_H, R7, 773 R8_H, R8, 774 R9_H, R9, 775 R10_H, R10, 776 R11_H, R11, 777 R12_H, R12, 778 /*R13_H, R13*/ // system thread id 779 R14_H, R14, 780 R15_H, R15, 781 R16_H, R16, // R16_thread 782 R17_H, R17, 783 R18_H, R18, 784 R19_H, R19, 785 R20_H, R20, 786 R21_H, R21, 787 R22_H, R22, 788 R23_H, R23, 789 R24_H, R24, 790 R25_H, R25, 791 R26_H, R26, 792 R27_H, R27, 793 R28_H, R28, 794 /*R29_H, R29,*/ // TODO: let allocator handle TOC!! 795 R30_H, R30, 796 R31_H, R31 797 ); 798 799 800 // ---------------------------- 801 // Special Class for Condition Code Flags Register 802 803 reg_class int_flags( 804 /*CCR0*/ // scratch 805 /*CCR1*/ // scratch 806 /*CCR2*/ // nv! 807 /*CCR3*/ // nv! 808 /*CCR4*/ // nv! 809 CCR5, 810 CCR6, 811 CCR7 812 ); 813 814 reg_class int_flags_ro( 815 CCR0, 816 CCR1, 817 CCR2, 818 CCR3, 819 CCR4, 820 CCR5, 821 CCR6, 822 CCR7 823 ); 824 825 reg_class int_flags_CR0(CCR0); 826 reg_class int_flags_CR1(CCR1); 827 reg_class int_flags_CR6(CCR6); 828 reg_class ctr_reg(SR_CTR); 829 830 // ---------------------------- 831 // Float Register Classes 832 // ---------------------------- 833 834 reg_class flt_reg( 835 F0, 836 F1, 837 F2, 838 F3, 839 F4, 840 F5, 841 F6, 842 F7, 843 F8, 844 F9, 845 F10, 846 F11, 847 F12, 848 F13, 849 F14, // nv! 850 F15, // nv! 851 F16, // nv! 852 F17, // nv! 853 F18, // nv! 854 F19, // nv! 855 F20, // nv! 856 F21, // nv! 857 F22, // nv! 858 F23, // nv! 859 F24, // nv! 860 F25, // nv! 861 F26, // nv! 862 F27, // nv! 863 F28, // nv! 864 F29, // nv! 865 F30, // nv! 866 F31 // nv! 867 ); 868 869 // Double precision float registers have virtual `high halves' that 870 // are needed by the allocator. 871 reg_class dbl_reg( 872 F0, F0_H, 873 F1, F1_H, 874 F2, F2_H, 875 F3, F3_H, 876 F4, F4_H, 877 F5, F5_H, 878 F6, F6_H, 879 F7, F7_H, 880 F8, F8_H, 881 F9, F9_H, 882 F10, F10_H, 883 F11, F11_H, 884 F12, F12_H, 885 F13, F13_H, 886 F14, F14_H, // nv! 887 F15, F15_H, // nv! 888 F16, F16_H, // nv! 889 F17, F17_H, // nv! 890 F18, F18_H, // nv! 891 F19, F19_H, // nv! 892 F20, F20_H, // nv! 893 F21, F21_H, // nv! 894 F22, F22_H, // nv! 895 F23, F23_H, // nv! 896 F24, F24_H, // nv! 897 F25, F25_H, // nv! 898 F26, F26_H, // nv! 899 F27, F27_H, // nv! 900 F28, F28_H, // nv! 901 F29, F29_H, // nv! 902 F30, F30_H, // nv! 903 F31, F31_H // nv! 904 ); 905 906 // ---------------------------- 907 // Vector-Scalar Register Class 908 // ---------------------------- 909 910 reg_class vs_reg( 911 // Attention: Only these ones are saved & restored at safepoint by RegisterSaver. 912 VSR32, 913 VSR33, 914 VSR34, 915 VSR35, 916 VSR36, 917 VSR37, 918 VSR38, 919 VSR39, 920 VSR40, 921 VSR41, 922 VSR42, 923 VSR43, 924 VSR44, 925 VSR45, 926 VSR46, 927 VSR47, 928 VSR48, 929 VSR49, 930 VSR50, 931 VSR51 932 // VSR52-VSR63 // nv! 933 ); 934 935 %} 936 937 //----------DEFINITION BLOCK--------------------------------------------------- 938 // Define name --> value mappings to inform the ADLC of an integer valued name 939 // Current support includes integer values in the range [0, 0x7FFFFFFF] 940 // Format: 941 // int_def <name> ( <int_value>, <expression>); 942 // Generated Code in ad_<arch>.hpp 943 // #define <name> (<expression>) 944 // // value == <int_value> 945 // Generated code in ad_<arch>.cpp adlc_verification() 946 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 947 // 948 definitions %{ 949 // The default cost (of an ALU instruction). 950 int_def DEFAULT_COST_LOW ( 30, 30); 951 int_def DEFAULT_COST ( 100, 100); 952 int_def HUGE_COST (1000000, 1000000); 953 954 // Memory refs 955 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 956 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 957 958 // Branches are even more expensive. 959 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 960 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 961 %} 962 963 964 //----------SOURCE BLOCK------------------------------------------------------- 965 // This is a block of C++ code which provides values, functions, and 966 // definitions necessary in the rest of the architecture description. 967 source_hpp %{ 968 // Header information of the source block. 969 // Method declarations/definitions which are used outside 970 // the ad-scope can conveniently be defined here. 971 // 972 // To keep related declarations/definitions/uses close together, 973 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 974 975 // Returns true if Node n is followed by a MemBar node that 976 // will do an acquire. If so, this node must not do the acquire 977 // operation. 978 bool followed_by_acquire(const Node *n); 979 %} 980 981 source %{ 982 983 // Should the Matcher clone shifts on addressing modes, expecting them 984 // to be subsumed into complex addressing expressions or compute them 985 // into registers? 986 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 987 return clone_base_plus_offset_address(m, mstack, address_visited); 988 } 989 990 void Compile::reshape_address(AddPNode* addp) { 991 } 992 993 // Optimize load-acquire. 994 // 995 // Check if acquire is unnecessary due to following operation that does 996 // acquire anyways. 997 // Walk the pattern: 998 // 999 // n: Load.acq 1000 // | 1001 // MemBarAcquire 1002 // | | 1003 // Proj(ctrl) Proj(mem) 1004 // | | 1005 // MemBarRelease/Volatile 1006 // 1007 bool followed_by_acquire(const Node *load) { 1008 assert(load->is_Load(), "So far implemented only for loads."); 1009 1010 // Find MemBarAcquire. 1011 const Node *mba = NULL; 1012 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 1013 const Node *out = load->fast_out(i); 1014 if (out->Opcode() == Op_MemBarAcquire) { 1015 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 1016 mba = out; 1017 break; 1018 } 1019 } 1020 if (!mba) return false; 1021 1022 // Find following MemBar node. 1023 // 1024 // The following node must be reachable by control AND memory 1025 // edge to assure no other operations are in between the two nodes. 1026 // 1027 // So first get the Proj node, mem_proj, to use it to iterate forward. 1028 Node *mem_proj = NULL; 1029 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 1030 mem_proj = mba->fast_out(i); // Runs out of bounds and asserts if Proj not found. 1031 assert(mem_proj->is_Proj(), "only projections here"); 1032 ProjNode *proj = mem_proj->as_Proj(); 1033 if (proj->_con == TypeFunc::Memory && 1034 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 1035 break; 1036 } 1037 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 1038 1039 // Search MemBar behind Proj. If there are other memory operations 1040 // behind the Proj we lost. 1041 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 1042 Node *x = mem_proj->fast_out(j); 1043 // Proj might have an edge to a store or load node which precedes the membar. 1044 if (x->is_Mem()) return false; 1045 1046 // On PPC64 release and volatile are implemented by an instruction 1047 // that also has acquire semantics. I.e. there is no need for an 1048 // acquire before these. 1049 int xop = x->Opcode(); 1050 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 1051 // Make sure we're not missing Call/Phi/MergeMem by checking 1052 // control edges. The control edge must directly lead back 1053 // to the MemBarAcquire 1054 Node *ctrl_proj = x->in(0); 1055 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 1056 return true; 1057 } 1058 } 1059 } 1060 1061 return false; 1062 } 1063 1064 #define __ _masm. 1065 1066 // Tertiary op of a LoadP or StoreP encoding. 1067 #define REGP_OP true 1068 1069 // **************************************************************************** 1070 1071 // REQUIRED FUNCTIONALITY 1072 1073 // !!!!! Special hack to get all type of calls to specify the byte offset 1074 // from the start of the call to the point where the return address 1075 // will point. 1076 1077 // PPC port: Removed use of lazy constant construct. 1078 1079 int MachCallStaticJavaNode::ret_addr_offset() { 1080 // It's only a single branch-and-link instruction. 1081 return 4; 1082 } 1083 1084 int MachCallDynamicJavaNode::ret_addr_offset() { 1085 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 1086 // postalloc expanded calls if we use inline caches and do not update method data. 1087 if (UseInlineCaches) 1088 return 4; 1089 1090 int vtable_index = this->_vtable_index; 1091 if (vtable_index < 0) { 1092 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 1093 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 1094 return 12; 1095 } else { 1096 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 1097 return 24; 1098 } 1099 } 1100 1101 int MachCallRuntimeNode::ret_addr_offset() { 1102 #if defined(ABI_ELFv2) 1103 return 28; 1104 #else 1105 return 40; 1106 #endif 1107 } 1108 1109 //============================================================================= 1110 1111 // condition code conversions 1112 1113 static int cc_to_boint(int cc) { 1114 return Assembler::bcondCRbiIs0 | (cc & 8); 1115 } 1116 1117 static int cc_to_inverse_boint(int cc) { 1118 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 1119 } 1120 1121 static int cc_to_biint(int cc, int flags_reg) { 1122 return (flags_reg << 2) | (cc & 3); 1123 } 1124 1125 //============================================================================= 1126 1127 // Compute padding required for nodes which need alignment. The padding 1128 // is the number of bytes (not instructions) which will be inserted before 1129 // the instruction. The padding must match the size of a NOP instruction. 1130 1131 // Currently not used on this platform. 1132 1133 //============================================================================= 1134 1135 // Indicate if the safepoint node needs the polling page as an input. 1136 bool SafePointNode::needs_polling_address_input() { 1137 // The address is loaded from thread by a seperate node. 1138 return true; 1139 } 1140 1141 //============================================================================= 1142 1143 // Emit an interrupt that is caught by the debugger (for debugging compiler). 1144 void emit_break(CodeBuffer &cbuf) { 1145 MacroAssembler _masm(&cbuf); 1146 __ illtrap(); 1147 } 1148 1149 #ifndef PRODUCT 1150 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1151 st->print("BREAKPOINT"); 1152 } 1153 #endif 1154 1155 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1156 emit_break(cbuf); 1157 } 1158 1159 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1160 return MachNode::size(ra_); 1161 } 1162 1163 //============================================================================= 1164 1165 void emit_nop(CodeBuffer &cbuf) { 1166 MacroAssembler _masm(&cbuf); 1167 __ nop(); 1168 } 1169 1170 static inline void emit_long(CodeBuffer &cbuf, int value) { 1171 *((int*)(cbuf.insts_end())) = value; 1172 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1173 } 1174 1175 //============================================================================= 1176 1177 %} // interrupt source 1178 1179 source_hpp %{ // Header information of the source block. 1180 1181 //-------------------------------------------------------------- 1182 //---< Used for optimization in Compile::Shorten_branches >--- 1183 //-------------------------------------------------------------- 1184 1185 class CallStubImpl { 1186 1187 public: 1188 1189 // Emit call stub, compiled java to interpreter. 1190 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1191 1192 // Size of call trampoline stub. 1193 // This doesn't need to be accurate to the byte, but it 1194 // must be larger than or equal to the real size of the stub. 1195 static uint size_call_trampoline() { 1196 return MacroAssembler::trampoline_stub_size; 1197 } 1198 1199 // number of relocations needed by a call trampoline stub 1200 static uint reloc_call_trampoline() { 1201 return 5; 1202 } 1203 1204 }; 1205 1206 %} // end source_hpp 1207 1208 source %{ 1209 1210 // Emit a trampoline stub for a call to a target which is too far away. 1211 // 1212 // code sequences: 1213 // 1214 // call-site: 1215 // branch-and-link to <destination> or <trampoline stub> 1216 // 1217 // Related trampoline stub for this call-site in the stub section: 1218 // load the call target from the constant pool 1219 // branch via CTR (LR/link still points to the call-site above) 1220 1221 void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1222 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1223 if (stub == NULL) { 1224 ciEnv::current()->record_out_of_memory_failure(); 1225 } 1226 } 1227 1228 //============================================================================= 1229 1230 // Emit an inline branch-and-link call and a related trampoline stub. 1231 // 1232 // code sequences: 1233 // 1234 // call-site: 1235 // branch-and-link to <destination> or <trampoline stub> 1236 // 1237 // Related trampoline stub for this call-site in the stub section: 1238 // load the call target from the constant pool 1239 // branch via CTR (LR/link still points to the call-site above) 1240 // 1241 1242 typedef struct { 1243 int insts_call_instruction_offset; 1244 int ret_addr_offset; 1245 } EmitCallOffsets; 1246 1247 // Emit a branch-and-link instruction that branches to a trampoline. 1248 // - Remember the offset of the branch-and-link instruction. 1249 // - Add a relocation at the branch-and-link instruction. 1250 // - Emit a branch-and-link. 1251 // - Remember the return pc offset. 1252 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1253 EmitCallOffsets offsets = { -1, -1 }; 1254 const int start_offset = __ offset(); 1255 offsets.insts_call_instruction_offset = __ offset(); 1256 1257 // No entry point given, use the current pc. 1258 if (entry_point == NULL) entry_point = __ pc(); 1259 1260 // Put the entry point as a constant into the constant pool. 1261 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1262 if (entry_point_toc_addr == NULL) { 1263 ciEnv::current()->record_out_of_memory_failure(); 1264 return offsets; 1265 } 1266 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1267 1268 // Emit the trampoline stub which will be related to the branch-and-link below. 1269 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1270 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1271 __ relocate(rtype); 1272 1273 // Note: At this point we do not have the address of the trampoline 1274 // stub, and the entry point might be too far away for bl, so __ pc() 1275 // serves as dummy and the bl will be patched later. 1276 __ bl((address) __ pc()); 1277 1278 offsets.ret_addr_offset = __ offset() - start_offset; 1279 1280 return offsets; 1281 } 1282 1283 //============================================================================= 1284 1285 // Factory for creating loadConL* nodes for large/small constant pool. 1286 1287 static inline jlong replicate_immF(float con) { 1288 // Replicate float con 2 times and pack into vector. 1289 int val = *((int*)&con); 1290 jlong lval = val; 1291 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1292 return lval; 1293 } 1294 1295 //============================================================================= 1296 1297 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1298 int Compile::ConstantTable::calculate_table_base_offset() const { 1299 return 0; // absolute addressing, no offset 1300 } 1301 1302 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1303 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1304 iRegPdstOper *op_dst = new iRegPdstOper(); 1305 MachNode *m1 = new loadToc_hiNode(); 1306 MachNode *m2 = new loadToc_loNode(); 1307 1308 m1->add_req(NULL); 1309 m2->add_req(NULL, m1); 1310 m1->_opnds[0] = op_dst; 1311 m2->_opnds[0] = op_dst; 1312 m2->_opnds[1] = op_dst; 1313 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1314 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1315 nodes->push(m1); 1316 nodes->push(m2); 1317 } 1318 1319 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1320 // Is postalloc expanded. 1321 ShouldNotReachHere(); 1322 } 1323 1324 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1325 return 0; 1326 } 1327 1328 #ifndef PRODUCT 1329 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1330 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1331 } 1332 #endif 1333 1334 //============================================================================= 1335 1336 #ifndef PRODUCT 1337 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1338 Compile* C = ra_->C; 1339 const long framesize = C->frame_slots() << LogBytesPerInt; 1340 1341 st->print("PROLOG\n\t"); 1342 if (C->need_stack_bang(framesize)) { 1343 st->print("stack_overflow_check\n\t"); 1344 } 1345 1346 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1347 st->print("save return pc\n\t"); 1348 st->print("push frame %ld\n\t", -framesize); 1349 } 1350 } 1351 #endif 1352 1353 // Macro used instead of the common __ to emulate the pipes of PPC. 1354 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1355 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1356 // still no scheduling of this code is possible, the micro scheduler is aware of the 1357 // code and can update its internal data. The following mechanism is used to achieve this: 1358 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1359 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1360 #if 0 // TODO: PPC port 1361 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1362 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1363 _masm. 1364 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1365 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1366 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1367 C->hb_scheduling()->_pdScheduling->advance_offset 1368 #else 1369 #define ___(op) if (UsePower6SchedulerPPC64) \ 1370 Unimplemented(); \ 1371 _masm. 1372 #define ___stop if (UsePower6SchedulerPPC64) \ 1373 Unimplemented() 1374 #define ___advance if (UsePower6SchedulerPPC64) \ 1375 Unimplemented() 1376 #endif 1377 1378 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1379 Compile* C = ra_->C; 1380 MacroAssembler _masm(&cbuf); 1381 1382 const long framesize = C->frame_size_in_bytes(); 1383 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1384 1385 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1386 1387 const Register return_pc = R20; // Must match return_addr() in frame section. 1388 const Register callers_sp = R21; 1389 const Register push_frame_temp = R22; 1390 const Register toc_temp = R23; 1391 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1392 1393 if (method_is_frameless) { 1394 // Add nop at beginning of all frameless methods to prevent any 1395 // oop instructions from getting overwritten by make_not_entrant 1396 // (patching attempt would fail). 1397 ___(nop) nop(); 1398 } else { 1399 // Get return pc. 1400 ___(mflr) mflr(return_pc); 1401 } 1402 1403 // Calls to C2R adapters often do not accept exceptional returns. 1404 // We require that their callers must bang for them. But be 1405 // careful, because some VM calls (such as call site linkage) can 1406 // use several kilobytes of stack. But the stack safety zone should 1407 // account for that. See bugs 4446381, 4468289, 4497237. 1408 1409 int bangsize = C->bang_size_in_bytes(); 1410 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1411 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1412 // Unfortunately we cannot use the function provided in 1413 // assembler.cpp as we have to emulate the pipes. So I had to 1414 // insert the code of generate_stack_overflow_check(), see 1415 // assembler.cpp for some illuminative comments. 1416 const int page_size = os::vm_page_size(); 1417 int bang_end = JavaThread::stack_shadow_zone_size(); 1418 1419 // This is how far the previous frame's stack banging extended. 1420 const int bang_end_safe = bang_end; 1421 1422 if (bangsize > page_size) { 1423 bang_end += bangsize; 1424 } 1425 1426 int bang_offset = bang_end_safe; 1427 1428 while (bang_offset <= bang_end) { 1429 // Need at least one stack bang at end of shadow zone. 1430 1431 // Again I had to copy code, this time from assembler_ppc.cpp, 1432 // bang_stack_with_offset - see there for comments. 1433 1434 // Stack grows down, caller passes positive offset. 1435 assert(bang_offset > 0, "must bang with positive offset"); 1436 1437 long stdoffset = -bang_offset; 1438 1439 if (Assembler::is_simm(stdoffset, 16)) { 1440 // Signed 16 bit offset, a simple std is ok. 1441 if (UseLoadInstructionsForStackBangingPPC64) { 1442 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1443 } else { 1444 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1445 } 1446 } else if (Assembler::is_simm(stdoffset, 31)) { 1447 // Use largeoffset calculations for addis & ld/std. 1448 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1449 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1450 1451 Register tmp = R11; 1452 ___(addis) addis(tmp, R1_SP, hi); 1453 if (UseLoadInstructionsForStackBangingPPC64) { 1454 ___(ld) ld(R0, lo, tmp); 1455 } else { 1456 ___(std) std(R0, lo, tmp); 1457 } 1458 } else { 1459 ShouldNotReachHere(); 1460 } 1461 1462 bang_offset += page_size; 1463 } 1464 // R11 trashed 1465 } // C->need_stack_bang(framesize) && UseStackBanging 1466 1467 unsigned int bytes = (unsigned int)framesize; 1468 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1469 ciMethod *currMethod = C->method(); 1470 1471 // Optimized version for most common case. 1472 if (UsePower6SchedulerPPC64 && 1473 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1474 !(false /* ConstantsALot TODO: PPC port*/)) { 1475 ___(or) mr(callers_sp, R1_SP); 1476 ___(std) std(return_pc, _abi(lr), R1_SP); 1477 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1478 return; 1479 } 1480 1481 if (!method_is_frameless) { 1482 // Get callers sp. 1483 ___(or) mr(callers_sp, R1_SP); 1484 1485 // Push method's frame, modifies SP. 1486 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1487 // The ABI is already accounted for in 'framesize' via the 1488 // 'out_preserve' area. 1489 Register tmp = push_frame_temp; 1490 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1491 if (Assembler::is_simm(-offset, 16)) { 1492 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1493 } else { 1494 long x = -offset; 1495 // Had to insert load_const(tmp, -offset). 1496 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1497 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1498 ___(rldicr) sldi(tmp, tmp, 32); 1499 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1500 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1501 1502 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1503 } 1504 } 1505 #if 0 // TODO: PPC port 1506 // For testing large constant pools, emit a lot of constants to constant pool. 1507 // "Randomize" const_size. 1508 if (ConstantsALot) { 1509 const int num_consts = const_size(); 1510 for (int i = 0; i < num_consts; i++) { 1511 __ long_constant(0xB0B5B00BBABE); 1512 } 1513 } 1514 #endif 1515 if (!method_is_frameless) { 1516 // Save return pc. 1517 ___(std) std(return_pc, _abi(lr), callers_sp); 1518 } 1519 1520 C->set_frame_complete(cbuf.insts_size()); 1521 } 1522 #undef ___ 1523 #undef ___stop 1524 #undef ___advance 1525 1526 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1527 // Variable size. determine dynamically. 1528 return MachNode::size(ra_); 1529 } 1530 1531 int MachPrologNode::reloc() const { 1532 // Return number of relocatable values contained in this instruction. 1533 return 1; // 1 reloc entry for load_const(toc). 1534 } 1535 1536 //============================================================================= 1537 1538 #ifndef PRODUCT 1539 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1540 Compile* C = ra_->C; 1541 1542 st->print("EPILOG\n\t"); 1543 st->print("restore return pc\n\t"); 1544 st->print("pop frame\n\t"); 1545 1546 if (do_polling() && C->is_method_compilation()) { 1547 st->print("touch polling page\n\t"); 1548 } 1549 } 1550 #endif 1551 1552 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1553 Compile* C = ra_->C; 1554 MacroAssembler _masm(&cbuf); 1555 1556 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1557 assert(framesize >= 0, "negative frame-size?"); 1558 1559 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1560 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1561 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1562 const Register polling_page = R12; 1563 1564 if (!method_is_frameless) { 1565 // Restore return pc relative to callers' sp. 1566 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1567 } 1568 1569 if (method_needs_polling) { 1570 if (SafepointMechanism::uses_thread_local_poll()) { 1571 __ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread); 1572 } else { 1573 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); 1574 } 1575 } 1576 1577 if (!method_is_frameless) { 1578 // Move return pc to LR. 1579 __ mtlr(return_pc); 1580 // Pop frame (fixed frame-size). 1581 __ addi(R1_SP, R1_SP, (int)framesize); 1582 } 1583 1584 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1585 __ reserved_stack_check(return_pc); 1586 } 1587 1588 if (method_needs_polling) { 1589 // We need to mark the code position where the load from the safepoint 1590 // polling page was emitted as relocInfo::poll_return_type here. 1591 __ relocate(relocInfo::poll_return_type); 1592 __ load_from_polling_page(polling_page); 1593 } 1594 } 1595 1596 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1597 // Variable size. Determine dynamically. 1598 return MachNode::size(ra_); 1599 } 1600 1601 int MachEpilogNode::reloc() const { 1602 // Return number of relocatable values contained in this instruction. 1603 return 1; // 1 for load_from_polling_page. 1604 } 1605 1606 const Pipeline * MachEpilogNode::pipeline() const { 1607 return MachNode::pipeline_class(); 1608 } 1609 1610 // This method seems to be obsolete. It is declared in machnode.hpp 1611 // and defined in all *.ad files, but it is never called. Should we 1612 // get rid of it? 1613 int MachEpilogNode::safepoint_offset() const { 1614 assert(do_polling(), "no return for this epilog node"); 1615 return 0; 1616 } 1617 1618 #if 0 // TODO: PPC port 1619 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1620 MacroAssembler _masm(&cbuf); 1621 if (LoadPollAddressFromThread) { 1622 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1623 } else { 1624 _masm.nop(); 1625 } 1626 } 1627 1628 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1629 if (LoadPollAddressFromThread) { 1630 return 4; 1631 } else { 1632 return 4; 1633 } 1634 } 1635 1636 #ifndef PRODUCT 1637 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1638 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1639 } 1640 #endif 1641 1642 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1643 return RSCRATCH1_BITS64_REG_mask(); 1644 } 1645 #endif // PPC port 1646 1647 // ============================================================================= 1648 1649 // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or 1650 // rc_stack. 1651 enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack }; 1652 1653 static enum RC rc_class(OptoReg::Name reg) { 1654 // Return the register class for the given register. The given register 1655 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1656 // enumeration in adGlobals_ppc.hpp. 1657 1658 if (reg == OptoReg::Bad) return rc_bad; 1659 1660 // We have 64 integer register halves, starting at index 0. 1661 if (reg < 64) return rc_int; 1662 1663 // We have 64 floating-point register halves, starting at index 64. 1664 if (reg < 64+64) return rc_float; 1665 1666 // We have 64 vector-scalar registers, starting at index 128. 1667 if (reg < 64+64+64) return rc_vs; 1668 1669 // Between float regs & stack are the flags regs. 1670 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1671 1672 return rc_stack; 1673 } 1674 1675 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1676 bool do_print, Compile* C, outputStream *st) { 1677 1678 assert(opcode == Assembler::LD_OPCODE || 1679 opcode == Assembler::STD_OPCODE || 1680 opcode == Assembler::LWZ_OPCODE || 1681 opcode == Assembler::STW_OPCODE || 1682 opcode == Assembler::LFD_OPCODE || 1683 opcode == Assembler::STFD_OPCODE || 1684 opcode == Assembler::LFS_OPCODE || 1685 opcode == Assembler::STFS_OPCODE, 1686 "opcode not supported"); 1687 1688 if (cbuf) { 1689 int d = 1690 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1691 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1692 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1693 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1694 } 1695 #ifndef PRODUCT 1696 else if (do_print) { 1697 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1698 op_str, 1699 Matcher::regName[reg], 1700 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1701 } 1702 #endif 1703 return 4; // size 1704 } 1705 1706 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1707 Compile* C = ra_->C; 1708 1709 // Get registers to move. 1710 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1711 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1712 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1713 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1714 1715 enum RC src_hi_rc = rc_class(src_hi); 1716 enum RC src_lo_rc = rc_class(src_lo); 1717 enum RC dst_hi_rc = rc_class(dst_hi); 1718 enum RC dst_lo_rc = rc_class(dst_lo); 1719 1720 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1721 if (src_hi != OptoReg::Bad) 1722 assert((src_lo&1)==0 && src_lo+1==src_hi && 1723 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1724 "expected aligned-adjacent pairs"); 1725 // Generate spill code! 1726 int size = 0; 1727 1728 if (src_lo == dst_lo && src_hi == dst_hi) 1729 return size; // Self copy, no move. 1730 1731 if (bottom_type()->isa_vect() != NULL && ideal_reg() == Op_VecX) { 1732 // Memory->Memory Spill. 1733 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1734 int src_offset = ra_->reg2offset(src_lo); 1735 int dst_offset = ra_->reg2offset(dst_lo); 1736 if (cbuf) { 1737 MacroAssembler _masm(cbuf); 1738 __ ld(R0, src_offset, R1_SP); 1739 __ std(R0, dst_offset, R1_SP); 1740 __ ld(R0, src_offset+8, R1_SP); 1741 __ std(R0, dst_offset+8, R1_SP); 1742 } 1743 size += 16; 1744 } 1745 // VectorSRegister->Memory Spill. 1746 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) { 1747 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1748 int dst_offset = ra_->reg2offset(dst_lo); 1749 if (cbuf) { 1750 MacroAssembler _masm(cbuf); 1751 __ addi(R0, R1_SP, dst_offset); 1752 __ stxvd2x(Rsrc, R0); 1753 } 1754 size += 8; 1755 } 1756 // Memory->VectorSRegister Spill. 1757 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) { 1758 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1759 int src_offset = ra_->reg2offset(src_lo); 1760 if (cbuf) { 1761 MacroAssembler _masm(cbuf); 1762 __ addi(R0, R1_SP, src_offset); 1763 __ lxvd2x(Rdst, R0); 1764 } 1765 size += 8; 1766 } 1767 // VectorSRegister->VectorSRegister. 1768 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) { 1769 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1770 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1771 if (cbuf) { 1772 MacroAssembler _masm(cbuf); 1773 __ xxlor(Rdst, Rsrc, Rsrc); 1774 } 1775 size += 4; 1776 } 1777 else { 1778 ShouldNotReachHere(); // No VSR spill. 1779 } 1780 return size; 1781 } 1782 1783 // -------------------------------------- 1784 // Memory->Memory Spill. Use R0 to hold the value. 1785 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1786 int src_offset = ra_->reg2offset(src_lo); 1787 int dst_offset = ra_->reg2offset(dst_lo); 1788 if (src_hi != OptoReg::Bad) { 1789 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1790 "expected same type of move for high parts"); 1791 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1792 if (!cbuf && !do_size) st->print("\n\t"); 1793 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1794 } else { 1795 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1796 if (!cbuf && !do_size) st->print("\n\t"); 1797 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1798 } 1799 return size; 1800 } 1801 1802 // -------------------------------------- 1803 // Check for float->int copy; requires a trip through memory. 1804 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1805 Unimplemented(); 1806 } 1807 1808 // -------------------------------------- 1809 // Check for integer reg-reg copy. 1810 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1811 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1812 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1813 size = (Rsrc != Rdst) ? 4 : 0; 1814 1815 if (cbuf) { 1816 MacroAssembler _masm(cbuf); 1817 if (size) { 1818 __ mr(Rdst, Rsrc); 1819 } 1820 } 1821 #ifndef PRODUCT 1822 else if (!do_size) { 1823 if (size) { 1824 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1825 } else { 1826 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1827 } 1828 } 1829 #endif 1830 return size; 1831 } 1832 1833 // Check for integer store. 1834 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1835 int dst_offset = ra_->reg2offset(dst_lo); 1836 if (src_hi != OptoReg::Bad) { 1837 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1838 "expected same type of move for high parts"); 1839 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1840 } else { 1841 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1842 } 1843 return size; 1844 } 1845 1846 // Check for integer load. 1847 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1848 int src_offset = ra_->reg2offset(src_lo); 1849 if (src_hi != OptoReg::Bad) { 1850 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1851 "expected same type of move for high parts"); 1852 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1853 } else { 1854 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1855 } 1856 return size; 1857 } 1858 1859 // Check for float reg-reg copy. 1860 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1861 if (cbuf) { 1862 MacroAssembler _masm(cbuf); 1863 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1864 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1865 __ fmr(Rdst, Rsrc); 1866 } 1867 #ifndef PRODUCT 1868 else if (!do_size) { 1869 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1870 } 1871 #endif 1872 return 4; 1873 } 1874 1875 // Check for float store. 1876 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1877 int dst_offset = ra_->reg2offset(dst_lo); 1878 if (src_hi != OptoReg::Bad) { 1879 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1880 "expected same type of move for high parts"); 1881 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1882 } else { 1883 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1884 } 1885 return size; 1886 } 1887 1888 // Check for float load. 1889 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1890 int src_offset = ra_->reg2offset(src_lo); 1891 if (src_hi != OptoReg::Bad) { 1892 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1893 "expected same type of move for high parts"); 1894 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1895 } else { 1896 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1897 } 1898 return size; 1899 } 1900 1901 // -------------------------------------------------------------------- 1902 // Check for hi bits still needing moving. Only happens for misaligned 1903 // arguments to native calls. 1904 if (src_hi == dst_hi) 1905 return size; // Self copy; no move. 1906 1907 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1908 ShouldNotReachHere(); // Unimplemented 1909 return 0; 1910 } 1911 1912 #ifndef PRODUCT 1913 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1914 if (!ra_) 1915 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1916 else 1917 implementation(NULL, ra_, false, st); 1918 } 1919 #endif 1920 1921 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1922 implementation(&cbuf, ra_, false, NULL); 1923 } 1924 1925 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1926 return implementation(NULL, ra_, true, NULL); 1927 } 1928 1929 #if 0 // TODO: PPC port 1930 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1931 #ifndef PRODUCT 1932 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1933 #endif 1934 assert(ra_->node_regs_max_index() != 0, ""); 1935 1936 // Get registers to move. 1937 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1938 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1939 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1940 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1941 1942 enum RC src_lo_rc = rc_class(src_lo); 1943 enum RC dst_lo_rc = rc_class(dst_lo); 1944 1945 if (src_lo == dst_lo && src_hi == dst_hi) 1946 return ppc64Opcode_none; // Self copy, no move. 1947 1948 // -------------------------------------- 1949 // Memory->Memory Spill. Use R0 to hold the value. 1950 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1951 return ppc64Opcode_compound; 1952 } 1953 1954 // -------------------------------------- 1955 // Check for float->int copy; requires a trip through memory. 1956 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1957 Unimplemented(); 1958 } 1959 1960 // -------------------------------------- 1961 // Check for integer reg-reg copy. 1962 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1963 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1964 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1965 if (Rsrc == Rdst) { 1966 return ppc64Opcode_none; 1967 } else { 1968 return ppc64Opcode_or; 1969 } 1970 } 1971 1972 // Check for integer store. 1973 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1974 if (src_hi != OptoReg::Bad) { 1975 return ppc64Opcode_std; 1976 } else { 1977 return ppc64Opcode_stw; 1978 } 1979 } 1980 1981 // Check for integer load. 1982 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1983 if (src_hi != OptoReg::Bad) { 1984 return ppc64Opcode_ld; 1985 } else { 1986 return ppc64Opcode_lwz; 1987 } 1988 } 1989 1990 // Check for float reg-reg copy. 1991 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1992 return ppc64Opcode_fmr; 1993 } 1994 1995 // Check for float store. 1996 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1997 if (src_hi != OptoReg::Bad) { 1998 return ppc64Opcode_stfd; 1999 } else { 2000 return ppc64Opcode_stfs; 2001 } 2002 } 2003 2004 // Check for float load. 2005 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 2006 if (src_hi != OptoReg::Bad) { 2007 return ppc64Opcode_lfd; 2008 } else { 2009 return ppc64Opcode_lfs; 2010 } 2011 } 2012 2013 // -------------------------------------------------------------------- 2014 // Check for hi bits still needing moving. Only happens for misaligned 2015 // arguments to native calls. 2016 if (src_hi == dst_hi) { 2017 return ppc64Opcode_none; // Self copy; no move. 2018 } 2019 2020 ShouldNotReachHere(); 2021 return ppc64Opcode_undefined; 2022 } 2023 #endif // PPC port 2024 2025 #ifndef PRODUCT 2026 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2027 st->print("NOP \t// %d nops to pad for loops.", _count); 2028 } 2029 #endif 2030 2031 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 2032 MacroAssembler _masm(&cbuf); 2033 // _count contains the number of nops needed for padding. 2034 for (int i = 0; i < _count; i++) { 2035 __ nop(); 2036 } 2037 } 2038 2039 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 2040 return _count * 4; 2041 } 2042 2043 #ifndef PRODUCT 2044 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2045 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2046 char reg_str[128]; 2047 ra_->dump_register(this, reg_str); 2048 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 2049 } 2050 #endif 2051 2052 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2053 MacroAssembler _masm(&cbuf); 2054 2055 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2056 int reg = ra_->get_encode(this); 2057 2058 if (Assembler::is_simm(offset, 16)) { 2059 __ addi(as_Register(reg), R1, offset); 2060 } else { 2061 ShouldNotReachHere(); 2062 } 2063 } 2064 2065 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2066 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2067 return 4; 2068 } 2069 2070 #ifndef PRODUCT 2071 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2072 st->print_cr("---- MachUEPNode ----"); 2073 st->print_cr("..."); 2074 } 2075 #endif 2076 2077 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2078 // This is the unverified entry point. 2079 MacroAssembler _masm(&cbuf); 2080 2081 // Inline_cache contains a klass. 2082 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 2083 Register receiver_klass = R12_scratch2; // tmp 2084 2085 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 2086 assert(R11_scratch1 == R11, "need prologue scratch register"); 2087 2088 // Check for NULL argument if we don't have implicit null checks. 2089 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 2090 if (TrapBasedNullChecks) { 2091 __ trap_null_check(R3_ARG1); 2092 } else { 2093 Label valid; 2094 __ cmpdi(CCR0, R3_ARG1, 0); 2095 __ bne_predict_taken(CCR0, valid); 2096 // We have a null argument, branch to ic_miss_stub. 2097 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2098 relocInfo::runtime_call_type); 2099 __ bind(valid); 2100 } 2101 } 2102 // Assume argument is not NULL, load klass from receiver. 2103 __ load_klass(receiver_klass, R3_ARG1); 2104 2105 if (TrapBasedICMissChecks) { 2106 __ trap_ic_miss_check(receiver_klass, ic_klass); 2107 } else { 2108 Label valid; 2109 __ cmpd(CCR0, receiver_klass, ic_klass); 2110 __ beq_predict_taken(CCR0, valid); 2111 // We have an unexpected klass, branch to ic_miss_stub. 2112 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2113 relocInfo::runtime_call_type); 2114 __ bind(valid); 2115 } 2116 2117 // Argument is valid and klass is as expected, continue. 2118 } 2119 2120 #if 0 // TODO: PPC port 2121 // Optimize UEP code on z (save a load_const() call in main path). 2122 int MachUEPNode::ep_offset() { 2123 return 0; 2124 } 2125 #endif 2126 2127 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2128 // Variable size. Determine dynamically. 2129 return MachNode::size(ra_); 2130 } 2131 2132 //============================================================================= 2133 2134 %} // interrupt source 2135 2136 source_hpp %{ // Header information of the source block. 2137 2138 class HandlerImpl { 2139 2140 public: 2141 2142 static int emit_exception_handler(CodeBuffer &cbuf); 2143 static int emit_deopt_handler(CodeBuffer& cbuf); 2144 2145 static uint size_exception_handler() { 2146 // The exception_handler is a b64_patchable. 2147 return MacroAssembler::b64_patchable_size; 2148 } 2149 2150 static uint size_deopt_handler() { 2151 // The deopt_handler is a bl64_patchable. 2152 return MacroAssembler::bl64_patchable_size; 2153 } 2154 2155 }; 2156 2157 %} // end source_hpp 2158 2159 source %{ 2160 2161 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2162 MacroAssembler _masm(&cbuf); 2163 2164 address base = __ start_a_stub(size_exception_handler()); 2165 if (base == NULL) return 0; // CodeBuffer::expand failed 2166 2167 int offset = __ offset(); 2168 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2169 relocInfo::runtime_call_type); 2170 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2171 __ end_a_stub(); 2172 2173 return offset; 2174 } 2175 2176 // The deopt_handler is like the exception handler, but it calls to 2177 // the deoptimization blob instead of jumping to the exception blob. 2178 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2179 MacroAssembler _masm(&cbuf); 2180 2181 address base = __ start_a_stub(size_deopt_handler()); 2182 if (base == NULL) return 0; // CodeBuffer::expand failed 2183 2184 int offset = __ offset(); 2185 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2186 relocInfo::runtime_call_type); 2187 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2188 __ end_a_stub(); 2189 2190 return offset; 2191 } 2192 2193 //============================================================================= 2194 2195 // Use a frame slots bias for frameless methods if accessing the stack. 2196 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2197 if (as_Register(reg_enc) == R1_SP) { 2198 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2199 } 2200 return 0; 2201 } 2202 2203 const bool Matcher::match_rule_supported(int opcode) { 2204 if (!has_match_rule(opcode)) 2205 return false; 2206 2207 switch (opcode) { 2208 case Op_SqrtD: 2209 return VM_Version::has_fsqrt(); 2210 case Op_CountLeadingZerosI: 2211 case Op_CountLeadingZerosL: 2212 if (!UseCountLeadingZerosInstructionsPPC64) 2213 return false; 2214 break; 2215 case Op_CountTrailingZerosI: 2216 case Op_CountTrailingZerosL: 2217 if (!UseCountLeadingZerosInstructionsPPC64 && 2218 !UseCountTrailingZerosInstructionsPPC64) 2219 return false; 2220 break; 2221 2222 case Op_PopCountI: 2223 case Op_PopCountL: 2224 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2225 2226 case Op_StrComp: 2227 return SpecialStringCompareTo; 2228 case Op_StrEquals: 2229 return SpecialStringEquals; 2230 case Op_StrIndexOf: 2231 case Op_StrIndexOfChar: 2232 return SpecialStringIndexOf; 2233 case Op_AddVB: 2234 case Op_AddVS: 2235 case Op_AddVI: 2236 case Op_AddVF: 2237 case Op_AddVD: 2238 case Op_SubVB: 2239 case Op_SubVS: 2240 case Op_SubVI: 2241 case Op_SubVF: 2242 case Op_SubVD: 2243 case Op_MulVS: 2244 case Op_MulVF: 2245 case Op_MulVD: 2246 case Op_DivVF: 2247 case Op_DivVD: 2248 case Op_AbsVF: 2249 case Op_AbsVD: 2250 case Op_NegVF: 2251 case Op_NegVD: 2252 case Op_SqrtVF: 2253 case Op_SqrtVD: 2254 case Op_AddVL: 2255 case Op_SubVL: 2256 case Op_MulVI: 2257 return SuperwordUseVSX; 2258 case Op_PopCountVI: 2259 return (SuperwordUseVSX && UsePopCountInstruction); 2260 case Op_FmaVF: 2261 case Op_FmaVD: 2262 return (SuperwordUseVSX && UseFMA); 2263 case Op_Digit: 2264 case Op_LowerCase: 2265 case Op_UpperCase: 2266 case Op_Whitespace: 2267 return UseCharacterCompareIntrinsics; 2268 } 2269 2270 return true; // Per default match rules are supported. 2271 } 2272 2273 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2274 2275 // TODO 2276 // identify extra cases that we might want to provide match rules for 2277 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2278 bool ret_value = match_rule_supported(opcode); 2279 // Add rules here. 2280 2281 return ret_value; // Per default match rules are supported. 2282 } 2283 2284 const bool Matcher::has_predicated_vectors(void) { 2285 return false; 2286 } 2287 2288 const int Matcher::float_pressure(int default_pressure_threshold) { 2289 return default_pressure_threshold; 2290 } 2291 2292 int Matcher::regnum_to_fpu_offset(int regnum) { 2293 // No user for this method? 2294 Unimplemented(); 2295 return 999; 2296 } 2297 2298 const bool Matcher::convL2FSupported(void) { 2299 // fcfids can do the conversion (>= Power7). 2300 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2301 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2302 } 2303 2304 // Vector width in bytes. 2305 const int Matcher::vector_width_in_bytes(BasicType bt) { 2306 if (SuperwordUseVSX) { 2307 assert(MaxVectorSize == 16, ""); 2308 return 16; 2309 } else { 2310 assert(MaxVectorSize == 8, ""); 2311 return 8; 2312 } 2313 } 2314 2315 // Vector ideal reg. 2316 const uint Matcher::vector_ideal_reg(int size) { 2317 if (SuperwordUseVSX) { 2318 assert(MaxVectorSize == 16 && size == 16, ""); 2319 return Op_VecX; 2320 } else { 2321 assert(MaxVectorSize == 8 && size == 8, ""); 2322 return Op_RegL; 2323 } 2324 } 2325 2326 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2327 fatal("vector shift is not supported"); 2328 return Node::NotAMachineReg; 2329 } 2330 2331 // Limits on vector size (number of elements) loaded into vector. 2332 const int Matcher::max_vector_size(const BasicType bt) { 2333 assert(is_java_primitive(bt), "only primitive type vectors"); 2334 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2335 } 2336 2337 const int Matcher::min_vector_size(const BasicType bt) { 2338 return max_vector_size(bt); // Same as max. 2339 } 2340 2341 // PPC doesn't support misaligned vectors store/load. 2342 const bool Matcher::misaligned_vectors_ok() { 2343 return !AlignVector; // can be changed by flag 2344 } 2345 2346 // PPC AES support not yet implemented 2347 const bool Matcher::pass_original_key_for_aes() { 2348 return false; 2349 } 2350 2351 // RETURNS: whether this branch offset is short enough that a short 2352 // branch can be used. 2353 // 2354 // If the platform does not provide any short branch variants, then 2355 // this method should return `false' for offset 0. 2356 // 2357 // `Compile::Fill_buffer' will decide on basis of this information 2358 // whether to do the pass `Compile::Shorten_branches' at all. 2359 // 2360 // And `Compile::Shorten_branches' will decide on basis of this 2361 // information whether to replace particular branch sites by short 2362 // ones. 2363 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2364 // Is the offset within the range of a ppc64 pc relative branch? 2365 bool b; 2366 2367 const int safety_zone = 3 * BytesPerInstWord; 2368 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2369 29 - 16 + 1 + 2); 2370 return b; 2371 } 2372 2373 const bool Matcher::isSimpleConstant64(jlong value) { 2374 // Probably always true, even if a temp register is required. 2375 return true; 2376 } 2377 /* TODO: PPC port 2378 // Make a new machine dependent decode node (with its operands). 2379 MachTypeNode *Matcher::make_decode_node() { 2380 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2381 "This method is only implemented for unscaled cOops mode so far"); 2382 MachTypeNode *decode = new decodeN_unscaledNode(); 2383 decode->set_opnd_array(0, new iRegPdstOper()); 2384 decode->set_opnd_array(1, new iRegNsrcOper()); 2385 return decode; 2386 } 2387 */ 2388 2389 // false => size gets scaled to BytesPerLong, ok. 2390 const bool Matcher::init_array_count_is_in_bytes = false; 2391 2392 // Use conditional move (CMOVL) on Power7. 2393 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2394 2395 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2396 // fsel doesn't accept a condition register as input, so this would be slightly different. 2397 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2398 2399 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2400 const bool Matcher::require_postalloc_expand = true; 2401 2402 // Do we need to mask the count passed to shift instructions or does 2403 // the cpu only look at the lower 5/6 bits anyway? 2404 // PowerPC requires masked shift counts. 2405 const bool Matcher::need_masked_shift_count = true; 2406 2407 // This affects two different things: 2408 // - how Decode nodes are matched 2409 // - how ImplicitNullCheck opportunities are recognized 2410 // If true, the matcher will try to remove all Decodes and match them 2411 // (as operands) into nodes. NullChecks are not prepared to deal with 2412 // Decodes by final_graph_reshaping(). 2413 // If false, final_graph_reshaping() forces the decode behind the Cmp 2414 // for a NullCheck. The matcher matches the Decode node into a register. 2415 // Implicit_null_check optimization moves the Decode along with the 2416 // memory operation back up before the NullCheck. 2417 bool Matcher::narrow_oop_use_complex_address() { 2418 // TODO: PPC port if (MatchDecodeNodes) return true; 2419 return false; 2420 } 2421 2422 bool Matcher::narrow_klass_use_complex_address() { 2423 NOT_LP64(ShouldNotCallThis()); 2424 assert(UseCompressedClassPointers, "only for compressed klass code"); 2425 // TODO: PPC port if (MatchDecodeNodes) return true; 2426 return false; 2427 } 2428 2429 bool Matcher::const_oop_prefer_decode() { 2430 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2431 return Universe::narrow_oop_base() == NULL; 2432 } 2433 2434 bool Matcher::const_klass_prefer_decode() { 2435 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2436 return Universe::narrow_klass_base() == NULL; 2437 } 2438 2439 // Is it better to copy float constants, or load them directly from memory? 2440 // Intel can load a float constant from a direct address, requiring no 2441 // extra registers. Most RISCs will have to materialize an address into a 2442 // register first, so they would do better to copy the constant from stack. 2443 const bool Matcher::rematerialize_float_constants = false; 2444 2445 // If CPU can load and store mis-aligned doubles directly then no fixup is 2446 // needed. Else we split the double into 2 integer pieces and move it 2447 // piece-by-piece. Only happens when passing doubles into C code as the 2448 // Java calling convention forces doubles to be aligned. 2449 const bool Matcher::misaligned_doubles_ok = true; 2450 2451 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2452 Unimplemented(); 2453 } 2454 2455 // Advertise here if the CPU requires explicit rounding operations 2456 // to implement the UseStrictFP mode. 2457 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2458 2459 // Do floats take an entire double register or just half? 2460 // 2461 // A float occupies a ppc64 double register. For the allocator, a 2462 // ppc64 double register appears as a pair of float registers. 2463 bool Matcher::float_in_double() { return true; } 2464 2465 // Do ints take an entire long register or just half? 2466 // The relevant question is how the int is callee-saved: 2467 // the whole long is written but de-opt'ing will have to extract 2468 // the relevant 32 bits. 2469 const bool Matcher::int_in_long = true; 2470 2471 // Constants for c2c and c calling conventions. 2472 2473 const MachRegisterNumbers iarg_reg[8] = { 2474 R3_num, R4_num, R5_num, R6_num, 2475 R7_num, R8_num, R9_num, R10_num 2476 }; 2477 2478 const MachRegisterNumbers farg_reg[13] = { 2479 F1_num, F2_num, F3_num, F4_num, 2480 F5_num, F6_num, F7_num, F8_num, 2481 F9_num, F10_num, F11_num, F12_num, 2482 F13_num 2483 }; 2484 2485 const MachRegisterNumbers vsarg_reg[64] = { 2486 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2487 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2488 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2489 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2490 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2491 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2492 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2493 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2494 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2495 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2496 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2497 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2498 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2499 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2500 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2501 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2502 }; 2503 2504 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2505 2506 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2507 2508 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2509 2510 // Return whether or not this register is ever used as an argument. This 2511 // function is used on startup to build the trampoline stubs in generateOptoStub. 2512 // Registers not mentioned will be killed by the VM call in the trampoline, and 2513 // arguments in those registers not be available to the callee. 2514 bool Matcher::can_be_java_arg(int reg) { 2515 // We return true for all registers contained in iarg_reg[] and 2516 // farg_reg[] and their virtual halves. 2517 // We must include the virtual halves in order to get STDs and LDs 2518 // instead of STWs and LWs in the trampoline stubs. 2519 2520 if ( reg == R3_num || reg == R3_H_num 2521 || reg == R4_num || reg == R4_H_num 2522 || reg == R5_num || reg == R5_H_num 2523 || reg == R6_num || reg == R6_H_num 2524 || reg == R7_num || reg == R7_H_num 2525 || reg == R8_num || reg == R8_H_num 2526 || reg == R9_num || reg == R9_H_num 2527 || reg == R10_num || reg == R10_H_num) 2528 return true; 2529 2530 if ( reg == F1_num || reg == F1_H_num 2531 || reg == F2_num || reg == F2_H_num 2532 || reg == F3_num || reg == F3_H_num 2533 || reg == F4_num || reg == F4_H_num 2534 || reg == F5_num || reg == F5_H_num 2535 || reg == F6_num || reg == F6_H_num 2536 || reg == F7_num || reg == F7_H_num 2537 || reg == F8_num || reg == F8_H_num 2538 || reg == F9_num || reg == F9_H_num 2539 || reg == F10_num || reg == F10_H_num 2540 || reg == F11_num || reg == F11_H_num 2541 || reg == F12_num || reg == F12_H_num 2542 || reg == F13_num || reg == F13_H_num) 2543 return true; 2544 2545 return false; 2546 } 2547 2548 bool Matcher::is_spillable_arg(int reg) { 2549 return can_be_java_arg(reg); 2550 } 2551 2552 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2553 return false; 2554 } 2555 2556 // Register for DIVI projection of divmodI. 2557 RegMask Matcher::divI_proj_mask() { 2558 ShouldNotReachHere(); 2559 return RegMask(); 2560 } 2561 2562 // Register for MODI projection of divmodI. 2563 RegMask Matcher::modI_proj_mask() { 2564 ShouldNotReachHere(); 2565 return RegMask(); 2566 } 2567 2568 // Register for DIVL projection of divmodL. 2569 RegMask Matcher::divL_proj_mask() { 2570 ShouldNotReachHere(); 2571 return RegMask(); 2572 } 2573 2574 // Register for MODL projection of divmodL. 2575 RegMask Matcher::modL_proj_mask() { 2576 ShouldNotReachHere(); 2577 return RegMask(); 2578 } 2579 2580 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2581 return RegMask(); 2582 } 2583 2584 const bool Matcher::convi2l_type_required = true; 2585 2586 %} 2587 2588 //----------ENCODING BLOCK----------------------------------------------------- 2589 // This block specifies the encoding classes used by the compiler to output 2590 // byte streams. Encoding classes are parameterized macros used by 2591 // Machine Instruction Nodes in order to generate the bit encoding of the 2592 // instruction. Operands specify their base encoding interface with the 2593 // interface keyword. There are currently supported four interfaces, 2594 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2595 // operand to generate a function which returns its register number when 2596 // queried. CONST_INTER causes an operand to generate a function which 2597 // returns the value of the constant when queried. MEMORY_INTER causes an 2598 // operand to generate four functions which return the Base Register, the 2599 // Index Register, the Scale Value, and the Offset Value of the operand when 2600 // queried. COND_INTER causes an operand to generate six functions which 2601 // return the encoding code (ie - encoding bits for the instruction) 2602 // associated with each basic boolean condition for a conditional instruction. 2603 // 2604 // Instructions specify two basic values for encoding. Again, a function 2605 // is available to check if the constant displacement is an oop. They use the 2606 // ins_encode keyword to specify their encoding classes (which must be 2607 // a sequence of enc_class names, and their parameters, specified in 2608 // the encoding block), and they use the 2609 // opcode keyword to specify, in order, their primary, secondary, and 2610 // tertiary opcode. Only the opcode sections which a particular instruction 2611 // needs for encoding need to be specified. 2612 encode %{ 2613 enc_class enc_unimplemented %{ 2614 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2615 MacroAssembler _masm(&cbuf); 2616 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2617 %} 2618 2619 enc_class enc_untested %{ 2620 #ifdef ASSERT 2621 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2622 MacroAssembler _masm(&cbuf); 2623 __ untested("Untested mach node encoding in AD file."); 2624 #else 2625 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2626 #endif 2627 %} 2628 2629 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2630 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2631 MacroAssembler _masm(&cbuf); 2632 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2633 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2634 %} 2635 2636 // Load acquire. 2637 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2638 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2639 MacroAssembler _masm(&cbuf); 2640 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2641 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2642 __ twi_0($dst$$Register); 2643 __ isync(); 2644 %} 2645 2646 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2647 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2648 2649 MacroAssembler _masm(&cbuf); 2650 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2651 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2652 %} 2653 2654 // Load acquire. 2655 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2656 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2657 2658 MacroAssembler _masm(&cbuf); 2659 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2660 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2661 __ twi_0($dst$$Register); 2662 __ isync(); 2663 %} 2664 2665 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2666 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2667 2668 MacroAssembler _masm(&cbuf); 2669 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2670 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2671 %} 2672 2673 // Load acquire. 2674 enc_class enc_lwz_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 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2680 __ twi_0($dst$$Register); 2681 __ isync(); 2682 %} 2683 2684 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2685 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2686 MacroAssembler _masm(&cbuf); 2687 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2688 // Operand 'ds' requires 4-alignment. 2689 assert((Idisp & 0x3) == 0, "unaligned offset"); 2690 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2691 %} 2692 2693 // Load acquire. 2694 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2695 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2696 MacroAssembler _masm(&cbuf); 2697 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2698 // Operand 'ds' requires 4-alignment. 2699 assert((Idisp & 0x3) == 0, "unaligned offset"); 2700 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2701 __ twi_0($dst$$Register); 2702 __ isync(); 2703 %} 2704 2705 enc_class enc_lfd(RegF dst, memory mem) %{ 2706 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2707 MacroAssembler _masm(&cbuf); 2708 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2709 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2710 %} 2711 2712 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2713 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2714 2715 MacroAssembler _masm(&cbuf); 2716 int toc_offset = 0; 2717 2718 address const_toc_addr; 2719 // Create a non-oop constant, no relocation needed. 2720 // If it is an IC, it has a virtual_call_Relocation. 2721 const_toc_addr = __ long_constant((jlong)$src$$constant); 2722 if (const_toc_addr == NULL) { 2723 ciEnv::current()->record_out_of_memory_failure(); 2724 return; 2725 } 2726 2727 // Get the constant's TOC offset. 2728 toc_offset = __ offset_to_method_toc(const_toc_addr); 2729 2730 // Keep the current instruction offset in mind. 2731 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2732 2733 __ ld($dst$$Register, toc_offset, $toc$$Register); 2734 %} 2735 2736 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2737 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2738 2739 MacroAssembler _masm(&cbuf); 2740 2741 if (!ra_->C->in_scratch_emit_size()) { 2742 address const_toc_addr; 2743 // Create a non-oop constant, no relocation needed. 2744 // If it is an IC, it has a virtual_call_Relocation. 2745 const_toc_addr = __ long_constant((jlong)$src$$constant); 2746 if (const_toc_addr == NULL) { 2747 ciEnv::current()->record_out_of_memory_failure(); 2748 return; 2749 } 2750 2751 // Get the constant's TOC offset. 2752 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2753 // Store the toc offset of the constant. 2754 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2755 2756 // Also keep the current instruction offset in mind. 2757 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2758 } 2759 2760 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2761 %} 2762 2763 %} // encode 2764 2765 source %{ 2766 2767 typedef struct { 2768 loadConL_hiNode *_large_hi; 2769 loadConL_loNode *_large_lo; 2770 loadConLNode *_small; 2771 MachNode *_last; 2772 } loadConLNodesTuple; 2773 2774 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2775 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2776 loadConLNodesTuple nodes; 2777 2778 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2779 if (large_constant_pool) { 2780 // Create new nodes. 2781 loadConL_hiNode *m1 = new loadConL_hiNode(); 2782 loadConL_loNode *m2 = new loadConL_loNode(); 2783 2784 // inputs for new nodes 2785 m1->add_req(NULL, toc); 2786 m2->add_req(NULL, m1); 2787 2788 // operands for new nodes 2789 m1->_opnds[0] = new iRegLdstOper(); // dst 2790 m1->_opnds[1] = immSrc; // src 2791 m1->_opnds[2] = new iRegPdstOper(); // toc 2792 m2->_opnds[0] = new iRegLdstOper(); // dst 2793 m2->_opnds[1] = immSrc; // src 2794 m2->_opnds[2] = new iRegLdstOper(); // base 2795 2796 // Initialize ins_attrib TOC fields. 2797 m1->_const_toc_offset = -1; 2798 m2->_const_toc_offset_hi_node = m1; 2799 2800 // Initialize ins_attrib instruction offset. 2801 m1->_cbuf_insts_offset = -1; 2802 2803 // register allocation for new nodes 2804 ra_->set_pair(m1->_idx, reg_second, reg_first); 2805 ra_->set_pair(m2->_idx, reg_second, reg_first); 2806 2807 // Create result. 2808 nodes._large_hi = m1; 2809 nodes._large_lo = m2; 2810 nodes._small = NULL; 2811 nodes._last = nodes._large_lo; 2812 assert(m2->bottom_type()->isa_long(), "must be long"); 2813 } else { 2814 loadConLNode *m2 = new loadConLNode(); 2815 2816 // inputs for new nodes 2817 m2->add_req(NULL, toc); 2818 2819 // operands for new nodes 2820 m2->_opnds[0] = new iRegLdstOper(); // dst 2821 m2->_opnds[1] = immSrc; // src 2822 m2->_opnds[2] = new iRegPdstOper(); // toc 2823 2824 // Initialize ins_attrib instruction offset. 2825 m2->_cbuf_insts_offset = -1; 2826 2827 // register allocation for new nodes 2828 ra_->set_pair(m2->_idx, reg_second, reg_first); 2829 2830 // Create result. 2831 nodes._large_hi = NULL; 2832 nodes._large_lo = NULL; 2833 nodes._small = m2; 2834 nodes._last = nodes._small; 2835 assert(m2->bottom_type()->isa_long(), "must be long"); 2836 } 2837 2838 return nodes; 2839 } 2840 2841 typedef struct { 2842 loadConL_hiNode *_large_hi; 2843 loadConL_loNode *_large_lo; 2844 mtvsrdNode *_moved; 2845 xxspltdNode *_replicated; 2846 loadConLNode *_small; 2847 MachNode *_last; 2848 } loadConLReplicatedNodesTuple; 2849 2850 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2851 vecXOper *dst, immI_0Oper *zero, 2852 OptoReg::Name reg_second, OptoReg::Name reg_first, 2853 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2854 loadConLReplicatedNodesTuple nodes; 2855 2856 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2857 if (large_constant_pool) { 2858 // Create new nodes. 2859 loadConL_hiNode *m1 = new loadConL_hiNode(); 2860 loadConL_loNode *m2 = new loadConL_loNode(); 2861 mtvsrdNode *m3 = new mtvsrdNode(); 2862 xxspltdNode *m4 = new xxspltdNode(); 2863 2864 // inputs for new nodes 2865 m1->add_req(NULL, toc); 2866 m2->add_req(NULL, m1); 2867 m3->add_req(NULL, m2); 2868 m4->add_req(NULL, m3); 2869 2870 // operands for new nodes 2871 m1->_opnds[0] = new iRegLdstOper(); // dst 2872 m1->_opnds[1] = immSrc; // src 2873 m1->_opnds[2] = new iRegPdstOper(); // toc 2874 2875 m2->_opnds[0] = new iRegLdstOper(); // dst 2876 m2->_opnds[1] = immSrc; // src 2877 m2->_opnds[2] = new iRegLdstOper(); // base 2878 2879 m3->_opnds[0] = new vecXOper(); // dst 2880 m3->_opnds[1] = new iRegLdstOper(); // src 2881 2882 m4->_opnds[0] = new vecXOper(); // dst 2883 m4->_opnds[1] = new vecXOper(); // src 2884 m4->_opnds[2] = zero; 2885 2886 // Initialize ins_attrib TOC fields. 2887 m1->_const_toc_offset = -1; 2888 m2->_const_toc_offset_hi_node = m1; 2889 2890 // Initialize ins_attrib instruction offset. 2891 m1->_cbuf_insts_offset = -1; 2892 2893 // register allocation for new nodes 2894 ra_->set_pair(m1->_idx, reg_second, reg_first); 2895 ra_->set_pair(m2->_idx, reg_second, reg_first); 2896 ra_->set1(m3->_idx, reg_second); 2897 ra_->set2(m3->_idx, reg_vec_first); 2898 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2899 2900 // Create result. 2901 nodes._large_hi = m1; 2902 nodes._large_lo = m2; 2903 nodes._moved = m3; 2904 nodes._replicated = m4; 2905 nodes._small = NULL; 2906 nodes._last = nodes._replicated; 2907 assert(m2->bottom_type()->isa_long(), "must be long"); 2908 } else { 2909 loadConLNode *m2 = new loadConLNode(); 2910 mtvsrdNode *m3 = new mtvsrdNode(); 2911 xxspltdNode *m4 = new xxspltdNode(); 2912 2913 // inputs for new nodes 2914 m2->add_req(NULL, toc); 2915 2916 // operands for new nodes 2917 m2->_opnds[0] = new iRegLdstOper(); // dst 2918 m2->_opnds[1] = immSrc; // src 2919 m2->_opnds[2] = new iRegPdstOper(); // toc 2920 2921 m3->_opnds[0] = new vecXOper(); // dst 2922 m3->_opnds[1] = new iRegLdstOper(); // src 2923 2924 m4->_opnds[0] = new vecXOper(); // dst 2925 m4->_opnds[1] = new vecXOper(); // src 2926 m4->_opnds[2] = zero; 2927 2928 // Initialize ins_attrib instruction offset. 2929 m2->_cbuf_insts_offset = -1; 2930 ra_->set1(m3->_idx, reg_second); 2931 ra_->set2(m3->_idx, reg_vec_first); 2932 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2933 2934 // register allocation for new nodes 2935 ra_->set_pair(m2->_idx, reg_second, reg_first); 2936 2937 // Create result. 2938 nodes._large_hi = NULL; 2939 nodes._large_lo = NULL; 2940 nodes._small = m2; 2941 nodes._moved = m3; 2942 nodes._replicated = m4; 2943 nodes._last = nodes._replicated; 2944 assert(m2->bottom_type()->isa_long(), "must be long"); 2945 } 2946 2947 return nodes; 2948 } 2949 2950 %} // source 2951 2952 encode %{ 2953 // Postalloc expand emitter for loading a long constant from the method's TOC. 2954 // Enc_class needed as consttanttablebase is not supported by postalloc 2955 // expand. 2956 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2957 // Create new nodes. 2958 loadConLNodesTuple loadConLNodes = 2959 loadConLNodesTuple_create(ra_, n_toc, op_src, 2960 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2961 2962 // Push new nodes. 2963 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2964 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2965 2966 // some asserts 2967 assert(nodes->length() >= 1, "must have created at least 1 node"); 2968 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2969 %} 2970 2971 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2972 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2973 2974 MacroAssembler _masm(&cbuf); 2975 int toc_offset = 0; 2976 2977 intptr_t val = $src$$constant; 2978 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2979 address const_toc_addr; 2980 if (constant_reloc == relocInfo::oop_type) { 2981 // Create an oop constant and a corresponding relocation. 2982 AddressLiteral a = __ allocate_oop_address((jobject)val); 2983 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2984 __ relocate(a.rspec()); 2985 } else if (constant_reloc == relocInfo::metadata_type) { 2986 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2987 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2988 __ relocate(a.rspec()); 2989 } else { 2990 // Create a non-oop constant, no relocation needed. 2991 const_toc_addr = __ long_constant((jlong)$src$$constant); 2992 } 2993 2994 if (const_toc_addr == NULL) { 2995 ciEnv::current()->record_out_of_memory_failure(); 2996 return; 2997 } 2998 // Get the constant's TOC offset. 2999 toc_offset = __ offset_to_method_toc(const_toc_addr); 3000 3001 __ ld($dst$$Register, toc_offset, $toc$$Register); 3002 %} 3003 3004 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 3005 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 3006 3007 MacroAssembler _masm(&cbuf); 3008 if (!ra_->C->in_scratch_emit_size()) { 3009 intptr_t val = $src$$constant; 3010 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 3011 address const_toc_addr; 3012 if (constant_reloc == relocInfo::oop_type) { 3013 // Create an oop constant and a corresponding relocation. 3014 AddressLiteral a = __ allocate_oop_address((jobject)val); 3015 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3016 __ relocate(a.rspec()); 3017 } else if (constant_reloc == relocInfo::metadata_type) { 3018 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 3019 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3020 __ relocate(a.rspec()); 3021 } else { // non-oop pointers, e.g. card mark base, heap top 3022 // Create a non-oop constant, no relocation needed. 3023 const_toc_addr = __ long_constant((jlong)$src$$constant); 3024 } 3025 3026 if (const_toc_addr == NULL) { 3027 ciEnv::current()->record_out_of_memory_failure(); 3028 return; 3029 } 3030 // Get the constant's TOC offset. 3031 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 3032 // Store the toc offset of the constant. 3033 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 3034 } 3035 3036 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 3037 %} 3038 3039 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 3040 // Enc_class needed as consttanttablebase is not supported by postalloc 3041 // expand. 3042 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 3043 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3044 if (large_constant_pool) { 3045 // Create new nodes. 3046 loadConP_hiNode *m1 = new loadConP_hiNode(); 3047 loadConP_loNode *m2 = new loadConP_loNode(); 3048 3049 // inputs for new nodes 3050 m1->add_req(NULL, n_toc); 3051 m2->add_req(NULL, m1); 3052 3053 // operands for new nodes 3054 m1->_opnds[0] = new iRegPdstOper(); // dst 3055 m1->_opnds[1] = op_src; // src 3056 m1->_opnds[2] = new iRegPdstOper(); // toc 3057 m2->_opnds[0] = new iRegPdstOper(); // dst 3058 m2->_opnds[1] = op_src; // src 3059 m2->_opnds[2] = new iRegLdstOper(); // base 3060 3061 // Initialize ins_attrib TOC fields. 3062 m1->_const_toc_offset = -1; 3063 m2->_const_toc_offset_hi_node = m1; 3064 3065 // Register allocation for new nodes. 3066 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3067 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3068 3069 nodes->push(m1); 3070 nodes->push(m2); 3071 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3072 } else { 3073 loadConPNode *m2 = new loadConPNode(); 3074 3075 // inputs for new nodes 3076 m2->add_req(NULL, n_toc); 3077 3078 // operands for new nodes 3079 m2->_opnds[0] = new iRegPdstOper(); // dst 3080 m2->_opnds[1] = op_src; // src 3081 m2->_opnds[2] = new iRegPdstOper(); // toc 3082 3083 // Register allocation for new nodes. 3084 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3085 3086 nodes->push(m2); 3087 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3088 } 3089 %} 3090 3091 // Enc_class needed as consttanttablebase is not supported by postalloc 3092 // expand. 3093 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3094 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3095 3096 MachNode *m2; 3097 if (large_constant_pool) { 3098 m2 = new loadConFCompNode(); 3099 } else { 3100 m2 = new loadConFNode(); 3101 } 3102 // inputs for new nodes 3103 m2->add_req(NULL, n_toc); 3104 3105 // operands for new nodes 3106 m2->_opnds[0] = op_dst; 3107 m2->_opnds[1] = op_src; 3108 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3109 3110 // register allocation for new nodes 3111 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3112 nodes->push(m2); 3113 %} 3114 3115 // Enc_class needed as consttanttablebase is not supported by postalloc 3116 // expand. 3117 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3118 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3119 3120 MachNode *m2; 3121 if (large_constant_pool) { 3122 m2 = new loadConDCompNode(); 3123 } else { 3124 m2 = new loadConDNode(); 3125 } 3126 // inputs for new nodes 3127 m2->add_req(NULL, n_toc); 3128 3129 // operands for new nodes 3130 m2->_opnds[0] = op_dst; 3131 m2->_opnds[1] = op_src; 3132 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3133 3134 // register allocation for new nodes 3135 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3136 nodes->push(m2); 3137 %} 3138 3139 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3140 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3141 MacroAssembler _masm(&cbuf); 3142 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3143 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3144 %} 3145 3146 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3147 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3148 MacroAssembler _masm(&cbuf); 3149 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3150 // Operand 'ds' requires 4-alignment. 3151 assert((Idisp & 0x3) == 0, "unaligned offset"); 3152 __ std($src$$Register, Idisp, $mem$$base$$Register); 3153 %} 3154 3155 enc_class enc_stfs(RegF src, memory mem) %{ 3156 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3157 MacroAssembler _masm(&cbuf); 3158 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3159 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3160 %} 3161 3162 enc_class enc_stfd(RegF src, memory mem) %{ 3163 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3164 MacroAssembler _masm(&cbuf); 3165 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3166 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3167 %} 3168 3169 // Use release_store for card-marking to ensure that previous 3170 // oop-stores are visible before the card-mark change. 3171 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3172 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3173 // FIXME: Implement this as a cmove and use a fixed condition code 3174 // register which is written on every transition to compiled code, 3175 // e.g. in call-stub and when returning from runtime stubs. 3176 // 3177 // Proposed code sequence for the cmove implementation: 3178 // 3179 // Label skip_release; 3180 // __ beq(CCRfixed, skip_release); 3181 // __ release(); 3182 // __ bind(skip_release); 3183 // __ stb(card mark); 3184 3185 MacroAssembler _masm(&cbuf); 3186 Label skip_storestore; 3187 3188 #if 0 // TODO: PPC port 3189 // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the 3190 // StoreStore barrier conditionally. 3191 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3192 __ cmpwi($crx$$CondRegister, R0, 0); 3193 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3194 #endif 3195 __ li(R0, 0); 3196 __ membar(Assembler::StoreStore); 3197 #if 0 // TODO: PPC port 3198 __ bind(skip_storestore); 3199 #endif 3200 3201 // Do the store. 3202 if ($mem$$index == 0) { 3203 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3204 } else { 3205 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3206 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3207 } 3208 %} 3209 3210 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3211 3212 if (VM_Version::has_isel()) { 3213 // use isel instruction with Power 7 3214 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3215 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3216 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3217 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3218 3219 n_compare->add_req(n_region, n_src); 3220 n_compare->_opnds[0] = op_crx; 3221 n_compare->_opnds[1] = op_src; 3222 n_compare->_opnds[2] = new immL16Oper(0); 3223 3224 n_sub_base->add_req(n_region, n_src); 3225 n_sub_base->_opnds[0] = op_dst; 3226 n_sub_base->_opnds[1] = op_src; 3227 n_sub_base->_bottom_type = _bottom_type; 3228 3229 n_shift->add_req(n_region, n_sub_base); 3230 n_shift->_opnds[0] = op_dst; 3231 n_shift->_opnds[1] = op_dst; 3232 n_shift->_bottom_type = _bottom_type; 3233 3234 n_cond_set->add_req(n_region, n_compare, n_shift); 3235 n_cond_set->_opnds[0] = op_dst; 3236 n_cond_set->_opnds[1] = op_crx; 3237 n_cond_set->_opnds[2] = op_dst; 3238 n_cond_set->_bottom_type = _bottom_type; 3239 3240 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3241 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3242 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3243 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3244 3245 nodes->push(n_compare); 3246 nodes->push(n_sub_base); 3247 nodes->push(n_shift); 3248 nodes->push(n_cond_set); 3249 3250 } else { 3251 // before Power 7 3252 moveRegNode *n_move = new moveRegNode(); 3253 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3254 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3255 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3256 3257 n_move->add_req(n_region, n_src); 3258 n_move->_opnds[0] = op_dst; 3259 n_move->_opnds[1] = op_src; 3260 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3261 3262 n_compare->add_req(n_region, n_src); 3263 n_compare->add_prec(n_move); 3264 3265 n_compare->_opnds[0] = op_crx; 3266 n_compare->_opnds[1] = op_src; 3267 n_compare->_opnds[2] = new immL16Oper(0); 3268 3269 n_sub_base->add_req(n_region, n_compare, n_src); 3270 n_sub_base->_opnds[0] = op_dst; 3271 n_sub_base->_opnds[1] = op_crx; 3272 n_sub_base->_opnds[2] = op_src; 3273 n_sub_base->_bottom_type = _bottom_type; 3274 3275 n_shift->add_req(n_region, n_sub_base); 3276 n_shift->_opnds[0] = op_dst; 3277 n_shift->_opnds[1] = op_dst; 3278 n_shift->_bottom_type = _bottom_type; 3279 3280 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3281 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3282 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3283 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3284 3285 nodes->push(n_move); 3286 nodes->push(n_compare); 3287 nodes->push(n_sub_base); 3288 nodes->push(n_shift); 3289 } 3290 3291 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3292 %} 3293 3294 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3295 3296 encodeP_subNode *n1 = new encodeP_subNode(); 3297 n1->add_req(n_region, n_src); 3298 n1->_opnds[0] = op_dst; 3299 n1->_opnds[1] = op_src; 3300 n1->_bottom_type = _bottom_type; 3301 3302 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3303 n2->add_req(n_region, n1); 3304 n2->_opnds[0] = op_dst; 3305 n2->_opnds[1] = op_dst; 3306 n2->_bottom_type = _bottom_type; 3307 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3308 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3309 3310 nodes->push(n1); 3311 nodes->push(n2); 3312 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3313 %} 3314 3315 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3316 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3317 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3318 3319 n_compare->add_req(n_region, n_src); 3320 n_compare->_opnds[0] = op_crx; 3321 n_compare->_opnds[1] = op_src; 3322 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3323 3324 n_shift->add_req(n_region, n_src); 3325 n_shift->_opnds[0] = op_dst; 3326 n_shift->_opnds[1] = op_src; 3327 n_shift->_bottom_type = _bottom_type; 3328 3329 if (VM_Version::has_isel()) { 3330 // use isel instruction with Power 7 3331 3332 decodeN_addNode *n_add_base = new decodeN_addNode(); 3333 n_add_base->add_req(n_region, n_shift); 3334 n_add_base->_opnds[0] = op_dst; 3335 n_add_base->_opnds[1] = op_dst; 3336 n_add_base->_bottom_type = _bottom_type; 3337 3338 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3339 n_cond_set->add_req(n_region, n_compare, n_add_base); 3340 n_cond_set->_opnds[0] = op_dst; 3341 n_cond_set->_opnds[1] = op_crx; 3342 n_cond_set->_opnds[2] = op_dst; 3343 n_cond_set->_bottom_type = _bottom_type; 3344 3345 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3346 ra_->set_oop(n_cond_set, true); 3347 3348 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3349 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3350 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3351 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3352 3353 nodes->push(n_compare); 3354 nodes->push(n_shift); 3355 nodes->push(n_add_base); 3356 nodes->push(n_cond_set); 3357 3358 } else { 3359 // before Power 7 3360 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3361 3362 n_add_base->add_req(n_region, n_compare, n_shift); 3363 n_add_base->_opnds[0] = op_dst; 3364 n_add_base->_opnds[1] = op_crx; 3365 n_add_base->_opnds[2] = op_dst; 3366 n_add_base->_bottom_type = _bottom_type; 3367 3368 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3369 ra_->set_oop(n_add_base, true); 3370 3371 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3372 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3373 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3374 3375 nodes->push(n_compare); 3376 nodes->push(n_shift); 3377 nodes->push(n_add_base); 3378 } 3379 %} 3380 3381 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3382 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3383 n1->add_req(n_region, n_src); 3384 n1->_opnds[0] = op_dst; 3385 n1->_opnds[1] = op_src; 3386 n1->_bottom_type = _bottom_type; 3387 3388 decodeN_addNode *n2 = new decodeN_addNode(); 3389 n2->add_req(n_region, n1); 3390 n2->_opnds[0] = op_dst; 3391 n2->_opnds[1] = op_dst; 3392 n2->_bottom_type = _bottom_type; 3393 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3394 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3395 3396 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3397 ra_->set_oop(n2, true); 3398 3399 nodes->push(n1); 3400 nodes->push(n2); 3401 %} 3402 3403 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3404 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3405 3406 MacroAssembler _masm(&cbuf); 3407 int cc = $cmp$$cmpcode; 3408 int flags_reg = $crx$$reg; 3409 Label done; 3410 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3411 // Branch if not (cmp crx). 3412 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3413 __ mr($dst$$Register, $src$$Register); 3414 // TODO PPC port __ endgroup_if_needed(_size == 12); 3415 __ bind(done); 3416 %} 3417 3418 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3419 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3420 3421 MacroAssembler _masm(&cbuf); 3422 Label done; 3423 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3424 // Branch if not (cmp crx). 3425 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3426 __ li($dst$$Register, $src$$constant); 3427 // TODO PPC port __ endgroup_if_needed(_size == 12); 3428 __ bind(done); 3429 %} 3430 3431 // This enc_class is needed so that scheduler gets proper 3432 // input mapping for latency computation. 3433 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3434 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3435 MacroAssembler _masm(&cbuf); 3436 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3437 %} 3438 3439 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3440 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3441 3442 MacroAssembler _masm(&cbuf); 3443 3444 Label done; 3445 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3446 __ li($dst$$Register, $zero$$constant); 3447 __ beq($crx$$CondRegister, done); 3448 __ li($dst$$Register, $notzero$$constant); 3449 __ bind(done); 3450 %} 3451 3452 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3453 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3454 3455 MacroAssembler _masm(&cbuf); 3456 3457 Label done; 3458 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3459 __ li($dst$$Register, $zero$$constant); 3460 __ beq($crx$$CondRegister, done); 3461 __ li($dst$$Register, $notzero$$constant); 3462 __ bind(done); 3463 %} 3464 3465 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3466 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3467 3468 MacroAssembler _masm(&cbuf); 3469 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3470 Label done; 3471 __ bso($crx$$CondRegister, done); 3472 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3473 // TODO PPC port __ endgroup_if_needed(_size == 12); 3474 __ bind(done); 3475 %} 3476 3477 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3478 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3479 3480 MacroAssembler _masm(&cbuf); 3481 Label done; 3482 __ bso($crx$$CondRegister, done); 3483 __ mffprd($dst$$Register, $src$$FloatRegister); 3484 // TODO PPC port __ endgroup_if_needed(_size == 12); 3485 __ bind(done); 3486 %} 3487 3488 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3489 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3490 3491 MacroAssembler _masm(&cbuf); 3492 Label d; // dummy 3493 __ bind(d); 3494 Label* p = ($lbl$$label); 3495 // `p' is `NULL' when this encoding class is used only to 3496 // determine the size of the encoded instruction. 3497 Label& l = (NULL == p)? d : *(p); 3498 int cc = $cmp$$cmpcode; 3499 int flags_reg = $crx$$reg; 3500 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3501 int bhint = Assembler::bhintNoHint; 3502 3503 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3504 if (_prob <= PROB_NEVER) { 3505 bhint = Assembler::bhintIsNotTaken; 3506 } else if (_prob >= PROB_ALWAYS) { 3507 bhint = Assembler::bhintIsTaken; 3508 } 3509 } 3510 3511 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3512 cc_to_biint(cc, flags_reg), 3513 l); 3514 %} 3515 3516 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3517 // The scheduler doesn't know about branch shortening, so we set the opcode 3518 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3519 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3520 3521 MacroAssembler _masm(&cbuf); 3522 Label d; // dummy 3523 __ bind(d); 3524 Label* p = ($lbl$$label); 3525 // `p' is `NULL' when this encoding class is used only to 3526 // determine the size of the encoded instruction. 3527 Label& l = (NULL == p)? d : *(p); 3528 int cc = $cmp$$cmpcode; 3529 int flags_reg = $crx$$reg; 3530 int bhint = Assembler::bhintNoHint; 3531 3532 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3533 if (_prob <= PROB_NEVER) { 3534 bhint = Assembler::bhintIsNotTaken; 3535 } else if (_prob >= PROB_ALWAYS) { 3536 bhint = Assembler::bhintIsTaken; 3537 } 3538 } 3539 3540 // Tell the conditional far branch to optimize itself when being relocated. 3541 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3542 cc_to_biint(cc, flags_reg), 3543 l, 3544 MacroAssembler::bc_far_optimize_on_relocate); 3545 %} 3546 3547 // Branch used with Power6 scheduling (can be shortened without changing the node). 3548 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3549 // The scheduler doesn't know about branch shortening, so we set the opcode 3550 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3551 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3552 3553 MacroAssembler _masm(&cbuf); 3554 Label d; // dummy 3555 __ bind(d); 3556 Label* p = ($lbl$$label); 3557 // `p' is `NULL' when this encoding class is used only to 3558 // determine the size of the encoded instruction. 3559 Label& l = (NULL == p)? d : *(p); 3560 int cc = $cmp$$cmpcode; 3561 int flags_reg = $crx$$reg; 3562 int bhint = Assembler::bhintNoHint; 3563 3564 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3565 if (_prob <= PROB_NEVER) { 3566 bhint = Assembler::bhintIsNotTaken; 3567 } else if (_prob >= PROB_ALWAYS) { 3568 bhint = Assembler::bhintIsTaken; 3569 } 3570 } 3571 3572 #if 0 // TODO: PPC port 3573 if (_size == 8) { 3574 // Tell the conditional far branch to optimize itself when being relocated. 3575 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3576 cc_to_biint(cc, flags_reg), 3577 l, 3578 MacroAssembler::bc_far_optimize_on_relocate); 3579 } else { 3580 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3581 cc_to_biint(cc, flags_reg), 3582 l); 3583 } 3584 #endif 3585 Unimplemented(); 3586 %} 3587 3588 // Postalloc expand emitter for loading a replicatef float constant from 3589 // the method's TOC. 3590 // Enc_class needed as consttanttablebase is not supported by postalloc 3591 // expand. 3592 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3593 // Create new nodes. 3594 3595 // Make an operand with the bit pattern to load as float. 3596 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3597 3598 loadConLNodesTuple loadConLNodes = 3599 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3600 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3601 3602 // Push new nodes. 3603 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3604 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3605 3606 assert(nodes->length() >= 1, "must have created at least 1 node"); 3607 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3608 %} 3609 3610 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3611 // Create new nodes. 3612 3613 // Make an operand with the bit pattern to load as float. 3614 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3615 immI_0Oper *op_zero = new immI_0Oper(0); 3616 3617 loadConLReplicatedNodesTuple loadConLNodes = 3618 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3619 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3620 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3621 3622 // Push new nodes. 3623 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3624 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3625 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3626 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3627 3628 assert(nodes->length() >= 1, "must have created at least 1 node"); 3629 %} 3630 3631 // This enc_class is needed so that scheduler gets proper 3632 // input mapping for latency computation. 3633 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3634 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3635 // Fake operand dst needed for PPC scheduler. 3636 assert($dst$$constant == 0x0, "dst must be 0x0"); 3637 3638 MacroAssembler _masm(&cbuf); 3639 // Mark the code position where the load from the safepoint 3640 // polling page was emitted as relocInfo::poll_type. 3641 __ relocate(relocInfo::poll_type); 3642 __ load_from_polling_page($poll$$Register); 3643 %} 3644 3645 // A Java static call or a runtime call. 3646 // 3647 // Branch-and-link relative to a trampoline. 3648 // The trampoline loads the target address and does a long branch to there. 3649 // In case we call java, the trampoline branches to a interpreter_stub 3650 // which loads the inline cache and the real call target from the constant pool. 3651 // 3652 // This basically looks like this: 3653 // 3654 // >>>> consts -+ -+ 3655 // | |- offset1 3656 // [call target1] | <-+ 3657 // [IC cache] |- offset2 3658 // [call target2] <--+ 3659 // 3660 // <<<< consts 3661 // >>>> insts 3662 // 3663 // bl offset16 -+ -+ ??? // How many bits available? 3664 // | | 3665 // <<<< insts | | 3666 // >>>> stubs | | 3667 // | |- trampoline_stub_Reloc 3668 // trampoline stub: | <-+ 3669 // r2 = toc | 3670 // r2 = [r2 + offset1] | // Load call target1 from const section 3671 // mtctr r2 | 3672 // bctr |- static_stub_Reloc 3673 // comp_to_interp_stub: <---+ 3674 // r1 = toc 3675 // ICreg = [r1 + IC_offset] // Load IC from const section 3676 // r1 = [r1 + offset2] // Load call target2 from const section 3677 // mtctr r1 3678 // bctr 3679 // 3680 // <<<< stubs 3681 // 3682 // The call instruction in the code either 3683 // - Branches directly to a compiled method if the offset is encodable in instruction. 3684 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3685 // - Branches to the compiled_to_interp stub if the target is interpreted. 3686 // 3687 // Further there are three relocations from the loads to the constants in 3688 // the constant section. 3689 // 3690 // Usage of r1 and r2 in the stubs allows to distinguish them. 3691 enc_class enc_java_static_call(method meth) %{ 3692 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3693 3694 MacroAssembler _masm(&cbuf); 3695 address entry_point = (address)$meth$$method; 3696 3697 if (!_method) { 3698 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3699 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3700 } else { 3701 // Remember the offset not the address. 3702 const int start_offset = __ offset(); 3703 3704 // The trampoline stub. 3705 // No entry point given, use the current pc. 3706 // Make sure branch fits into 3707 if (entry_point == 0) entry_point = __ pc(); 3708 3709 // Put the entry point as a constant into the constant pool. 3710 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3711 if (entry_point_toc_addr == NULL) { 3712 ciEnv::current()->record_out_of_memory_failure(); 3713 return; 3714 } 3715 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3716 3717 // Emit the trampoline stub which will be related to the branch-and-link below. 3718 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3719 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3720 int method_index = resolved_method_index(cbuf); 3721 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3722 : static_call_Relocation::spec(method_index)); 3723 3724 // The real call. 3725 // Note: At this point we do not have the address of the trampoline 3726 // stub, and the entry point might be too far away for bl, so __ pc() 3727 // serves as dummy and the bl will be patched later. 3728 cbuf.set_insts_mark(); 3729 __ bl(__ pc()); // Emits a relocation. 3730 3731 // The stub for call to interpreter. 3732 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3733 if (stub == NULL) { 3734 ciEnv::current()->record_failure("CodeCache is full"); 3735 return; 3736 } 3737 } 3738 %} 3739 3740 // Second node of expanded dynamic call - the call. 3741 enc_class enc_java_dynamic_call_sched(method meth) %{ 3742 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3743 3744 MacroAssembler _masm(&cbuf); 3745 3746 if (!ra_->C->in_scratch_emit_size()) { 3747 // Create a call trampoline stub for the given method. 3748 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3749 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3750 if (entry_point_const == NULL) { 3751 ciEnv::current()->record_out_of_memory_failure(); 3752 return; 3753 } 3754 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3755 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3756 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3757 3758 // Build relocation at call site with ic position as data. 3759 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3760 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3761 "must have one, but can't have both"); 3762 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3763 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3764 "must contain instruction offset"); 3765 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3766 ? _load_ic_hi_node->_cbuf_insts_offset 3767 : _load_ic_node->_cbuf_insts_offset; 3768 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3769 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3770 "should be load from TOC"); 3771 int method_index = resolved_method_index(cbuf); 3772 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3773 } 3774 3775 // At this point I do not have the address of the trampoline stub, 3776 // and the entry point might be too far away for bl. Pc() serves 3777 // as dummy and bl will be patched later. 3778 __ bl((address) __ pc()); 3779 %} 3780 3781 // postalloc expand emitter for virtual calls. 3782 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3783 3784 // Create the nodes for loading the IC from the TOC. 3785 loadConLNodesTuple loadConLNodes_IC = 3786 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3787 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3788 3789 // Create the call node. 3790 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3791 call->_method_handle_invoke = _method_handle_invoke; 3792 call->_vtable_index = _vtable_index; 3793 call->_method = _method; 3794 call->_bci = _bci; 3795 call->_optimized_virtual = _optimized_virtual; 3796 call->_tf = _tf; 3797 call->_entry_point = _entry_point; 3798 call->_cnt = _cnt; 3799 call->_argsize = _argsize; 3800 call->_oop_map = _oop_map; 3801 call->_jvms = _jvms; 3802 call->_jvmadj = _jvmadj; 3803 call->_in_rms = _in_rms; 3804 call->_nesting = _nesting; 3805 call->_override_symbolic_info = _override_symbolic_info; 3806 3807 // New call needs all inputs of old call. 3808 // Req... 3809 for (uint i = 0; i < req(); ++i) { 3810 // The expanded node does not need toc any more. 3811 // Add the inline cache constant here instead. This expresses the 3812 // register of the inline cache must be live at the call. 3813 // Else we would have to adapt JVMState by -1. 3814 if (i == mach_constant_base_node_input()) { 3815 call->add_req(loadConLNodes_IC._last); 3816 } else { 3817 call->add_req(in(i)); 3818 } 3819 } 3820 // ...as well as prec 3821 for (uint i = req(); i < len(); ++i) { 3822 call->add_prec(in(i)); 3823 } 3824 3825 // Remember nodes loading the inline cache into r19. 3826 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3827 call->_load_ic_node = loadConLNodes_IC._small; 3828 3829 // Operands for new nodes. 3830 call->_opnds[0] = _opnds[0]; 3831 call->_opnds[1] = _opnds[1]; 3832 3833 // Only the inline cache is associated with a register. 3834 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3835 3836 // Push new nodes. 3837 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3838 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3839 nodes->push(call); 3840 %} 3841 3842 // Compound version of call dynamic 3843 // Toc is only passed so that it can be used in ins_encode statement. 3844 // In the code we have to use $constanttablebase. 3845 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3846 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3847 MacroAssembler _masm(&cbuf); 3848 int start_offset = __ offset(); 3849 3850 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3851 #if 0 3852 int vtable_index = this->_vtable_index; 3853 if (_vtable_index < 0) { 3854 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3855 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3856 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3857 3858 // Virtual call relocation will point to ic load. 3859 address virtual_call_meta_addr = __ pc(); 3860 // Load a clear inline cache. 3861 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3862 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3863 if (!success) { 3864 ciEnv::current()->record_out_of_memory_failure(); 3865 return; 3866 } 3867 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3868 // to determine who we intended to call. 3869 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3870 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3871 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3872 "Fix constant in ret_addr_offset()"); 3873 } else { 3874 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3875 // Go thru the vtable. Get receiver klass. Receiver already 3876 // checked for non-null. If we'll go thru a C2I adapter, the 3877 // interpreter expects method in R19_method. 3878 3879 __ load_klass(R11_scratch1, R3); 3880 3881 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3882 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3883 __ li(R19_method, v_off); 3884 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3885 // NOTE: for vtable dispatches, the vtable entry will never be 3886 // null. However it may very well end up in handle_wrong_method 3887 // if the method is abstract for the particular class. 3888 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3889 // Call target. Either compiled code or C2I adapter. 3890 __ mtctr(R11_scratch1); 3891 __ bctrl(); 3892 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3893 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3894 } 3895 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3896 "Fix constant in ret_addr_offset()"); 3897 } 3898 #endif 3899 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3900 %} 3901 3902 // a runtime call 3903 enc_class enc_java_to_runtime_call (method meth) %{ 3904 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3905 3906 MacroAssembler _masm(&cbuf); 3907 const address start_pc = __ pc(); 3908 3909 #if defined(ABI_ELFv2) 3910 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3911 __ call_c(entry, relocInfo::runtime_call_type); 3912 #else 3913 // The function we're going to call. 3914 FunctionDescriptor fdtemp; 3915 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3916 3917 Register Rtoc = R12_scratch2; 3918 // Calculate the method's TOC. 3919 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3920 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3921 // pool entries; call_c_using_toc will optimize the call. 3922 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3923 if (!success) { 3924 ciEnv::current()->record_out_of_memory_failure(); 3925 return; 3926 } 3927 #endif 3928 3929 // Check the ret_addr_offset. 3930 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3931 "Fix constant in ret_addr_offset()"); 3932 %} 3933 3934 // Move to ctr for leaf call. 3935 // This enc_class is needed so that scheduler gets proper 3936 // input mapping for latency computation. 3937 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3938 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3939 MacroAssembler _masm(&cbuf); 3940 __ mtctr($src$$Register); 3941 %} 3942 3943 // Postalloc expand emitter for runtime leaf calls. 3944 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3945 loadConLNodesTuple loadConLNodes_Entry; 3946 #if defined(ABI_ELFv2) 3947 jlong entry_address = (jlong) this->entry_point(); 3948 assert(entry_address, "need address here"); 3949 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3950 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3951 #else 3952 // Get the struct that describes the function we are about to call. 3953 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3954 assert(fd, "need fd here"); 3955 jlong entry_address = (jlong) fd->entry(); 3956 // new nodes 3957 loadConLNodesTuple loadConLNodes_Env; 3958 loadConLNodesTuple loadConLNodes_Toc; 3959 3960 // Create nodes and operands for loading the entry point. 3961 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3962 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3963 3964 3965 // Create nodes and operands for loading the env pointer. 3966 if (fd->env() != NULL) { 3967 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3968 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3969 } else { 3970 loadConLNodes_Env._large_hi = NULL; 3971 loadConLNodes_Env._large_lo = NULL; 3972 loadConLNodes_Env._small = NULL; 3973 loadConLNodes_Env._last = new loadConL16Node(); 3974 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3975 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3976 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3977 } 3978 3979 // Create nodes and operands for loading the Toc point. 3980 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3981 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3982 #endif // ABI_ELFv2 3983 // mtctr node 3984 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3985 3986 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3987 mtctr->add_req(0, loadConLNodes_Entry._last); 3988 3989 mtctr->_opnds[0] = new iRegLdstOper(); 3990 mtctr->_opnds[1] = new iRegLdstOper(); 3991 3992 // call node 3993 MachCallLeafNode *call = new CallLeafDirectNode(); 3994 3995 call->_opnds[0] = _opnds[0]; 3996 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3997 3998 // Make the new call node look like the old one. 3999 call->_name = _name; 4000 call->_tf = _tf; 4001 call->_entry_point = _entry_point; 4002 call->_cnt = _cnt; 4003 call->_argsize = _argsize; 4004 call->_oop_map = _oop_map; 4005 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 4006 call->_jvms = NULL; 4007 call->_jvmadj = _jvmadj; 4008 call->_in_rms = _in_rms; 4009 call->_nesting = _nesting; 4010 4011 4012 // New call needs all inputs of old call. 4013 // Req... 4014 for (uint i = 0; i < req(); ++i) { 4015 if (i != mach_constant_base_node_input()) { 4016 call->add_req(in(i)); 4017 } 4018 } 4019 4020 // These must be reqired edges, as the registers are live up to 4021 // the call. Else the constants are handled as kills. 4022 call->add_req(mtctr); 4023 #if !defined(ABI_ELFv2) 4024 call->add_req(loadConLNodes_Env._last); 4025 call->add_req(loadConLNodes_Toc._last); 4026 #endif 4027 4028 // ...as well as prec 4029 for (uint i = req(); i < len(); ++i) { 4030 call->add_prec(in(i)); 4031 } 4032 4033 // registers 4034 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 4035 4036 // Insert the new nodes. 4037 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 4038 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 4039 #if !defined(ABI_ELFv2) 4040 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 4041 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 4042 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 4043 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 4044 #endif 4045 nodes->push(mtctr); 4046 nodes->push(call); 4047 %} 4048 %} 4049 4050 //----------FRAME-------------------------------------------------------------- 4051 // Definition of frame structure and management information. 4052 4053 frame %{ 4054 // What direction does stack grow in (assumed to be same for native & Java). 4055 stack_direction(TOWARDS_LOW); 4056 4057 // These two registers define part of the calling convention between 4058 // compiled code and the interpreter. 4059 4060 // Inline Cache Register or method for I2C. 4061 inline_cache_reg(R19); // R19_method 4062 4063 // Method Oop Register when calling interpreter. 4064 interpreter_method_oop_reg(R19); // R19_method 4065 4066 // Optional: name the operand used by cisc-spilling to access 4067 // [stack_pointer + offset]. 4068 cisc_spilling_operand_name(indOffset); 4069 4070 // Number of stack slots consumed by a Monitor enter. 4071 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 4072 4073 // Compiled code's Frame Pointer. 4074 frame_pointer(R1); // R1_SP 4075 4076 // Interpreter stores its frame pointer in a register which is 4077 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 4078 // interpreted java to compiled java. 4079 // 4080 // R14_state holds pointer to caller's cInterpreter. 4081 interpreter_frame_pointer(R14); // R14_state 4082 4083 stack_alignment(frame::alignment_in_bytes); 4084 4085 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4086 4087 // Number of outgoing stack slots killed above the 4088 // out_preserve_stack_slots for calls to C. Supports the var-args 4089 // backing area for register parms. 4090 // 4091 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4092 4093 // The after-PROLOG location of the return address. Location of 4094 // return address specifies a type (REG or STACK) and a number 4095 // representing the register number (i.e. - use a register name) or 4096 // stack slot. 4097 // 4098 // A: Link register is stored in stack slot ... 4099 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4100 // J: Therefore, we make sure that the link register is also in R11_scratch1 4101 // at the end of the prolog. 4102 // B: We use R20, now. 4103 //return_addr(REG R20); 4104 4105 // G: After reading the comments made by all the luminaries on their 4106 // failure to tell the compiler where the return address really is, 4107 // I hardly dare to try myself. However, I'm convinced it's in slot 4108 // 4 what apparently works and saves us some spills. 4109 return_addr(STACK 4); 4110 4111 // This is the body of the function 4112 // 4113 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4114 // uint length, // length of array 4115 // bool is_outgoing) 4116 // 4117 // The `sig' array is to be updated. sig[j] represents the location 4118 // of the j-th argument, either a register or a stack slot. 4119 4120 // Comment taken from i486.ad: 4121 // Body of function which returns an integer array locating 4122 // arguments either in registers or in stack slots. Passed an array 4123 // of ideal registers called "sig" and a "length" count. Stack-slot 4124 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4125 // arguments for a CALLEE. Incoming stack arguments are 4126 // automatically biased by the preserve_stack_slots field above. 4127 calling_convention %{ 4128 // No difference between ingoing/outgoing. Just pass false. 4129 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4130 %} 4131 4132 // Comment taken from i486.ad: 4133 // Body of function which returns an integer array locating 4134 // arguments either in registers or in stack slots. Passed an array 4135 // of ideal registers called "sig" and a "length" count. Stack-slot 4136 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4137 // arguments for a CALLEE. Incoming stack arguments are 4138 // automatically biased by the preserve_stack_slots field above. 4139 c_calling_convention %{ 4140 // This is obviously always outgoing. 4141 // C argument in register AND stack slot. 4142 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4143 %} 4144 4145 // Location of native (C/C++) and interpreter return values. This 4146 // is specified to be the same as Java. In the 32-bit VM, long 4147 // values are actually returned from native calls in O0:O1 and 4148 // returned to the interpreter in I0:I1. The copying to and from 4149 // the register pairs is done by the appropriate call and epilog 4150 // opcodes. This simplifies the register allocator. 4151 c_return_value %{ 4152 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4153 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4154 "only return normal values"); 4155 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4156 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4157 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4158 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4159 %} 4160 4161 // Location of compiled Java return values. Same as C 4162 return_value %{ 4163 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4164 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4165 "only return normal values"); 4166 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4167 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4168 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4169 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4170 %} 4171 %} 4172 4173 4174 //----------ATTRIBUTES--------------------------------------------------------- 4175 4176 //----------Operand Attributes------------------------------------------------- 4177 op_attrib op_cost(1); // Required cost attribute. 4178 4179 //----------Instruction Attributes--------------------------------------------- 4180 4181 // Cost attribute. required. 4182 ins_attrib ins_cost(DEFAULT_COST); 4183 4184 // Is this instruction a non-matching short branch variant of some 4185 // long branch? Not required. 4186 ins_attrib ins_short_branch(0); 4187 4188 ins_attrib ins_is_TrapBasedCheckNode(true); 4189 4190 // Number of constants. 4191 // This instruction uses the given number of constants 4192 // (optional attribute). 4193 // This is needed to determine in time whether the constant pool will 4194 // exceed 4000 entries. Before postalloc_expand the overall number of constants 4195 // is determined. It's also used to compute the constant pool size 4196 // in Output(). 4197 ins_attrib ins_num_consts(0); 4198 4199 // Required alignment attribute (must be a power of 2) specifies the 4200 // alignment that some part of the instruction (not necessarily the 4201 // start) requires. If > 1, a compute_padding() function must be 4202 // provided for the instruction. 4203 ins_attrib ins_alignment(1); 4204 4205 // Enforce/prohibit rematerializations. 4206 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4207 // then rematerialization of that instruction is prohibited and the 4208 // instruction's value will be spilled if necessary. 4209 // Causes that MachNode::rematerialize() returns false. 4210 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 4211 // then rematerialization should be enforced and a copy of the instruction 4212 // should be inserted if possible; rematerialization is not guaranteed. 4213 // Note: this may result in rematerializations in front of every use. 4214 // Causes that MachNode::rematerialize() can return true. 4215 // (optional attribute) 4216 ins_attrib ins_cannot_rematerialize(false); 4217 ins_attrib ins_should_rematerialize(false); 4218 4219 // Instruction has variable size depending on alignment. 4220 ins_attrib ins_variable_size_depending_on_alignment(false); 4221 4222 // Instruction is a nop. 4223 ins_attrib ins_is_nop(false); 4224 4225 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4226 ins_attrib ins_use_mach_if_fast_lock_node(false); 4227 4228 // Field for the toc offset of a constant. 4229 // 4230 // This is needed if the toc offset is not encodable as an immediate in 4231 // the PPC load instruction. If so, the upper (hi) bits of the offset are 4232 // added to the toc, and from this a load with immediate is performed. 4233 // With postalloc expand, we get two nodes that require the same offset 4234 // but which don't know about each other. The offset is only known 4235 // when the constant is added to the constant pool during emitting. 4236 // It is generated in the 'hi'-node adding the upper bits, and saved 4237 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 4238 // the offset from there when it gets encoded. 4239 ins_attrib ins_field_const_toc_offset(0); 4240 ins_attrib ins_field_const_toc_offset_hi_node(0); 4241 4242 // A field that can hold the instructions offset in the code buffer. 4243 // Set in the nodes emitter. 4244 ins_attrib ins_field_cbuf_insts_offset(-1); 4245 4246 // Fields for referencing a call's load-IC-node. 4247 // If the toc offset can not be encoded as an immediate in a load, we 4248 // use two nodes. 4249 ins_attrib ins_field_load_ic_hi_node(0); 4250 ins_attrib ins_field_load_ic_node(0); 4251 4252 //----------OPERANDS----------------------------------------------------------- 4253 // Operand definitions must precede instruction definitions for correct 4254 // parsing in the ADLC because operands constitute user defined types 4255 // which are used in instruction definitions. 4256 // 4257 // Formats are generated automatically for constants and base registers. 4258 4259 operand vecX() %{ 4260 constraint(ALLOC_IN_RC(vs_reg)); 4261 match(VecX); 4262 4263 format %{ %} 4264 interface(REG_INTER); 4265 %} 4266 4267 //----------Simple Operands---------------------------------------------------- 4268 // Immediate Operands 4269 4270 // Integer Immediate: 32-bit 4271 operand immI() %{ 4272 match(ConI); 4273 op_cost(40); 4274 format %{ %} 4275 interface(CONST_INTER); 4276 %} 4277 4278 operand immI8() %{ 4279 predicate(Assembler::is_simm(n->get_int(), 8)); 4280 op_cost(0); 4281 match(ConI); 4282 format %{ %} 4283 interface(CONST_INTER); 4284 %} 4285 4286 // Integer Immediate: 16-bit 4287 operand immI16() %{ 4288 predicate(Assembler::is_simm(n->get_int(), 16)); 4289 op_cost(0); 4290 match(ConI); 4291 format %{ %} 4292 interface(CONST_INTER); 4293 %} 4294 4295 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4296 operand immIhi16() %{ 4297 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4298 match(ConI); 4299 op_cost(0); 4300 format %{ %} 4301 interface(CONST_INTER); 4302 %} 4303 4304 operand immInegpow2() %{ 4305 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 4306 match(ConI); 4307 op_cost(0); 4308 format %{ %} 4309 interface(CONST_INTER); 4310 %} 4311 4312 operand immIpow2minus1() %{ 4313 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 4314 match(ConI); 4315 op_cost(0); 4316 format %{ %} 4317 interface(CONST_INTER); 4318 %} 4319 4320 operand immIpowerOf2() %{ 4321 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 4322 match(ConI); 4323 op_cost(0); 4324 format %{ %} 4325 interface(CONST_INTER); 4326 %} 4327 4328 // Unsigned Integer Immediate: the values 0-31 4329 operand uimmI5() %{ 4330 predicate(Assembler::is_uimm(n->get_int(), 5)); 4331 match(ConI); 4332 op_cost(0); 4333 format %{ %} 4334 interface(CONST_INTER); 4335 %} 4336 4337 // Unsigned Integer Immediate: 6-bit 4338 operand uimmI6() %{ 4339 predicate(Assembler::is_uimm(n->get_int(), 6)); 4340 match(ConI); 4341 op_cost(0); 4342 format %{ %} 4343 interface(CONST_INTER); 4344 %} 4345 4346 // Unsigned Integer Immediate: 6-bit int, greater than 32 4347 operand uimmI6_ge32() %{ 4348 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4349 match(ConI); 4350 op_cost(0); 4351 format %{ %} 4352 interface(CONST_INTER); 4353 %} 4354 4355 // Unsigned Integer Immediate: 15-bit 4356 operand uimmI15() %{ 4357 predicate(Assembler::is_uimm(n->get_int(), 15)); 4358 match(ConI); 4359 op_cost(0); 4360 format %{ %} 4361 interface(CONST_INTER); 4362 %} 4363 4364 // Unsigned Integer Immediate: 16-bit 4365 operand uimmI16() %{ 4366 predicate(Assembler::is_uimm(n->get_int(), 16)); 4367 match(ConI); 4368 op_cost(0); 4369 format %{ %} 4370 interface(CONST_INTER); 4371 %} 4372 4373 // constant 'int 0'. 4374 operand immI_0() %{ 4375 predicate(n->get_int() == 0); 4376 match(ConI); 4377 op_cost(0); 4378 format %{ %} 4379 interface(CONST_INTER); 4380 %} 4381 4382 // constant 'int 1'. 4383 operand immI_1() %{ 4384 predicate(n->get_int() == 1); 4385 match(ConI); 4386 op_cost(0); 4387 format %{ %} 4388 interface(CONST_INTER); 4389 %} 4390 4391 // constant 'int -1'. 4392 operand immI_minus1() %{ 4393 predicate(n->get_int() == -1); 4394 match(ConI); 4395 op_cost(0); 4396 format %{ %} 4397 interface(CONST_INTER); 4398 %} 4399 4400 // int value 16. 4401 operand immI_16() %{ 4402 predicate(n->get_int() == 16); 4403 match(ConI); 4404 op_cost(0); 4405 format %{ %} 4406 interface(CONST_INTER); 4407 %} 4408 4409 // int value 24. 4410 operand immI_24() %{ 4411 predicate(n->get_int() == 24); 4412 match(ConI); 4413 op_cost(0); 4414 format %{ %} 4415 interface(CONST_INTER); 4416 %} 4417 4418 // Compressed oops constants 4419 // Pointer Immediate 4420 operand immN() %{ 4421 match(ConN); 4422 4423 op_cost(10); 4424 format %{ %} 4425 interface(CONST_INTER); 4426 %} 4427 4428 // NULL Pointer Immediate 4429 operand immN_0() %{ 4430 predicate(n->get_narrowcon() == 0); 4431 match(ConN); 4432 4433 op_cost(0); 4434 format %{ %} 4435 interface(CONST_INTER); 4436 %} 4437 4438 // Compressed klass constants 4439 operand immNKlass() %{ 4440 match(ConNKlass); 4441 4442 op_cost(0); 4443 format %{ %} 4444 interface(CONST_INTER); 4445 %} 4446 4447 // This operand can be used to avoid matching of an instruct 4448 // with chain rule. 4449 operand immNKlass_NM() %{ 4450 match(ConNKlass); 4451 predicate(false); 4452 op_cost(0); 4453 format %{ %} 4454 interface(CONST_INTER); 4455 %} 4456 4457 // Pointer Immediate: 64-bit 4458 operand immP() %{ 4459 match(ConP); 4460 op_cost(0); 4461 format %{ %} 4462 interface(CONST_INTER); 4463 %} 4464 4465 // Operand to avoid match of loadConP. 4466 // This operand can be used to avoid matching of an instruct 4467 // with chain rule. 4468 operand immP_NM() %{ 4469 match(ConP); 4470 predicate(false); 4471 op_cost(0); 4472 format %{ %} 4473 interface(CONST_INTER); 4474 %} 4475 4476 // costant 'pointer 0'. 4477 operand immP_0() %{ 4478 predicate(n->get_ptr() == 0); 4479 match(ConP); 4480 op_cost(0); 4481 format %{ %} 4482 interface(CONST_INTER); 4483 %} 4484 4485 // pointer 0x0 or 0x1 4486 operand immP_0or1() %{ 4487 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4488 match(ConP); 4489 op_cost(0); 4490 format %{ %} 4491 interface(CONST_INTER); 4492 %} 4493 4494 operand immL() %{ 4495 match(ConL); 4496 op_cost(40); 4497 format %{ %} 4498 interface(CONST_INTER); 4499 %} 4500 4501 operand immLmax30() %{ 4502 predicate((n->get_long() <= 30)); 4503 match(ConL); 4504 op_cost(0); 4505 format %{ %} 4506 interface(CONST_INTER); 4507 %} 4508 4509 // Long Immediate: 16-bit 4510 operand immL16() %{ 4511 predicate(Assembler::is_simm(n->get_long(), 16)); 4512 match(ConL); 4513 op_cost(0); 4514 format %{ %} 4515 interface(CONST_INTER); 4516 %} 4517 4518 // Long Immediate: 16-bit, 4-aligned 4519 operand immL16Alg4() %{ 4520 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4521 match(ConL); 4522 op_cost(0); 4523 format %{ %} 4524 interface(CONST_INTER); 4525 %} 4526 4527 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4528 operand immL32hi16() %{ 4529 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4530 match(ConL); 4531 op_cost(0); 4532 format %{ %} 4533 interface(CONST_INTER); 4534 %} 4535 4536 // Long Immediate: 32-bit 4537 operand immL32() %{ 4538 predicate(Assembler::is_simm(n->get_long(), 32)); 4539 match(ConL); 4540 op_cost(0); 4541 format %{ %} 4542 interface(CONST_INTER); 4543 %} 4544 4545 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4546 operand immLhighest16() %{ 4547 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4548 match(ConL); 4549 op_cost(0); 4550 format %{ %} 4551 interface(CONST_INTER); 4552 %} 4553 4554 operand immLnegpow2() %{ 4555 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4556 match(ConL); 4557 op_cost(0); 4558 format %{ %} 4559 interface(CONST_INTER); 4560 %} 4561 4562 operand immLpow2minus1() %{ 4563 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4564 (n->get_long() != (jlong)0xffffffffffffffffL)); 4565 match(ConL); 4566 op_cost(0); 4567 format %{ %} 4568 interface(CONST_INTER); 4569 %} 4570 4571 // constant 'long 0'. 4572 operand immL_0() %{ 4573 predicate(n->get_long() == 0L); 4574 match(ConL); 4575 op_cost(0); 4576 format %{ %} 4577 interface(CONST_INTER); 4578 %} 4579 4580 // constat ' long -1'. 4581 operand immL_minus1() %{ 4582 predicate(n->get_long() == -1L); 4583 match(ConL); 4584 op_cost(0); 4585 format %{ %} 4586 interface(CONST_INTER); 4587 %} 4588 4589 // Long Immediate: low 32-bit mask 4590 operand immL_32bits() %{ 4591 predicate(n->get_long() == 0xFFFFFFFFL); 4592 match(ConL); 4593 op_cost(0); 4594 format %{ %} 4595 interface(CONST_INTER); 4596 %} 4597 4598 // Unsigned Long Immediate: 16-bit 4599 operand uimmL16() %{ 4600 predicate(Assembler::is_uimm(n->get_long(), 16)); 4601 match(ConL); 4602 op_cost(0); 4603 format %{ %} 4604 interface(CONST_INTER); 4605 %} 4606 4607 // Float Immediate 4608 operand immF() %{ 4609 match(ConF); 4610 op_cost(40); 4611 format %{ %} 4612 interface(CONST_INTER); 4613 %} 4614 4615 // Float Immediate: +0.0f. 4616 operand immF_0() %{ 4617 predicate(jint_cast(n->getf()) == 0); 4618 match(ConF); 4619 4620 op_cost(0); 4621 format %{ %} 4622 interface(CONST_INTER); 4623 %} 4624 4625 // Double Immediate 4626 operand immD() %{ 4627 match(ConD); 4628 op_cost(40); 4629 format %{ %} 4630 interface(CONST_INTER); 4631 %} 4632 4633 // Integer Register Operands 4634 // Integer Destination Register 4635 // See definition of reg_class bits32_reg_rw. 4636 operand iRegIdst() %{ 4637 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4638 match(RegI); 4639 match(rscratch1RegI); 4640 match(rscratch2RegI); 4641 match(rarg1RegI); 4642 match(rarg2RegI); 4643 match(rarg3RegI); 4644 match(rarg4RegI); 4645 format %{ %} 4646 interface(REG_INTER); 4647 %} 4648 4649 // Integer Source Register 4650 // See definition of reg_class bits32_reg_ro. 4651 operand iRegIsrc() %{ 4652 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4653 match(RegI); 4654 match(rscratch1RegI); 4655 match(rscratch2RegI); 4656 match(rarg1RegI); 4657 match(rarg2RegI); 4658 match(rarg3RegI); 4659 match(rarg4RegI); 4660 format %{ %} 4661 interface(REG_INTER); 4662 %} 4663 4664 operand rscratch1RegI() %{ 4665 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4666 match(iRegIdst); 4667 format %{ %} 4668 interface(REG_INTER); 4669 %} 4670 4671 operand rscratch2RegI() %{ 4672 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4673 match(iRegIdst); 4674 format %{ %} 4675 interface(REG_INTER); 4676 %} 4677 4678 operand rarg1RegI() %{ 4679 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4680 match(iRegIdst); 4681 format %{ %} 4682 interface(REG_INTER); 4683 %} 4684 4685 operand rarg2RegI() %{ 4686 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4687 match(iRegIdst); 4688 format %{ %} 4689 interface(REG_INTER); 4690 %} 4691 4692 operand rarg3RegI() %{ 4693 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4694 match(iRegIdst); 4695 format %{ %} 4696 interface(REG_INTER); 4697 %} 4698 4699 operand rarg4RegI() %{ 4700 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4701 match(iRegIdst); 4702 format %{ %} 4703 interface(REG_INTER); 4704 %} 4705 4706 operand rarg1RegL() %{ 4707 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4708 match(iRegLdst); 4709 format %{ %} 4710 interface(REG_INTER); 4711 %} 4712 4713 operand rarg2RegL() %{ 4714 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4715 match(iRegLdst); 4716 format %{ %} 4717 interface(REG_INTER); 4718 %} 4719 4720 operand rarg3RegL() %{ 4721 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4722 match(iRegLdst); 4723 format %{ %} 4724 interface(REG_INTER); 4725 %} 4726 4727 operand rarg4RegL() %{ 4728 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4729 match(iRegLdst); 4730 format %{ %} 4731 interface(REG_INTER); 4732 %} 4733 4734 // Pointer Destination Register 4735 // See definition of reg_class bits64_reg_rw. 4736 operand iRegPdst() %{ 4737 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4738 match(RegP); 4739 match(rscratch1RegP); 4740 match(rscratch2RegP); 4741 match(rarg1RegP); 4742 match(rarg2RegP); 4743 match(rarg3RegP); 4744 match(rarg4RegP); 4745 format %{ %} 4746 interface(REG_INTER); 4747 %} 4748 4749 // Pointer Destination Register 4750 // Operand not using r11 and r12 (killed in epilog). 4751 operand iRegPdstNoScratch() %{ 4752 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4753 match(RegP); 4754 match(rarg1RegP); 4755 match(rarg2RegP); 4756 match(rarg3RegP); 4757 match(rarg4RegP); 4758 format %{ %} 4759 interface(REG_INTER); 4760 %} 4761 4762 // Pointer Source Register 4763 // See definition of reg_class bits64_reg_ro. 4764 operand iRegPsrc() %{ 4765 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4766 match(RegP); 4767 match(iRegPdst); 4768 match(rscratch1RegP); 4769 match(rscratch2RegP); 4770 match(rarg1RegP); 4771 match(rarg2RegP); 4772 match(rarg3RegP); 4773 match(rarg4RegP); 4774 match(threadRegP); 4775 format %{ %} 4776 interface(REG_INTER); 4777 %} 4778 4779 // Thread operand. 4780 operand threadRegP() %{ 4781 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4782 match(iRegPdst); 4783 format %{ "R16" %} 4784 interface(REG_INTER); 4785 %} 4786 4787 operand rscratch1RegP() %{ 4788 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4789 match(iRegPdst); 4790 format %{ "R11" %} 4791 interface(REG_INTER); 4792 %} 4793 4794 operand rscratch2RegP() %{ 4795 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4796 match(iRegPdst); 4797 format %{ %} 4798 interface(REG_INTER); 4799 %} 4800 4801 operand rarg1RegP() %{ 4802 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4803 match(iRegPdst); 4804 format %{ %} 4805 interface(REG_INTER); 4806 %} 4807 4808 operand rarg2RegP() %{ 4809 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4810 match(iRegPdst); 4811 format %{ %} 4812 interface(REG_INTER); 4813 %} 4814 4815 operand rarg3RegP() %{ 4816 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4817 match(iRegPdst); 4818 format %{ %} 4819 interface(REG_INTER); 4820 %} 4821 4822 operand rarg4RegP() %{ 4823 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4824 match(iRegPdst); 4825 format %{ %} 4826 interface(REG_INTER); 4827 %} 4828 4829 operand iRegNsrc() %{ 4830 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4831 match(RegN); 4832 match(iRegNdst); 4833 4834 format %{ %} 4835 interface(REG_INTER); 4836 %} 4837 4838 operand iRegNdst() %{ 4839 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4840 match(RegN); 4841 4842 format %{ %} 4843 interface(REG_INTER); 4844 %} 4845 4846 // Long Destination Register 4847 // See definition of reg_class bits64_reg_rw. 4848 operand iRegLdst() %{ 4849 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4850 match(RegL); 4851 match(rscratch1RegL); 4852 match(rscratch2RegL); 4853 format %{ %} 4854 interface(REG_INTER); 4855 %} 4856 4857 // Long Source Register 4858 // See definition of reg_class bits64_reg_ro. 4859 operand iRegLsrc() %{ 4860 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4861 match(RegL); 4862 match(iRegLdst); 4863 match(rscratch1RegL); 4864 match(rscratch2RegL); 4865 format %{ %} 4866 interface(REG_INTER); 4867 %} 4868 4869 // Special operand for ConvL2I. 4870 operand iRegL2Isrc(iRegLsrc reg) %{ 4871 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4872 match(ConvL2I reg); 4873 format %{ "ConvL2I($reg)" %} 4874 interface(REG_INTER) 4875 %} 4876 4877 operand rscratch1RegL() %{ 4878 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4879 match(RegL); 4880 format %{ %} 4881 interface(REG_INTER); 4882 %} 4883 4884 operand rscratch2RegL() %{ 4885 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4886 match(RegL); 4887 format %{ %} 4888 interface(REG_INTER); 4889 %} 4890 4891 // Condition Code Flag Registers 4892 operand flagsReg() %{ 4893 constraint(ALLOC_IN_RC(int_flags)); 4894 match(RegFlags); 4895 format %{ %} 4896 interface(REG_INTER); 4897 %} 4898 4899 operand flagsRegSrc() %{ 4900 constraint(ALLOC_IN_RC(int_flags_ro)); 4901 match(RegFlags); 4902 match(flagsReg); 4903 match(flagsRegCR0); 4904 format %{ %} 4905 interface(REG_INTER); 4906 %} 4907 4908 // Condition Code Flag Register CR0 4909 operand flagsRegCR0() %{ 4910 constraint(ALLOC_IN_RC(int_flags_CR0)); 4911 match(RegFlags); 4912 format %{ "CR0" %} 4913 interface(REG_INTER); 4914 %} 4915 4916 operand flagsRegCR1() %{ 4917 constraint(ALLOC_IN_RC(int_flags_CR1)); 4918 match(RegFlags); 4919 format %{ "CR1" %} 4920 interface(REG_INTER); 4921 %} 4922 4923 operand flagsRegCR6() %{ 4924 constraint(ALLOC_IN_RC(int_flags_CR6)); 4925 match(RegFlags); 4926 format %{ "CR6" %} 4927 interface(REG_INTER); 4928 %} 4929 4930 operand regCTR() %{ 4931 constraint(ALLOC_IN_RC(ctr_reg)); 4932 // RegFlags should work. Introducing a RegSpecial type would cause a 4933 // lot of changes. 4934 match(RegFlags); 4935 format %{"SR_CTR" %} 4936 interface(REG_INTER); 4937 %} 4938 4939 operand regD() %{ 4940 constraint(ALLOC_IN_RC(dbl_reg)); 4941 match(RegD); 4942 format %{ %} 4943 interface(REG_INTER); 4944 %} 4945 4946 operand regF() %{ 4947 constraint(ALLOC_IN_RC(flt_reg)); 4948 match(RegF); 4949 format %{ %} 4950 interface(REG_INTER); 4951 %} 4952 4953 // Special Registers 4954 4955 // Method Register 4956 operand inline_cache_regP(iRegPdst reg) %{ 4957 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4958 match(reg); 4959 format %{ %} 4960 interface(REG_INTER); 4961 %} 4962 4963 operand compiler_method_oop_regP(iRegPdst reg) %{ 4964 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4965 match(reg); 4966 format %{ %} 4967 interface(REG_INTER); 4968 %} 4969 4970 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4971 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4972 match(reg); 4973 format %{ %} 4974 interface(REG_INTER); 4975 %} 4976 4977 // Operands to remove register moves in unscaled mode. 4978 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4979 operand iRegP2N(iRegPsrc reg) %{ 4980 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4981 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4982 match(EncodeP reg); 4983 format %{ "$reg" %} 4984 interface(REG_INTER) 4985 %} 4986 4987 operand iRegN2P(iRegNsrc reg) %{ 4988 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4989 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4990 match(DecodeN reg); 4991 format %{ "$reg" %} 4992 interface(REG_INTER) 4993 %} 4994 4995 operand iRegN2P_klass(iRegNsrc reg) %{ 4996 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4997 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4998 match(DecodeNKlass reg); 4999 format %{ "$reg" %} 5000 interface(REG_INTER) 5001 %} 5002 5003 //----------Complex Operands--------------------------------------------------- 5004 // Indirect Memory Reference 5005 operand indirect(iRegPsrc reg) %{ 5006 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5007 match(reg); 5008 op_cost(100); 5009 format %{ "[$reg]" %} 5010 interface(MEMORY_INTER) %{ 5011 base($reg); 5012 index(0x0); 5013 scale(0x0); 5014 disp(0x0); 5015 %} 5016 %} 5017 5018 // Indirect with Offset 5019 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 5020 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5021 match(AddP reg offset); 5022 op_cost(100); 5023 format %{ "[$reg + $offset]" %} 5024 interface(MEMORY_INTER) %{ 5025 base($reg); 5026 index(0x0); 5027 scale(0x0); 5028 disp($offset); 5029 %} 5030 %} 5031 5032 // Indirect with 4-aligned Offset 5033 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 5034 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5035 match(AddP reg offset); 5036 op_cost(100); 5037 format %{ "[$reg + $offset]" %} 5038 interface(MEMORY_INTER) %{ 5039 base($reg); 5040 index(0x0); 5041 scale(0x0); 5042 disp($offset); 5043 %} 5044 %} 5045 5046 //----------Complex Operands for Compressed OOPs------------------------------- 5047 // Compressed OOPs with narrow_oop_shift == 0. 5048 5049 // Indirect Memory Reference, compressed OOP 5050 operand indirectNarrow(iRegNsrc reg) %{ 5051 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5052 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5053 match(DecodeN reg); 5054 op_cost(100); 5055 format %{ "[$reg]" %} 5056 interface(MEMORY_INTER) %{ 5057 base($reg); 5058 index(0x0); 5059 scale(0x0); 5060 disp(0x0); 5061 %} 5062 %} 5063 5064 operand indirectNarrow_klass(iRegNsrc reg) %{ 5065 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5066 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5067 match(DecodeNKlass reg); 5068 op_cost(100); 5069 format %{ "[$reg]" %} 5070 interface(MEMORY_INTER) %{ 5071 base($reg); 5072 index(0x0); 5073 scale(0x0); 5074 disp(0x0); 5075 %} 5076 %} 5077 5078 // Indirect with Offset, compressed OOP 5079 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 5080 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5081 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5082 match(AddP (DecodeN reg) offset); 5083 op_cost(100); 5084 format %{ "[$reg + $offset]" %} 5085 interface(MEMORY_INTER) %{ 5086 base($reg); 5087 index(0x0); 5088 scale(0x0); 5089 disp($offset); 5090 %} 5091 %} 5092 5093 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5094 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5095 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5096 match(AddP (DecodeNKlass reg) offset); 5097 op_cost(100); 5098 format %{ "[$reg + $offset]" %} 5099 interface(MEMORY_INTER) %{ 5100 base($reg); 5101 index(0x0); 5102 scale(0x0); 5103 disp($offset); 5104 %} 5105 %} 5106 5107 // Indirect with 4-aligned Offset, compressed OOP 5108 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 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 indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5123 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_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 //----------Special Memory Operands-------------------------------------------- 5137 // Stack Slot Operand 5138 // 5139 // This operand is used for loading and storing temporary values on 5140 // the stack where a match requires a value to flow through memory. 5141 operand stackSlotI(sRegI reg) %{ 5142 constraint(ALLOC_IN_RC(stack_slots)); 5143 op_cost(100); 5144 //match(RegI); 5145 format %{ "[sp+$reg]" %} 5146 interface(MEMORY_INTER) %{ 5147 base(0x1); // R1_SP 5148 index(0x0); 5149 scale(0x0); 5150 disp($reg); // Stack Offset 5151 %} 5152 %} 5153 5154 operand stackSlotL(sRegL reg) %{ 5155 constraint(ALLOC_IN_RC(stack_slots)); 5156 op_cost(100); 5157 //match(RegL); 5158 format %{ "[sp+$reg]" %} 5159 interface(MEMORY_INTER) %{ 5160 base(0x1); // R1_SP 5161 index(0x0); 5162 scale(0x0); 5163 disp($reg); // Stack Offset 5164 %} 5165 %} 5166 5167 operand stackSlotP(sRegP reg) %{ 5168 constraint(ALLOC_IN_RC(stack_slots)); 5169 op_cost(100); 5170 //match(RegP); 5171 format %{ "[sp+$reg]" %} 5172 interface(MEMORY_INTER) %{ 5173 base(0x1); // R1_SP 5174 index(0x0); 5175 scale(0x0); 5176 disp($reg); // Stack Offset 5177 %} 5178 %} 5179 5180 operand stackSlotF(sRegF reg) %{ 5181 constraint(ALLOC_IN_RC(stack_slots)); 5182 op_cost(100); 5183 //match(RegF); 5184 format %{ "[sp+$reg]" %} 5185 interface(MEMORY_INTER) %{ 5186 base(0x1); // R1_SP 5187 index(0x0); 5188 scale(0x0); 5189 disp($reg); // Stack Offset 5190 %} 5191 %} 5192 5193 operand stackSlotD(sRegD reg) %{ 5194 constraint(ALLOC_IN_RC(stack_slots)); 5195 op_cost(100); 5196 //match(RegD); 5197 format %{ "[sp+$reg]" %} 5198 interface(MEMORY_INTER) %{ 5199 base(0x1); // R1_SP 5200 index(0x0); 5201 scale(0x0); 5202 disp($reg); // Stack Offset 5203 %} 5204 %} 5205 5206 // Operands for expressing Control Flow 5207 // NOTE: Label is a predefined operand which should not be redefined in 5208 // the AD file. It is generically handled within the ADLC. 5209 5210 //----------Conditional Branch Operands---------------------------------------- 5211 // Comparison Op 5212 // 5213 // This is the operation of the comparison, and is limited to the 5214 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5215 // (!=). 5216 // 5217 // Other attributes of the comparison, such as unsignedness, are specified 5218 // by the comparison instruction that sets a condition code flags register. 5219 // That result is represented by a flags operand whose subtype is appropriate 5220 // to the unsignedness (etc.) of the comparison. 5221 // 5222 // Later, the instruction which matches both the Comparison Op (a Bool) and 5223 // the flags (produced by the Cmp) specifies the coding of the comparison op 5224 // by matching a specific subtype of Bool operand below. 5225 5226 // When used for floating point comparisons: unordered same as less. 5227 operand cmpOp() %{ 5228 match(Bool); 5229 format %{ "" %} 5230 interface(COND_INTER) %{ 5231 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5232 // BO & BI 5233 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5234 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5235 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5236 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5237 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5238 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5239 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5240 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5241 %} 5242 %} 5243 5244 //----------OPERAND CLASSES---------------------------------------------------- 5245 // Operand Classes are groups of operands that are used to simplify 5246 // instruction definitions by not requiring the AD writer to specify 5247 // seperate instructions for every form of operand when the 5248 // instruction accepts multiple operand types with the same basic 5249 // encoding and format. The classic case of this is memory operands. 5250 // Indirect is not included since its use is limited to Compare & Swap. 5251 5252 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5253 // Memory operand where offsets are 4-aligned. Required for ld, std. 5254 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5255 opclass indirectMemory(indirect, indirectNarrow); 5256 5257 // Special opclass for I and ConvL2I. 5258 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5259 5260 // Operand classes to match encode and decode. iRegN_P2N is only used 5261 // for storeN. I have never seen an encode node elsewhere. 5262 opclass iRegN_P2N(iRegNsrc, iRegP2N); 5263 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5264 5265 //----------PIPELINE----------------------------------------------------------- 5266 5267 pipeline %{ 5268 5269 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5270 // J. Res. & Dev., No. 1, Jan. 2002. 5271 5272 //----------ATTRIBUTES--------------------------------------------------------- 5273 attributes %{ 5274 5275 // Power4 instructions are of fixed length. 5276 fixed_size_instructions; 5277 5278 // TODO: if `bundle' means number of instructions fetched 5279 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5280 // max instructions issued per cycle, this is 5. 5281 max_instructions_per_bundle = 8; 5282 5283 // A Power4 instruction is 4 bytes long. 5284 instruction_unit_size = 4; 5285 5286 // The Power4 processor fetches 64 bytes... 5287 instruction_fetch_unit_size = 64; 5288 5289 // ...in one line 5290 instruction_fetch_units = 1 5291 5292 // Unused, list one so that array generated by adlc is not empty. 5293 // Aix compiler chokes if _nop_count = 0. 5294 nops(fxNop); 5295 %} 5296 5297 //----------RESOURCES---------------------------------------------------------- 5298 // Resources are the functional units available to the machine 5299 resources( 5300 PPC_BR, // branch unit 5301 PPC_CR, // condition unit 5302 PPC_FX1, // integer arithmetic unit 1 5303 PPC_FX2, // integer arithmetic unit 2 5304 PPC_LDST1, // load/store unit 1 5305 PPC_LDST2, // load/store unit 2 5306 PPC_FP1, // float arithmetic unit 1 5307 PPC_FP2, // float arithmetic unit 2 5308 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5309 PPC_FX = PPC_FX1 | PPC_FX2, 5310 PPC_FP = PPC_FP1 | PPC_FP2 5311 ); 5312 5313 //----------PIPELINE DESCRIPTION----------------------------------------------- 5314 // Pipeline Description specifies the stages in the machine's pipeline 5315 pipe_desc( 5316 // Power4 longest pipeline path 5317 PPC_IF, // instruction fetch 5318 PPC_IC, 5319 //PPC_BP, // branch prediction 5320 PPC_D0, // decode 5321 PPC_D1, // decode 5322 PPC_D2, // decode 5323 PPC_D3, // decode 5324 PPC_Xfer1, 5325 PPC_GD, // group definition 5326 PPC_MP, // map 5327 PPC_ISS, // issue 5328 PPC_RF, // resource fetch 5329 PPC_EX1, // execute (all units) 5330 PPC_EX2, // execute (FP, LDST) 5331 PPC_EX3, // execute (FP, LDST) 5332 PPC_EX4, // execute (FP) 5333 PPC_EX5, // execute (FP) 5334 PPC_EX6, // execute (FP) 5335 PPC_WB, // write back 5336 PPC_Xfer2, 5337 PPC_CP 5338 ); 5339 5340 //----------PIPELINE CLASSES--------------------------------------------------- 5341 // Pipeline Classes describe the stages in which input and output are 5342 // referenced by the hardware pipeline. 5343 5344 // Simple pipeline classes. 5345 5346 // Default pipeline class. 5347 pipe_class pipe_class_default() %{ 5348 single_instruction; 5349 fixed_latency(2); 5350 %} 5351 5352 // Pipeline class for empty instructions. 5353 pipe_class pipe_class_empty() %{ 5354 single_instruction; 5355 fixed_latency(0); 5356 %} 5357 5358 // Pipeline class for compares. 5359 pipe_class pipe_class_compare() %{ 5360 single_instruction; 5361 fixed_latency(16); 5362 %} 5363 5364 // Pipeline class for traps. 5365 pipe_class pipe_class_trap() %{ 5366 single_instruction; 5367 fixed_latency(100); 5368 %} 5369 5370 // Pipeline class for memory operations. 5371 pipe_class pipe_class_memory() %{ 5372 single_instruction; 5373 fixed_latency(16); 5374 %} 5375 5376 // Pipeline class for call. 5377 pipe_class pipe_class_call() %{ 5378 single_instruction; 5379 fixed_latency(100); 5380 %} 5381 5382 // Define the class for the Nop node. 5383 define %{ 5384 MachNop = pipe_class_default; 5385 %} 5386 5387 %} 5388 5389 //----------INSTRUCTIONS------------------------------------------------------- 5390 5391 // Naming of instructions: 5392 // opA_operB / opA_operB_operC: 5393 // Operation 'op' with one or two source operands 'oper'. Result 5394 // type is A, source operand types are B and C. 5395 // Iff A == B == C, B and C are left out. 5396 // 5397 // The instructions are ordered according to the following scheme: 5398 // - loads 5399 // - load constants 5400 // - prefetch 5401 // - store 5402 // - encode/decode 5403 // - membar 5404 // - conditional moves 5405 // - compare & swap 5406 // - arithmetic and logic operations 5407 // * int: Add, Sub, Mul, Div, Mod 5408 // * int: lShift, arShift, urShift, rot 5409 // * float: Add, Sub, Mul, Div 5410 // * and, or, xor ... 5411 // - register moves: float <-> int, reg <-> stack, repl 5412 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5413 // - conv (low level type cast requiring bit changes (sign extend etc) 5414 // - compares, range & zero checks. 5415 // - branches 5416 // - complex operations, intrinsics, min, max, replicate 5417 // - lock 5418 // - Calls 5419 // 5420 // If there are similar instructions with different types they are sorted: 5421 // int before float 5422 // small before big 5423 // signed before unsigned 5424 // e.g., loadS before loadUS before loadI before loadF. 5425 5426 5427 //----------Load/Store Instructions-------------------------------------------- 5428 5429 //----------Load Instructions-------------------------------------------------- 5430 5431 // Converts byte to int. 5432 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5433 // reuses the 'amount' operand, but adlc expects that operand specification 5434 // and operands in match rule are equivalent. 5435 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5436 effect(DEF dst, USE src); 5437 format %{ "EXTSB $dst, $src \t// byte->int" %} 5438 size(4); 5439 ins_encode %{ 5440 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5441 __ extsb($dst$$Register, $src$$Register); 5442 %} 5443 ins_pipe(pipe_class_default); 5444 %} 5445 5446 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5447 // match-rule, false predicate 5448 match(Set dst (LoadB mem)); 5449 predicate(false); 5450 5451 format %{ "LBZ $dst, $mem" %} 5452 size(4); 5453 ins_encode( enc_lbz(dst, mem) ); 5454 ins_pipe(pipe_class_memory); 5455 %} 5456 5457 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5458 // match-rule, false predicate 5459 match(Set dst (LoadB mem)); 5460 predicate(false); 5461 5462 format %{ "LBZ $dst, $mem\n\t" 5463 "TWI $dst\n\t" 5464 "ISYNC" %} 5465 size(12); 5466 ins_encode( enc_lbz_ac(dst, mem) ); 5467 ins_pipe(pipe_class_memory); 5468 %} 5469 5470 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5471 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5472 match(Set dst (LoadB mem)); 5473 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5474 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5475 expand %{ 5476 iRegIdst tmp; 5477 loadUB_indirect(tmp, mem); 5478 convB2I_reg_2(dst, tmp); 5479 %} 5480 %} 5481 5482 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5483 match(Set dst (LoadB mem)); 5484 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5485 expand %{ 5486 iRegIdst tmp; 5487 loadUB_indirect_ac(tmp, mem); 5488 convB2I_reg_2(dst, tmp); 5489 %} 5490 %} 5491 5492 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5493 // match-rule, false predicate 5494 match(Set dst (LoadB mem)); 5495 predicate(false); 5496 5497 format %{ "LBZ $dst, $mem" %} 5498 size(4); 5499 ins_encode( enc_lbz(dst, mem) ); 5500 ins_pipe(pipe_class_memory); 5501 %} 5502 5503 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5504 // match-rule, false predicate 5505 match(Set dst (LoadB mem)); 5506 predicate(false); 5507 5508 format %{ "LBZ $dst, $mem\n\t" 5509 "TWI $dst\n\t" 5510 "ISYNC" %} 5511 size(12); 5512 ins_encode( enc_lbz_ac(dst, mem) ); 5513 ins_pipe(pipe_class_memory); 5514 %} 5515 5516 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5517 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5518 match(Set dst (LoadB mem)); 5519 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5520 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5521 5522 expand %{ 5523 iRegIdst tmp; 5524 loadUB_indOffset16(tmp, mem); 5525 convB2I_reg_2(dst, tmp); 5526 %} 5527 %} 5528 5529 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5530 match(Set dst (LoadB mem)); 5531 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5532 5533 expand %{ 5534 iRegIdst tmp; 5535 loadUB_indOffset16_ac(tmp, mem); 5536 convB2I_reg_2(dst, tmp); 5537 %} 5538 %} 5539 5540 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5541 instruct loadUB(iRegIdst dst, memory mem) %{ 5542 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5543 match(Set dst (LoadUB mem)); 5544 ins_cost(MEMORY_REF_COST); 5545 5546 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5547 size(4); 5548 ins_encode( enc_lbz(dst, mem) ); 5549 ins_pipe(pipe_class_memory); 5550 %} 5551 5552 // Load Unsigned Byte (8bit UNsigned) acquire. 5553 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5554 match(Set dst (LoadUB mem)); 5555 ins_cost(3*MEMORY_REF_COST); 5556 5557 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5558 "TWI $dst\n\t" 5559 "ISYNC" %} 5560 size(12); 5561 ins_encode( enc_lbz_ac(dst, mem) ); 5562 ins_pipe(pipe_class_memory); 5563 %} 5564 5565 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5566 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5567 match(Set dst (ConvI2L (LoadUB mem))); 5568 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5569 ins_cost(MEMORY_REF_COST); 5570 5571 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5572 size(4); 5573 ins_encode( enc_lbz(dst, mem) ); 5574 ins_pipe(pipe_class_memory); 5575 %} 5576 5577 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5578 match(Set dst (ConvI2L (LoadUB mem))); 5579 ins_cost(3*MEMORY_REF_COST); 5580 5581 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5582 "TWI $dst\n\t" 5583 "ISYNC" %} 5584 size(12); 5585 ins_encode( enc_lbz_ac(dst, mem) ); 5586 ins_pipe(pipe_class_memory); 5587 %} 5588 5589 // Load Short (16bit signed) 5590 instruct loadS(iRegIdst dst, memory mem) %{ 5591 match(Set dst (LoadS mem)); 5592 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5593 ins_cost(MEMORY_REF_COST); 5594 5595 format %{ "LHA $dst, $mem" %} 5596 size(4); 5597 ins_encode %{ 5598 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5599 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5600 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5601 %} 5602 ins_pipe(pipe_class_memory); 5603 %} 5604 5605 // Load Short (16bit signed) acquire. 5606 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5607 match(Set dst (LoadS mem)); 5608 ins_cost(3*MEMORY_REF_COST); 5609 5610 format %{ "LHA $dst, $mem\t acquire\n\t" 5611 "TWI $dst\n\t" 5612 "ISYNC" %} 5613 size(12); 5614 ins_encode %{ 5615 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5616 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5617 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5618 __ twi_0($dst$$Register); 5619 __ isync(); 5620 %} 5621 ins_pipe(pipe_class_memory); 5622 %} 5623 5624 // Load Char (16bit unsigned) 5625 instruct loadUS(iRegIdst dst, memory mem) %{ 5626 match(Set dst (LoadUS mem)); 5627 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5628 ins_cost(MEMORY_REF_COST); 5629 5630 format %{ "LHZ $dst, $mem" %} 5631 size(4); 5632 ins_encode( enc_lhz(dst, mem) ); 5633 ins_pipe(pipe_class_memory); 5634 %} 5635 5636 // Load Char (16bit unsigned) acquire. 5637 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5638 match(Set dst (LoadUS mem)); 5639 ins_cost(3*MEMORY_REF_COST); 5640 5641 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5642 "TWI $dst\n\t" 5643 "ISYNC" %} 5644 size(12); 5645 ins_encode( enc_lhz_ac(dst, mem) ); 5646 ins_pipe(pipe_class_memory); 5647 %} 5648 5649 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5650 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5651 match(Set dst (ConvI2L (LoadUS mem))); 5652 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5653 ins_cost(MEMORY_REF_COST); 5654 5655 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5656 size(4); 5657 ins_encode( enc_lhz(dst, mem) ); 5658 ins_pipe(pipe_class_memory); 5659 %} 5660 5661 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5662 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5663 match(Set dst (ConvI2L (LoadUS mem))); 5664 ins_cost(3*MEMORY_REF_COST); 5665 5666 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5667 "TWI $dst\n\t" 5668 "ISYNC" %} 5669 size(12); 5670 ins_encode( enc_lhz_ac(dst, mem) ); 5671 ins_pipe(pipe_class_memory); 5672 %} 5673 5674 // Load Integer. 5675 instruct loadI(iRegIdst dst, memory mem) %{ 5676 match(Set dst (LoadI mem)); 5677 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5678 ins_cost(MEMORY_REF_COST); 5679 5680 format %{ "LWZ $dst, $mem" %} 5681 size(4); 5682 ins_encode( enc_lwz(dst, mem) ); 5683 ins_pipe(pipe_class_memory); 5684 %} 5685 5686 // Load Integer acquire. 5687 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5688 match(Set dst (LoadI mem)); 5689 ins_cost(3*MEMORY_REF_COST); 5690 5691 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5692 "TWI $dst\n\t" 5693 "ISYNC" %} 5694 size(12); 5695 ins_encode( enc_lwz_ac(dst, mem) ); 5696 ins_pipe(pipe_class_memory); 5697 %} 5698 5699 // Match loading integer and casting it to unsigned int in 5700 // long register. 5701 // LoadI + ConvI2L + AndL 0xffffffff. 5702 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5703 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5704 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5705 ins_cost(MEMORY_REF_COST); 5706 5707 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5708 size(4); 5709 ins_encode( enc_lwz(dst, mem) ); 5710 ins_pipe(pipe_class_memory); 5711 %} 5712 5713 // Match loading integer and casting it to long. 5714 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5715 match(Set dst (ConvI2L (LoadI mem))); 5716 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5717 ins_cost(MEMORY_REF_COST); 5718 5719 format %{ "LWA $dst, $mem \t// loadI2L" %} 5720 size(4); 5721 ins_encode %{ 5722 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5723 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5724 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5725 %} 5726 ins_pipe(pipe_class_memory); 5727 %} 5728 5729 // Match loading integer and casting it to long - acquire. 5730 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5731 match(Set dst (ConvI2L (LoadI mem))); 5732 ins_cost(3*MEMORY_REF_COST); 5733 5734 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5735 "TWI $dst\n\t" 5736 "ISYNC" %} 5737 size(12); 5738 ins_encode %{ 5739 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5740 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5741 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5742 __ twi_0($dst$$Register); 5743 __ isync(); 5744 %} 5745 ins_pipe(pipe_class_memory); 5746 %} 5747 5748 // Load Long - aligned 5749 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5750 match(Set dst (LoadL mem)); 5751 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5752 ins_cost(MEMORY_REF_COST); 5753 5754 format %{ "LD $dst, $mem \t// long" %} 5755 size(4); 5756 ins_encode( enc_ld(dst, mem) ); 5757 ins_pipe(pipe_class_memory); 5758 %} 5759 5760 // Load Long - aligned acquire. 5761 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5762 match(Set dst (LoadL mem)); 5763 ins_cost(3*MEMORY_REF_COST); 5764 5765 format %{ "LD $dst, $mem \t// long acquire\n\t" 5766 "TWI $dst\n\t" 5767 "ISYNC" %} 5768 size(12); 5769 ins_encode( enc_ld_ac(dst, mem) ); 5770 ins_pipe(pipe_class_memory); 5771 %} 5772 5773 // Load Long - UNaligned 5774 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5775 match(Set dst (LoadL_unaligned mem)); 5776 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5777 ins_cost(MEMORY_REF_COST); 5778 5779 format %{ "LD $dst, $mem \t// unaligned long" %} 5780 size(4); 5781 ins_encode( enc_ld(dst, mem) ); 5782 ins_pipe(pipe_class_memory); 5783 %} 5784 5785 // Load nodes for superwords 5786 5787 // Load Aligned Packed Byte 5788 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5789 predicate(n->as_LoadVector()->memory_size() == 8); 5790 match(Set dst (LoadVector mem)); 5791 ins_cost(MEMORY_REF_COST); 5792 5793 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5794 size(4); 5795 ins_encode( enc_ld(dst, mem) ); 5796 ins_pipe(pipe_class_memory); 5797 %} 5798 5799 // Load Aligned Packed Byte 5800 instruct loadV16(vecX dst, indirect mem) %{ 5801 predicate(n->as_LoadVector()->memory_size() == 16); 5802 match(Set dst (LoadVector mem)); 5803 ins_cost(MEMORY_REF_COST); 5804 5805 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5806 size(4); 5807 ins_encode %{ 5808 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5809 %} 5810 ins_pipe(pipe_class_default); 5811 %} 5812 5813 // Load Range, range = array length (=jint) 5814 instruct loadRange(iRegIdst dst, memory mem) %{ 5815 match(Set dst (LoadRange mem)); 5816 ins_cost(MEMORY_REF_COST); 5817 5818 format %{ "LWZ $dst, $mem \t// range" %} 5819 size(4); 5820 ins_encode( enc_lwz(dst, mem) ); 5821 ins_pipe(pipe_class_memory); 5822 %} 5823 5824 // Load Compressed Pointer 5825 instruct loadN(iRegNdst dst, memory mem) %{ 5826 match(Set dst (LoadN mem)); 5827 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5828 ins_cost(MEMORY_REF_COST); 5829 5830 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5831 size(4); 5832 ins_encode( enc_lwz(dst, mem) ); 5833 ins_pipe(pipe_class_memory); 5834 %} 5835 5836 // Load Compressed Pointer acquire. 5837 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5838 match(Set dst (LoadN mem)); 5839 ins_cost(3*MEMORY_REF_COST); 5840 5841 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5842 "TWI $dst\n\t" 5843 "ISYNC" %} 5844 size(12); 5845 ins_encode( enc_lwz_ac(dst, mem) ); 5846 ins_pipe(pipe_class_memory); 5847 %} 5848 5849 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5850 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5851 match(Set dst (DecodeN (LoadN mem))); 5852 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5853 ins_cost(MEMORY_REF_COST); 5854 5855 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5856 size(4); 5857 ins_encode( enc_lwz(dst, mem) ); 5858 ins_pipe(pipe_class_memory); 5859 %} 5860 5861 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5862 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5863 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5864 _kids[0]->_leaf->as_Load()->is_unordered()); 5865 ins_cost(MEMORY_REF_COST); 5866 5867 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5868 size(4); 5869 ins_encode( enc_lwz(dst, mem) ); 5870 ins_pipe(pipe_class_memory); 5871 %} 5872 5873 // Load Pointer 5874 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5875 match(Set dst (LoadP mem)); 5876 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5877 ins_cost(MEMORY_REF_COST); 5878 5879 format %{ "LD $dst, $mem \t// ptr" %} 5880 size(4); 5881 ins_encode( enc_ld(dst, mem) ); 5882 ins_pipe(pipe_class_memory); 5883 %} 5884 5885 // Load Pointer acquire. 5886 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5887 match(Set dst (LoadP mem)); 5888 ins_cost(3*MEMORY_REF_COST); 5889 5890 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5891 "TWI $dst\n\t" 5892 "ISYNC" %} 5893 size(12); 5894 ins_encode( enc_ld_ac(dst, mem) ); 5895 ins_pipe(pipe_class_memory); 5896 %} 5897 5898 // LoadP + CastP2L 5899 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5900 match(Set dst (CastP2X (LoadP mem))); 5901 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5902 ins_cost(MEMORY_REF_COST); 5903 5904 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5905 size(4); 5906 ins_encode( enc_ld(dst, mem) ); 5907 ins_pipe(pipe_class_memory); 5908 %} 5909 5910 // Load compressed klass pointer. 5911 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5912 match(Set dst (LoadNKlass mem)); 5913 ins_cost(MEMORY_REF_COST); 5914 5915 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5916 size(4); 5917 ins_encode( enc_lwz(dst, mem) ); 5918 ins_pipe(pipe_class_memory); 5919 %} 5920 5921 // Load Klass Pointer 5922 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5923 match(Set dst (LoadKlass mem)); 5924 ins_cost(MEMORY_REF_COST); 5925 5926 format %{ "LD $dst, $mem \t// klass ptr" %} 5927 size(4); 5928 ins_encode( enc_ld(dst, mem) ); 5929 ins_pipe(pipe_class_memory); 5930 %} 5931 5932 // Load Float 5933 instruct loadF(regF dst, memory mem) %{ 5934 match(Set dst (LoadF mem)); 5935 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5936 ins_cost(MEMORY_REF_COST); 5937 5938 format %{ "LFS $dst, $mem" %} 5939 size(4); 5940 ins_encode %{ 5941 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5942 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5943 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5944 %} 5945 ins_pipe(pipe_class_memory); 5946 %} 5947 5948 // Load Float acquire. 5949 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5950 match(Set dst (LoadF mem)); 5951 effect(TEMP cr0); 5952 ins_cost(3*MEMORY_REF_COST); 5953 5954 format %{ "LFS $dst, $mem \t// acquire\n\t" 5955 "FCMPU cr0, $dst, $dst\n\t" 5956 "BNE cr0, next\n" 5957 "next:\n\t" 5958 "ISYNC" %} 5959 size(16); 5960 ins_encode %{ 5961 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5962 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5963 Label next; 5964 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5965 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5966 __ bne(CCR0, next); 5967 __ bind(next); 5968 __ isync(); 5969 %} 5970 ins_pipe(pipe_class_memory); 5971 %} 5972 5973 // Load Double - aligned 5974 instruct loadD(regD dst, memory mem) %{ 5975 match(Set dst (LoadD mem)); 5976 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5977 ins_cost(MEMORY_REF_COST); 5978 5979 format %{ "LFD $dst, $mem" %} 5980 size(4); 5981 ins_encode( enc_lfd(dst, mem) ); 5982 ins_pipe(pipe_class_memory); 5983 %} 5984 5985 // Load Double - aligned acquire. 5986 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5987 match(Set dst (LoadD mem)); 5988 effect(TEMP cr0); 5989 ins_cost(3*MEMORY_REF_COST); 5990 5991 format %{ "LFD $dst, $mem \t// acquire\n\t" 5992 "FCMPU cr0, $dst, $dst\n\t" 5993 "BNE cr0, next\n" 5994 "next:\n\t" 5995 "ISYNC" %} 5996 size(16); 5997 ins_encode %{ 5998 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5999 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6000 Label next; 6001 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 6002 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 6003 __ bne(CCR0, next); 6004 __ bind(next); 6005 __ isync(); 6006 %} 6007 ins_pipe(pipe_class_memory); 6008 %} 6009 6010 // Load Double - UNaligned 6011 instruct loadD_unaligned(regD dst, memory mem) %{ 6012 match(Set dst (LoadD_unaligned mem)); 6013 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 6014 ins_cost(MEMORY_REF_COST); 6015 6016 format %{ "LFD $dst, $mem" %} 6017 size(4); 6018 ins_encode( enc_lfd(dst, mem) ); 6019 ins_pipe(pipe_class_memory); 6020 %} 6021 6022 //----------Constants-------------------------------------------------------- 6023 6024 // Load MachConstantTableBase: add hi offset to global toc. 6025 // TODO: Handle hidden register r29 in bundler! 6026 instruct loadToc_hi(iRegLdst dst) %{ 6027 effect(DEF dst); 6028 ins_cost(DEFAULT_COST); 6029 6030 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 6031 size(4); 6032 ins_encode %{ 6033 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6034 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 6035 %} 6036 ins_pipe(pipe_class_default); 6037 %} 6038 6039 // Load MachConstantTableBase: add lo offset to global toc. 6040 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 6041 effect(DEF dst, USE src); 6042 ins_cost(DEFAULT_COST); 6043 6044 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 6045 size(4); 6046 ins_encode %{ 6047 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6048 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 6049 %} 6050 ins_pipe(pipe_class_default); 6051 %} 6052 6053 // Load 16-bit integer constant 0xssss???? 6054 instruct loadConI16(iRegIdst dst, immI16 src) %{ 6055 match(Set dst src); 6056 6057 format %{ "LI $dst, $src" %} 6058 size(4); 6059 ins_encode %{ 6060 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6061 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6062 %} 6063 ins_pipe(pipe_class_default); 6064 %} 6065 6066 // Load integer constant 0x????0000 6067 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 6068 match(Set dst src); 6069 ins_cost(DEFAULT_COST); 6070 6071 format %{ "LIS $dst, $src.hi" %} 6072 size(4); 6073 ins_encode %{ 6074 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6075 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 6076 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6077 %} 6078 ins_pipe(pipe_class_default); 6079 %} 6080 6081 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 6082 // and sign extended), this adds the low 16 bits. 6083 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6084 // no match-rule, false predicate 6085 effect(DEF dst, USE src1, USE src2); 6086 predicate(false); 6087 6088 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6089 size(4); 6090 ins_encode %{ 6091 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6092 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6093 %} 6094 ins_pipe(pipe_class_default); 6095 %} 6096 6097 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6098 match(Set dst src); 6099 ins_cost(DEFAULT_COST*2); 6100 6101 expand %{ 6102 // Would like to use $src$$constant. 6103 immI16 srcLo %{ _opnds[1]->constant() %} 6104 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6105 immIhi16 srcHi %{ _opnds[1]->constant() %} 6106 iRegIdst tmpI; 6107 loadConIhi16(tmpI, srcHi); 6108 loadConI32_lo16(dst, tmpI, srcLo); 6109 %} 6110 %} 6111 6112 // No constant pool entries required. 6113 instruct loadConL16(iRegLdst dst, immL16 src) %{ 6114 match(Set dst src); 6115 6116 format %{ "LI $dst, $src \t// long" %} 6117 size(4); 6118 ins_encode %{ 6119 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6120 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6121 %} 6122 ins_pipe(pipe_class_default); 6123 %} 6124 6125 // Load long constant 0xssssssss????0000 6126 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6127 match(Set dst src); 6128 ins_cost(DEFAULT_COST); 6129 6130 format %{ "LIS $dst, $src.hi \t// long" %} 6131 size(4); 6132 ins_encode %{ 6133 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6134 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6135 %} 6136 ins_pipe(pipe_class_default); 6137 %} 6138 6139 // To load a 32 bit constant: merge lower 16 bits into already loaded 6140 // high 16 bits. 6141 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6142 // no match-rule, false predicate 6143 effect(DEF dst, USE src1, USE src2); 6144 predicate(false); 6145 6146 format %{ "ORI $dst, $src1, $src2.lo" %} 6147 size(4); 6148 ins_encode %{ 6149 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6150 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6151 %} 6152 ins_pipe(pipe_class_default); 6153 %} 6154 6155 // Load 32-bit long constant 6156 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6157 match(Set dst src); 6158 ins_cost(DEFAULT_COST*2); 6159 6160 expand %{ 6161 // Would like to use $src$$constant. 6162 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6163 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6164 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6165 iRegLdst tmpL; 6166 loadConL32hi16(tmpL, srcHi); 6167 loadConL32_lo16(dst, tmpL, srcLo); 6168 %} 6169 %} 6170 6171 // Load long constant 0x????000000000000. 6172 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6173 match(Set dst src); 6174 ins_cost(DEFAULT_COST); 6175 6176 expand %{ 6177 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6178 immI shift32 %{ 32 %} 6179 iRegLdst tmpL; 6180 loadConL32hi16(tmpL, srcHi); 6181 lshiftL_regL_immI(dst, tmpL, shift32); 6182 %} 6183 %} 6184 6185 // Expand node for constant pool load: small offset. 6186 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6187 effect(DEF dst, USE src, USE toc); 6188 ins_cost(MEMORY_REF_COST); 6189 6190 ins_num_consts(1); 6191 // Needed so that CallDynamicJavaDirect can compute the address of this 6192 // instruction for relocation. 6193 ins_field_cbuf_insts_offset(int); 6194 6195 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6196 size(4); 6197 ins_encode( enc_load_long_constL(dst, src, toc) ); 6198 ins_pipe(pipe_class_memory); 6199 %} 6200 6201 // Expand node for constant pool load: large offset. 6202 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6203 effect(DEF dst, USE src, USE toc); 6204 predicate(false); 6205 6206 ins_num_consts(1); 6207 ins_field_const_toc_offset(int); 6208 // Needed so that CallDynamicJavaDirect can compute the address of this 6209 // instruction for relocation. 6210 ins_field_cbuf_insts_offset(int); 6211 6212 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6213 size(4); 6214 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6215 ins_pipe(pipe_class_default); 6216 %} 6217 6218 // Expand node for constant pool load: large offset. 6219 // No constant pool entries required. 6220 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6221 effect(DEF dst, USE src, USE base); 6222 predicate(false); 6223 6224 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6225 6226 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6227 size(4); 6228 ins_encode %{ 6229 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6230 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6231 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6232 %} 6233 ins_pipe(pipe_class_memory); 6234 %} 6235 6236 // Load long constant from constant table. Expand in case of 6237 // offset > 16 bit is needed. 6238 // Adlc adds toc node MachConstantTableBase. 6239 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6240 match(Set dst src); 6241 ins_cost(MEMORY_REF_COST); 6242 6243 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6244 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6245 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6246 %} 6247 6248 // Load NULL as compressed oop. 6249 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6250 match(Set dst src); 6251 ins_cost(DEFAULT_COST); 6252 6253 format %{ "LI $dst, $src \t// compressed ptr" %} 6254 size(4); 6255 ins_encode %{ 6256 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6257 __ li($dst$$Register, 0); 6258 %} 6259 ins_pipe(pipe_class_default); 6260 %} 6261 6262 // Load hi part of compressed oop constant. 6263 instruct loadConN_hi(iRegNdst dst, immN src) %{ 6264 effect(DEF dst, USE src); 6265 ins_cost(DEFAULT_COST); 6266 6267 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6268 size(4); 6269 ins_encode %{ 6270 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6271 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6272 %} 6273 ins_pipe(pipe_class_default); 6274 %} 6275 6276 // Add lo part of compressed oop constant to already loaded hi part. 6277 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6278 effect(DEF dst, USE src1, USE src2); 6279 ins_cost(DEFAULT_COST); 6280 6281 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6282 size(4); 6283 ins_encode %{ 6284 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6285 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6286 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6287 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6288 __ relocate(rspec, 1); 6289 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6290 %} 6291 ins_pipe(pipe_class_default); 6292 %} 6293 6294 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6295 effect(DEF dst, USE src, USE shift, USE mask_begin); 6296 6297 size(4); 6298 ins_encode %{ 6299 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6300 %} 6301 ins_pipe(pipe_class_default); 6302 %} 6303 6304 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6305 // leaving the upper 32 bits with sign-extension bits. 6306 // This clears these bits: dst = src & 0xFFFFFFFF. 6307 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6308 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6309 effect(DEF dst, USE src); 6310 predicate(false); 6311 6312 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6313 size(4); 6314 ins_encode %{ 6315 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6316 __ clrldi($dst$$Register, $src$$Register, 0x20); 6317 %} 6318 ins_pipe(pipe_class_default); 6319 %} 6320 6321 // Optimize DecodeN for disjoint base. 6322 // Load base of compressed oops into a register 6323 instruct loadBase(iRegLdst dst) %{ 6324 effect(DEF dst); 6325 6326 format %{ "LoadConst $dst, heapbase" %} 6327 ins_encode %{ 6328 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6329 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 6330 %} 6331 ins_pipe(pipe_class_default); 6332 %} 6333 6334 // Loading ConN must be postalloc expanded so that edges between 6335 // the nodes are safe. They may not interfere with a safepoint. 6336 // GL TODO: This needs three instructions: better put this into the constant pool. 6337 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6338 match(Set dst src); 6339 ins_cost(DEFAULT_COST*2); 6340 6341 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6342 postalloc_expand %{ 6343 MachNode *m1 = new loadConN_hiNode(); 6344 MachNode *m2 = new loadConN_loNode(); 6345 MachNode *m3 = new clearMs32bNode(); 6346 m1->add_req(NULL); 6347 m2->add_req(NULL, m1); 6348 m3->add_req(NULL, m2); 6349 m1->_opnds[0] = op_dst; 6350 m1->_opnds[1] = op_src; 6351 m2->_opnds[0] = op_dst; 6352 m2->_opnds[1] = op_dst; 6353 m2->_opnds[2] = op_src; 6354 m3->_opnds[0] = op_dst; 6355 m3->_opnds[1] = op_dst; 6356 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6357 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6358 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6359 nodes->push(m1); 6360 nodes->push(m2); 6361 nodes->push(m3); 6362 %} 6363 %} 6364 6365 // We have seen a safepoint between the hi and lo parts, and this node was handled 6366 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6367 // not a narrow oop. 6368 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6369 match(Set dst src); 6370 effect(DEF dst, USE src); 6371 ins_cost(DEFAULT_COST); 6372 6373 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6374 size(4); 6375 ins_encode %{ 6376 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6377 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 6378 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6379 %} 6380 ins_pipe(pipe_class_default); 6381 %} 6382 6383 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6384 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6385 match(Set dst src1); 6386 effect(TEMP src2); 6387 ins_cost(DEFAULT_COST); 6388 6389 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6390 size(4); 6391 ins_encode %{ 6392 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6393 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6394 %} 6395 ins_pipe(pipe_class_default); 6396 %} 6397 6398 // This needs a match rule so that build_oop_map knows this is 6399 // not a narrow oop. 6400 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6401 match(Set dst src1); 6402 effect(TEMP src2); 6403 ins_cost(DEFAULT_COST); 6404 6405 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6406 size(4); 6407 ins_encode %{ 6408 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6409 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 6410 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6411 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6412 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6413 6414 __ relocate(rspec, 1); 6415 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6416 %} 6417 ins_pipe(pipe_class_default); 6418 %} 6419 6420 // Loading ConNKlass must be postalloc expanded so that edges between 6421 // the nodes are safe. They may not interfere with a safepoint. 6422 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6423 match(Set dst src); 6424 ins_cost(DEFAULT_COST*2); 6425 6426 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6427 postalloc_expand %{ 6428 // Load high bits into register. Sign extended. 6429 MachNode *m1 = new loadConNKlass_hiNode(); 6430 m1->add_req(NULL); 6431 m1->_opnds[0] = op_dst; 6432 m1->_opnds[1] = op_src; 6433 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6434 nodes->push(m1); 6435 6436 MachNode *m2 = m1; 6437 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 6438 // Value might be 1-extended. Mask out these bits. 6439 m2 = new loadConNKlass_maskNode(); 6440 m2->add_req(NULL, m1); 6441 m2->_opnds[0] = op_dst; 6442 m2->_opnds[1] = op_src; 6443 m2->_opnds[2] = op_dst; 6444 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6445 nodes->push(m2); 6446 } 6447 6448 MachNode *m3 = new loadConNKlass_loNode(); 6449 m3->add_req(NULL, m2); 6450 m3->_opnds[0] = op_dst; 6451 m3->_opnds[1] = op_src; 6452 m3->_opnds[2] = op_dst; 6453 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6454 nodes->push(m3); 6455 %} 6456 %} 6457 6458 // 0x1 is used in object initialization (initial object header). 6459 // No constant pool entries required. 6460 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6461 match(Set dst src); 6462 6463 format %{ "LI $dst, $src \t// ptr" %} 6464 size(4); 6465 ins_encode %{ 6466 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6467 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6468 %} 6469 ins_pipe(pipe_class_default); 6470 %} 6471 6472 // Expand node for constant pool load: small offset. 6473 // The match rule is needed to generate the correct bottom_type(), 6474 // however this node should never match. The use of predicate is not 6475 // possible since ADLC forbids predicates for chain rules. The higher 6476 // costs do not prevent matching in this case. For that reason the 6477 // operand immP_NM with predicate(false) is used. 6478 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6479 match(Set dst src); 6480 effect(TEMP toc); 6481 6482 ins_num_consts(1); 6483 6484 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6485 size(4); 6486 ins_encode( enc_load_long_constP(dst, src, toc) ); 6487 ins_pipe(pipe_class_memory); 6488 %} 6489 6490 // Expand node for constant pool load: large offset. 6491 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6492 effect(DEF dst, USE src, USE toc); 6493 predicate(false); 6494 6495 ins_num_consts(1); 6496 ins_field_const_toc_offset(int); 6497 6498 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6499 size(4); 6500 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6501 ins_pipe(pipe_class_default); 6502 %} 6503 6504 // Expand node for constant pool load: large offset. 6505 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6506 match(Set dst src); 6507 effect(TEMP base); 6508 6509 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6510 6511 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6512 size(4); 6513 ins_encode %{ 6514 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6515 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6516 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6517 %} 6518 ins_pipe(pipe_class_memory); 6519 %} 6520 6521 // Load pointer constant from constant table. Expand in case an 6522 // offset > 16 bit is needed. 6523 // Adlc adds toc node MachConstantTableBase. 6524 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6525 match(Set dst src); 6526 ins_cost(MEMORY_REF_COST); 6527 6528 // This rule does not use "expand" because then 6529 // the result type is not known to be an Oop. An ADLC 6530 // enhancement will be needed to make that work - not worth it! 6531 6532 // If this instruction rematerializes, it prolongs the live range 6533 // of the toc node, causing illegal graphs. 6534 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6535 ins_cannot_rematerialize(true); 6536 6537 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6538 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6539 %} 6540 6541 // Expand node for constant pool load: small offset. 6542 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6543 effect(DEF dst, USE src, USE toc); 6544 ins_cost(MEMORY_REF_COST); 6545 6546 ins_num_consts(1); 6547 6548 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6549 size(4); 6550 ins_encode %{ 6551 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6552 address float_address = __ float_constant($src$$constant); 6553 if (float_address == NULL) { 6554 ciEnv::current()->record_out_of_memory_failure(); 6555 return; 6556 } 6557 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6558 %} 6559 ins_pipe(pipe_class_memory); 6560 %} 6561 6562 // Expand node for constant pool load: large offset. 6563 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6564 effect(DEF dst, USE src, USE toc); 6565 ins_cost(MEMORY_REF_COST); 6566 6567 ins_num_consts(1); 6568 6569 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6570 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6571 "ADDIS $toc, $toc, -offset_hi"%} 6572 size(12); 6573 ins_encode %{ 6574 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6575 FloatRegister Rdst = $dst$$FloatRegister; 6576 Register Rtoc = $toc$$Register; 6577 address float_address = __ float_constant($src$$constant); 6578 if (float_address == NULL) { 6579 ciEnv::current()->record_out_of_memory_failure(); 6580 return; 6581 } 6582 int offset = __ offset_to_method_toc(float_address); 6583 int hi = (offset + (1<<15))>>16; 6584 int lo = offset - hi * (1<<16); 6585 6586 __ addis(Rtoc, Rtoc, hi); 6587 __ lfs(Rdst, lo, Rtoc); 6588 __ addis(Rtoc, Rtoc, -hi); 6589 %} 6590 ins_pipe(pipe_class_memory); 6591 %} 6592 6593 // Adlc adds toc node MachConstantTableBase. 6594 instruct loadConF_Ex(regF dst, immF src) %{ 6595 match(Set dst src); 6596 ins_cost(MEMORY_REF_COST); 6597 6598 // See loadConP. 6599 ins_cannot_rematerialize(true); 6600 6601 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6602 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6603 %} 6604 6605 // Expand node for constant pool load: small offset. 6606 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6607 effect(DEF dst, USE src, USE toc); 6608 ins_cost(MEMORY_REF_COST); 6609 6610 ins_num_consts(1); 6611 6612 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6613 size(4); 6614 ins_encode %{ 6615 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6616 address float_address = __ double_constant($src$$constant); 6617 if (float_address == NULL) { 6618 ciEnv::current()->record_out_of_memory_failure(); 6619 return; 6620 } 6621 int offset = __ offset_to_method_toc(float_address); 6622 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6623 %} 6624 ins_pipe(pipe_class_memory); 6625 %} 6626 6627 // Expand node for constant pool load: large offset. 6628 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6629 effect(DEF dst, USE src, USE toc); 6630 ins_cost(MEMORY_REF_COST); 6631 6632 ins_num_consts(1); 6633 6634 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6635 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6636 "ADDIS $toc, $toc, -offset_hi" %} 6637 size(12); 6638 ins_encode %{ 6639 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6640 FloatRegister Rdst = $dst$$FloatRegister; 6641 Register Rtoc = $toc$$Register; 6642 address float_address = __ double_constant($src$$constant); 6643 if (float_address == NULL) { 6644 ciEnv::current()->record_out_of_memory_failure(); 6645 return; 6646 } 6647 int offset = __ offset_to_method_toc(float_address); 6648 int hi = (offset + (1<<15))>>16; 6649 int lo = offset - hi * (1<<16); 6650 6651 __ addis(Rtoc, Rtoc, hi); 6652 __ lfd(Rdst, lo, Rtoc); 6653 __ addis(Rtoc, Rtoc, -hi); 6654 %} 6655 ins_pipe(pipe_class_memory); 6656 %} 6657 6658 // Adlc adds toc node MachConstantTableBase. 6659 instruct loadConD_Ex(regD dst, immD src) %{ 6660 match(Set dst src); 6661 ins_cost(MEMORY_REF_COST); 6662 6663 // See loadConP. 6664 ins_cannot_rematerialize(true); 6665 6666 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6667 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6668 %} 6669 6670 // Prefetch instructions. 6671 // Must be safe to execute with invalid address (cannot fault). 6672 6673 // Special prefetch versions which use the dcbz instruction. 6674 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6675 match(PrefetchAllocation (AddP mem src)); 6676 predicate(AllocatePrefetchStyle == 3); 6677 ins_cost(MEMORY_REF_COST); 6678 6679 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6680 size(4); 6681 ins_encode %{ 6682 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6683 __ dcbz($src$$Register, $mem$$base$$Register); 6684 %} 6685 ins_pipe(pipe_class_memory); 6686 %} 6687 6688 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6689 match(PrefetchAllocation mem); 6690 predicate(AllocatePrefetchStyle == 3); 6691 ins_cost(MEMORY_REF_COST); 6692 6693 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6694 size(4); 6695 ins_encode %{ 6696 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6697 __ dcbz($mem$$base$$Register); 6698 %} 6699 ins_pipe(pipe_class_memory); 6700 %} 6701 6702 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6703 match(PrefetchAllocation (AddP mem src)); 6704 predicate(AllocatePrefetchStyle != 3); 6705 ins_cost(MEMORY_REF_COST); 6706 6707 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6708 size(4); 6709 ins_encode %{ 6710 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6711 __ dcbtst($src$$Register, $mem$$base$$Register); 6712 %} 6713 ins_pipe(pipe_class_memory); 6714 %} 6715 6716 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6717 match(PrefetchAllocation mem); 6718 predicate(AllocatePrefetchStyle != 3); 6719 ins_cost(MEMORY_REF_COST); 6720 6721 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6722 size(4); 6723 ins_encode %{ 6724 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6725 __ dcbtst($mem$$base$$Register); 6726 %} 6727 ins_pipe(pipe_class_memory); 6728 %} 6729 6730 //----------Store Instructions------------------------------------------------- 6731 6732 // Store Byte 6733 instruct storeB(memory mem, iRegIsrc src) %{ 6734 match(Set mem (StoreB mem src)); 6735 ins_cost(MEMORY_REF_COST); 6736 6737 format %{ "STB $src, $mem \t// byte" %} 6738 size(4); 6739 ins_encode %{ 6740 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6741 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6742 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6743 %} 6744 ins_pipe(pipe_class_memory); 6745 %} 6746 6747 // Store Char/Short 6748 instruct storeC(memory mem, iRegIsrc src) %{ 6749 match(Set mem (StoreC mem src)); 6750 ins_cost(MEMORY_REF_COST); 6751 6752 format %{ "STH $src, $mem \t// short" %} 6753 size(4); 6754 ins_encode %{ 6755 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6756 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6757 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6758 %} 6759 ins_pipe(pipe_class_memory); 6760 %} 6761 6762 // Store Integer 6763 instruct storeI(memory mem, iRegIsrc src) %{ 6764 match(Set mem (StoreI mem src)); 6765 ins_cost(MEMORY_REF_COST); 6766 6767 format %{ "STW $src, $mem" %} 6768 size(4); 6769 ins_encode( enc_stw(src, mem) ); 6770 ins_pipe(pipe_class_memory); 6771 %} 6772 6773 // ConvL2I + StoreI. 6774 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6775 match(Set mem (StoreI mem (ConvL2I src))); 6776 ins_cost(MEMORY_REF_COST); 6777 6778 format %{ "STW l2i($src), $mem" %} 6779 size(4); 6780 ins_encode( enc_stw(src, mem) ); 6781 ins_pipe(pipe_class_memory); 6782 %} 6783 6784 // Store Long 6785 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6786 match(Set mem (StoreL mem src)); 6787 ins_cost(MEMORY_REF_COST); 6788 6789 format %{ "STD $src, $mem \t// long" %} 6790 size(4); 6791 ins_encode( enc_std(src, mem) ); 6792 ins_pipe(pipe_class_memory); 6793 %} 6794 6795 // Store super word nodes. 6796 6797 // Store Aligned Packed Byte long register to memory 6798 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6799 predicate(n->as_StoreVector()->memory_size() == 8); 6800 match(Set mem (StoreVector mem src)); 6801 ins_cost(MEMORY_REF_COST); 6802 6803 format %{ "STD $mem, $src \t// packed8B" %} 6804 size(4); 6805 ins_encode( enc_std(src, mem) ); 6806 ins_pipe(pipe_class_memory); 6807 %} 6808 6809 // Store Packed Byte long register to memory 6810 instruct storeV16(indirect mem, vecX src) %{ 6811 predicate(n->as_StoreVector()->memory_size() == 16); 6812 match(Set mem (StoreVector mem src)); 6813 ins_cost(MEMORY_REF_COST); 6814 6815 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6816 size(4); 6817 ins_encode %{ 6818 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6819 %} 6820 ins_pipe(pipe_class_default); 6821 %} 6822 6823 // Store Compressed Oop 6824 instruct storeN(memory dst, iRegN_P2N src) %{ 6825 match(Set dst (StoreN dst src)); 6826 ins_cost(MEMORY_REF_COST); 6827 6828 format %{ "STW $src, $dst \t// compressed oop" %} 6829 size(4); 6830 ins_encode( enc_stw(src, dst) ); 6831 ins_pipe(pipe_class_memory); 6832 %} 6833 6834 // Store Compressed KLass 6835 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6836 match(Set dst (StoreNKlass dst src)); 6837 ins_cost(MEMORY_REF_COST); 6838 6839 format %{ "STW $src, $dst \t// compressed klass" %} 6840 size(4); 6841 ins_encode( enc_stw(src, dst) ); 6842 ins_pipe(pipe_class_memory); 6843 %} 6844 6845 // Store Pointer 6846 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6847 match(Set dst (StoreP dst src)); 6848 ins_cost(MEMORY_REF_COST); 6849 6850 format %{ "STD $src, $dst \t// ptr" %} 6851 size(4); 6852 ins_encode( enc_std(src, dst) ); 6853 ins_pipe(pipe_class_memory); 6854 %} 6855 6856 // Store Float 6857 instruct storeF(memory mem, regF src) %{ 6858 match(Set mem (StoreF mem src)); 6859 ins_cost(MEMORY_REF_COST); 6860 6861 format %{ "STFS $src, $mem" %} 6862 size(4); 6863 ins_encode( enc_stfs(src, mem) ); 6864 ins_pipe(pipe_class_memory); 6865 %} 6866 6867 // Store Double 6868 instruct storeD(memory mem, regD src) %{ 6869 match(Set mem (StoreD mem src)); 6870 ins_cost(MEMORY_REF_COST); 6871 6872 format %{ "STFD $src, $mem" %} 6873 size(4); 6874 ins_encode( enc_stfd(src, mem) ); 6875 ins_pipe(pipe_class_memory); 6876 %} 6877 6878 //----------Store Instructions With Zeros-------------------------------------- 6879 6880 // Card-mark for CMS garbage collection. 6881 // This cardmark does an optimization so that it must not always 6882 // do a releasing store. For this, it gets the address of 6883 // CMSCollectorCardTableBarrierSetBSExt::_requires_release as input. 6884 // (Using releaseFieldAddr in the match rule is a hack.) 6885 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6886 match(Set mem (StoreCM mem releaseFieldAddr)); 6887 effect(TEMP crx); 6888 predicate(false); 6889 ins_cost(MEMORY_REF_COST); 6890 6891 // See loadConP. 6892 ins_cannot_rematerialize(true); 6893 6894 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6895 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6896 ins_pipe(pipe_class_memory); 6897 %} 6898 6899 // Card-mark for CMS garbage collection. 6900 // This cardmark does an optimization so that it must not always 6901 // do a releasing store. For this, it needs the constant address of 6902 // CMSCollectorCardTableBarrierSetBSExt::_requires_release. 6903 // This constant address is split off here by expand so we can use 6904 // adlc / matcher functionality to load it from the constant section. 6905 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6906 match(Set mem (StoreCM mem zero)); 6907 predicate(UseConcMarkSweepGC); 6908 6909 expand %{ 6910 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableBarrierSetBSExt::requires_release_address() */ %} 6911 iRegLdst releaseFieldAddress; 6912 flagsReg crx; 6913 loadConL_Ex(releaseFieldAddress, baseImm); 6914 storeCM_CMS(mem, releaseFieldAddress, crx); 6915 %} 6916 %} 6917 6918 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6919 match(Set mem (StoreCM mem zero)); 6920 predicate(UseG1GC); 6921 ins_cost(MEMORY_REF_COST); 6922 6923 ins_cannot_rematerialize(true); 6924 6925 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6926 size(8); 6927 ins_encode %{ 6928 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6929 __ li(R0, 0); 6930 //__ release(); // G1: oops are allowed to get visible after dirty marking 6931 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6932 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6933 %} 6934 ins_pipe(pipe_class_memory); 6935 %} 6936 6937 // Convert oop pointer into compressed form. 6938 6939 // Nodes for postalloc expand. 6940 6941 // Shift node for expand. 6942 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6943 // The match rule is needed to make it a 'MachTypeNode'! 6944 match(Set dst (EncodeP src)); 6945 predicate(false); 6946 6947 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6948 size(4); 6949 ins_encode %{ 6950 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6951 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6952 %} 6953 ins_pipe(pipe_class_default); 6954 %} 6955 6956 // Add node for expand. 6957 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6958 // The match rule is needed to make it a 'MachTypeNode'! 6959 match(Set dst (EncodeP src)); 6960 predicate(false); 6961 6962 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6963 ins_encode %{ 6964 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6965 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6966 %} 6967 ins_pipe(pipe_class_default); 6968 %} 6969 6970 // Conditional sub base. 6971 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6972 // The match rule is needed to make it a 'MachTypeNode'! 6973 match(Set dst (EncodeP (Binary crx src1))); 6974 predicate(false); 6975 6976 format %{ "BEQ $crx, done\n\t" 6977 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6978 "done:" %} 6979 ins_encode %{ 6980 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6981 Label done; 6982 __ beq($crx$$CondRegister, done); 6983 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6984 __ bind(done); 6985 %} 6986 ins_pipe(pipe_class_default); 6987 %} 6988 6989 // Power 7 can use isel instruction 6990 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6991 // The match rule is needed to make it a 'MachTypeNode'! 6992 match(Set dst (EncodeP (Binary crx src1))); 6993 predicate(false); 6994 6995 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6996 size(4); 6997 ins_encode %{ 6998 // This is a Power7 instruction for which no machine description exists. 6999 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7000 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7001 %} 7002 ins_pipe(pipe_class_default); 7003 %} 7004 7005 // Disjoint narrow oop base. 7006 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7007 match(Set dst (EncodeP src)); 7008 predicate(Universe::narrow_oop_base_disjoint()); 7009 7010 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7011 size(4); 7012 ins_encode %{ 7013 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7014 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 7015 %} 7016 ins_pipe(pipe_class_default); 7017 %} 7018 7019 // shift != 0, base != 0 7020 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 7021 match(Set dst (EncodeP src)); 7022 effect(TEMP crx); 7023 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 7024 Universe::narrow_oop_shift() != 0 && 7025 Universe::narrow_oop_base_overlaps()); 7026 7027 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 7028 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 7029 %} 7030 7031 // shift != 0, base != 0 7032 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 7033 match(Set dst (EncodeP src)); 7034 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 7035 Universe::narrow_oop_shift() != 0 && 7036 Universe::narrow_oop_base_overlaps()); 7037 7038 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 7039 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 7040 %} 7041 7042 // shift != 0, base == 0 7043 // TODO: This is the same as encodeP_shift. Merge! 7044 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 7045 match(Set dst (EncodeP src)); 7046 predicate(Universe::narrow_oop_shift() != 0 && 7047 Universe::narrow_oop_base() ==0); 7048 7049 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 7050 size(4); 7051 ins_encode %{ 7052 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7053 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 7054 %} 7055 ins_pipe(pipe_class_default); 7056 %} 7057 7058 // Compressed OOPs with narrow_oop_shift == 0. 7059 // shift == 0, base == 0 7060 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 7061 match(Set dst (EncodeP src)); 7062 predicate(Universe::narrow_oop_shift() == 0); 7063 7064 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 7065 // variable size, 0 or 4. 7066 ins_encode %{ 7067 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7068 __ mr_if_needed($dst$$Register, $src$$Register); 7069 %} 7070 ins_pipe(pipe_class_default); 7071 %} 7072 7073 // Decode nodes. 7074 7075 // Shift node for expand. 7076 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 7077 // The match rule is needed to make it a 'MachTypeNode'! 7078 match(Set dst (DecodeN src)); 7079 predicate(false); 7080 7081 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 7082 size(4); 7083 ins_encode %{ 7084 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7085 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7086 %} 7087 ins_pipe(pipe_class_default); 7088 %} 7089 7090 // Add node for expand. 7091 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7092 // The match rule is needed to make it a 'MachTypeNode'! 7093 match(Set dst (DecodeN src)); 7094 predicate(false); 7095 7096 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7097 ins_encode %{ 7098 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7099 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7100 %} 7101 ins_pipe(pipe_class_default); 7102 %} 7103 7104 // conditianal add base for expand 7105 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7106 // The match rule is needed to make it a 'MachTypeNode'! 7107 // NOTICE that the rule is nonsense - we just have to make sure that: 7108 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7109 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7110 match(Set dst (DecodeN (Binary crx src))); 7111 predicate(false); 7112 7113 format %{ "BEQ $crx, done\n\t" 7114 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7115 "done:" %} 7116 ins_encode %{ 7117 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7118 Label done; 7119 __ beq($crx$$CondRegister, done); 7120 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7121 __ bind(done); 7122 %} 7123 ins_pipe(pipe_class_default); 7124 %} 7125 7126 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7127 // The match rule is needed to make it a 'MachTypeNode'! 7128 // NOTICE that the rule is nonsense - we just have to make sure that: 7129 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7130 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7131 match(Set dst (DecodeN (Binary crx src1))); 7132 predicate(false); 7133 7134 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7135 size(4); 7136 ins_encode %{ 7137 // This is a Power7 instruction for which no machine description exists. 7138 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7139 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7140 %} 7141 ins_pipe(pipe_class_default); 7142 %} 7143 7144 // shift != 0, base != 0 7145 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7146 match(Set dst (DecodeN src)); 7147 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7148 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7149 Universe::narrow_oop_shift() != 0 && 7150 Universe::narrow_oop_base() != 0); 7151 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7152 effect(TEMP crx); 7153 7154 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7155 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7156 %} 7157 7158 // shift != 0, base == 0 7159 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7160 match(Set dst (DecodeN src)); 7161 predicate(Universe::narrow_oop_shift() != 0 && 7162 Universe::narrow_oop_base() == 0); 7163 7164 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7165 size(4); 7166 ins_encode %{ 7167 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7168 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7169 %} 7170 ins_pipe(pipe_class_default); 7171 %} 7172 7173 // Optimize DecodeN for disjoint base. 7174 // Shift narrow oop and or it into register that already contains the heap base. 7175 // Base == dst must hold, and is assured by construction in postaloc_expand. 7176 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7177 match(Set dst (DecodeN src)); 7178 effect(TEMP base); 7179 predicate(false); 7180 7181 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7182 size(4); 7183 ins_encode %{ 7184 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7185 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 7186 %} 7187 ins_pipe(pipe_class_default); 7188 %} 7189 7190 // Optimize DecodeN for disjoint base. 7191 // This node requires only one cycle on the critical path. 7192 // We must postalloc_expand as we can not express use_def effects where 7193 // the used register is L and the def'ed register P. 7194 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7195 match(Set dst (DecodeN src)); 7196 effect(TEMP_DEF dst); 7197 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7198 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7199 Universe::narrow_oop_base_disjoint()); 7200 ins_cost(DEFAULT_COST); 7201 7202 format %{ "MOV $dst, heapbase \t\n" 7203 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7204 postalloc_expand %{ 7205 loadBaseNode *n1 = new loadBaseNode(); 7206 n1->add_req(NULL); 7207 n1->_opnds[0] = op_dst; 7208 7209 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7210 n2->add_req(n_region, n_src, n1); 7211 n2->_opnds[0] = op_dst; 7212 n2->_opnds[1] = op_src; 7213 n2->_opnds[2] = op_dst; 7214 n2->_bottom_type = _bottom_type; 7215 7216 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7217 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7218 7219 nodes->push(n1); 7220 nodes->push(n2); 7221 %} 7222 %} 7223 7224 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7225 match(Set dst (DecodeN src)); 7226 effect(TEMP_DEF dst, TEMP crx); 7227 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7228 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7229 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 7230 ins_cost(3 * DEFAULT_COST); 7231 7232 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7233 postalloc_expand %{ 7234 loadBaseNode *n1 = new loadBaseNode(); 7235 n1->add_req(NULL); 7236 n1->_opnds[0] = op_dst; 7237 7238 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7239 n_compare->add_req(n_region, n_src); 7240 n_compare->_opnds[0] = op_crx; 7241 n_compare->_opnds[1] = op_src; 7242 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7243 7244 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7245 n2->add_req(n_region, n_src, n1); 7246 n2->_opnds[0] = op_dst; 7247 n2->_opnds[1] = op_src; 7248 n2->_opnds[2] = op_dst; 7249 n2->_bottom_type = _bottom_type; 7250 7251 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7252 n_cond_set->add_req(n_region, n_compare, n2); 7253 n_cond_set->_opnds[0] = op_dst; 7254 n_cond_set->_opnds[1] = op_crx; 7255 n_cond_set->_opnds[2] = op_dst; 7256 n_cond_set->_bottom_type = _bottom_type; 7257 7258 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7259 ra_->set_oop(n_cond_set, true); 7260 7261 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7262 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7263 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7264 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7265 7266 nodes->push(n1); 7267 nodes->push(n_compare); 7268 nodes->push(n2); 7269 nodes->push(n_cond_set); 7270 %} 7271 %} 7272 7273 // src != 0, shift != 0, base != 0 7274 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7275 match(Set dst (DecodeN src)); 7276 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7277 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7278 Universe::narrow_oop_shift() != 0 && 7279 Universe::narrow_oop_base() != 0); 7280 ins_cost(2 * DEFAULT_COST); 7281 7282 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7283 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7284 %} 7285 7286 // Compressed OOPs with narrow_oop_shift == 0. 7287 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7288 match(Set dst (DecodeN src)); 7289 predicate(Universe::narrow_oop_shift() == 0); 7290 ins_cost(DEFAULT_COST); 7291 7292 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7293 // variable size, 0 or 4. 7294 ins_encode %{ 7295 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7296 __ mr_if_needed($dst$$Register, $src$$Register); 7297 %} 7298 ins_pipe(pipe_class_default); 7299 %} 7300 7301 // Convert compressed oop into int for vectors alignment masking. 7302 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7303 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7304 predicate(Universe::narrow_oop_shift() == 0); 7305 ins_cost(DEFAULT_COST); 7306 7307 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7308 // variable size, 0 or 4. 7309 ins_encode %{ 7310 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7311 __ mr_if_needed($dst$$Register, $src$$Register); 7312 %} 7313 ins_pipe(pipe_class_default); 7314 %} 7315 7316 // Convert klass pointer into compressed form. 7317 7318 // Nodes for postalloc expand. 7319 7320 // Shift node for expand. 7321 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7322 // The match rule is needed to make it a 'MachTypeNode'! 7323 match(Set dst (EncodePKlass src)); 7324 predicate(false); 7325 7326 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7327 size(4); 7328 ins_encode %{ 7329 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7330 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7331 %} 7332 ins_pipe(pipe_class_default); 7333 %} 7334 7335 // Add node for expand. 7336 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7337 // The match rule is needed to make it a 'MachTypeNode'! 7338 match(Set dst (EncodePKlass (Binary base src))); 7339 predicate(false); 7340 7341 format %{ "SUB $dst, $base, $src \t// encode" %} 7342 size(4); 7343 ins_encode %{ 7344 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7345 __ subf($dst$$Register, $base$$Register, $src$$Register); 7346 %} 7347 ins_pipe(pipe_class_default); 7348 %} 7349 7350 // Disjoint narrow oop base. 7351 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7352 match(Set dst (EncodePKlass src)); 7353 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 7354 7355 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7356 size(4); 7357 ins_encode %{ 7358 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7359 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 7360 %} 7361 ins_pipe(pipe_class_default); 7362 %} 7363 7364 // shift != 0, base != 0 7365 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7366 match(Set dst (EncodePKlass (Binary base src))); 7367 predicate(false); 7368 7369 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7370 postalloc_expand %{ 7371 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7372 n1->add_req(n_region, n_base, n_src); 7373 n1->_opnds[0] = op_dst; 7374 n1->_opnds[1] = op_base; 7375 n1->_opnds[2] = op_src; 7376 n1->_bottom_type = _bottom_type; 7377 7378 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7379 n2->add_req(n_region, n1); 7380 n2->_opnds[0] = op_dst; 7381 n2->_opnds[1] = op_dst; 7382 n2->_bottom_type = _bottom_type; 7383 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7384 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7385 7386 nodes->push(n1); 7387 nodes->push(n2); 7388 %} 7389 %} 7390 7391 // shift != 0, base != 0 7392 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7393 match(Set dst (EncodePKlass src)); 7394 //predicate(Universe::narrow_klass_shift() != 0 && 7395 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 7396 7397 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7398 ins_cost(DEFAULT_COST*2); // Don't count constant. 7399 expand %{ 7400 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 7401 iRegLdst base; 7402 loadConL_Ex(base, baseImm); 7403 encodePKlass_not_null_Ex(dst, base, src); 7404 %} 7405 %} 7406 7407 // Decode nodes. 7408 7409 // Shift node for expand. 7410 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7411 // The match rule is needed to make it a 'MachTypeNode'! 7412 match(Set dst (DecodeNKlass src)); 7413 predicate(false); 7414 7415 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7416 size(4); 7417 ins_encode %{ 7418 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7419 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7420 %} 7421 ins_pipe(pipe_class_default); 7422 %} 7423 7424 // Add node for expand. 7425 7426 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7427 // The match rule is needed to make it a 'MachTypeNode'! 7428 match(Set dst (DecodeNKlass (Binary base src))); 7429 predicate(false); 7430 7431 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7432 size(4); 7433 ins_encode %{ 7434 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7435 __ add($dst$$Register, $base$$Register, $src$$Register); 7436 %} 7437 ins_pipe(pipe_class_default); 7438 %} 7439 7440 // src != 0, shift != 0, base != 0 7441 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7442 match(Set dst (DecodeNKlass (Binary base src))); 7443 //effect(kill src); // We need a register for the immediate result after shifting. 7444 predicate(false); 7445 7446 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7447 postalloc_expand %{ 7448 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7449 n1->add_req(n_region, n_base, n_src); 7450 n1->_opnds[0] = op_dst; 7451 n1->_opnds[1] = op_base; 7452 n1->_opnds[2] = op_src; 7453 n1->_bottom_type = _bottom_type; 7454 7455 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7456 n2->add_req(n_region, n1); 7457 n2->_opnds[0] = op_dst; 7458 n2->_opnds[1] = op_dst; 7459 n2->_bottom_type = _bottom_type; 7460 7461 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7462 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7463 7464 nodes->push(n1); 7465 nodes->push(n2); 7466 %} 7467 %} 7468 7469 // src != 0, shift != 0, base != 0 7470 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7471 match(Set dst (DecodeNKlass src)); 7472 // predicate(Universe::narrow_klass_shift() != 0 && 7473 // Universe::narrow_klass_base() != 0); 7474 7475 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7476 7477 ins_cost(DEFAULT_COST*2); // Don't count constant. 7478 expand %{ 7479 // We add first, then we shift. Like this, we can get along with one register less. 7480 // But we have to load the base pre-shifted. 7481 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7482 iRegLdst base; 7483 loadConL_Ex(base, baseImm); 7484 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7485 %} 7486 %} 7487 7488 //----------MemBar Instructions----------------------------------------------- 7489 // Memory barrier flavors 7490 7491 instruct membar_acquire() %{ 7492 match(LoadFence); 7493 ins_cost(4*MEMORY_REF_COST); 7494 7495 format %{ "MEMBAR-acquire" %} 7496 size(4); 7497 ins_encode %{ 7498 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7499 __ acquire(); 7500 %} 7501 ins_pipe(pipe_class_default); 7502 %} 7503 7504 instruct unnecessary_membar_acquire() %{ 7505 match(MemBarAcquire); 7506 ins_cost(0); 7507 7508 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7509 size(0); 7510 ins_encode( /*empty*/ ); 7511 ins_pipe(pipe_class_default); 7512 %} 7513 7514 instruct membar_acquire_lock() %{ 7515 match(MemBarAcquireLock); 7516 ins_cost(0); 7517 7518 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7519 size(0); 7520 ins_encode( /*empty*/ ); 7521 ins_pipe(pipe_class_default); 7522 %} 7523 7524 instruct membar_release() %{ 7525 match(MemBarRelease); 7526 match(StoreFence); 7527 ins_cost(4*MEMORY_REF_COST); 7528 7529 format %{ "MEMBAR-release" %} 7530 size(4); 7531 ins_encode %{ 7532 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7533 __ release(); 7534 %} 7535 ins_pipe(pipe_class_default); 7536 %} 7537 7538 instruct membar_storestore() %{ 7539 match(MemBarStoreStore); 7540 ins_cost(4*MEMORY_REF_COST); 7541 7542 format %{ "MEMBAR-store-store" %} 7543 size(4); 7544 ins_encode %{ 7545 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7546 __ membar(Assembler::StoreStore); 7547 %} 7548 ins_pipe(pipe_class_default); 7549 %} 7550 7551 instruct membar_release_lock() %{ 7552 match(MemBarReleaseLock); 7553 ins_cost(0); 7554 7555 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7556 size(0); 7557 ins_encode( /*empty*/ ); 7558 ins_pipe(pipe_class_default); 7559 %} 7560 7561 instruct membar_volatile() %{ 7562 match(MemBarVolatile); 7563 ins_cost(4*MEMORY_REF_COST); 7564 7565 format %{ "MEMBAR-volatile" %} 7566 size(4); 7567 ins_encode %{ 7568 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7569 __ fence(); 7570 %} 7571 ins_pipe(pipe_class_default); 7572 %} 7573 7574 // This optimization is wrong on PPC. The following pattern is not supported: 7575 // MemBarVolatile 7576 // ^ ^ 7577 // | | 7578 // CtrlProj MemProj 7579 // ^ ^ 7580 // | | 7581 // | Load 7582 // | 7583 // MemBarVolatile 7584 // 7585 // The first MemBarVolatile could get optimized out! According to 7586 // Vladimir, this pattern can not occur on Oracle platforms. 7587 // However, it does occur on PPC64 (because of membars in 7588 // inline_unsafe_load_store). 7589 // 7590 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7591 // Don't forget to look at the implementation of post_store_load_barrier again, 7592 // we did other fixes in that method. 7593 //instruct unnecessary_membar_volatile() %{ 7594 // match(MemBarVolatile); 7595 // predicate(Matcher::post_store_load_barrier(n)); 7596 // ins_cost(0); 7597 // 7598 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7599 // size(0); 7600 // ins_encode( /*empty*/ ); 7601 // ins_pipe(pipe_class_default); 7602 //%} 7603 7604 instruct membar_CPUOrder() %{ 7605 match(MemBarCPUOrder); 7606 ins_cost(0); 7607 7608 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7609 size(0); 7610 ins_encode( /*empty*/ ); 7611 ins_pipe(pipe_class_default); 7612 %} 7613 7614 //----------Conditional Move--------------------------------------------------- 7615 7616 // Cmove using isel. 7617 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7618 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7619 predicate(VM_Version::has_isel()); 7620 ins_cost(DEFAULT_COST); 7621 7622 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7623 size(4); 7624 ins_encode %{ 7625 // This is a Power7 instruction for which no machine description 7626 // exists. Anyways, the scheduler should be off on Power7. 7627 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7628 int cc = $cmp$$cmpcode; 7629 __ isel($dst$$Register, $crx$$CondRegister, 7630 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7631 %} 7632 ins_pipe(pipe_class_default); 7633 %} 7634 7635 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7636 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7637 predicate(!VM_Version::has_isel()); 7638 ins_cost(DEFAULT_COST+BRANCH_COST); 7639 7640 ins_variable_size_depending_on_alignment(true); 7641 7642 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7643 // Worst case is branch + move + stop, no stop without scheduler 7644 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7645 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7646 ins_pipe(pipe_class_default); 7647 %} 7648 7649 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7650 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7651 ins_cost(DEFAULT_COST+BRANCH_COST); 7652 7653 ins_variable_size_depending_on_alignment(true); 7654 7655 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7656 // Worst case is branch + move + stop, no stop without scheduler 7657 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7658 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7659 ins_pipe(pipe_class_default); 7660 %} 7661 7662 // Cmove using isel. 7663 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7664 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7665 predicate(VM_Version::has_isel()); 7666 ins_cost(DEFAULT_COST); 7667 7668 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7669 size(4); 7670 ins_encode %{ 7671 // This is a Power7 instruction for which no machine description 7672 // exists. Anyways, the scheduler should be off on Power7. 7673 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7674 int cc = $cmp$$cmpcode; 7675 __ isel($dst$$Register, $crx$$CondRegister, 7676 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7677 %} 7678 ins_pipe(pipe_class_default); 7679 %} 7680 7681 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7682 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7683 predicate(!VM_Version::has_isel()); 7684 ins_cost(DEFAULT_COST+BRANCH_COST); 7685 7686 ins_variable_size_depending_on_alignment(true); 7687 7688 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7689 // Worst case is branch + move + stop, no stop without scheduler. 7690 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7691 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7692 ins_pipe(pipe_class_default); 7693 %} 7694 7695 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7696 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7697 ins_cost(DEFAULT_COST+BRANCH_COST); 7698 7699 ins_variable_size_depending_on_alignment(true); 7700 7701 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7702 // Worst case is branch + move + stop, no stop without scheduler. 7703 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7704 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7705 ins_pipe(pipe_class_default); 7706 %} 7707 7708 // Cmove using isel. 7709 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7710 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7711 predicate(VM_Version::has_isel()); 7712 ins_cost(DEFAULT_COST); 7713 7714 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7715 size(4); 7716 ins_encode %{ 7717 // This is a Power7 instruction for which no machine description 7718 // exists. Anyways, the scheduler should be off on Power7. 7719 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7720 int cc = $cmp$$cmpcode; 7721 __ isel($dst$$Register, $crx$$CondRegister, 7722 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7723 %} 7724 ins_pipe(pipe_class_default); 7725 %} 7726 7727 // Conditional move for RegN. Only cmov(reg, reg). 7728 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7729 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7730 predicate(!VM_Version::has_isel()); 7731 ins_cost(DEFAULT_COST+BRANCH_COST); 7732 7733 ins_variable_size_depending_on_alignment(true); 7734 7735 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7736 // Worst case is branch + move + stop, no stop without scheduler. 7737 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7738 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7739 ins_pipe(pipe_class_default); 7740 %} 7741 7742 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7743 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7744 ins_cost(DEFAULT_COST+BRANCH_COST); 7745 7746 ins_variable_size_depending_on_alignment(true); 7747 7748 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7749 // Worst case is branch + move + stop, no stop without scheduler. 7750 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7751 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7752 ins_pipe(pipe_class_default); 7753 %} 7754 7755 // Cmove using isel. 7756 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7757 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7758 predicate(VM_Version::has_isel()); 7759 ins_cost(DEFAULT_COST); 7760 7761 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7762 size(4); 7763 ins_encode %{ 7764 // This is a Power7 instruction for which no machine description 7765 // exists. Anyways, the scheduler should be off on Power7. 7766 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7767 int cc = $cmp$$cmpcode; 7768 __ isel($dst$$Register, $crx$$CondRegister, 7769 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7770 %} 7771 ins_pipe(pipe_class_default); 7772 %} 7773 7774 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7775 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7776 predicate(!VM_Version::has_isel()); 7777 ins_cost(DEFAULT_COST+BRANCH_COST); 7778 7779 ins_variable_size_depending_on_alignment(true); 7780 7781 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7782 // Worst case is branch + move + stop, no stop without scheduler. 7783 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7784 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7785 ins_pipe(pipe_class_default); 7786 %} 7787 7788 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7789 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7790 ins_cost(DEFAULT_COST+BRANCH_COST); 7791 7792 ins_variable_size_depending_on_alignment(true); 7793 7794 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7795 // Worst case is branch + move + stop, no stop without scheduler. 7796 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7797 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7798 ins_pipe(pipe_class_default); 7799 %} 7800 7801 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7802 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7803 ins_cost(DEFAULT_COST+BRANCH_COST); 7804 7805 ins_variable_size_depending_on_alignment(true); 7806 7807 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7808 // Worst case is branch + move + stop, no stop without scheduler. 7809 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7810 ins_encode %{ 7811 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7812 Label done; 7813 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7814 // Branch if not (cmp crx). 7815 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7816 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7817 // TODO PPC port __ endgroup_if_needed(_size == 12); 7818 __ bind(done); 7819 %} 7820 ins_pipe(pipe_class_default); 7821 %} 7822 7823 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7824 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7825 ins_cost(DEFAULT_COST+BRANCH_COST); 7826 7827 ins_variable_size_depending_on_alignment(true); 7828 7829 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7830 // Worst case is branch + move + stop, no stop without scheduler. 7831 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7832 ins_encode %{ 7833 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7834 Label done; 7835 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7836 // Branch if not (cmp crx). 7837 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7838 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7839 // TODO PPC port __ endgroup_if_needed(_size == 12); 7840 __ bind(done); 7841 %} 7842 ins_pipe(pipe_class_default); 7843 %} 7844 7845 //----------Conditional_store-------------------------------------------------- 7846 // Conditional-store of the updated heap-top. 7847 // Used during allocation of the shared heap. 7848 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7849 7850 // As compareAndSwapL, but return flag register instead of boolean value in 7851 // int register. 7852 // Used by sun/misc/AtomicLongCSImpl.java. 7853 // Mem_ptr must be a memory operand, else this node does not get 7854 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7855 // can be rematerialized which leads to errors. 7856 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7857 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7858 effect(TEMP cr0); 7859 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7860 ins_encode %{ 7861 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7862 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7863 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7864 noreg, NULL, true); 7865 %} 7866 ins_pipe(pipe_class_default); 7867 %} 7868 7869 // As compareAndSwapP, but return flag register instead of boolean value in 7870 // int register. 7871 // This instruction is matched if UseTLAB is off. 7872 // Mem_ptr must be a memory operand, else this node does not get 7873 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7874 // can be rematerialized which leads to errors. 7875 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7876 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7877 ins_cost(2*MEMORY_REF_COST); 7878 7879 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7880 ins_encode %{ 7881 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7882 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7883 %} 7884 ins_pipe(pipe_class_memory); 7885 %} 7886 7887 // Implement LoadPLocked. Must be ordered against changes of the memory location 7888 // by storePConditional. 7889 // Don't know whether this is ever used. 7890 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7891 match(Set dst (LoadPLocked mem)); 7892 ins_cost(2*MEMORY_REF_COST); 7893 7894 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7895 size(4); 7896 ins_encode %{ 7897 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7898 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7899 %} 7900 ins_pipe(pipe_class_memory); 7901 %} 7902 7903 //----------Compare-And-Swap--------------------------------------------------- 7904 7905 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7906 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7907 // matched. 7908 7909 // Strong versions: 7910 7911 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7912 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7913 predicate(VM_Version::has_lqarx()); 7914 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7915 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7916 ins_encode %{ 7917 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7918 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7919 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7920 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7921 $res$$Register, true); 7922 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7923 __ isync(); 7924 } else { 7925 __ sync(); 7926 } 7927 %} 7928 ins_pipe(pipe_class_default); 7929 %} 7930 7931 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7932 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7933 predicate(!VM_Version::has_lqarx()); 7934 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7935 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7936 ins_encode %{ 7937 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7938 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7939 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7940 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7941 $res$$Register, true); 7942 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7943 __ isync(); 7944 } else { 7945 __ sync(); 7946 } 7947 %} 7948 ins_pipe(pipe_class_default); 7949 %} 7950 7951 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7952 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7953 predicate(VM_Version::has_lqarx()); 7954 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7955 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7956 ins_encode %{ 7957 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7958 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7959 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7960 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7961 $res$$Register, true); 7962 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7963 __ isync(); 7964 } else { 7965 __ sync(); 7966 } 7967 %} 7968 ins_pipe(pipe_class_default); 7969 %} 7970 7971 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7972 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7973 predicate(!VM_Version::has_lqarx()); 7974 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7975 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7976 ins_encode %{ 7977 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7978 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7979 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7980 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7981 $res$$Register, true); 7982 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7983 __ isync(); 7984 } else { 7985 __ sync(); 7986 } 7987 %} 7988 ins_pipe(pipe_class_default); 7989 %} 7990 7991 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7992 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7993 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7994 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7995 ins_encode %{ 7996 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7997 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7998 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7999 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8000 $res$$Register, true); 8001 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8002 __ isync(); 8003 } else { 8004 __ sync(); 8005 } 8006 %} 8007 ins_pipe(pipe_class_default); 8008 %} 8009 8010 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8011 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 8012 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8013 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8014 ins_encode %{ 8015 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8016 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8017 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8018 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8019 $res$$Register, true); 8020 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8021 __ isync(); 8022 } else { 8023 __ sync(); 8024 } 8025 %} 8026 ins_pipe(pipe_class_default); 8027 %} 8028 8029 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8030 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 8031 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8032 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8033 ins_encode %{ 8034 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8035 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8036 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8037 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8038 $res$$Register, NULL, true); 8039 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8040 __ isync(); 8041 } else { 8042 __ sync(); 8043 } 8044 %} 8045 ins_pipe(pipe_class_default); 8046 %} 8047 8048 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8049 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 8050 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8051 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8052 ins_encode %{ 8053 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8054 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8055 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8056 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8057 $res$$Register, NULL, true); 8058 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8059 __ isync(); 8060 } else { 8061 __ sync(); 8062 } 8063 %} 8064 ins_pipe(pipe_class_default); 8065 %} 8066 8067 // Weak versions: 8068 8069 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8070 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8071 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8072 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8073 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8074 ins_encode %{ 8075 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8076 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8077 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8078 MacroAssembler::MemBarNone, 8079 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8080 %} 8081 ins_pipe(pipe_class_default); 8082 %} 8083 8084 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8085 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8086 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8087 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8088 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8089 ins_encode %{ 8090 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8091 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8092 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8093 MacroAssembler::MemBarNone, 8094 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8095 %} 8096 ins_pipe(pipe_class_default); 8097 %} 8098 8099 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8100 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8101 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8102 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8103 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8104 ins_encode %{ 8105 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8106 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8107 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8108 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8109 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8110 %} 8111 ins_pipe(pipe_class_default); 8112 %} 8113 8114 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8115 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8116 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8117 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8118 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8119 ins_encode %{ 8120 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8121 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8122 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8123 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8124 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8125 %} 8126 ins_pipe(pipe_class_default); 8127 %} 8128 8129 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8130 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8131 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8132 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8133 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8134 ins_encode %{ 8135 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8136 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8137 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8138 MacroAssembler::MemBarNone, 8139 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8140 %} 8141 ins_pipe(pipe_class_default); 8142 %} 8143 8144 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8145 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8146 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8147 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8148 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8149 ins_encode %{ 8150 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8151 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8152 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8153 MacroAssembler::MemBarNone, 8154 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8155 %} 8156 ins_pipe(pipe_class_default); 8157 %} 8158 8159 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8160 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8161 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8162 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8163 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8164 ins_encode %{ 8165 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8166 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8167 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8168 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8169 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8170 %} 8171 ins_pipe(pipe_class_default); 8172 %} 8173 8174 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8175 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8176 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8177 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8178 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8179 ins_encode %{ 8180 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8181 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8182 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8183 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8184 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8185 %} 8186 ins_pipe(pipe_class_default); 8187 %} 8188 8189 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8190 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8191 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8192 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8193 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8194 ins_encode %{ 8195 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8196 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8197 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8198 MacroAssembler::MemBarNone, 8199 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8200 %} 8201 ins_pipe(pipe_class_default); 8202 %} 8203 8204 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8205 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8206 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8207 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8208 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8209 ins_encode %{ 8210 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8211 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8212 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8213 // value is never passed to caller. 8214 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8215 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8216 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8217 %} 8218 ins_pipe(pipe_class_default); 8219 %} 8220 8221 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8222 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8223 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8224 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8225 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8226 ins_encode %{ 8227 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8228 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8229 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8230 MacroAssembler::MemBarNone, 8231 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8232 %} 8233 ins_pipe(pipe_class_default); 8234 %} 8235 8236 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8237 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8238 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8239 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8240 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8241 ins_encode %{ 8242 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8243 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8244 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8245 // value is never passed to caller. 8246 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8247 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8248 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8249 %} 8250 ins_pipe(pipe_class_default); 8251 %} 8252 8253 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8254 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8255 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8256 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8257 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8258 ins_encode %{ 8259 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8260 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8261 // value is never passed to caller. 8262 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8263 MacroAssembler::MemBarNone, 8264 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8265 %} 8266 ins_pipe(pipe_class_default); 8267 %} 8268 8269 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8270 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8271 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8272 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8273 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 8274 ins_encode %{ 8275 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8276 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8277 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8278 // value is never passed to caller. 8279 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8280 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8281 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8282 %} 8283 ins_pipe(pipe_class_default); 8284 %} 8285 8286 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8287 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8288 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8289 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8290 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8291 ins_encode %{ 8292 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8293 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8294 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8295 MacroAssembler::MemBarNone, 8296 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8297 %} 8298 ins_pipe(pipe_class_default); 8299 %} 8300 8301 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8302 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8303 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8304 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8305 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8306 ins_encode %{ 8307 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8308 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8309 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8310 // value is never passed to caller. 8311 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8312 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8313 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8314 %} 8315 ins_pipe(pipe_class_default); 8316 %} 8317 8318 // CompareAndExchange 8319 8320 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8321 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8322 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8323 effect(TEMP_DEF res, TEMP cr0); 8324 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8325 ins_encode %{ 8326 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8327 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8328 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8329 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8330 noreg, true); 8331 %} 8332 ins_pipe(pipe_class_default); 8333 %} 8334 8335 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8336 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8337 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8338 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8339 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8340 ins_encode %{ 8341 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8342 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8343 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8344 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8345 noreg, true); 8346 %} 8347 ins_pipe(pipe_class_default); 8348 %} 8349 8350 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8351 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8352 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8353 effect(TEMP_DEF res, TEMP cr0); 8354 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8355 ins_encode %{ 8356 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8357 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8358 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8359 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8360 noreg, true); 8361 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8362 __ isync(); 8363 } else { 8364 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8365 __ sync(); 8366 } 8367 %} 8368 ins_pipe(pipe_class_default); 8369 %} 8370 8371 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8372 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8373 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8374 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8375 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8376 ins_encode %{ 8377 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8378 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8379 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8380 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8381 noreg, true); 8382 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8383 __ isync(); 8384 } else { 8385 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8386 __ sync(); 8387 } 8388 %} 8389 ins_pipe(pipe_class_default); 8390 %} 8391 8392 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8393 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8394 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8395 effect(TEMP_DEF res, TEMP cr0); 8396 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8397 ins_encode %{ 8398 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8399 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8400 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8401 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8402 noreg, true); 8403 %} 8404 ins_pipe(pipe_class_default); 8405 %} 8406 8407 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8408 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8409 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8410 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8411 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8412 ins_encode %{ 8413 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8414 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8415 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8416 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8417 noreg, true); 8418 %} 8419 ins_pipe(pipe_class_default); 8420 %} 8421 8422 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8423 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8424 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8425 effect(TEMP_DEF res, TEMP cr0); 8426 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8427 ins_encode %{ 8428 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8429 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8430 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8431 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8432 noreg, true); 8433 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8434 __ isync(); 8435 } else { 8436 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8437 __ sync(); 8438 } 8439 %} 8440 ins_pipe(pipe_class_default); 8441 %} 8442 8443 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8444 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8445 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8446 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8447 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8448 ins_encode %{ 8449 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8450 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8451 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8452 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8453 noreg, true); 8454 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8455 __ isync(); 8456 } else { 8457 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8458 __ sync(); 8459 } 8460 %} 8461 ins_pipe(pipe_class_default); 8462 %} 8463 8464 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8465 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8466 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8467 effect(TEMP_DEF res, TEMP cr0); 8468 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8469 ins_encode %{ 8470 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8471 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8472 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8473 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8474 noreg, true); 8475 %} 8476 ins_pipe(pipe_class_default); 8477 %} 8478 8479 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8480 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8481 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8482 effect(TEMP_DEF res, TEMP cr0); 8483 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8484 ins_encode %{ 8485 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8486 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8487 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8488 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8489 noreg, true); 8490 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8491 __ isync(); 8492 } else { 8493 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8494 __ sync(); 8495 } 8496 %} 8497 ins_pipe(pipe_class_default); 8498 %} 8499 8500 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8501 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8502 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8503 effect(TEMP_DEF res, TEMP cr0); 8504 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8505 ins_encode %{ 8506 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8507 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8508 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8509 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8510 noreg, true); 8511 %} 8512 ins_pipe(pipe_class_default); 8513 %} 8514 8515 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8516 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8517 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8518 effect(TEMP_DEF res, TEMP cr0); 8519 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8520 ins_encode %{ 8521 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8522 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8523 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8524 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8525 noreg, true); 8526 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8527 __ isync(); 8528 } else { 8529 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8530 __ sync(); 8531 } 8532 %} 8533 ins_pipe(pipe_class_default); 8534 %} 8535 8536 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8537 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8538 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8539 effect(TEMP_DEF res, TEMP cr0); 8540 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8541 ins_encode %{ 8542 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8543 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8544 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8545 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8546 noreg, NULL, true); 8547 %} 8548 ins_pipe(pipe_class_default); 8549 %} 8550 8551 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8552 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8553 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8554 effect(TEMP_DEF res, TEMP cr0); 8555 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8556 ins_encode %{ 8557 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8558 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8559 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8560 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8561 noreg, NULL, true); 8562 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8563 __ isync(); 8564 } else { 8565 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8566 __ sync(); 8567 } 8568 %} 8569 ins_pipe(pipe_class_default); 8570 %} 8571 8572 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8573 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8574 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8575 effect(TEMP_DEF res, TEMP cr0); 8576 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8577 ins_encode %{ 8578 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8579 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8580 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8581 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8582 noreg, NULL, true); 8583 %} 8584 ins_pipe(pipe_class_default); 8585 %} 8586 8587 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8588 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8589 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8590 effect(TEMP_DEF res, TEMP cr0); 8591 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8592 ins_encode %{ 8593 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8594 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8595 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8596 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8597 noreg, NULL, true); 8598 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8599 __ isync(); 8600 } else { 8601 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8602 __ sync(); 8603 } 8604 %} 8605 ins_pipe(pipe_class_default); 8606 %} 8607 8608 // Special RMW 8609 8610 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8611 match(Set res (GetAndAddB mem_ptr src)); 8612 predicate(VM_Version::has_lqarx()); 8613 effect(TEMP_DEF res, TEMP cr0); 8614 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8615 ins_encode %{ 8616 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8617 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8618 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8619 __ isync(); 8620 } else { 8621 __ sync(); 8622 } 8623 %} 8624 ins_pipe(pipe_class_default); 8625 %} 8626 8627 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8628 match(Set res (GetAndAddB mem_ptr src)); 8629 predicate(!VM_Version::has_lqarx()); 8630 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8631 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8632 ins_encode %{ 8633 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8634 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8635 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8636 __ isync(); 8637 } else { 8638 __ sync(); 8639 } 8640 %} 8641 ins_pipe(pipe_class_default); 8642 %} 8643 8644 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8645 match(Set res (GetAndAddS mem_ptr src)); 8646 predicate(VM_Version::has_lqarx()); 8647 effect(TEMP_DEF res, TEMP cr0); 8648 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8649 ins_encode %{ 8650 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8651 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8652 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8653 __ isync(); 8654 } else { 8655 __ sync(); 8656 } 8657 %} 8658 ins_pipe(pipe_class_default); 8659 %} 8660 8661 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8662 match(Set res (GetAndAddS mem_ptr src)); 8663 predicate(!VM_Version::has_lqarx()); 8664 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8665 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8666 ins_encode %{ 8667 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8668 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8669 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8670 __ isync(); 8671 } else { 8672 __ sync(); 8673 } 8674 %} 8675 ins_pipe(pipe_class_default); 8676 %} 8677 8678 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8679 match(Set res (GetAndAddI mem_ptr src)); 8680 effect(TEMP_DEF res, TEMP cr0); 8681 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8682 ins_encode %{ 8683 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8684 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8685 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8686 __ isync(); 8687 } else { 8688 __ sync(); 8689 } 8690 %} 8691 ins_pipe(pipe_class_default); 8692 %} 8693 8694 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8695 match(Set res (GetAndAddL mem_ptr src)); 8696 effect(TEMP_DEF res, TEMP cr0); 8697 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8698 ins_encode %{ 8699 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8700 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8701 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8702 __ isync(); 8703 } else { 8704 __ sync(); 8705 } 8706 %} 8707 ins_pipe(pipe_class_default); 8708 %} 8709 8710 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8711 match(Set res (GetAndSetB mem_ptr src)); 8712 predicate(VM_Version::has_lqarx()); 8713 effect(TEMP_DEF res, TEMP cr0); 8714 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8715 ins_encode %{ 8716 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8717 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8718 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8719 __ isync(); 8720 } else { 8721 __ sync(); 8722 } 8723 %} 8724 ins_pipe(pipe_class_default); 8725 %} 8726 8727 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8728 match(Set res (GetAndSetB mem_ptr src)); 8729 predicate(!VM_Version::has_lqarx()); 8730 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8731 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8732 ins_encode %{ 8733 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8734 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8735 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8736 __ isync(); 8737 } else { 8738 __ sync(); 8739 } 8740 %} 8741 ins_pipe(pipe_class_default); 8742 %} 8743 8744 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8745 match(Set res (GetAndSetS mem_ptr src)); 8746 predicate(VM_Version::has_lqarx()); 8747 effect(TEMP_DEF res, TEMP cr0); 8748 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8749 ins_encode %{ 8750 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8751 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8752 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8753 __ isync(); 8754 } else { 8755 __ sync(); 8756 } 8757 %} 8758 ins_pipe(pipe_class_default); 8759 %} 8760 8761 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8762 match(Set res (GetAndSetS mem_ptr src)); 8763 predicate(!VM_Version::has_lqarx()); 8764 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8765 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8766 ins_encode %{ 8767 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8768 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8769 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8770 __ isync(); 8771 } else { 8772 __ sync(); 8773 } 8774 %} 8775 ins_pipe(pipe_class_default); 8776 %} 8777 8778 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8779 match(Set res (GetAndSetI mem_ptr src)); 8780 effect(TEMP_DEF res, TEMP cr0); 8781 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8782 ins_encode %{ 8783 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8784 MacroAssembler::cmpxchgx_hint_atomic_update()); 8785 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8786 __ isync(); 8787 } else { 8788 __ sync(); 8789 } 8790 %} 8791 ins_pipe(pipe_class_default); 8792 %} 8793 8794 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8795 match(Set res (GetAndSetL mem_ptr src)); 8796 effect(TEMP_DEF res, TEMP cr0); 8797 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8798 ins_encode %{ 8799 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8800 MacroAssembler::cmpxchgx_hint_atomic_update()); 8801 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8802 __ isync(); 8803 } else { 8804 __ sync(); 8805 } 8806 %} 8807 ins_pipe(pipe_class_default); 8808 %} 8809 8810 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8811 match(Set res (GetAndSetP mem_ptr src)); 8812 effect(TEMP_DEF res, TEMP cr0); 8813 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8814 ins_encode %{ 8815 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8816 MacroAssembler::cmpxchgx_hint_atomic_update()); 8817 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8818 __ isync(); 8819 } else { 8820 __ sync(); 8821 } 8822 %} 8823 ins_pipe(pipe_class_default); 8824 %} 8825 8826 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8827 match(Set res (GetAndSetN mem_ptr src)); 8828 effect(TEMP_DEF res, TEMP cr0); 8829 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8830 ins_encode %{ 8831 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8832 MacroAssembler::cmpxchgx_hint_atomic_update()); 8833 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8834 __ isync(); 8835 } else { 8836 __ sync(); 8837 } 8838 %} 8839 ins_pipe(pipe_class_default); 8840 %} 8841 8842 //----------Arithmetic Instructions-------------------------------------------- 8843 // Addition Instructions 8844 8845 // Register Addition 8846 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8847 match(Set dst (AddI src1 src2)); 8848 format %{ "ADD $dst, $src1, $src2" %} 8849 size(4); 8850 ins_encode %{ 8851 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8852 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8853 %} 8854 ins_pipe(pipe_class_default); 8855 %} 8856 8857 // Expand does not work with above instruct. (??) 8858 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8859 // no match-rule 8860 effect(DEF dst, USE src1, USE src2); 8861 format %{ "ADD $dst, $src1, $src2" %} 8862 size(4); 8863 ins_encode %{ 8864 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8865 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8866 %} 8867 ins_pipe(pipe_class_default); 8868 %} 8869 8870 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8871 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8872 ins_cost(DEFAULT_COST*3); 8873 8874 expand %{ 8875 // FIXME: we should do this in the ideal world. 8876 iRegIdst tmp1; 8877 iRegIdst tmp2; 8878 addI_reg_reg(tmp1, src1, src2); 8879 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8880 addI_reg_reg(dst, tmp1, tmp2); 8881 %} 8882 %} 8883 8884 // Immediate Addition 8885 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8886 match(Set dst (AddI src1 src2)); 8887 format %{ "ADDI $dst, $src1, $src2" %} 8888 size(4); 8889 ins_encode %{ 8890 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8891 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8892 %} 8893 ins_pipe(pipe_class_default); 8894 %} 8895 8896 // Immediate Addition with 16-bit shifted operand 8897 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8898 match(Set dst (AddI src1 src2)); 8899 format %{ "ADDIS $dst, $src1, $src2" %} 8900 size(4); 8901 ins_encode %{ 8902 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8903 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8904 %} 8905 ins_pipe(pipe_class_default); 8906 %} 8907 8908 // Long Addition 8909 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8910 match(Set dst (AddL src1 src2)); 8911 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8912 size(4); 8913 ins_encode %{ 8914 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8915 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8916 %} 8917 ins_pipe(pipe_class_default); 8918 %} 8919 8920 // Expand does not work with above instruct. (??) 8921 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8922 // no match-rule 8923 effect(DEF dst, USE src1, USE src2); 8924 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8925 size(4); 8926 ins_encode %{ 8927 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8928 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8929 %} 8930 ins_pipe(pipe_class_default); 8931 %} 8932 8933 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8934 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8935 ins_cost(DEFAULT_COST*3); 8936 8937 expand %{ 8938 // FIXME: we should do this in the ideal world. 8939 iRegLdst tmp1; 8940 iRegLdst tmp2; 8941 addL_reg_reg(tmp1, src1, src2); 8942 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8943 addL_reg_reg(dst, tmp1, tmp2); 8944 %} 8945 %} 8946 8947 // AddL + ConvL2I. 8948 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8949 match(Set dst (ConvL2I (AddL src1 src2))); 8950 8951 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8952 size(4); 8953 ins_encode %{ 8954 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8955 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8956 %} 8957 ins_pipe(pipe_class_default); 8958 %} 8959 8960 // No constant pool entries required. 8961 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8962 match(Set dst (AddL src1 src2)); 8963 8964 format %{ "ADDI $dst, $src1, $src2" %} 8965 size(4); 8966 ins_encode %{ 8967 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8968 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8969 %} 8970 ins_pipe(pipe_class_default); 8971 %} 8972 8973 // Long Immediate Addition with 16-bit shifted operand. 8974 // No constant pool entries required. 8975 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8976 match(Set dst (AddL src1 src2)); 8977 8978 format %{ "ADDIS $dst, $src1, $src2" %} 8979 size(4); 8980 ins_encode %{ 8981 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8982 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8983 %} 8984 ins_pipe(pipe_class_default); 8985 %} 8986 8987 // Pointer Register Addition 8988 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8989 match(Set dst (AddP src1 src2)); 8990 format %{ "ADD $dst, $src1, $src2" %} 8991 size(4); 8992 ins_encode %{ 8993 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8994 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8995 %} 8996 ins_pipe(pipe_class_default); 8997 %} 8998 8999 // Pointer Immediate Addition 9000 // No constant pool entries required. 9001 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 9002 match(Set dst (AddP src1 src2)); 9003 9004 format %{ "ADDI $dst, $src1, $src2" %} 9005 size(4); 9006 ins_encode %{ 9007 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 9008 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 9009 %} 9010 ins_pipe(pipe_class_default); 9011 %} 9012 9013 // Pointer Immediate Addition with 16-bit shifted operand. 9014 // No constant pool entries required. 9015 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 9016 match(Set dst (AddP src1 src2)); 9017 9018 format %{ "ADDIS $dst, $src1, $src2" %} 9019 size(4); 9020 ins_encode %{ 9021 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 9022 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 9023 %} 9024 ins_pipe(pipe_class_default); 9025 %} 9026 9027 //--------------------- 9028 // Subtraction Instructions 9029 9030 // Register Subtraction 9031 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9032 match(Set dst (SubI src1 src2)); 9033 format %{ "SUBF $dst, $src2, $src1" %} 9034 size(4); 9035 ins_encode %{ 9036 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9037 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9038 %} 9039 ins_pipe(pipe_class_default); 9040 %} 9041 9042 // Immediate Subtraction 9043 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 9044 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 9045 9046 // SubI from constant (using subfic). 9047 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 9048 match(Set dst (SubI src1 src2)); 9049 format %{ "SUBI $dst, $src1, $src2" %} 9050 9051 size(4); 9052 ins_encode %{ 9053 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 9054 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 9055 %} 9056 ins_pipe(pipe_class_default); 9057 %} 9058 9059 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 9060 // positive integers and 0xF...F for negative ones. 9061 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 9062 // no match-rule, false predicate 9063 effect(DEF dst, USE src); 9064 predicate(false); 9065 9066 format %{ "SRAWI $dst, $src, #31" %} 9067 size(4); 9068 ins_encode %{ 9069 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9070 __ srawi($dst$$Register, $src$$Register, 0x1f); 9071 %} 9072 ins_pipe(pipe_class_default); 9073 %} 9074 9075 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 9076 match(Set dst (AbsI src)); 9077 ins_cost(DEFAULT_COST*3); 9078 9079 expand %{ 9080 iRegIdst tmp1; 9081 iRegIdst tmp2; 9082 signmask32I_regI(tmp1, src); 9083 xorI_reg_reg(tmp2, tmp1, src); 9084 subI_reg_reg(dst, tmp2, tmp1); 9085 %} 9086 %} 9087 9088 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9089 match(Set dst (SubI zero src2)); 9090 format %{ "NEG $dst, $src2" %} 9091 size(4); 9092 ins_encode %{ 9093 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9094 __ neg($dst$$Register, $src2$$Register); 9095 %} 9096 ins_pipe(pipe_class_default); 9097 %} 9098 9099 // Long subtraction 9100 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9101 match(Set dst (SubL src1 src2)); 9102 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9103 size(4); 9104 ins_encode %{ 9105 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9106 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9107 %} 9108 ins_pipe(pipe_class_default); 9109 %} 9110 9111 // SubL + convL2I. 9112 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9113 match(Set dst (ConvL2I (SubL src1 src2))); 9114 9115 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9116 size(4); 9117 ins_encode %{ 9118 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9119 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9120 %} 9121 ins_pipe(pipe_class_default); 9122 %} 9123 9124 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9125 // positive longs and 0xF...F for negative ones. 9126 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9127 // no match-rule, false predicate 9128 effect(DEF dst, USE src); 9129 predicate(false); 9130 9131 format %{ "SRADI $dst, $src, #63" %} 9132 size(4); 9133 ins_encode %{ 9134 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9135 __ sradi($dst$$Register, $src$$Register, 0x3f); 9136 %} 9137 ins_pipe(pipe_class_default); 9138 %} 9139 9140 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9141 // positive longs and 0xF...F for negative ones. 9142 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9143 // no match-rule, false predicate 9144 effect(DEF dst, USE src); 9145 predicate(false); 9146 9147 format %{ "SRADI $dst, $src, #63" %} 9148 size(4); 9149 ins_encode %{ 9150 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9151 __ sradi($dst$$Register, $src$$Register, 0x3f); 9152 %} 9153 ins_pipe(pipe_class_default); 9154 %} 9155 9156 // Long negation 9157 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9158 match(Set dst (SubL zero src2)); 9159 format %{ "NEG $dst, $src2 \t// long" %} 9160 size(4); 9161 ins_encode %{ 9162 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9163 __ neg($dst$$Register, $src2$$Register); 9164 %} 9165 ins_pipe(pipe_class_default); 9166 %} 9167 9168 // NegL + ConvL2I. 9169 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9170 match(Set dst (ConvL2I (SubL zero src2))); 9171 9172 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9173 size(4); 9174 ins_encode %{ 9175 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9176 __ neg($dst$$Register, $src2$$Register); 9177 %} 9178 ins_pipe(pipe_class_default); 9179 %} 9180 9181 // Multiplication Instructions 9182 // Integer Multiplication 9183 9184 // Register Multiplication 9185 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9186 match(Set dst (MulI src1 src2)); 9187 ins_cost(DEFAULT_COST); 9188 9189 format %{ "MULLW $dst, $src1, $src2" %} 9190 size(4); 9191 ins_encode %{ 9192 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9193 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9194 %} 9195 ins_pipe(pipe_class_default); 9196 %} 9197 9198 // Immediate Multiplication 9199 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9200 match(Set dst (MulI src1 src2)); 9201 ins_cost(DEFAULT_COST); 9202 9203 format %{ "MULLI $dst, $src1, $src2" %} 9204 size(4); 9205 ins_encode %{ 9206 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9207 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9208 %} 9209 ins_pipe(pipe_class_default); 9210 %} 9211 9212 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9213 match(Set dst (MulL src1 src2)); 9214 ins_cost(DEFAULT_COST); 9215 9216 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9217 size(4); 9218 ins_encode %{ 9219 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9220 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9221 %} 9222 ins_pipe(pipe_class_default); 9223 %} 9224 9225 // Multiply high for optimized long division by constant. 9226 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9227 match(Set dst (MulHiL src1 src2)); 9228 ins_cost(DEFAULT_COST); 9229 9230 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9231 size(4); 9232 ins_encode %{ 9233 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9234 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9235 %} 9236 ins_pipe(pipe_class_default); 9237 %} 9238 9239 // Immediate Multiplication 9240 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9241 match(Set dst (MulL src1 src2)); 9242 ins_cost(DEFAULT_COST); 9243 9244 format %{ "MULLI $dst, $src1, $src2" %} 9245 size(4); 9246 ins_encode %{ 9247 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9248 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9249 %} 9250 ins_pipe(pipe_class_default); 9251 %} 9252 9253 // Integer Division with Immediate -1: Negate. 9254 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9255 match(Set dst (DivI src1 src2)); 9256 ins_cost(DEFAULT_COST); 9257 9258 format %{ "NEG $dst, $src1 \t// /-1" %} 9259 size(4); 9260 ins_encode %{ 9261 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9262 __ neg($dst$$Register, $src1$$Register); 9263 %} 9264 ins_pipe(pipe_class_default); 9265 %} 9266 9267 // Integer Division with constant, but not -1. 9268 // We should be able to improve this by checking the type of src2. 9269 // It might well be that src2 is known to be positive. 9270 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9271 match(Set dst (DivI src1 src2)); 9272 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9273 ins_cost(2*DEFAULT_COST); 9274 9275 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9276 size(4); 9277 ins_encode %{ 9278 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9279 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9280 %} 9281 ins_pipe(pipe_class_default); 9282 %} 9283 9284 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9285 effect(USE_DEF dst, USE src1, USE crx); 9286 predicate(false); 9287 9288 ins_variable_size_depending_on_alignment(true); 9289 9290 format %{ "CMOVE $dst, neg($src1), $crx" %} 9291 // Worst case is branch + move + stop, no stop without scheduler. 9292 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9293 ins_encode %{ 9294 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9295 Label done; 9296 __ bne($crx$$CondRegister, done); 9297 __ neg($dst$$Register, $src1$$Register); 9298 // TODO PPC port __ endgroup_if_needed(_size == 12); 9299 __ bind(done); 9300 %} 9301 ins_pipe(pipe_class_default); 9302 %} 9303 9304 // Integer Division with Registers not containing constants. 9305 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9306 match(Set dst (DivI src1 src2)); 9307 ins_cost(10*DEFAULT_COST); 9308 9309 expand %{ 9310 immI16 imm %{ (int)-1 %} 9311 flagsReg tmp1; 9312 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9313 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9314 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9315 %} 9316 %} 9317 9318 // Long Division with Immediate -1: Negate. 9319 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9320 match(Set dst (DivL src1 src2)); 9321 ins_cost(DEFAULT_COST); 9322 9323 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9324 size(4); 9325 ins_encode %{ 9326 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9327 __ neg($dst$$Register, $src1$$Register); 9328 %} 9329 ins_pipe(pipe_class_default); 9330 %} 9331 9332 // Long Division with constant, but not -1. 9333 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9334 match(Set dst (DivL src1 src2)); 9335 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9336 ins_cost(2*DEFAULT_COST); 9337 9338 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9339 size(4); 9340 ins_encode %{ 9341 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9342 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9343 %} 9344 ins_pipe(pipe_class_default); 9345 %} 9346 9347 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9348 effect(USE_DEF dst, USE src1, USE crx); 9349 predicate(false); 9350 9351 ins_variable_size_depending_on_alignment(true); 9352 9353 format %{ "CMOVE $dst, neg($src1), $crx" %} 9354 // Worst case is branch + move + stop, no stop without scheduler. 9355 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9356 ins_encode %{ 9357 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9358 Label done; 9359 __ bne($crx$$CondRegister, done); 9360 __ neg($dst$$Register, $src1$$Register); 9361 // TODO PPC port __ endgroup_if_needed(_size == 12); 9362 __ bind(done); 9363 %} 9364 ins_pipe(pipe_class_default); 9365 %} 9366 9367 // Long Division with Registers not containing constants. 9368 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9369 match(Set dst (DivL src1 src2)); 9370 ins_cost(10*DEFAULT_COST); 9371 9372 expand %{ 9373 immL16 imm %{ (int)-1 %} 9374 flagsReg tmp1; 9375 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9376 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9377 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9378 %} 9379 %} 9380 9381 // Integer Remainder with registers. 9382 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9383 match(Set dst (ModI src1 src2)); 9384 ins_cost(10*DEFAULT_COST); 9385 9386 expand %{ 9387 immI16 imm %{ (int)-1 %} 9388 flagsReg tmp1; 9389 iRegIdst tmp2; 9390 iRegIdst tmp3; 9391 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9392 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9393 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9394 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9395 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9396 %} 9397 %} 9398 9399 // Long Remainder with registers 9400 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9401 match(Set dst (ModL src1 src2)); 9402 ins_cost(10*DEFAULT_COST); 9403 9404 expand %{ 9405 immL16 imm %{ (int)-1 %} 9406 flagsReg tmp1; 9407 iRegLdst tmp2; 9408 iRegLdst tmp3; 9409 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9410 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9411 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9412 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9413 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9414 %} 9415 %} 9416 9417 // Integer Shift Instructions 9418 9419 // Register Shift Left 9420 9421 // Clear all but the lowest #mask bits. 9422 // Used to normalize shift amounts in registers. 9423 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9424 // no match-rule, false predicate 9425 effect(DEF dst, USE src, USE mask); 9426 predicate(false); 9427 9428 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9429 size(4); 9430 ins_encode %{ 9431 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9432 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9433 %} 9434 ins_pipe(pipe_class_default); 9435 %} 9436 9437 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9438 // no match-rule, false predicate 9439 effect(DEF dst, USE src1, USE src2); 9440 predicate(false); 9441 9442 format %{ "SLW $dst, $src1, $src2" %} 9443 size(4); 9444 ins_encode %{ 9445 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9446 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9447 %} 9448 ins_pipe(pipe_class_default); 9449 %} 9450 9451 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9452 match(Set dst (LShiftI src1 src2)); 9453 ins_cost(DEFAULT_COST*2); 9454 expand %{ 9455 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9456 iRegIdst tmpI; 9457 maskI_reg_imm(tmpI, src2, mask); 9458 lShiftI_reg_reg(dst, src1, tmpI); 9459 %} 9460 %} 9461 9462 // Register Shift Left Immediate 9463 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9464 match(Set dst (LShiftI src1 src2)); 9465 9466 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9467 size(4); 9468 ins_encode %{ 9469 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9470 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9471 %} 9472 ins_pipe(pipe_class_default); 9473 %} 9474 9475 // AndI with negpow2-constant + LShiftI 9476 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9477 match(Set dst (LShiftI (AndI src1 src2) src3)); 9478 predicate(UseRotateAndMaskInstructionsPPC64); 9479 9480 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9481 size(4); 9482 ins_encode %{ 9483 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9484 long src2 = $src2$$constant; 9485 long src3 = $src3$$constant; 9486 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9487 if (maskbits >= 32) { 9488 __ li($dst$$Register, 0); // addi 9489 } else { 9490 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9491 } 9492 %} 9493 ins_pipe(pipe_class_default); 9494 %} 9495 9496 // RShiftI + AndI with negpow2-constant + LShiftI 9497 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9498 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9499 predicate(UseRotateAndMaskInstructionsPPC64); 9500 9501 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9502 size(4); 9503 ins_encode %{ 9504 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9505 long src2 = $src2$$constant; 9506 long src3 = $src3$$constant; 9507 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9508 if (maskbits >= 32) { 9509 __ li($dst$$Register, 0); // addi 9510 } else { 9511 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9512 } 9513 %} 9514 ins_pipe(pipe_class_default); 9515 %} 9516 9517 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9518 // no match-rule, false predicate 9519 effect(DEF dst, USE src1, USE src2); 9520 predicate(false); 9521 9522 format %{ "SLD $dst, $src1, $src2" %} 9523 size(4); 9524 ins_encode %{ 9525 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9526 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9527 %} 9528 ins_pipe(pipe_class_default); 9529 %} 9530 9531 // Register Shift Left 9532 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9533 match(Set dst (LShiftL src1 src2)); 9534 ins_cost(DEFAULT_COST*2); 9535 expand %{ 9536 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9537 iRegIdst tmpI; 9538 maskI_reg_imm(tmpI, src2, mask); 9539 lShiftL_regL_regI(dst, src1, tmpI); 9540 %} 9541 %} 9542 9543 // Register Shift Left Immediate 9544 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9545 match(Set dst (LShiftL src1 src2)); 9546 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9547 size(4); 9548 ins_encode %{ 9549 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9550 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9551 %} 9552 ins_pipe(pipe_class_default); 9553 %} 9554 9555 // If we shift more than 32 bits, we need not convert I2L. 9556 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9557 match(Set dst (LShiftL (ConvI2L src1) src2)); 9558 ins_cost(DEFAULT_COST); 9559 9560 size(4); 9561 format %{ "SLDI $dst, i2l($src1), $src2" %} 9562 ins_encode %{ 9563 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9564 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9565 %} 9566 ins_pipe(pipe_class_default); 9567 %} 9568 9569 // Shift a postivie int to the left. 9570 // Clrlsldi clears the upper 32 bits and shifts. 9571 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9572 match(Set dst (LShiftL (ConvI2L src1) src2)); 9573 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9574 9575 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9576 size(4); 9577 ins_encode %{ 9578 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9579 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9580 %} 9581 ins_pipe(pipe_class_default); 9582 %} 9583 9584 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9585 // no match-rule, false predicate 9586 effect(DEF dst, USE src1, USE src2); 9587 predicate(false); 9588 9589 format %{ "SRAW $dst, $src1, $src2" %} 9590 size(4); 9591 ins_encode %{ 9592 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9593 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9594 %} 9595 ins_pipe(pipe_class_default); 9596 %} 9597 9598 // Register Arithmetic Shift Right 9599 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9600 match(Set dst (RShiftI src1 src2)); 9601 ins_cost(DEFAULT_COST*2); 9602 expand %{ 9603 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9604 iRegIdst tmpI; 9605 maskI_reg_imm(tmpI, src2, mask); 9606 arShiftI_reg_reg(dst, src1, tmpI); 9607 %} 9608 %} 9609 9610 // Register Arithmetic Shift Right Immediate 9611 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9612 match(Set dst (RShiftI src1 src2)); 9613 9614 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9615 size(4); 9616 ins_encode %{ 9617 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9618 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9619 %} 9620 ins_pipe(pipe_class_default); 9621 %} 9622 9623 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9624 // no match-rule, false predicate 9625 effect(DEF dst, USE src1, USE src2); 9626 predicate(false); 9627 9628 format %{ "SRAD $dst, $src1, $src2" %} 9629 size(4); 9630 ins_encode %{ 9631 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9632 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9633 %} 9634 ins_pipe(pipe_class_default); 9635 %} 9636 9637 // Register Shift Right Arithmetic Long 9638 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9639 match(Set dst (RShiftL src1 src2)); 9640 ins_cost(DEFAULT_COST*2); 9641 9642 expand %{ 9643 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9644 iRegIdst tmpI; 9645 maskI_reg_imm(tmpI, src2, mask); 9646 arShiftL_regL_regI(dst, src1, tmpI); 9647 %} 9648 %} 9649 9650 // Register Shift Right Immediate 9651 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9652 match(Set dst (RShiftL src1 src2)); 9653 9654 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9655 size(4); 9656 ins_encode %{ 9657 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9658 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9659 %} 9660 ins_pipe(pipe_class_default); 9661 %} 9662 9663 // RShiftL + ConvL2I 9664 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9665 match(Set dst (ConvL2I (RShiftL src1 src2))); 9666 9667 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9668 size(4); 9669 ins_encode %{ 9670 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9671 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9672 %} 9673 ins_pipe(pipe_class_default); 9674 %} 9675 9676 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9677 // no match-rule, false predicate 9678 effect(DEF dst, USE src1, USE src2); 9679 predicate(false); 9680 9681 format %{ "SRW $dst, $src1, $src2" %} 9682 size(4); 9683 ins_encode %{ 9684 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9685 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9686 %} 9687 ins_pipe(pipe_class_default); 9688 %} 9689 9690 // Register Shift Right 9691 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9692 match(Set dst (URShiftI src1 src2)); 9693 ins_cost(DEFAULT_COST*2); 9694 9695 expand %{ 9696 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9697 iRegIdst tmpI; 9698 maskI_reg_imm(tmpI, src2, mask); 9699 urShiftI_reg_reg(dst, src1, tmpI); 9700 %} 9701 %} 9702 9703 // Register Shift Right Immediate 9704 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9705 match(Set dst (URShiftI src1 src2)); 9706 9707 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9708 size(4); 9709 ins_encode %{ 9710 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9711 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9712 %} 9713 ins_pipe(pipe_class_default); 9714 %} 9715 9716 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9717 // no match-rule, false predicate 9718 effect(DEF dst, USE src1, USE src2); 9719 predicate(false); 9720 9721 format %{ "SRD $dst, $src1, $src2" %} 9722 size(4); 9723 ins_encode %{ 9724 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9725 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9726 %} 9727 ins_pipe(pipe_class_default); 9728 %} 9729 9730 // Register Shift Right 9731 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9732 match(Set dst (URShiftL src1 src2)); 9733 ins_cost(DEFAULT_COST*2); 9734 9735 expand %{ 9736 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9737 iRegIdst tmpI; 9738 maskI_reg_imm(tmpI, src2, mask); 9739 urShiftL_regL_regI(dst, src1, tmpI); 9740 %} 9741 %} 9742 9743 // Register Shift Right Immediate 9744 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9745 match(Set dst (URShiftL src1 src2)); 9746 9747 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9748 size(4); 9749 ins_encode %{ 9750 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9751 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9752 %} 9753 ins_pipe(pipe_class_default); 9754 %} 9755 9756 // URShiftL + ConvL2I. 9757 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9758 match(Set dst (ConvL2I (URShiftL src1 src2))); 9759 9760 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9761 size(4); 9762 ins_encode %{ 9763 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9764 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9765 %} 9766 ins_pipe(pipe_class_default); 9767 %} 9768 9769 // Register Shift Right Immediate with a CastP2X 9770 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9771 match(Set dst (URShiftL (CastP2X src1) src2)); 9772 9773 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9774 size(4); 9775 ins_encode %{ 9776 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9777 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9778 %} 9779 ins_pipe(pipe_class_default); 9780 %} 9781 9782 // Bitfield Extract: URShiftI + AndI 9783 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9784 match(Set dst (AndI (URShiftI src1 src2) src3)); 9785 9786 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9787 size(4); 9788 ins_encode %{ 9789 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9790 int rshift = ($src2$$constant) & 0x1f; 9791 int length = log2_long(((jlong) $src3$$constant) + 1); 9792 if (rshift + length > 32) { 9793 // if necessary, adjust mask to omit rotated bits. 9794 length = 32 - rshift; 9795 } 9796 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9797 %} 9798 ins_pipe(pipe_class_default); 9799 %} 9800 9801 // Bitfield Extract: URShiftL + AndL 9802 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9803 match(Set dst (AndL (URShiftL src1 src2) src3)); 9804 9805 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9806 size(4); 9807 ins_encode %{ 9808 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9809 int rshift = ($src2$$constant) & 0x3f; 9810 int length = log2_long(((jlong) $src3$$constant) + 1); 9811 if (rshift + length > 64) { 9812 // if necessary, adjust mask to omit rotated bits. 9813 length = 64 - rshift; 9814 } 9815 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9816 %} 9817 ins_pipe(pipe_class_default); 9818 %} 9819 9820 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9821 match(Set dst (ConvL2I (ConvI2L src))); 9822 9823 format %{ "EXTSW $dst, $src \t// int->int" %} 9824 size(4); 9825 ins_encode %{ 9826 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9827 __ extsw($dst$$Register, $src$$Register); 9828 %} 9829 ins_pipe(pipe_class_default); 9830 %} 9831 9832 //----------Rotate Instructions------------------------------------------------ 9833 9834 // Rotate Left by 8-bit immediate 9835 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9836 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9837 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9838 9839 format %{ "ROTLWI $dst, $src, $lshift" %} 9840 size(4); 9841 ins_encode %{ 9842 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9843 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9844 %} 9845 ins_pipe(pipe_class_default); 9846 %} 9847 9848 // Rotate Right by 8-bit immediate 9849 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9850 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9851 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9852 9853 format %{ "ROTRWI $dst, $rshift" %} 9854 size(4); 9855 ins_encode %{ 9856 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9857 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9858 %} 9859 ins_pipe(pipe_class_default); 9860 %} 9861 9862 //----------Floating Point Arithmetic Instructions----------------------------- 9863 9864 // Add float single precision 9865 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9866 match(Set dst (AddF src1 src2)); 9867 9868 format %{ "FADDS $dst, $src1, $src2" %} 9869 size(4); 9870 ins_encode %{ 9871 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9872 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9873 %} 9874 ins_pipe(pipe_class_default); 9875 %} 9876 9877 // Add float double precision 9878 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9879 match(Set dst (AddD src1 src2)); 9880 9881 format %{ "FADD $dst, $src1, $src2" %} 9882 size(4); 9883 ins_encode %{ 9884 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9885 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9886 %} 9887 ins_pipe(pipe_class_default); 9888 %} 9889 9890 // Sub float single precision 9891 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9892 match(Set dst (SubF src1 src2)); 9893 9894 format %{ "FSUBS $dst, $src1, $src2" %} 9895 size(4); 9896 ins_encode %{ 9897 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9898 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9899 %} 9900 ins_pipe(pipe_class_default); 9901 %} 9902 9903 // Sub float double precision 9904 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9905 match(Set dst (SubD src1 src2)); 9906 format %{ "FSUB $dst, $src1, $src2" %} 9907 size(4); 9908 ins_encode %{ 9909 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9910 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9911 %} 9912 ins_pipe(pipe_class_default); 9913 %} 9914 9915 // Mul float single precision 9916 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9917 match(Set dst (MulF src1 src2)); 9918 format %{ "FMULS $dst, $src1, $src2" %} 9919 size(4); 9920 ins_encode %{ 9921 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9922 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9923 %} 9924 ins_pipe(pipe_class_default); 9925 %} 9926 9927 // Mul float double precision 9928 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9929 match(Set dst (MulD src1 src2)); 9930 format %{ "FMUL $dst, $src1, $src2" %} 9931 size(4); 9932 ins_encode %{ 9933 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9934 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9935 %} 9936 ins_pipe(pipe_class_default); 9937 %} 9938 9939 // Div float single precision 9940 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9941 match(Set dst (DivF src1 src2)); 9942 format %{ "FDIVS $dst, $src1, $src2" %} 9943 size(4); 9944 ins_encode %{ 9945 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9946 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9947 %} 9948 ins_pipe(pipe_class_default); 9949 %} 9950 9951 // Div float double precision 9952 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9953 match(Set dst (DivD src1 src2)); 9954 format %{ "FDIV $dst, $src1, $src2" %} 9955 size(4); 9956 ins_encode %{ 9957 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9958 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9959 %} 9960 ins_pipe(pipe_class_default); 9961 %} 9962 9963 // Absolute float single precision 9964 instruct absF_reg(regF dst, regF src) %{ 9965 match(Set dst (AbsF src)); 9966 format %{ "FABS $dst, $src \t// float" %} 9967 size(4); 9968 ins_encode %{ 9969 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9970 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9971 %} 9972 ins_pipe(pipe_class_default); 9973 %} 9974 9975 // Absolute float double precision 9976 instruct absD_reg(regD dst, regD src) %{ 9977 match(Set dst (AbsD src)); 9978 format %{ "FABS $dst, $src \t// double" %} 9979 size(4); 9980 ins_encode %{ 9981 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9982 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9983 %} 9984 ins_pipe(pipe_class_default); 9985 %} 9986 9987 instruct negF_reg(regF dst, regF src) %{ 9988 match(Set dst (NegF src)); 9989 format %{ "FNEG $dst, $src \t// float" %} 9990 size(4); 9991 ins_encode %{ 9992 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9993 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9994 %} 9995 ins_pipe(pipe_class_default); 9996 %} 9997 9998 instruct negD_reg(regD dst, regD src) %{ 9999 match(Set dst (NegD src)); 10000 format %{ "FNEG $dst, $src \t// double" %} 10001 size(4); 10002 ins_encode %{ 10003 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 10004 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 10005 %} 10006 ins_pipe(pipe_class_default); 10007 %} 10008 10009 // AbsF + NegF. 10010 instruct negF_absF_reg(regF dst, regF src) %{ 10011 match(Set dst (NegF (AbsF src))); 10012 format %{ "FNABS $dst, $src \t// float" %} 10013 size(4); 10014 ins_encode %{ 10015 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10016 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10017 %} 10018 ins_pipe(pipe_class_default); 10019 %} 10020 10021 // AbsD + NegD. 10022 instruct negD_absD_reg(regD dst, regD src) %{ 10023 match(Set dst (NegD (AbsD src))); 10024 format %{ "FNABS $dst, $src \t// double" %} 10025 size(4); 10026 ins_encode %{ 10027 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10028 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10029 %} 10030 ins_pipe(pipe_class_default); 10031 %} 10032 10033 // VM_Version::has_fsqrt() decides if this node will be used. 10034 // Sqrt float double precision 10035 instruct sqrtD_reg(regD dst, regD src) %{ 10036 match(Set dst (SqrtD src)); 10037 format %{ "FSQRT $dst, $src" %} 10038 size(4); 10039 ins_encode %{ 10040 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 10041 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 10042 %} 10043 ins_pipe(pipe_class_default); 10044 %} 10045 10046 // Single-precision sqrt. 10047 instruct sqrtF_reg(regF dst, regF src) %{ 10048 match(Set dst (SqrtF src)); 10049 predicate(VM_Version::has_fsqrts()); 10050 ins_cost(DEFAULT_COST); 10051 10052 format %{ "FSQRTS $dst, $src" %} 10053 size(4); 10054 ins_encode %{ 10055 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 10056 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 10057 %} 10058 ins_pipe(pipe_class_default); 10059 %} 10060 10061 instruct roundDouble_nop(regD dst) %{ 10062 match(Set dst (RoundDouble dst)); 10063 ins_cost(0); 10064 10065 format %{ " -- \t// RoundDouble not needed - empty" %} 10066 size(0); 10067 // PPC results are already "rounded" (i.e., normal-format IEEE). 10068 ins_encode( /*empty*/ ); 10069 ins_pipe(pipe_class_default); 10070 %} 10071 10072 instruct roundFloat_nop(regF dst) %{ 10073 match(Set dst (RoundFloat dst)); 10074 ins_cost(0); 10075 10076 format %{ " -- \t// RoundFloat not needed - empty" %} 10077 size(0); 10078 // PPC results are already "rounded" (i.e., normal-format IEEE). 10079 ins_encode( /*empty*/ ); 10080 ins_pipe(pipe_class_default); 10081 %} 10082 10083 10084 // Multiply-Accumulate 10085 // src1 * src2 + src3 10086 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10087 match(Set dst (FmaF src3 (Binary src1 src2))); 10088 10089 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10090 size(4); 10091 ins_encode %{ 10092 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10093 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10094 %} 10095 ins_pipe(pipe_class_default); 10096 %} 10097 10098 // src1 * src2 + src3 10099 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10100 match(Set dst (FmaD src3 (Binary src1 src2))); 10101 10102 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10103 size(4); 10104 ins_encode %{ 10105 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10106 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10107 %} 10108 ins_pipe(pipe_class_default); 10109 %} 10110 10111 // -src1 * src2 + src3 = -(src1*src2-src3) 10112 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10113 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10114 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10115 10116 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10117 size(4); 10118 ins_encode %{ 10119 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10120 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10121 %} 10122 ins_pipe(pipe_class_default); 10123 %} 10124 10125 // -src1 * src2 + src3 = -(src1*src2-src3) 10126 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10127 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10128 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10129 10130 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10131 size(4); 10132 ins_encode %{ 10133 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10134 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10135 %} 10136 ins_pipe(pipe_class_default); 10137 %} 10138 10139 // -src1 * src2 - src3 = -(src1*src2+src3) 10140 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10141 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10142 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10143 10144 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10145 size(4); 10146 ins_encode %{ 10147 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10148 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10149 %} 10150 ins_pipe(pipe_class_default); 10151 %} 10152 10153 // -src1 * src2 - src3 = -(src1*src2+src3) 10154 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10155 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10156 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10157 10158 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10159 size(4); 10160 ins_encode %{ 10161 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10162 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10163 %} 10164 ins_pipe(pipe_class_default); 10165 %} 10166 10167 // src1 * src2 - src3 10168 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10169 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10170 10171 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10172 size(4); 10173 ins_encode %{ 10174 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10175 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10176 %} 10177 ins_pipe(pipe_class_default); 10178 %} 10179 10180 // src1 * src2 - src3 10181 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10182 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10183 10184 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10185 size(4); 10186 ins_encode %{ 10187 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10188 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10189 %} 10190 ins_pipe(pipe_class_default); 10191 %} 10192 10193 10194 //----------Logical Instructions----------------------------------------------- 10195 10196 // And Instructions 10197 10198 // Register And 10199 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10200 match(Set dst (AndI src1 src2)); 10201 format %{ "AND $dst, $src1, $src2" %} 10202 size(4); 10203 ins_encode %{ 10204 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10205 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10206 %} 10207 ins_pipe(pipe_class_default); 10208 %} 10209 10210 // Left shifted Immediate And 10211 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10212 match(Set dst (AndI src1 src2)); 10213 effect(KILL cr0); 10214 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10215 size(4); 10216 ins_encode %{ 10217 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10218 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10219 %} 10220 ins_pipe(pipe_class_default); 10221 %} 10222 10223 // Immediate And 10224 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10225 match(Set dst (AndI src1 src2)); 10226 effect(KILL cr0); 10227 10228 format %{ "ANDI $dst, $src1, $src2" %} 10229 size(4); 10230 ins_encode %{ 10231 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10232 // FIXME: avoid andi_ ? 10233 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10234 %} 10235 ins_pipe(pipe_class_default); 10236 %} 10237 10238 // Immediate And where the immediate is a negative power of 2. 10239 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10240 match(Set dst (AndI src1 src2)); 10241 format %{ "ANDWI $dst, $src1, $src2" %} 10242 size(4); 10243 ins_encode %{ 10244 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10245 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10246 %} 10247 ins_pipe(pipe_class_default); 10248 %} 10249 10250 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10251 match(Set dst (AndI src1 src2)); 10252 format %{ "ANDWI $dst, $src1, $src2" %} 10253 size(4); 10254 ins_encode %{ 10255 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10256 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10257 %} 10258 ins_pipe(pipe_class_default); 10259 %} 10260 10261 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10262 match(Set dst (AndI src1 src2)); 10263 predicate(UseRotateAndMaskInstructionsPPC64); 10264 format %{ "ANDWI $dst, $src1, $src2" %} 10265 size(4); 10266 ins_encode %{ 10267 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10268 __ rlwinm($dst$$Register, $src1$$Register, 0, 10269 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10270 %} 10271 ins_pipe(pipe_class_default); 10272 %} 10273 10274 // Register And Long 10275 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10276 match(Set dst (AndL src1 src2)); 10277 ins_cost(DEFAULT_COST); 10278 10279 format %{ "AND $dst, $src1, $src2 \t// long" %} 10280 size(4); 10281 ins_encode %{ 10282 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10283 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10284 %} 10285 ins_pipe(pipe_class_default); 10286 %} 10287 10288 // Immediate And long 10289 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10290 match(Set dst (AndL src1 src2)); 10291 effect(KILL cr0); 10292 10293 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10294 size(4); 10295 ins_encode %{ 10296 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10297 // FIXME: avoid andi_ ? 10298 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10299 %} 10300 ins_pipe(pipe_class_default); 10301 %} 10302 10303 // Immediate And Long where the immediate is a negative power of 2. 10304 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10305 match(Set dst (AndL src1 src2)); 10306 format %{ "ANDDI $dst, $src1, $src2" %} 10307 size(4); 10308 ins_encode %{ 10309 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10310 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10311 %} 10312 ins_pipe(pipe_class_default); 10313 %} 10314 10315 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10316 match(Set dst (AndL src1 src2)); 10317 format %{ "ANDDI $dst, $src1, $src2" %} 10318 size(4); 10319 ins_encode %{ 10320 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10321 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10322 %} 10323 ins_pipe(pipe_class_default); 10324 %} 10325 10326 // AndL + ConvL2I. 10327 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10328 match(Set dst (ConvL2I (AndL src1 src2))); 10329 ins_cost(DEFAULT_COST); 10330 10331 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10332 size(4); 10333 ins_encode %{ 10334 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10335 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10336 %} 10337 ins_pipe(pipe_class_default); 10338 %} 10339 10340 // Or Instructions 10341 10342 // Register Or 10343 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10344 match(Set dst (OrI src1 src2)); 10345 format %{ "OR $dst, $src1, $src2" %} 10346 size(4); 10347 ins_encode %{ 10348 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10349 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10350 %} 10351 ins_pipe(pipe_class_default); 10352 %} 10353 10354 // Expand does not work with above instruct. (??) 10355 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10356 // no match-rule 10357 effect(DEF dst, USE src1, USE src2); 10358 format %{ "OR $dst, $src1, $src2" %} 10359 size(4); 10360 ins_encode %{ 10361 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10362 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10363 %} 10364 ins_pipe(pipe_class_default); 10365 %} 10366 10367 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10368 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10369 ins_cost(DEFAULT_COST*3); 10370 10371 expand %{ 10372 // FIXME: we should do this in the ideal world. 10373 iRegIdst tmp1; 10374 iRegIdst tmp2; 10375 orI_reg_reg(tmp1, src1, src2); 10376 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10377 orI_reg_reg(dst, tmp1, tmp2); 10378 %} 10379 %} 10380 10381 // Immediate Or 10382 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10383 match(Set dst (OrI src1 src2)); 10384 format %{ "ORI $dst, $src1, $src2" %} 10385 size(4); 10386 ins_encode %{ 10387 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10388 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10389 %} 10390 ins_pipe(pipe_class_default); 10391 %} 10392 10393 // Register Or Long 10394 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10395 match(Set dst (OrL src1 src2)); 10396 ins_cost(DEFAULT_COST); 10397 10398 size(4); 10399 format %{ "OR $dst, $src1, $src2 \t// long" %} 10400 ins_encode %{ 10401 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10402 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10403 %} 10404 ins_pipe(pipe_class_default); 10405 %} 10406 10407 // OrL + ConvL2I. 10408 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10409 match(Set dst (ConvL2I (OrL src1 src2))); 10410 ins_cost(DEFAULT_COST); 10411 10412 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10413 size(4); 10414 ins_encode %{ 10415 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10416 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10417 %} 10418 ins_pipe(pipe_class_default); 10419 %} 10420 10421 // Immediate Or long 10422 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10423 match(Set dst (OrL src1 con)); 10424 ins_cost(DEFAULT_COST); 10425 10426 format %{ "ORI $dst, $src1, $con \t// long" %} 10427 size(4); 10428 ins_encode %{ 10429 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10430 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10431 %} 10432 ins_pipe(pipe_class_default); 10433 %} 10434 10435 // Xor Instructions 10436 10437 // Register Xor 10438 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10439 match(Set dst (XorI src1 src2)); 10440 format %{ "XOR $dst, $src1, $src2" %} 10441 size(4); 10442 ins_encode %{ 10443 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10444 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10445 %} 10446 ins_pipe(pipe_class_default); 10447 %} 10448 10449 // Expand does not work with above instruct. (??) 10450 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10451 // no match-rule 10452 effect(DEF dst, USE src1, USE src2); 10453 format %{ "XOR $dst, $src1, $src2" %} 10454 size(4); 10455 ins_encode %{ 10456 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10457 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10458 %} 10459 ins_pipe(pipe_class_default); 10460 %} 10461 10462 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10463 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10464 ins_cost(DEFAULT_COST*3); 10465 10466 expand %{ 10467 // FIXME: we should do this in the ideal world. 10468 iRegIdst tmp1; 10469 iRegIdst tmp2; 10470 xorI_reg_reg(tmp1, src1, src2); 10471 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10472 xorI_reg_reg(dst, tmp1, tmp2); 10473 %} 10474 %} 10475 10476 // Immediate Xor 10477 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10478 match(Set dst (XorI src1 src2)); 10479 format %{ "XORI $dst, $src1, $src2" %} 10480 size(4); 10481 ins_encode %{ 10482 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10483 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10484 %} 10485 ins_pipe(pipe_class_default); 10486 %} 10487 10488 // Register Xor Long 10489 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10490 match(Set dst (XorL src1 src2)); 10491 ins_cost(DEFAULT_COST); 10492 10493 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10494 size(4); 10495 ins_encode %{ 10496 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10497 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10498 %} 10499 ins_pipe(pipe_class_default); 10500 %} 10501 10502 // XorL + ConvL2I. 10503 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10504 match(Set dst (ConvL2I (XorL src1 src2))); 10505 ins_cost(DEFAULT_COST); 10506 10507 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10508 size(4); 10509 ins_encode %{ 10510 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10511 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10512 %} 10513 ins_pipe(pipe_class_default); 10514 %} 10515 10516 // Immediate Xor Long 10517 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10518 match(Set dst (XorL src1 src2)); 10519 ins_cost(DEFAULT_COST); 10520 10521 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10522 size(4); 10523 ins_encode %{ 10524 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10525 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10526 %} 10527 ins_pipe(pipe_class_default); 10528 %} 10529 10530 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10531 match(Set dst (XorI src1 src2)); 10532 ins_cost(DEFAULT_COST); 10533 10534 format %{ "NOT $dst, $src1 ($src2)" %} 10535 size(4); 10536 ins_encode %{ 10537 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10538 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10539 %} 10540 ins_pipe(pipe_class_default); 10541 %} 10542 10543 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10544 match(Set dst (XorL src1 src2)); 10545 ins_cost(DEFAULT_COST); 10546 10547 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10548 size(4); 10549 ins_encode %{ 10550 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10551 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10552 %} 10553 ins_pipe(pipe_class_default); 10554 %} 10555 10556 // And-complement 10557 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10558 match(Set dst (AndI (XorI src1 src2) src3)); 10559 ins_cost(DEFAULT_COST); 10560 10561 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10562 size(4); 10563 ins_encode( enc_andc(dst, src3, src1) ); 10564 ins_pipe(pipe_class_default); 10565 %} 10566 10567 // And-complement 10568 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10569 // no match-rule, false predicate 10570 effect(DEF dst, USE src1, USE src2); 10571 predicate(false); 10572 10573 format %{ "ANDC $dst, $src1, $src2" %} 10574 size(4); 10575 ins_encode %{ 10576 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10577 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10578 %} 10579 ins_pipe(pipe_class_default); 10580 %} 10581 10582 //----------Moves between int/long and float/double---------------------------- 10583 // 10584 // The following rules move values from int/long registers/stack-locations 10585 // to float/double registers/stack-locations and vice versa, without doing any 10586 // conversions. These rules are used to implement the bit-conversion methods 10587 // of java.lang.Float etc., e.g. 10588 // int floatToIntBits(float value) 10589 // float intBitsToFloat(int bits) 10590 // 10591 // Notes on the implementation on ppc64: 10592 // For Power7 and earlier, the rules are limited to those which move between a 10593 // register and a stack-location, because we always have to go through memory 10594 // when moving between a float register and an integer register. 10595 // This restriction is removed in Power8 with the introduction of the mtfprd 10596 // and mffprd instructions. 10597 10598 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10599 match(Set dst (MoveL2D src)); 10600 predicate(VM_Version::has_mtfprd()); 10601 10602 format %{ "MTFPRD $dst, $src" %} 10603 size(4); 10604 ins_encode %{ 10605 __ mtfprd($dst$$FloatRegister, $src$$Register); 10606 %} 10607 ins_pipe(pipe_class_default); 10608 %} 10609 10610 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10611 // no match-rule, false predicate 10612 effect(DEF dst, USE src); 10613 predicate(false); 10614 10615 format %{ "MTFPRWA $dst, $src" %} 10616 size(4); 10617 ins_encode %{ 10618 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10619 %} 10620 ins_pipe(pipe_class_default); 10621 %} 10622 10623 //---------- Chain stack slots between similar types -------- 10624 10625 // These are needed so that the rules below can match. 10626 10627 // Load integer from stack slot 10628 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10629 match(Set dst src); 10630 ins_cost(MEMORY_REF_COST); 10631 10632 format %{ "LWZ $dst, $src" %} 10633 size(4); 10634 ins_encode( enc_lwz(dst, src) ); 10635 ins_pipe(pipe_class_memory); 10636 %} 10637 10638 // Store integer to stack slot 10639 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10640 match(Set dst src); 10641 ins_cost(MEMORY_REF_COST); 10642 10643 format %{ "STW $src, $dst \t// stk" %} 10644 size(4); 10645 ins_encode( enc_stw(src, dst) ); // rs=rt 10646 ins_pipe(pipe_class_memory); 10647 %} 10648 10649 // Load long from stack slot 10650 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10651 match(Set dst src); 10652 ins_cost(MEMORY_REF_COST); 10653 10654 format %{ "LD $dst, $src \t// long" %} 10655 size(4); 10656 ins_encode( enc_ld(dst, src) ); 10657 ins_pipe(pipe_class_memory); 10658 %} 10659 10660 // Store long to stack slot 10661 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10662 match(Set dst src); 10663 ins_cost(MEMORY_REF_COST); 10664 10665 format %{ "STD $src, $dst \t// long" %} 10666 size(4); 10667 ins_encode( enc_std(src, dst) ); // rs=rt 10668 ins_pipe(pipe_class_memory); 10669 %} 10670 10671 //----------Moves between int and float 10672 10673 // Move float value from float stack-location to integer register. 10674 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10675 match(Set dst (MoveF2I src)); 10676 ins_cost(MEMORY_REF_COST); 10677 10678 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10679 size(4); 10680 ins_encode( enc_lwz(dst, src) ); 10681 ins_pipe(pipe_class_memory); 10682 %} 10683 10684 // Move float value from float register to integer stack-location. 10685 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10686 match(Set dst (MoveF2I src)); 10687 ins_cost(MEMORY_REF_COST); 10688 10689 format %{ "STFS $src, $dst \t// MoveF2I" %} 10690 size(4); 10691 ins_encode( enc_stfs(src, dst) ); 10692 ins_pipe(pipe_class_memory); 10693 %} 10694 10695 // Move integer value from integer stack-location to float register. 10696 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10697 match(Set dst (MoveI2F src)); 10698 ins_cost(MEMORY_REF_COST); 10699 10700 format %{ "LFS $dst, $src \t// MoveI2F" %} 10701 size(4); 10702 ins_encode %{ 10703 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10704 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10705 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10706 %} 10707 ins_pipe(pipe_class_memory); 10708 %} 10709 10710 // Move integer value from integer register to float stack-location. 10711 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10712 match(Set dst (MoveI2F src)); 10713 ins_cost(MEMORY_REF_COST); 10714 10715 format %{ "STW $src, $dst \t// MoveI2F" %} 10716 size(4); 10717 ins_encode( enc_stw(src, dst) ); 10718 ins_pipe(pipe_class_memory); 10719 %} 10720 10721 //----------Moves between long and float 10722 10723 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10724 // no match-rule, false predicate 10725 effect(DEF dst, USE src); 10726 predicate(false); 10727 10728 format %{ "storeD $src, $dst \t// STACK" %} 10729 size(4); 10730 ins_encode( enc_stfd(src, dst) ); 10731 ins_pipe(pipe_class_default); 10732 %} 10733 10734 //----------Moves between long and double 10735 10736 // Move double value from double stack-location to long register. 10737 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10738 match(Set dst (MoveD2L src)); 10739 ins_cost(MEMORY_REF_COST); 10740 size(4); 10741 format %{ "LD $dst, $src \t// MoveD2L" %} 10742 ins_encode( enc_ld(dst, src) ); 10743 ins_pipe(pipe_class_memory); 10744 %} 10745 10746 // Move double value from double register to long stack-location. 10747 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10748 match(Set dst (MoveD2L src)); 10749 effect(DEF dst, USE src); 10750 ins_cost(MEMORY_REF_COST); 10751 10752 format %{ "STFD $src, $dst \t// MoveD2L" %} 10753 size(4); 10754 ins_encode( enc_stfd(src, dst) ); 10755 ins_pipe(pipe_class_memory); 10756 %} 10757 10758 // Move long value from long stack-location to double register. 10759 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10760 match(Set dst (MoveL2D src)); 10761 ins_cost(MEMORY_REF_COST); 10762 10763 format %{ "LFD $dst, $src \t// MoveL2D" %} 10764 size(4); 10765 ins_encode( enc_lfd(dst, src) ); 10766 ins_pipe(pipe_class_memory); 10767 %} 10768 10769 // Move long value from long register to double stack-location. 10770 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10771 match(Set dst (MoveL2D src)); 10772 ins_cost(MEMORY_REF_COST); 10773 10774 format %{ "STD $src, $dst \t// MoveL2D" %} 10775 size(4); 10776 ins_encode( enc_std(src, dst) ); 10777 ins_pipe(pipe_class_memory); 10778 %} 10779 10780 //----------Register Move Instructions----------------------------------------- 10781 10782 // Replicate for Superword 10783 10784 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10785 predicate(false); 10786 effect(DEF dst, USE src); 10787 10788 format %{ "MR $dst, $src \t// replicate " %} 10789 // variable size, 0 or 4. 10790 ins_encode %{ 10791 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10792 __ mr_if_needed($dst$$Register, $src$$Register); 10793 %} 10794 ins_pipe(pipe_class_default); 10795 %} 10796 10797 //----------Cast instructions (Java-level type cast)--------------------------- 10798 10799 // Cast Long to Pointer for unsafe natives. 10800 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10801 match(Set dst (CastX2P src)); 10802 10803 format %{ "MR $dst, $src \t// Long->Ptr" %} 10804 // variable size, 0 or 4. 10805 ins_encode %{ 10806 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10807 __ mr_if_needed($dst$$Register, $src$$Register); 10808 %} 10809 ins_pipe(pipe_class_default); 10810 %} 10811 10812 // Cast Pointer to Long for unsafe natives. 10813 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10814 match(Set dst (CastP2X src)); 10815 10816 format %{ "MR $dst, $src \t// Ptr->Long" %} 10817 // variable size, 0 or 4. 10818 ins_encode %{ 10819 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10820 __ mr_if_needed($dst$$Register, $src$$Register); 10821 %} 10822 ins_pipe(pipe_class_default); 10823 %} 10824 10825 instruct castPP(iRegPdst dst) %{ 10826 match(Set dst (CastPP dst)); 10827 format %{ " -- \t// castPP of $dst" %} 10828 size(0); 10829 ins_encode( /*empty*/ ); 10830 ins_pipe(pipe_class_default); 10831 %} 10832 10833 instruct castII(iRegIdst dst) %{ 10834 match(Set dst (CastII dst)); 10835 format %{ " -- \t// castII of $dst" %} 10836 size(0); 10837 ins_encode( /*empty*/ ); 10838 ins_pipe(pipe_class_default); 10839 %} 10840 10841 instruct checkCastPP(iRegPdst dst) %{ 10842 match(Set dst (CheckCastPP dst)); 10843 format %{ " -- \t// checkcastPP of $dst" %} 10844 size(0); 10845 ins_encode( /*empty*/ ); 10846 ins_pipe(pipe_class_default); 10847 %} 10848 10849 //----------Convert instructions----------------------------------------------- 10850 10851 // Convert to boolean. 10852 10853 // int_to_bool(src) : { 1 if src != 0 10854 // { 0 else 10855 // 10856 // strategy: 10857 // 1) Count leading zeros of 32 bit-value src, 10858 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10859 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10860 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10861 10862 // convI2Bool 10863 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10864 match(Set dst (Conv2B src)); 10865 predicate(UseCountLeadingZerosInstructionsPPC64); 10866 ins_cost(DEFAULT_COST); 10867 10868 expand %{ 10869 immI shiftAmount %{ 0x5 %} 10870 uimmI16 mask %{ 0x1 %} 10871 iRegIdst tmp1; 10872 iRegIdst tmp2; 10873 countLeadingZerosI(tmp1, src); 10874 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10875 xorI_reg_uimm16(dst, tmp2, mask); 10876 %} 10877 %} 10878 10879 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10880 match(Set dst (Conv2B src)); 10881 effect(TEMP crx); 10882 predicate(!UseCountLeadingZerosInstructionsPPC64); 10883 ins_cost(DEFAULT_COST); 10884 10885 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10886 "LI $dst, #0\n\t" 10887 "BEQ $crx, done\n\t" 10888 "LI $dst, #1\n" 10889 "done:" %} 10890 size(16); 10891 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10892 ins_pipe(pipe_class_compare); 10893 %} 10894 10895 // ConvI2B + XorI 10896 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10897 match(Set dst (XorI (Conv2B src) mask)); 10898 predicate(UseCountLeadingZerosInstructionsPPC64); 10899 ins_cost(DEFAULT_COST); 10900 10901 expand %{ 10902 immI shiftAmount %{ 0x5 %} 10903 iRegIdst tmp1; 10904 countLeadingZerosI(tmp1, src); 10905 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10906 %} 10907 %} 10908 10909 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10910 match(Set dst (XorI (Conv2B src) mask)); 10911 effect(TEMP crx); 10912 predicate(!UseCountLeadingZerosInstructionsPPC64); 10913 ins_cost(DEFAULT_COST); 10914 10915 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10916 "LI $dst, #1\n\t" 10917 "BEQ $crx, done\n\t" 10918 "LI $dst, #0\n" 10919 "done:" %} 10920 size(16); 10921 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10922 ins_pipe(pipe_class_compare); 10923 %} 10924 10925 // AndI 0b0..010..0 + ConvI2B 10926 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10927 match(Set dst (Conv2B (AndI src mask))); 10928 predicate(UseRotateAndMaskInstructionsPPC64); 10929 ins_cost(DEFAULT_COST); 10930 10931 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10932 size(4); 10933 ins_encode %{ 10934 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10935 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10936 %} 10937 ins_pipe(pipe_class_default); 10938 %} 10939 10940 // Convert pointer to boolean. 10941 // 10942 // ptr_to_bool(src) : { 1 if src != 0 10943 // { 0 else 10944 // 10945 // strategy: 10946 // 1) Count leading zeros of 64 bit-value src, 10947 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10948 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10949 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10950 10951 // ConvP2B 10952 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10953 match(Set dst (Conv2B src)); 10954 predicate(UseCountLeadingZerosInstructionsPPC64); 10955 ins_cost(DEFAULT_COST); 10956 10957 expand %{ 10958 immI shiftAmount %{ 0x6 %} 10959 uimmI16 mask %{ 0x1 %} 10960 iRegIdst tmp1; 10961 iRegIdst tmp2; 10962 countLeadingZerosP(tmp1, src); 10963 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10964 xorI_reg_uimm16(dst, tmp2, mask); 10965 %} 10966 %} 10967 10968 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10969 match(Set dst (Conv2B src)); 10970 effect(TEMP crx); 10971 predicate(!UseCountLeadingZerosInstructionsPPC64); 10972 ins_cost(DEFAULT_COST); 10973 10974 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10975 "LI $dst, #0\n\t" 10976 "BEQ $crx, done\n\t" 10977 "LI $dst, #1\n" 10978 "done:" %} 10979 size(16); 10980 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10981 ins_pipe(pipe_class_compare); 10982 %} 10983 10984 // ConvP2B + XorI 10985 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10986 match(Set dst (XorI (Conv2B src) mask)); 10987 predicate(UseCountLeadingZerosInstructionsPPC64); 10988 ins_cost(DEFAULT_COST); 10989 10990 expand %{ 10991 immI shiftAmount %{ 0x6 %} 10992 iRegIdst tmp1; 10993 countLeadingZerosP(tmp1, src); 10994 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10995 %} 10996 %} 10997 10998 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10999 match(Set dst (XorI (Conv2B src) mask)); 11000 effect(TEMP crx); 11001 predicate(!UseCountLeadingZerosInstructionsPPC64); 11002 ins_cost(DEFAULT_COST); 11003 11004 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 11005 "LI $dst, #1\n\t" 11006 "BEQ $crx, done\n\t" 11007 "LI $dst, #0\n" 11008 "done:" %} 11009 size(16); 11010 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 11011 ins_pipe(pipe_class_compare); 11012 %} 11013 11014 // if src1 < src2, return -1 else return 0 11015 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 11016 match(Set dst (CmpLTMask src1 src2)); 11017 ins_cost(DEFAULT_COST*4); 11018 11019 expand %{ 11020 iRegLdst src1s; 11021 iRegLdst src2s; 11022 iRegLdst diff; 11023 convI2L_reg(src1s, src1); // Ensure proper sign extension. 11024 convI2L_reg(src2s, src2); // Ensure proper sign extension. 11025 subL_reg_reg(diff, src1s, src2s); 11026 // Need to consider >=33 bit result, therefore we need signmaskL. 11027 signmask64I_regL(dst, diff); 11028 %} 11029 %} 11030 11031 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 11032 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 11033 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 11034 size(4); 11035 ins_encode %{ 11036 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 11037 __ srawi($dst$$Register, $src1$$Register, 0x1f); 11038 %} 11039 ins_pipe(pipe_class_default); 11040 %} 11041 11042 //----------Arithmetic Conversion Instructions--------------------------------- 11043 11044 // Convert to Byte -- nop 11045 // Convert to Short -- nop 11046 11047 // Convert to Int 11048 11049 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 11050 match(Set dst (RShiftI (LShiftI src amount) amount)); 11051 format %{ "EXTSB $dst, $src \t// byte->int" %} 11052 size(4); 11053 ins_encode %{ 11054 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 11055 __ extsb($dst$$Register, $src$$Register); 11056 %} 11057 ins_pipe(pipe_class_default); 11058 %} 11059 11060 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 11061 effect(DEF dst, USE src); 11062 11063 size(4); 11064 ins_encode %{ 11065 __ extsh($dst$$Register, $src$$Register); 11066 %} 11067 ins_pipe(pipe_class_default); 11068 %} 11069 11070 // LShiftI 16 + RShiftI 16 converts short to int. 11071 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 11072 match(Set dst (RShiftI (LShiftI src amount) amount)); 11073 format %{ "EXTSH $dst, $src \t// short->int" %} 11074 size(4); 11075 ins_encode %{ 11076 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 11077 __ extsh($dst$$Register, $src$$Register); 11078 %} 11079 ins_pipe(pipe_class_default); 11080 %} 11081 11082 // ConvL2I + ConvI2L: Sign extend int in long register. 11083 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11084 match(Set dst (ConvI2L (ConvL2I src))); 11085 11086 format %{ "EXTSW $dst, $src \t// long->long" %} 11087 size(4); 11088 ins_encode %{ 11089 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11090 __ extsw($dst$$Register, $src$$Register); 11091 %} 11092 ins_pipe(pipe_class_default); 11093 %} 11094 11095 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11096 match(Set dst (ConvL2I src)); 11097 format %{ "MR $dst, $src \t// long->int" %} 11098 // variable size, 0 or 4 11099 ins_encode %{ 11100 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11101 __ mr_if_needed($dst$$Register, $src$$Register); 11102 %} 11103 ins_pipe(pipe_class_default); 11104 %} 11105 11106 instruct convD2IRaw_regD(regD dst, regD src) %{ 11107 // no match-rule, false predicate 11108 effect(DEF dst, USE src); 11109 predicate(false); 11110 11111 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11112 size(4); 11113 ins_encode %{ 11114 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11115 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11116 %} 11117 ins_pipe(pipe_class_default); 11118 %} 11119 11120 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 11121 // no match-rule, false predicate 11122 effect(DEF dst, USE crx, USE src); 11123 predicate(false); 11124 11125 ins_variable_size_depending_on_alignment(true); 11126 11127 format %{ "cmovI $crx, $dst, $src" %} 11128 // Worst case is branch + move + stop, no stop without scheduler. 11129 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11130 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11131 ins_pipe(pipe_class_default); 11132 %} 11133 11134 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11135 // no match-rule, false predicate 11136 effect(DEF dst, USE crx, USE src); 11137 predicate(false); 11138 11139 ins_variable_size_depending_on_alignment(true); 11140 11141 format %{ "cmovI $crx, $dst, $src" %} 11142 // Worst case is branch + move + stop, no stop without scheduler. 11143 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11144 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11145 ins_pipe(pipe_class_default); 11146 %} 11147 11148 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11149 // no match-rule, false predicate 11150 effect(DEF dst, USE crx, USE mem); 11151 predicate(false); 11152 11153 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11154 postalloc_expand %{ 11155 // 11156 // replaces 11157 // 11158 // region dst crx mem 11159 // \ | | / 11160 // dst=cmovI_bso_stackSlotL_conLvalue0 11161 // 11162 // with 11163 // 11164 // region dst 11165 // \ / 11166 // dst=loadConI16(0) 11167 // | 11168 // ^ region dst crx mem 11169 // | \ | | / 11170 // dst=cmovI_bso_stackSlotL 11171 // 11172 11173 // Create new nodes. 11174 MachNode *m1 = new loadConI16Node(); 11175 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11176 11177 // inputs for new nodes 11178 m1->add_req(n_region); 11179 m2->add_req(n_region, n_crx, n_mem); 11180 11181 // precedences for new nodes 11182 m2->add_prec(m1); 11183 11184 // operands for new nodes 11185 m1->_opnds[0] = op_dst; 11186 m1->_opnds[1] = new immI16Oper(0); 11187 11188 m2->_opnds[0] = op_dst; 11189 m2->_opnds[1] = op_crx; 11190 m2->_opnds[2] = op_mem; 11191 11192 // registers for new nodes 11193 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11194 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11195 11196 // Insert new nodes. 11197 nodes->push(m1); 11198 nodes->push(m2); 11199 %} 11200 %} 11201 11202 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11203 // no match-rule, false predicate 11204 effect(DEF dst, USE crx, USE src); 11205 predicate(false); 11206 11207 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11208 postalloc_expand %{ 11209 // 11210 // replaces 11211 // 11212 // region dst crx src 11213 // \ | | / 11214 // dst=cmovI_bso_reg_conLvalue0 11215 // 11216 // with 11217 // 11218 // region dst 11219 // \ / 11220 // dst=loadConI16(0) 11221 // | 11222 // ^ region dst crx src 11223 // | \ | | / 11224 // dst=cmovI_bso_reg 11225 // 11226 11227 // Create new nodes. 11228 MachNode *m1 = new loadConI16Node(); 11229 MachNode *m2 = new cmovI_bso_regNode(); 11230 11231 // inputs for new nodes 11232 m1->add_req(n_region); 11233 m2->add_req(n_region, n_crx, n_src); 11234 11235 // precedences for new nodes 11236 m2->add_prec(m1); 11237 11238 // operands for new nodes 11239 m1->_opnds[0] = op_dst; 11240 m1->_opnds[1] = new immI16Oper(0); 11241 11242 m2->_opnds[0] = op_dst; 11243 m2->_opnds[1] = op_crx; 11244 m2->_opnds[2] = op_src; 11245 11246 // registers for new nodes 11247 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11248 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11249 11250 // Insert new nodes. 11251 nodes->push(m1); 11252 nodes->push(m2); 11253 %} 11254 %} 11255 11256 // Double to Int conversion, NaN is mapped to 0. 11257 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11258 match(Set dst (ConvD2I src)); 11259 predicate(!VM_Version::has_mtfprd()); 11260 ins_cost(DEFAULT_COST); 11261 11262 expand %{ 11263 regD tmpD; 11264 stackSlotL tmpS; 11265 flagsReg crx; 11266 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11267 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11268 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11269 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11270 %} 11271 %} 11272 11273 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11274 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11275 match(Set dst (ConvD2I src)); 11276 predicate(VM_Version::has_mtfprd()); 11277 ins_cost(DEFAULT_COST); 11278 11279 expand %{ 11280 regD tmpD; 11281 flagsReg crx; 11282 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11283 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11284 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11285 %} 11286 %} 11287 11288 instruct convF2IRaw_regF(regF dst, regF src) %{ 11289 // no match-rule, false predicate 11290 effect(DEF dst, USE src); 11291 predicate(false); 11292 11293 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11294 size(4); 11295 ins_encode %{ 11296 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11297 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11298 %} 11299 ins_pipe(pipe_class_default); 11300 %} 11301 11302 // Float to Int conversion, NaN is mapped to 0. 11303 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11304 match(Set dst (ConvF2I src)); 11305 predicate(!VM_Version::has_mtfprd()); 11306 ins_cost(DEFAULT_COST); 11307 11308 expand %{ 11309 regF tmpF; 11310 stackSlotL tmpS; 11311 flagsReg crx; 11312 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11313 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11314 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11315 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11316 %} 11317 %} 11318 11319 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11320 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11321 match(Set dst (ConvF2I src)); 11322 predicate(VM_Version::has_mtfprd()); 11323 ins_cost(DEFAULT_COST); 11324 11325 expand %{ 11326 regF tmpF; 11327 flagsReg crx; 11328 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11329 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11330 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11331 %} 11332 %} 11333 11334 // Convert to Long 11335 11336 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11337 match(Set dst (ConvI2L src)); 11338 format %{ "EXTSW $dst, $src \t// int->long" %} 11339 size(4); 11340 ins_encode %{ 11341 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11342 __ extsw($dst$$Register, $src$$Register); 11343 %} 11344 ins_pipe(pipe_class_default); 11345 %} 11346 11347 // Zero-extend: convert unsigned int to long (convUI2L). 11348 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11349 match(Set dst (AndL (ConvI2L src) mask)); 11350 ins_cost(DEFAULT_COST); 11351 11352 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11353 size(4); 11354 ins_encode %{ 11355 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11356 __ clrldi($dst$$Register, $src$$Register, 32); 11357 %} 11358 ins_pipe(pipe_class_default); 11359 %} 11360 11361 // Zero-extend: convert unsigned int to long in long register. 11362 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11363 match(Set dst (AndL src mask)); 11364 ins_cost(DEFAULT_COST); 11365 11366 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11367 size(4); 11368 ins_encode %{ 11369 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11370 __ clrldi($dst$$Register, $src$$Register, 32); 11371 %} 11372 ins_pipe(pipe_class_default); 11373 %} 11374 11375 instruct convF2LRaw_regF(regF dst, regF src) %{ 11376 // no match-rule, false predicate 11377 effect(DEF dst, USE src); 11378 predicate(false); 11379 11380 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11381 size(4); 11382 ins_encode %{ 11383 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11384 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11385 %} 11386 ins_pipe(pipe_class_default); 11387 %} 11388 11389 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 11390 // no match-rule, false predicate 11391 effect(DEF dst, USE crx, USE src); 11392 predicate(false); 11393 11394 ins_variable_size_depending_on_alignment(true); 11395 11396 format %{ "cmovL $crx, $dst, $src" %} 11397 // Worst case is branch + move + stop, no stop without scheduler. 11398 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11399 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11400 ins_pipe(pipe_class_default); 11401 %} 11402 11403 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11404 // no match-rule, false predicate 11405 effect(DEF dst, USE crx, USE src); 11406 predicate(false); 11407 11408 ins_variable_size_depending_on_alignment(true); 11409 11410 format %{ "cmovL $crx, $dst, $src" %} 11411 // Worst case is branch + move + stop, no stop without scheduler. 11412 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11413 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11414 ins_pipe(pipe_class_default); 11415 %} 11416 11417 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11418 // no match-rule, false predicate 11419 effect(DEF dst, USE crx, USE mem); 11420 predicate(false); 11421 11422 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11423 postalloc_expand %{ 11424 // 11425 // replaces 11426 // 11427 // region dst crx mem 11428 // \ | | / 11429 // dst=cmovL_bso_stackSlotL_conLvalue0 11430 // 11431 // with 11432 // 11433 // region dst 11434 // \ / 11435 // dst=loadConL16(0) 11436 // | 11437 // ^ region dst crx mem 11438 // | \ | | / 11439 // dst=cmovL_bso_stackSlotL 11440 // 11441 11442 // Create new nodes. 11443 MachNode *m1 = new loadConL16Node(); 11444 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11445 11446 // inputs for new nodes 11447 m1->add_req(n_region); 11448 m2->add_req(n_region, n_crx, n_mem); 11449 m2->add_prec(m1); 11450 11451 // operands for new nodes 11452 m1->_opnds[0] = op_dst; 11453 m1->_opnds[1] = new immL16Oper(0); 11454 m2->_opnds[0] = op_dst; 11455 m2->_opnds[1] = op_crx; 11456 m2->_opnds[2] = op_mem; 11457 11458 // registers for new nodes 11459 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11460 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11461 11462 // Insert new nodes. 11463 nodes->push(m1); 11464 nodes->push(m2); 11465 %} 11466 %} 11467 11468 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11469 // no match-rule, false predicate 11470 effect(DEF dst, USE crx, USE src); 11471 predicate(false); 11472 11473 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11474 postalloc_expand %{ 11475 // 11476 // replaces 11477 // 11478 // region dst crx src 11479 // \ | | / 11480 // dst=cmovL_bso_reg_conLvalue0 11481 // 11482 // with 11483 // 11484 // region dst 11485 // \ / 11486 // dst=loadConL16(0) 11487 // | 11488 // ^ region dst crx src 11489 // | \ | | / 11490 // dst=cmovL_bso_reg 11491 // 11492 11493 // Create new nodes. 11494 MachNode *m1 = new loadConL16Node(); 11495 MachNode *m2 = new cmovL_bso_regNode(); 11496 11497 // inputs for new nodes 11498 m1->add_req(n_region); 11499 m2->add_req(n_region, n_crx, n_src); 11500 m2->add_prec(m1); 11501 11502 // operands for new nodes 11503 m1->_opnds[0] = op_dst; 11504 m1->_opnds[1] = new immL16Oper(0); 11505 m2->_opnds[0] = op_dst; 11506 m2->_opnds[1] = op_crx; 11507 m2->_opnds[2] = op_src; 11508 11509 // registers for new nodes 11510 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11511 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11512 11513 // Insert new nodes. 11514 nodes->push(m1); 11515 nodes->push(m2); 11516 %} 11517 %} 11518 11519 // Float to Long conversion, NaN is mapped to 0. 11520 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11521 match(Set dst (ConvF2L src)); 11522 predicate(!VM_Version::has_mtfprd()); 11523 ins_cost(DEFAULT_COST); 11524 11525 expand %{ 11526 regF tmpF; 11527 stackSlotL tmpS; 11528 flagsReg crx; 11529 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11530 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11531 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11532 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11533 %} 11534 %} 11535 11536 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11537 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11538 match(Set dst (ConvF2L src)); 11539 predicate(VM_Version::has_mtfprd()); 11540 ins_cost(DEFAULT_COST); 11541 11542 expand %{ 11543 regF tmpF; 11544 flagsReg crx; 11545 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11546 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11547 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11548 %} 11549 %} 11550 11551 instruct convD2LRaw_regD(regD dst, regD src) %{ 11552 // no match-rule, false predicate 11553 effect(DEF dst, USE src); 11554 predicate(false); 11555 11556 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11557 size(4); 11558 ins_encode %{ 11559 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11560 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11561 %} 11562 ins_pipe(pipe_class_default); 11563 %} 11564 11565 // Double to Long conversion, NaN is mapped to 0. 11566 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11567 match(Set dst (ConvD2L src)); 11568 predicate(!VM_Version::has_mtfprd()); 11569 ins_cost(DEFAULT_COST); 11570 11571 expand %{ 11572 regD tmpD; 11573 stackSlotL tmpS; 11574 flagsReg crx; 11575 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11576 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11577 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11578 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11579 %} 11580 %} 11581 11582 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11583 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11584 match(Set dst (ConvD2L src)); 11585 predicate(VM_Version::has_mtfprd()); 11586 ins_cost(DEFAULT_COST); 11587 11588 expand %{ 11589 regD tmpD; 11590 flagsReg crx; 11591 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11592 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11593 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11594 %} 11595 %} 11596 11597 // Convert to Float 11598 11599 // Placed here as needed in expand. 11600 instruct convL2DRaw_regD(regD dst, regD src) %{ 11601 // no match-rule, false predicate 11602 effect(DEF dst, USE src); 11603 predicate(false); 11604 11605 format %{ "FCFID $dst, $src \t// convL2D" %} 11606 size(4); 11607 ins_encode %{ 11608 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11609 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11610 %} 11611 ins_pipe(pipe_class_default); 11612 %} 11613 11614 // Placed here as needed in expand. 11615 instruct convD2F_reg(regF dst, regD src) %{ 11616 match(Set dst (ConvD2F src)); 11617 format %{ "FRSP $dst, $src \t// convD2F" %} 11618 size(4); 11619 ins_encode %{ 11620 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11621 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11622 %} 11623 ins_pipe(pipe_class_default); 11624 %} 11625 11626 // Integer to Float conversion. 11627 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11628 match(Set dst (ConvI2F src)); 11629 predicate(!VM_Version::has_fcfids()); 11630 ins_cost(DEFAULT_COST); 11631 11632 expand %{ 11633 iRegLdst tmpL; 11634 stackSlotL tmpS; 11635 regD tmpD; 11636 regD tmpD2; 11637 convI2L_reg(tmpL, src); // Sign-extension int to long. 11638 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11639 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11640 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11641 convD2F_reg(dst, tmpD2); // Convert double to float. 11642 %} 11643 %} 11644 11645 instruct convL2FRaw_regF(regF dst, regD src) %{ 11646 // no match-rule, false predicate 11647 effect(DEF dst, USE src); 11648 predicate(false); 11649 11650 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11651 size(4); 11652 ins_encode %{ 11653 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11654 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11655 %} 11656 ins_pipe(pipe_class_default); 11657 %} 11658 11659 // Integer to Float conversion. Special version for Power7. 11660 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11661 match(Set dst (ConvI2F src)); 11662 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11663 ins_cost(DEFAULT_COST); 11664 11665 expand %{ 11666 iRegLdst tmpL; 11667 stackSlotL tmpS; 11668 regD tmpD; 11669 convI2L_reg(tmpL, src); // Sign-extension int to long. 11670 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11671 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11672 convL2FRaw_regF(dst, tmpD); // Convert to float. 11673 %} 11674 %} 11675 11676 // Integer to Float conversion. Special version for Power8. 11677 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11678 match(Set dst (ConvI2F src)); 11679 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11680 ins_cost(DEFAULT_COST); 11681 11682 expand %{ 11683 regD tmpD; 11684 moveI2D_reg(tmpD, src); 11685 convL2FRaw_regF(dst, tmpD); // Convert to float. 11686 %} 11687 %} 11688 11689 // L2F to avoid runtime call. 11690 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11691 match(Set dst (ConvL2F src)); 11692 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11693 ins_cost(DEFAULT_COST); 11694 11695 expand %{ 11696 stackSlotL tmpS; 11697 regD tmpD; 11698 regL_to_stkL(tmpS, src); // Store long to stack. 11699 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11700 convL2FRaw_regF(dst, tmpD); // Convert to float. 11701 %} 11702 %} 11703 11704 // L2F to avoid runtime call. Special version for Power8. 11705 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11706 match(Set dst (ConvL2F src)); 11707 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11708 ins_cost(DEFAULT_COST); 11709 11710 expand %{ 11711 regD tmpD; 11712 moveL2D_reg(tmpD, src); 11713 convL2FRaw_regF(dst, tmpD); // Convert to float. 11714 %} 11715 %} 11716 11717 // Moved up as used in expand. 11718 //instruct convD2F_reg(regF dst, regD src) %{%} 11719 11720 // Convert to Double 11721 11722 // Integer to Double conversion. 11723 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11724 match(Set dst (ConvI2D src)); 11725 predicate(!VM_Version::has_mtfprd()); 11726 ins_cost(DEFAULT_COST); 11727 11728 expand %{ 11729 iRegLdst tmpL; 11730 stackSlotL tmpS; 11731 regD tmpD; 11732 convI2L_reg(tmpL, src); // Sign-extension int to long. 11733 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11734 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11735 convL2DRaw_regD(dst, tmpD); // Convert to double. 11736 %} 11737 %} 11738 11739 // Integer to Double conversion. Special version for Power8. 11740 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11741 match(Set dst (ConvI2D src)); 11742 predicate(VM_Version::has_mtfprd()); 11743 ins_cost(DEFAULT_COST); 11744 11745 expand %{ 11746 regD tmpD; 11747 moveI2D_reg(tmpD, src); 11748 convL2DRaw_regD(dst, tmpD); // Convert to double. 11749 %} 11750 %} 11751 11752 // Long to Double conversion 11753 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11754 match(Set dst (ConvL2D src)); 11755 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11756 11757 expand %{ 11758 regD tmpD; 11759 moveL2D_stack_reg(tmpD, src); 11760 convL2DRaw_regD(dst, tmpD); 11761 %} 11762 %} 11763 11764 // Long to Double conversion. Special version for Power8. 11765 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11766 match(Set dst (ConvL2D src)); 11767 predicate(VM_Version::has_mtfprd()); 11768 ins_cost(DEFAULT_COST); 11769 11770 expand %{ 11771 regD tmpD; 11772 moveL2D_reg(tmpD, src); 11773 convL2DRaw_regD(dst, tmpD); // Convert to double. 11774 %} 11775 %} 11776 11777 instruct convF2D_reg(regD dst, regF src) %{ 11778 match(Set dst (ConvF2D src)); 11779 format %{ "FMR $dst, $src \t// float->double" %} 11780 // variable size, 0 or 4 11781 ins_encode %{ 11782 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11783 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11784 %} 11785 ins_pipe(pipe_class_default); 11786 %} 11787 11788 //----------Control Flow Instructions------------------------------------------ 11789 // Compare Instructions 11790 11791 // Compare Integers 11792 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11793 match(Set crx (CmpI src1 src2)); 11794 size(4); 11795 format %{ "CMPW $crx, $src1, $src2" %} 11796 ins_encode %{ 11797 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11798 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11799 %} 11800 ins_pipe(pipe_class_compare); 11801 %} 11802 11803 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11804 match(Set crx (CmpI src1 src2)); 11805 format %{ "CMPWI $crx, $src1, $src2" %} 11806 size(4); 11807 ins_encode %{ 11808 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11809 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11810 %} 11811 ins_pipe(pipe_class_compare); 11812 %} 11813 11814 // (src1 & src2) == 0? 11815 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11816 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11817 // r0 is killed 11818 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11819 size(4); 11820 ins_encode %{ 11821 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11822 __ andi_(R0, $src1$$Register, $src2$$constant); 11823 %} 11824 ins_pipe(pipe_class_compare); 11825 %} 11826 11827 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11828 match(Set crx (CmpL src1 src2)); 11829 format %{ "CMPD $crx, $src1, $src2" %} 11830 size(4); 11831 ins_encode %{ 11832 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11833 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11834 %} 11835 ins_pipe(pipe_class_compare); 11836 %} 11837 11838 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11839 match(Set crx (CmpL src1 src2)); 11840 format %{ "CMPDI $crx, $src1, $src2" %} 11841 size(4); 11842 ins_encode %{ 11843 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11844 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11845 %} 11846 ins_pipe(pipe_class_compare); 11847 %} 11848 11849 // Added CmpUL for LoopPredicate. 11850 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11851 match(Set crx (CmpUL src1 src2)); 11852 format %{ "CMPLD $crx, $src1, $src2" %} 11853 size(4); 11854 ins_encode %{ 11855 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11856 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11857 %} 11858 ins_pipe(pipe_class_compare); 11859 %} 11860 11861 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11862 match(Set crx (CmpUL src1 src2)); 11863 format %{ "CMPLDI $crx, $src1, $src2" %} 11864 size(4); 11865 ins_encode %{ 11866 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11867 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11868 %} 11869 ins_pipe(pipe_class_compare); 11870 %} 11871 11872 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11873 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11874 // r0 is killed 11875 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11876 size(4); 11877 ins_encode %{ 11878 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11879 __ and_(R0, $src1$$Register, $src2$$Register); 11880 %} 11881 ins_pipe(pipe_class_compare); 11882 %} 11883 11884 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11885 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11886 // r0 is killed 11887 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11888 size(4); 11889 ins_encode %{ 11890 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11891 __ andi_(R0, $src1$$Register, $src2$$constant); 11892 %} 11893 ins_pipe(pipe_class_compare); 11894 %} 11895 11896 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11897 // no match-rule, false predicate 11898 effect(DEF dst, USE crx); 11899 predicate(false); 11900 11901 ins_variable_size_depending_on_alignment(true); 11902 11903 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11904 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11905 size((false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16)); 11906 ins_encode %{ 11907 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11908 Label done; 11909 // li(Rdst, 0); // equal -> 0 11910 __ beq($crx$$CondRegister, done); 11911 __ li($dst$$Register, 1); // greater -> +1 11912 __ bgt($crx$$CondRegister, done); 11913 __ li($dst$$Register, -1); // unordered or less -> -1 11914 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11915 __ bind(done); 11916 %} 11917 ins_pipe(pipe_class_compare); 11918 %} 11919 11920 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11921 // no match-rule, false predicate 11922 effect(DEF dst, USE crx); 11923 predicate(false); 11924 11925 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11926 postalloc_expand %{ 11927 // 11928 // replaces 11929 // 11930 // region crx 11931 // \ | 11932 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11933 // 11934 // with 11935 // 11936 // region 11937 // \ 11938 // dst=loadConI16(0) 11939 // | 11940 // ^ region crx 11941 // | \ | 11942 // dst=cmovI_conIvalueMinus1_conIvalue1 11943 // 11944 11945 // Create new nodes. 11946 MachNode *m1 = new loadConI16Node(); 11947 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11948 11949 // inputs for new nodes 11950 m1->add_req(n_region); 11951 m2->add_req(n_region, n_crx); 11952 m2->add_prec(m1); 11953 11954 // operands for new nodes 11955 m1->_opnds[0] = op_dst; 11956 m1->_opnds[1] = new immI16Oper(0); 11957 m2->_opnds[0] = op_dst; 11958 m2->_opnds[1] = op_crx; 11959 11960 // registers for new nodes 11961 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11962 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11963 11964 // Insert new nodes. 11965 nodes->push(m1); 11966 nodes->push(m2); 11967 %} 11968 %} 11969 11970 // Manifest a CmpL3 result in an integer register. Very painful. 11971 // This is the test to avoid. 11972 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11973 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11974 match(Set dst (CmpL3 src1 src2)); 11975 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11976 11977 expand %{ 11978 flagsReg tmp1; 11979 cmpL_reg_reg(tmp1, src1, src2); 11980 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11981 %} 11982 %} 11983 11984 // Implicit range checks. 11985 // A range check in the ideal world has one of the following shapes: 11986 // - (If le (CmpU length index)), (IfTrue throw exception) 11987 // - (If lt (CmpU index length)), (IfFalse throw exception) 11988 // 11989 // Match range check 'If le (CmpU length index)'. 11990 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11991 match(If cmp (CmpU src_length index)); 11992 effect(USE labl); 11993 predicate(TrapBasedRangeChecks && 11994 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11995 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11996 (Matcher::branches_to_uncommon_trap(_leaf))); 11997 11998 ins_is_TrapBasedCheckNode(true); 11999 12000 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 12001 size(4); 12002 ins_encode %{ 12003 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12004 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 12005 __ trap_range_check_le($src_length$$Register, $index$$constant); 12006 } else { 12007 // Both successors are uncommon traps, probability is 0. 12008 // Node got flipped during fixup flow. 12009 assert($cmp$$cmpcode == 0x9, "must be greater"); 12010 __ trap_range_check_g($src_length$$Register, $index$$constant); 12011 } 12012 %} 12013 ins_pipe(pipe_class_trap); 12014 %} 12015 12016 // Match range check 'If lt (CmpU index length)'. 12017 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 12018 match(If cmp (CmpU src_index src_length)); 12019 effect(USE labl); 12020 predicate(TrapBasedRangeChecks && 12021 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12022 _leaf->as_If()->_prob >= PROB_ALWAYS && 12023 (Matcher::branches_to_uncommon_trap(_leaf))); 12024 12025 ins_is_TrapBasedCheckNode(true); 12026 12027 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 12028 size(4); 12029 ins_encode %{ 12030 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 12031 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12032 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 12033 } else { 12034 // Both successors are uncommon traps, probability is 0. 12035 // Node got flipped during fixup flow. 12036 assert($cmp$$cmpcode == 0x8, "must be less"); 12037 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 12038 } 12039 %} 12040 ins_pipe(pipe_class_trap); 12041 %} 12042 12043 // Match range check 'If lt (CmpU index length)'. 12044 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 12045 match(If cmp (CmpU src_index length)); 12046 effect(USE labl); 12047 predicate(TrapBasedRangeChecks && 12048 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12049 _leaf->as_If()->_prob >= PROB_ALWAYS && 12050 (Matcher::branches_to_uncommon_trap(_leaf))); 12051 12052 ins_is_TrapBasedCheckNode(true); 12053 12054 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 12055 size(4); 12056 ins_encode %{ 12057 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12058 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12059 __ trap_range_check_ge($src_index$$Register, $length$$constant); 12060 } else { 12061 // Both successors are uncommon traps, probability is 0. 12062 // Node got flipped during fixup flow. 12063 assert($cmp$$cmpcode == 0x8, "must be less"); 12064 __ trap_range_check_l($src_index$$Register, $length$$constant); 12065 } 12066 %} 12067 ins_pipe(pipe_class_trap); 12068 %} 12069 12070 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 12071 match(Set crx (CmpU src1 src2)); 12072 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 12073 size(4); 12074 ins_encode %{ 12075 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12076 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12077 %} 12078 ins_pipe(pipe_class_compare); 12079 %} 12080 12081 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 12082 match(Set crx (CmpU src1 src2)); 12083 size(4); 12084 format %{ "CMPLWI $crx, $src1, $src2" %} 12085 ins_encode %{ 12086 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12087 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12088 %} 12089 ins_pipe(pipe_class_compare); 12090 %} 12091 12092 // Implicit zero checks (more implicit null checks). 12093 // No constant pool entries required. 12094 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12095 match(If cmp (CmpN value zero)); 12096 effect(USE labl); 12097 predicate(TrapBasedNullChecks && 12098 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12099 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12100 Matcher::branches_to_uncommon_trap(_leaf)); 12101 ins_cost(1); 12102 12103 ins_is_TrapBasedCheckNode(true); 12104 12105 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12106 size(4); 12107 ins_encode %{ 12108 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12109 if ($cmp$$cmpcode == 0xA) { 12110 __ trap_null_check($value$$Register); 12111 } else { 12112 // Both successors are uncommon traps, probability is 0. 12113 // Node got flipped during fixup flow. 12114 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12115 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12116 } 12117 %} 12118 ins_pipe(pipe_class_trap); 12119 %} 12120 12121 // Compare narrow oops. 12122 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12123 match(Set crx (CmpN src1 src2)); 12124 12125 size(4); 12126 ins_cost(2); 12127 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12128 ins_encode %{ 12129 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12130 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12131 %} 12132 ins_pipe(pipe_class_compare); 12133 %} 12134 12135 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12136 match(Set crx (CmpN src1 src2)); 12137 // Make this more expensive than zeroCheckN_iReg_imm0. 12138 ins_cost(2); 12139 12140 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12141 size(4); 12142 ins_encode %{ 12143 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12144 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12145 %} 12146 ins_pipe(pipe_class_compare); 12147 %} 12148 12149 // Implicit zero checks (more implicit null checks). 12150 // No constant pool entries required. 12151 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12152 match(If cmp (CmpP value zero)); 12153 effect(USE labl); 12154 predicate(TrapBasedNullChecks && 12155 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12156 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12157 Matcher::branches_to_uncommon_trap(_leaf)); 12158 ins_cost(1); // Should not be cheaper than zeroCheckN. 12159 12160 ins_is_TrapBasedCheckNode(true); 12161 12162 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12163 size(4); 12164 ins_encode %{ 12165 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12166 if ($cmp$$cmpcode == 0xA) { 12167 __ trap_null_check($value$$Register); 12168 } else { 12169 // Both successors are uncommon traps, probability is 0. 12170 // Node got flipped during fixup flow. 12171 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12172 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12173 } 12174 %} 12175 ins_pipe(pipe_class_trap); 12176 %} 12177 12178 // Compare Pointers 12179 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12180 match(Set crx (CmpP src1 src2)); 12181 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12182 size(4); 12183 ins_encode %{ 12184 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12185 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12186 %} 12187 ins_pipe(pipe_class_compare); 12188 %} 12189 12190 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12191 match(Set crx (CmpP src1 src2)); 12192 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12193 size(4); 12194 ins_encode %{ 12195 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12196 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12197 %} 12198 ins_pipe(pipe_class_compare); 12199 %} 12200 12201 // Used in postalloc expand. 12202 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12203 // This match rule prevents reordering of node before a safepoint. 12204 // This only makes sense if this instructions is used exclusively 12205 // for the expansion of EncodeP! 12206 match(Set crx (CmpP src1 src2)); 12207 predicate(false); 12208 12209 format %{ "CMPDI $crx, $src1, $src2" %} 12210 size(4); 12211 ins_encode %{ 12212 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12213 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12214 %} 12215 ins_pipe(pipe_class_compare); 12216 %} 12217 12218 //----------Float Compares---------------------------------------------------- 12219 12220 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12221 // Needs matchrule, see cmpDUnordered. 12222 match(Set crx (CmpF src1 src2)); 12223 // no match-rule, false predicate 12224 predicate(false); 12225 12226 format %{ "cmpFUrd $crx, $src1, $src2" %} 12227 size(4); 12228 ins_encode %{ 12229 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12230 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12231 %} 12232 ins_pipe(pipe_class_default); 12233 %} 12234 12235 instruct cmov_bns_less(flagsReg crx) %{ 12236 // no match-rule, false predicate 12237 effect(DEF crx); 12238 predicate(false); 12239 12240 ins_variable_size_depending_on_alignment(true); 12241 12242 format %{ "cmov $crx" %} 12243 // Worst case is branch + move + stop, no stop without scheduler. 12244 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12)); 12245 ins_encode %{ 12246 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12247 Label done; 12248 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12249 __ li(R0, 0); 12250 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12251 // TODO PPC port __ endgroup_if_needed(_size == 16); 12252 __ bind(done); 12253 %} 12254 ins_pipe(pipe_class_default); 12255 %} 12256 12257 // Compare floating, generate condition code. 12258 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12259 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12260 // 12261 // The following code sequence occurs a lot in mpegaudio: 12262 // 12263 // block BXX: 12264 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12265 // cmpFUrd CCR6, F11, F9 12266 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12267 // cmov CCR6 12268 // 8: instruct branchConSched: 12269 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12270 match(Set crx (CmpF src1 src2)); 12271 ins_cost(DEFAULT_COST+BRANCH_COST); 12272 12273 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12274 postalloc_expand %{ 12275 // 12276 // replaces 12277 // 12278 // region src1 src2 12279 // \ | | 12280 // crx=cmpF_reg_reg 12281 // 12282 // with 12283 // 12284 // region src1 src2 12285 // \ | | 12286 // crx=cmpFUnordered_reg_reg 12287 // | 12288 // ^ region 12289 // | \ 12290 // crx=cmov_bns_less 12291 // 12292 12293 // Create new nodes. 12294 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12295 MachNode *m2 = new cmov_bns_lessNode(); 12296 12297 // inputs for new nodes 12298 m1->add_req(n_region, n_src1, n_src2); 12299 m2->add_req(n_region); 12300 m2->add_prec(m1); 12301 12302 // operands for new nodes 12303 m1->_opnds[0] = op_crx; 12304 m1->_opnds[1] = op_src1; 12305 m1->_opnds[2] = op_src2; 12306 m2->_opnds[0] = op_crx; 12307 12308 // registers for new nodes 12309 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12310 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12311 12312 // Insert new nodes. 12313 nodes->push(m1); 12314 nodes->push(m2); 12315 %} 12316 %} 12317 12318 // Compare float, generate -1,0,1 12319 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12320 match(Set dst (CmpF3 src1 src2)); 12321 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12322 12323 expand %{ 12324 flagsReg tmp1; 12325 cmpFUnordered_reg_reg(tmp1, src1, src2); 12326 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12327 %} 12328 %} 12329 12330 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12331 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12332 // node right before the conditional move using it. 12333 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12334 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12335 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12336 // conditional move was supposed to be spilled. 12337 match(Set crx (CmpD src1 src2)); 12338 // False predicate, shall not be matched. 12339 predicate(false); 12340 12341 format %{ "cmpFUrd $crx, $src1, $src2" %} 12342 size(4); 12343 ins_encode %{ 12344 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12345 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12346 %} 12347 ins_pipe(pipe_class_default); 12348 %} 12349 12350 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12351 match(Set crx (CmpD src1 src2)); 12352 ins_cost(DEFAULT_COST+BRANCH_COST); 12353 12354 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12355 postalloc_expand %{ 12356 // 12357 // replaces 12358 // 12359 // region src1 src2 12360 // \ | | 12361 // crx=cmpD_reg_reg 12362 // 12363 // with 12364 // 12365 // region src1 src2 12366 // \ | | 12367 // crx=cmpDUnordered_reg_reg 12368 // | 12369 // ^ region 12370 // | \ 12371 // crx=cmov_bns_less 12372 // 12373 12374 // create new nodes 12375 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12376 MachNode *m2 = new cmov_bns_lessNode(); 12377 12378 // inputs for new nodes 12379 m1->add_req(n_region, n_src1, n_src2); 12380 m2->add_req(n_region); 12381 m2->add_prec(m1); 12382 12383 // operands for new nodes 12384 m1->_opnds[0] = op_crx; 12385 m1->_opnds[1] = op_src1; 12386 m1->_opnds[2] = op_src2; 12387 m2->_opnds[0] = op_crx; 12388 12389 // registers for new nodes 12390 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12391 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12392 12393 // Insert new nodes. 12394 nodes->push(m1); 12395 nodes->push(m2); 12396 %} 12397 %} 12398 12399 // Compare double, generate -1,0,1 12400 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12401 match(Set dst (CmpD3 src1 src2)); 12402 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12403 12404 expand %{ 12405 flagsReg tmp1; 12406 cmpDUnordered_reg_reg(tmp1, src1, src2); 12407 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12408 %} 12409 %} 12410 12411 // Compare char 12412 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12413 match(Set dst (Digit src1)); 12414 effect(TEMP src2, TEMP crx); 12415 ins_cost(3 * DEFAULT_COST); 12416 12417 format %{ "LI $src2, 0x3930\n\t" 12418 "CMPRB $crx, 0, $src1, $src2\n\t" 12419 "SETB $dst, $crx" %} 12420 size(12); 12421 ins_encode %{ 12422 // 0x30: 0, 0x39: 9 12423 __ li($src2$$Register, 0x3930); 12424 // compare src1 with ranges 0x30 to 0x39 12425 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12426 __ setb($dst$$Register, $crx$$CondRegister); 12427 %} 12428 ins_pipe(pipe_class_default); 12429 %} 12430 12431 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12432 match(Set dst (LowerCase src1)); 12433 effect(TEMP src2, TEMP crx); 12434 ins_cost(12 * DEFAULT_COST); 12435 12436 format %{ "LI $src2, 0x7A61\n\t" 12437 "CMPRB $crx, 0, $src1, $src2\n\t" 12438 "BGT $crx, done\n\t" 12439 "LIS $src2, (signed short)0xF6DF\n\t" 12440 "ORI $src2, $src2, 0xFFF8\n\t" 12441 "CMPRB $crx, 1, $src1, $src2\n\t" 12442 "BGT $crx, done\n\t" 12443 "LIS $src2, (signed short)0xAAB5\n\t" 12444 "ORI $src2, $src2, 0xBABA\n\t" 12445 "INSRDI $src2, $src2, 32, 0\n\t" 12446 "CMPEQB $crx, 1, $src1, $src2\n" 12447 "done:\n\t" 12448 "SETB $dst, $crx" %} 12449 12450 size(48); 12451 ins_encode %{ 12452 Label done; 12453 // 0x61: a, 0x7A: z 12454 __ li($src2$$Register, 0x7A61); 12455 // compare src1 with ranges 0x61 to 0x7A 12456 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12457 __ bgt($crx$$CondRegister, done); 12458 12459 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case 12460 __ lis($src2$$Register, (signed short)0xF6DF); 12461 __ ori($src2$$Register, $src2$$Register, 0xFFF8); 12462 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF 12463 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12464 __ bgt($crx$$CondRegister, done); 12465 12466 // 0xAA: feminine ordinal indicator 12467 // 0xB5: micro sign 12468 // 0xBA: masculine ordinal indicator 12469 __ lis($src2$$Register, (signed short)0xAAB5); 12470 __ ori($src2$$Register, $src2$$Register, 0xBABA); 12471 __ insrdi($src2$$Register, $src2$$Register, 32, 0); 12472 // compare src1 with 0xAA, 0xB5, and 0xBA 12473 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register); 12474 12475 __ bind(done); 12476 __ setb($dst$$Register, $crx$$CondRegister); 12477 %} 12478 ins_pipe(pipe_class_default); 12479 %} 12480 12481 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12482 match(Set dst (UpperCase src1)); 12483 effect(TEMP src2, TEMP crx); 12484 ins_cost(7 * DEFAULT_COST); 12485 12486 format %{ "LI $src2, 0x5A41\n\t" 12487 "CMPRB $crx, 0, $src1, $src2\n\t" 12488 "BGT $crx, done\n\t" 12489 "LIS $src2, (signed short)0xD6C0\n\t" 12490 "ORI $src2, $src2, 0xDED8\n\t" 12491 "CMPRB $crx, 1, $src1, $src2\n" 12492 "done:\n\t" 12493 "SETB $dst, $crx" %} 12494 12495 size(28); 12496 ins_encode %{ 12497 Label done; 12498 // 0x41: A, 0x5A: Z 12499 __ li($src2$$Register, 0x5A41); 12500 // compare src1 with a range 0x41 to 0x5A 12501 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12502 __ bgt($crx$$CondRegister, done); 12503 12504 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case 12505 __ lis($src2$$Register, (signed short)0xD6C0); 12506 __ ori($src2$$Register, $src2$$Register, 0xDED8); 12507 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE 12508 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12509 12510 __ bind(done); 12511 __ setb($dst$$Register, $crx$$CondRegister); 12512 %} 12513 ins_pipe(pipe_class_default); 12514 %} 12515 12516 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12517 match(Set dst (Whitespace src1)); 12518 effect(TEMP src2, TEMP crx); 12519 ins_cost(4 * DEFAULT_COST); 12520 12521 format %{ "LI $src2, 0x0D09\n\t" 12522 "ADDIS $src2, 0x201C\n\t" 12523 "CMPRB $crx, 1, $src1, $src2\n\t" 12524 "SETB $dst, $crx" %} 12525 size(16); 12526 ins_encode %{ 12527 // 0x09 to 0x0D, 0x1C to 0x20 12528 __ li($src2$$Register, 0x0D09); 12529 __ addis($src2$$Register, $src2$$Register, 0x0201C); 12530 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20 12531 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12532 __ setb($dst$$Register, $crx$$CondRegister); 12533 %} 12534 ins_pipe(pipe_class_default); 12535 %} 12536 12537 //----------Branches--------------------------------------------------------- 12538 // Jump 12539 12540 // Direct Branch. 12541 instruct branch(label labl) %{ 12542 match(Goto); 12543 effect(USE labl); 12544 ins_cost(BRANCH_COST); 12545 12546 format %{ "B $labl" %} 12547 size(4); 12548 ins_encode %{ 12549 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12550 Label d; // dummy 12551 __ bind(d); 12552 Label* p = $labl$$label; 12553 // `p' is `NULL' when this encoding class is used only to 12554 // determine the size of the encoded instruction. 12555 Label& l = (NULL == p)? d : *(p); 12556 __ b(l); 12557 %} 12558 ins_pipe(pipe_class_default); 12559 %} 12560 12561 // Conditional Near Branch 12562 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12563 // Same match rule as `branchConFar'. 12564 match(If cmp crx); 12565 effect(USE lbl); 12566 ins_cost(BRANCH_COST); 12567 12568 // If set to 1 this indicates that the current instruction is a 12569 // short variant of a long branch. This avoids using this 12570 // instruction in first-pass matching. It will then only be used in 12571 // the `Shorten_branches' pass. 12572 ins_short_branch(1); 12573 12574 format %{ "B$cmp $crx, $lbl" %} 12575 size(4); 12576 ins_encode( enc_bc(crx, cmp, lbl) ); 12577 ins_pipe(pipe_class_default); 12578 %} 12579 12580 // This is for cases when the ppc64 `bc' instruction does not 12581 // reach far enough. So we emit a far branch here, which is more 12582 // expensive. 12583 // 12584 // Conditional Far Branch 12585 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12586 // Same match rule as `branchCon'. 12587 match(If cmp crx); 12588 effect(USE crx, USE lbl); 12589 predicate(!false /* TODO: PPC port HB_Schedule*/); 12590 // Higher cost than `branchCon'. 12591 ins_cost(5*BRANCH_COST); 12592 12593 // This is not a short variant of a branch, but the long variant. 12594 ins_short_branch(0); 12595 12596 format %{ "B_FAR$cmp $crx, $lbl" %} 12597 size(8); 12598 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12599 ins_pipe(pipe_class_default); 12600 %} 12601 12602 // Conditional Branch used with Power6 scheduler (can be far or short). 12603 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12604 // Same match rule as `branchCon'. 12605 match(If cmp crx); 12606 effect(USE crx, USE lbl); 12607 predicate(false /* TODO: PPC port HB_Schedule*/); 12608 // Higher cost than `branchCon'. 12609 ins_cost(5*BRANCH_COST); 12610 12611 // Actually size doesn't depend on alignment but on shortening. 12612 ins_variable_size_depending_on_alignment(true); 12613 // long variant. 12614 ins_short_branch(0); 12615 12616 format %{ "B_FAR$cmp $crx, $lbl" %} 12617 size(8); // worst case 12618 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12619 ins_pipe(pipe_class_default); 12620 %} 12621 12622 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12623 match(CountedLoopEnd cmp crx); 12624 effect(USE labl); 12625 ins_cost(BRANCH_COST); 12626 12627 // short variant. 12628 ins_short_branch(1); 12629 12630 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12631 size(4); 12632 ins_encode( enc_bc(crx, cmp, labl) ); 12633 ins_pipe(pipe_class_default); 12634 %} 12635 12636 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12637 match(CountedLoopEnd cmp crx); 12638 effect(USE labl); 12639 predicate(!false /* TODO: PPC port HB_Schedule */); 12640 ins_cost(BRANCH_COST); 12641 12642 // Long variant. 12643 ins_short_branch(0); 12644 12645 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12646 size(8); 12647 ins_encode( enc_bc_far(crx, cmp, labl) ); 12648 ins_pipe(pipe_class_default); 12649 %} 12650 12651 // Conditional Branch used with Power6 scheduler (can be far or short). 12652 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12653 match(CountedLoopEnd cmp crx); 12654 effect(USE labl); 12655 predicate(false /* TODO: PPC port HB_Schedule */); 12656 // Higher cost than `branchCon'. 12657 ins_cost(5*BRANCH_COST); 12658 12659 // Actually size doesn't depend on alignment but on shortening. 12660 ins_variable_size_depending_on_alignment(true); 12661 // Long variant. 12662 ins_short_branch(0); 12663 12664 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12665 size(8); // worst case 12666 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12667 ins_pipe(pipe_class_default); 12668 %} 12669 12670 // ============================================================================ 12671 // Java runtime operations, intrinsics and other complex operations. 12672 12673 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12674 // array for an instance of the superklass. Set a hidden internal cache on a 12675 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12676 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12677 // 12678 // GL TODO: Improve this. 12679 // - result should not be a TEMP 12680 // - Add match rule as on sparc avoiding additional Cmp. 12681 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12682 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12683 match(Set result (PartialSubtypeCheck subklass superklass)); 12684 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12685 ins_cost(DEFAULT_COST*10); 12686 12687 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12688 ins_encode %{ 12689 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12690 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12691 $tmp_klass$$Register, NULL, $result$$Register); 12692 %} 12693 ins_pipe(pipe_class_default); 12694 %} 12695 12696 // inlined locking and unlocking 12697 12698 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12699 match(Set crx (FastLock oop box)); 12700 effect(TEMP tmp1, TEMP tmp2); 12701 predicate(!Compile::current()->use_rtm()); 12702 12703 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12704 ins_encode %{ 12705 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12706 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12707 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12708 UseBiasedLocking && !UseOptoBiasInlining); 12709 // If locking was successfull, crx should indicate 'EQ'. 12710 // The compiler generates a branch to the runtime call to 12711 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12712 %} 12713 ins_pipe(pipe_class_compare); 12714 %} 12715 12716 // Separate version for TM. Use bound register for box to enable USE_KILL. 12717 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12718 match(Set crx (FastLock oop box)); 12719 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12720 predicate(Compile::current()->use_rtm()); 12721 12722 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12723 ins_encode %{ 12724 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12725 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12726 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12727 /*Biased Locking*/ false, 12728 _rtm_counters, _stack_rtm_counters, 12729 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12730 /*TM*/ true, ra_->C->profile_rtm()); 12731 // If locking was successfull, crx should indicate 'EQ'. 12732 // The compiler generates a branch to the runtime call to 12733 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12734 %} 12735 ins_pipe(pipe_class_compare); 12736 %} 12737 12738 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12739 match(Set crx (FastUnlock oop box)); 12740 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12741 predicate(!Compile::current()->use_rtm()); 12742 12743 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12744 ins_encode %{ 12745 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12746 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12747 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12748 UseBiasedLocking && !UseOptoBiasInlining, 12749 false); 12750 // If unlocking was successfull, crx should indicate 'EQ'. 12751 // The compiler generates a branch to the runtime call to 12752 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12753 %} 12754 ins_pipe(pipe_class_compare); 12755 %} 12756 12757 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12758 match(Set crx (FastUnlock oop box)); 12759 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12760 predicate(Compile::current()->use_rtm()); 12761 12762 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12763 ins_encode %{ 12764 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12765 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12766 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12767 /*Biased Locking*/ false, /*TM*/ true); 12768 // If unlocking was successfull, crx should indicate 'EQ'. 12769 // The compiler generates a branch to the runtime call to 12770 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12771 %} 12772 ins_pipe(pipe_class_compare); 12773 %} 12774 12775 // Align address. 12776 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12777 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12778 12779 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12780 size(4); 12781 ins_encode %{ 12782 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12783 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12784 %} 12785 ins_pipe(pipe_class_default); 12786 %} 12787 12788 // Array size computation. 12789 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12790 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12791 12792 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12793 size(4); 12794 ins_encode %{ 12795 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12796 __ subf($dst$$Register, $start$$Register, $end$$Register); 12797 %} 12798 ins_pipe(pipe_class_default); 12799 %} 12800 12801 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12802 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12803 match(Set dummy (ClearArray cnt base)); 12804 effect(USE_KILL base, KILL ctr); 12805 ins_cost(2 * MEMORY_REF_COST); 12806 12807 format %{ "ClearArray $cnt, $base" %} 12808 ins_encode %{ 12809 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12810 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12811 %} 12812 ins_pipe(pipe_class_default); 12813 %} 12814 12815 // Clear-array with constant large array length. 12816 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12817 match(Set dummy (ClearArray cnt base)); 12818 effect(USE_KILL base, TEMP tmp, KILL ctr); 12819 ins_cost(3 * MEMORY_REF_COST); 12820 12821 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12822 ins_encode %{ 12823 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12824 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12825 %} 12826 ins_pipe(pipe_class_default); 12827 %} 12828 12829 // Clear-array with dynamic array length. 12830 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12831 match(Set dummy (ClearArray cnt base)); 12832 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12833 ins_cost(4 * MEMORY_REF_COST); 12834 12835 format %{ "ClearArray $cnt, $base" %} 12836 ins_encode %{ 12837 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12838 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12839 %} 12840 ins_pipe(pipe_class_default); 12841 %} 12842 12843 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12844 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12845 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12846 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12847 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12848 ins_cost(300); 12849 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12850 ins_encode %{ 12851 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12852 __ string_compare($str1$$Register, $str2$$Register, 12853 $cnt1$$Register, $cnt2$$Register, 12854 $tmp$$Register, 12855 $result$$Register, StrIntrinsicNode::LL); 12856 %} 12857 ins_pipe(pipe_class_default); 12858 %} 12859 12860 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12861 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12862 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12863 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12864 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12865 ins_cost(300); 12866 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12867 ins_encode %{ 12868 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12869 __ string_compare($str1$$Register, $str2$$Register, 12870 $cnt1$$Register, $cnt2$$Register, 12871 $tmp$$Register, 12872 $result$$Register, StrIntrinsicNode::UU); 12873 %} 12874 ins_pipe(pipe_class_default); 12875 %} 12876 12877 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12878 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12879 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12880 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12881 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12882 ins_cost(300); 12883 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12884 ins_encode %{ 12885 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12886 __ string_compare($str1$$Register, $str2$$Register, 12887 $cnt1$$Register, $cnt2$$Register, 12888 $tmp$$Register, 12889 $result$$Register, StrIntrinsicNode::LU); 12890 %} 12891 ins_pipe(pipe_class_default); 12892 %} 12893 12894 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12895 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12896 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12897 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12898 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12899 ins_cost(300); 12900 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12901 ins_encode %{ 12902 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12903 __ string_compare($str2$$Register, $str1$$Register, 12904 $cnt2$$Register, $cnt1$$Register, 12905 $tmp$$Register, 12906 $result$$Register, StrIntrinsicNode::UL); 12907 %} 12908 ins_pipe(pipe_class_default); 12909 %} 12910 12911 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12912 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12913 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12914 match(Set result (StrEquals (Binary str1 str2) cnt)); 12915 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12916 ins_cost(300); 12917 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12918 ins_encode %{ 12919 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12920 __ array_equals(false, $str1$$Register, $str2$$Register, 12921 $cnt$$Register, $tmp$$Register, 12922 $result$$Register, true /* byte */); 12923 %} 12924 ins_pipe(pipe_class_default); 12925 %} 12926 12927 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12928 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12929 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12930 match(Set result (StrEquals (Binary str1 str2) cnt)); 12931 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12932 ins_cost(300); 12933 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12934 ins_encode %{ 12935 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12936 __ array_equals(false, $str1$$Register, $str2$$Register, 12937 $cnt$$Register, $tmp$$Register, 12938 $result$$Register, false /* byte */); 12939 %} 12940 ins_pipe(pipe_class_default); 12941 %} 12942 12943 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12944 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12945 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12946 match(Set result (AryEq ary1 ary2)); 12947 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12948 ins_cost(300); 12949 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12950 ins_encode %{ 12951 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12952 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12953 $tmp1$$Register, $tmp2$$Register, 12954 $result$$Register, true /* byte */); 12955 %} 12956 ins_pipe(pipe_class_default); 12957 %} 12958 12959 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12960 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12961 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12962 match(Set result (AryEq ary1 ary2)); 12963 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12964 ins_cost(300); 12965 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12966 ins_encode %{ 12967 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12968 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12969 $tmp1$$Register, $tmp2$$Register, 12970 $result$$Register, false /* byte */); 12971 %} 12972 ins_pipe(pipe_class_default); 12973 %} 12974 12975 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12976 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12977 iRegIdst tmp1, iRegIdst tmp2, 12978 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12979 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12980 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12981 // Required for EA: check if it is still a type_array. 12982 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12983 ins_cost(150); 12984 12985 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12986 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12987 12988 ins_encode %{ 12989 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12990 immPOper *needleOper = (immPOper *)$needleImm; 12991 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12992 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12993 jchar chr; 12994 #ifdef VM_LITTLE_ENDIAN 12995 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12996 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12997 #else 12998 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12999 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 13000 #endif 13001 __ string_indexof_char($result$$Register, 13002 $haystack$$Register, $haycnt$$Register, 13003 R0, chr, 13004 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13005 %} 13006 ins_pipe(pipe_class_compare); 13007 %} 13008 13009 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13010 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13011 iRegIdst tmp1, iRegIdst tmp2, 13012 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13013 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13014 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13015 // Required for EA: check if it is still a type_array. 13016 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13017 ins_cost(150); 13018 13019 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13020 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13021 13022 ins_encode %{ 13023 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13024 immPOper *needleOper = (immPOper *)$needleImm; 13025 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13026 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13027 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13028 __ string_indexof_char($result$$Register, 13029 $haystack$$Register, $haycnt$$Register, 13030 R0, chr, 13031 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13032 %} 13033 ins_pipe(pipe_class_compare); 13034 %} 13035 13036 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13037 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13038 iRegIdst tmp1, iRegIdst tmp2, 13039 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13040 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13041 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13042 // Required for EA: check if it is still a type_array. 13043 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13044 ins_cost(150); 13045 13046 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13047 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13048 13049 ins_encode %{ 13050 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13051 immPOper *needleOper = (immPOper *)$needleImm; 13052 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13053 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13054 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13055 __ string_indexof_char($result$$Register, 13056 $haystack$$Register, $haycnt$$Register, 13057 R0, chr, 13058 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13059 %} 13060 ins_pipe(pipe_class_compare); 13061 %} 13062 13063 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13064 rscratch2RegP needle, immI_1 needlecntImm, 13065 iRegIdst tmp1, iRegIdst tmp2, 13066 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13067 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13068 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13069 // Required for EA: check if it is still a type_array. 13070 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13071 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13072 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13073 ins_cost(180); 13074 13075 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13076 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13077 ins_encode %{ 13078 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13079 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13080 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13081 guarantee(needle_values, "sanity"); 13082 jchar chr; 13083 #ifdef VM_LITTLE_ENDIAN 13084 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 13085 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 13086 #else 13087 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 13088 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 13089 #endif 13090 __ string_indexof_char($result$$Register, 13091 $haystack$$Register, $haycnt$$Register, 13092 R0, chr, 13093 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13094 %} 13095 ins_pipe(pipe_class_compare); 13096 %} 13097 13098 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13099 rscratch2RegP needle, immI_1 needlecntImm, 13100 iRegIdst tmp1, iRegIdst tmp2, 13101 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13102 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13103 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13104 // Required for EA: check if it is still a type_array. 13105 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13106 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13107 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13108 ins_cost(180); 13109 13110 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13111 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13112 ins_encode %{ 13113 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13114 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13115 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13116 guarantee(needle_values, "sanity"); 13117 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13118 __ string_indexof_char($result$$Register, 13119 $haystack$$Register, $haycnt$$Register, 13120 R0, chr, 13121 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13122 %} 13123 ins_pipe(pipe_class_compare); 13124 %} 13125 13126 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13127 rscratch2RegP needle, immI_1 needlecntImm, 13128 iRegIdst tmp1, iRegIdst tmp2, 13129 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13130 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13131 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13132 // Required for EA: check if it is still a type_array. 13133 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13134 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13135 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13136 ins_cost(180); 13137 13138 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13139 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13140 ins_encode %{ 13141 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13142 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13143 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13144 guarantee(needle_values, "sanity"); 13145 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13146 __ string_indexof_char($result$$Register, 13147 $haystack$$Register, $haycnt$$Register, 13148 R0, chr, 13149 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13150 %} 13151 ins_pipe(pipe_class_compare); 13152 %} 13153 13154 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13155 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 13156 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13157 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 13158 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13159 ins_cost(180); 13160 13161 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 13162 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13163 ins_encode %{ 13164 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13165 __ string_indexof_char($result$$Register, 13166 $haystack$$Register, $haycnt$$Register, 13167 $ch$$Register, 0 /* this is not used if the character is already in a register */, 13168 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13169 %} 13170 ins_pipe(pipe_class_compare); 13171 %} 13172 13173 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13174 iRegPsrc needle, uimmI15 needlecntImm, 13175 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13176 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13177 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13178 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13179 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13180 // Required for EA: check if it is still a type_array. 13181 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13182 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13183 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13184 ins_cost(250); 13185 13186 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13187 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13188 ins_encode %{ 13189 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13190 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13191 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13192 13193 __ string_indexof($result$$Register, 13194 $haystack$$Register, $haycnt$$Register, 13195 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13196 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13197 %} 13198 ins_pipe(pipe_class_compare); 13199 %} 13200 13201 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13202 iRegPsrc needle, uimmI15 needlecntImm, 13203 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13204 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13205 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13206 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13207 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13208 // Required for EA: check if it is still a type_array. 13209 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13210 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13211 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13212 ins_cost(250); 13213 13214 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13215 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13216 ins_encode %{ 13217 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13218 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13219 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13220 13221 __ string_indexof($result$$Register, 13222 $haystack$$Register, $haycnt$$Register, 13223 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13224 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13225 %} 13226 ins_pipe(pipe_class_compare); 13227 %} 13228 13229 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13230 iRegPsrc needle, uimmI15 needlecntImm, 13231 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13232 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13233 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13234 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13235 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13236 // Required for EA: check if it is still a type_array. 13237 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13238 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13239 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13240 ins_cost(250); 13241 13242 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13243 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13244 ins_encode %{ 13245 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13246 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13247 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13248 13249 __ string_indexof($result$$Register, 13250 $haystack$$Register, $haycnt$$Register, 13251 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13252 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13253 %} 13254 ins_pipe(pipe_class_compare); 13255 %} 13256 13257 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13258 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13259 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13260 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13261 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13262 TEMP_DEF result, 13263 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13264 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13265 ins_cost(300); 13266 13267 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13268 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13269 ins_encode %{ 13270 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13271 __ string_indexof($result$$Register, 13272 $haystack$$Register, $haycnt$$Register, 13273 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13274 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13275 %} 13276 ins_pipe(pipe_class_compare); 13277 %} 13278 13279 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13280 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13281 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13282 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13283 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13284 TEMP_DEF result, 13285 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13286 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13287 ins_cost(300); 13288 13289 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13290 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13291 ins_encode %{ 13292 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13293 __ string_indexof($result$$Register, 13294 $haystack$$Register, $haycnt$$Register, 13295 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13296 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13297 %} 13298 ins_pipe(pipe_class_compare); 13299 %} 13300 13301 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13302 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13303 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13304 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13305 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13306 TEMP_DEF result, 13307 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13308 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13309 ins_cost(300); 13310 13311 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13312 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13313 ins_encode %{ 13314 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13315 __ string_indexof($result$$Register, 13316 $haystack$$Register, $haycnt$$Register, 13317 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13318 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13319 %} 13320 ins_pipe(pipe_class_compare); 13321 %} 13322 13323 // char[] to byte[] compression 13324 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13325 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13326 match(Set result (StrCompressedCopy src (Binary dst len))); 13327 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13328 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13329 ins_cost(300); 13330 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13331 ins_encode %{ 13332 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13333 Label Lskip, Ldone; 13334 __ li($result$$Register, 0); 13335 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13336 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13337 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13338 __ beq(CCR0, Lskip); 13339 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13340 __ bind(Lskip); 13341 __ mr($result$$Register, $len$$Register); 13342 __ bind(Ldone); 13343 %} 13344 ins_pipe(pipe_class_default); 13345 %} 13346 13347 // byte[] to char[] inflation 13348 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13349 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13350 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13351 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13352 ins_cost(300); 13353 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13354 ins_encode %{ 13355 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13356 Label Ldone; 13357 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13358 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13359 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13360 __ beq(CCR0, Ldone); 13361 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13362 __ bind(Ldone); 13363 %} 13364 ins_pipe(pipe_class_default); 13365 %} 13366 13367 // StringCoding.java intrinsics 13368 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13369 regCTR ctr, flagsRegCR0 cr0) 13370 %{ 13371 match(Set result (HasNegatives ary1 len)); 13372 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13373 ins_cost(300); 13374 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13375 ins_encode %{ 13376 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13377 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13378 $tmp1$$Register, $tmp2$$Register); 13379 %} 13380 ins_pipe(pipe_class_default); 13381 %} 13382 13383 // encode char[] to byte[] in ISO_8859_1 13384 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13385 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13386 match(Set result (EncodeISOArray src (Binary dst len))); 13387 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13388 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13389 ins_cost(300); 13390 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13391 ins_encode %{ 13392 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13393 Label Lslow, Lfailure1, Lfailure2, Ldone; 13394 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13395 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13396 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13397 __ beq(CCR0, Ldone); 13398 __ bind(Lslow); 13399 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13400 __ li($result$$Register, 0); 13401 __ b(Ldone); 13402 13403 __ bind(Lfailure1); 13404 __ mr($result$$Register, $len$$Register); 13405 __ mfctr($tmp1$$Register); 13406 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13407 __ beq(CCR0, Ldone); 13408 __ b(Lslow); 13409 13410 __ bind(Lfailure2); 13411 __ mfctr($result$$Register); // Remaining characters. 13412 13413 __ bind(Ldone); 13414 __ subf($result$$Register, $result$$Register, $len$$Register); 13415 %} 13416 ins_pipe(pipe_class_default); 13417 %} 13418 13419 13420 //---------- Min/Max Instructions --------------------------------------------- 13421 13422 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13423 match(Set dst (MinI src1 src2)); 13424 ins_cost(DEFAULT_COST*6); 13425 13426 expand %{ 13427 iRegLdst src1s; 13428 iRegLdst src2s; 13429 iRegLdst diff; 13430 iRegLdst sm; 13431 iRegLdst doz; // difference or zero 13432 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13433 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13434 subL_reg_reg(diff, src2s, src1s); 13435 // Need to consider >=33 bit result, therefore we need signmaskL. 13436 signmask64L_regL(sm, diff); 13437 andL_reg_reg(doz, diff, sm); // <=0 13438 addI_regL_regL(dst, doz, src1s); 13439 %} 13440 %} 13441 13442 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13443 match(Set dst (MinI src1 src2)); 13444 effect(KILL cr0); 13445 predicate(VM_Version::has_isel()); 13446 ins_cost(DEFAULT_COST*2); 13447 13448 ins_encode %{ 13449 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13450 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13451 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13452 %} 13453 ins_pipe(pipe_class_default); 13454 %} 13455 13456 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13457 match(Set dst (MaxI src1 src2)); 13458 ins_cost(DEFAULT_COST*6); 13459 13460 expand %{ 13461 iRegLdst src1s; 13462 iRegLdst src2s; 13463 iRegLdst diff; 13464 iRegLdst sm; 13465 iRegLdst doz; // difference or zero 13466 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13467 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13468 subL_reg_reg(diff, src2s, src1s); 13469 // Need to consider >=33 bit result, therefore we need signmaskL. 13470 signmask64L_regL(sm, diff); 13471 andcL_reg_reg(doz, diff, sm); // >=0 13472 addI_regL_regL(dst, doz, src1s); 13473 %} 13474 %} 13475 13476 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13477 match(Set dst (MaxI src1 src2)); 13478 effect(KILL cr0); 13479 predicate(VM_Version::has_isel()); 13480 ins_cost(DEFAULT_COST*2); 13481 13482 ins_encode %{ 13483 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13484 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13485 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13486 %} 13487 ins_pipe(pipe_class_default); 13488 %} 13489 13490 //---------- Population Count Instructions ------------------------------------ 13491 13492 // Popcnt for Power7. 13493 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13494 match(Set dst (PopCountI src)); 13495 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13496 ins_cost(DEFAULT_COST); 13497 13498 format %{ "POPCNTW $dst, $src" %} 13499 size(4); 13500 ins_encode %{ 13501 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13502 __ popcntw($dst$$Register, $src$$Register); 13503 %} 13504 ins_pipe(pipe_class_default); 13505 %} 13506 13507 // Popcnt for Power7. 13508 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13509 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13510 match(Set dst (PopCountL src)); 13511 ins_cost(DEFAULT_COST); 13512 13513 format %{ "POPCNTD $dst, $src" %} 13514 size(4); 13515 ins_encode %{ 13516 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13517 __ popcntd($dst$$Register, $src$$Register); 13518 %} 13519 ins_pipe(pipe_class_default); 13520 %} 13521 13522 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13523 match(Set dst (CountLeadingZerosI src)); 13524 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13525 ins_cost(DEFAULT_COST); 13526 13527 format %{ "CNTLZW $dst, $src" %} 13528 size(4); 13529 ins_encode %{ 13530 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13531 __ cntlzw($dst$$Register, $src$$Register); 13532 %} 13533 ins_pipe(pipe_class_default); 13534 %} 13535 13536 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13537 match(Set dst (CountLeadingZerosL src)); 13538 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13539 ins_cost(DEFAULT_COST); 13540 13541 format %{ "CNTLZD $dst, $src" %} 13542 size(4); 13543 ins_encode %{ 13544 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13545 __ cntlzd($dst$$Register, $src$$Register); 13546 %} 13547 ins_pipe(pipe_class_default); 13548 %} 13549 13550 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13551 // no match-rule, false predicate 13552 effect(DEF dst, USE src); 13553 predicate(false); 13554 13555 format %{ "CNTLZD $dst, $src" %} 13556 size(4); 13557 ins_encode %{ 13558 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13559 __ cntlzd($dst$$Register, $src$$Register); 13560 %} 13561 ins_pipe(pipe_class_default); 13562 %} 13563 13564 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13565 match(Set dst (CountTrailingZerosI src)); 13566 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13567 ins_cost(DEFAULT_COST); 13568 13569 expand %{ 13570 immI16 imm1 %{ (int)-1 %} 13571 immI16 imm2 %{ (int)32 %} 13572 immI_minus1 m1 %{ -1 %} 13573 iRegIdst tmpI1; 13574 iRegIdst tmpI2; 13575 iRegIdst tmpI3; 13576 addI_reg_imm16(tmpI1, src, imm1); 13577 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13578 countLeadingZerosI(tmpI3, tmpI2); 13579 subI_imm16_reg(dst, imm2, tmpI3); 13580 %} 13581 %} 13582 13583 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{ 13584 match(Set dst (CountTrailingZerosI src)); 13585 predicate(UseCountTrailingZerosInstructionsPPC64); 13586 ins_cost(DEFAULT_COST); 13587 13588 format %{ "CNTTZW $dst, $src" %} 13589 size(4); 13590 ins_encode %{ 13591 __ cnttzw($dst$$Register, $src$$Register); 13592 %} 13593 ins_pipe(pipe_class_default); 13594 %} 13595 13596 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13597 match(Set dst (CountTrailingZerosL src)); 13598 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13599 ins_cost(DEFAULT_COST); 13600 13601 expand %{ 13602 immL16 imm1 %{ (long)-1 %} 13603 immI16 imm2 %{ (int)64 %} 13604 iRegLdst tmpL1; 13605 iRegLdst tmpL2; 13606 iRegIdst tmpL3; 13607 addL_reg_imm16(tmpL1, src, imm1); 13608 andcL_reg_reg(tmpL2, tmpL1, src); 13609 countLeadingZerosL(tmpL3, tmpL2); 13610 subI_imm16_reg(dst, imm2, tmpL3); 13611 %} 13612 %} 13613 13614 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{ 13615 match(Set dst (CountTrailingZerosL src)); 13616 predicate(UseCountTrailingZerosInstructionsPPC64); 13617 ins_cost(DEFAULT_COST); 13618 13619 format %{ "CNTTZD $dst, $src" %} 13620 size(4); 13621 ins_encode %{ 13622 __ cnttzd($dst$$Register, $src$$Register); 13623 %} 13624 ins_pipe(pipe_class_default); 13625 %} 13626 13627 // Expand nodes for byte_reverse_int. 13628 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13629 effect(DEF dst, USE src, USE pos, USE shift); 13630 predicate(false); 13631 13632 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13633 size(4); 13634 ins_encode %{ 13635 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13636 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13637 %} 13638 ins_pipe(pipe_class_default); 13639 %} 13640 13641 // As insrwi_a, but with USE_DEF. 13642 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13643 effect(USE_DEF dst, USE src, USE pos, USE shift); 13644 predicate(false); 13645 13646 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13647 size(4); 13648 ins_encode %{ 13649 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13650 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13651 %} 13652 ins_pipe(pipe_class_default); 13653 %} 13654 13655 // Just slightly faster than java implementation. 13656 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13657 match(Set dst (ReverseBytesI src)); 13658 ins_cost(7*DEFAULT_COST); 13659 13660 expand %{ 13661 immI16 imm24 %{ (int) 24 %} 13662 immI16 imm16 %{ (int) 16 %} 13663 immI16 imm8 %{ (int) 8 %} 13664 immI16 imm4 %{ (int) 4 %} 13665 immI16 imm0 %{ (int) 0 %} 13666 iRegLdst tmpI1; 13667 iRegLdst tmpI2; 13668 iRegLdst tmpI3; 13669 13670 urShiftI_reg_imm(tmpI1, src, imm24); 13671 insrwi_a(dst, tmpI1, imm24, imm8); 13672 urShiftI_reg_imm(tmpI2, src, imm16); 13673 insrwi(dst, tmpI2, imm8, imm16); 13674 urShiftI_reg_imm(tmpI3, src, imm8); 13675 insrwi(dst, tmpI3, imm8, imm8); 13676 insrwi(dst, src, imm0, imm8); 13677 %} 13678 %} 13679 13680 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13681 match(Set dst (ReverseBytesL src)); 13682 ins_cost(15*DEFAULT_COST); 13683 13684 expand %{ 13685 immI16 imm56 %{ (int) 56 %} 13686 immI16 imm48 %{ (int) 48 %} 13687 immI16 imm40 %{ (int) 40 %} 13688 immI16 imm32 %{ (int) 32 %} 13689 immI16 imm24 %{ (int) 24 %} 13690 immI16 imm16 %{ (int) 16 %} 13691 immI16 imm8 %{ (int) 8 %} 13692 immI16 imm0 %{ (int) 0 %} 13693 iRegLdst tmpL1; 13694 iRegLdst tmpL2; 13695 iRegLdst tmpL3; 13696 iRegLdst tmpL4; 13697 iRegLdst tmpL5; 13698 iRegLdst tmpL6; 13699 13700 // src : |a|b|c|d|e|f|g|h| 13701 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13702 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13703 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13704 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13705 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13706 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13707 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13708 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13709 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13710 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13711 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13712 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13713 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13714 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13715 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13716 %} 13717 %} 13718 13719 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13720 match(Set dst (ReverseBytesUS src)); 13721 ins_cost(2*DEFAULT_COST); 13722 13723 expand %{ 13724 immI16 imm16 %{ (int) 16 %} 13725 immI16 imm8 %{ (int) 8 %} 13726 13727 urShiftI_reg_imm(dst, src, imm8); 13728 insrwi(dst, src, imm16, imm8); 13729 %} 13730 %} 13731 13732 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13733 match(Set dst (ReverseBytesS src)); 13734 ins_cost(3*DEFAULT_COST); 13735 13736 expand %{ 13737 immI16 imm16 %{ (int) 16 %} 13738 immI16 imm8 %{ (int) 8 %} 13739 iRegLdst tmpI1; 13740 13741 urShiftI_reg_imm(tmpI1, src, imm8); 13742 insrwi(tmpI1, src, imm16, imm8); 13743 extsh(dst, tmpI1); 13744 %} 13745 %} 13746 13747 // Load Integer reversed byte order 13748 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13749 match(Set dst (ReverseBytesI (LoadI mem))); 13750 ins_cost(MEMORY_REF_COST); 13751 13752 size(4); 13753 ins_encode %{ 13754 __ lwbrx($dst$$Register, $mem$$Register); 13755 %} 13756 ins_pipe(pipe_class_default); 13757 %} 13758 13759 // Load Long - aligned and reversed 13760 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13761 match(Set dst (ReverseBytesL (LoadL mem))); 13762 predicate(VM_Version::has_ldbrx()); 13763 ins_cost(MEMORY_REF_COST); 13764 13765 size(4); 13766 ins_encode %{ 13767 __ ldbrx($dst$$Register, $mem$$Register); 13768 %} 13769 ins_pipe(pipe_class_default); 13770 %} 13771 13772 // Load unsigned short / char reversed byte order 13773 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13774 match(Set dst (ReverseBytesUS (LoadUS mem))); 13775 ins_cost(MEMORY_REF_COST); 13776 13777 size(4); 13778 ins_encode %{ 13779 __ lhbrx($dst$$Register, $mem$$Register); 13780 %} 13781 ins_pipe(pipe_class_default); 13782 %} 13783 13784 // Load short reversed byte order 13785 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13786 match(Set dst (ReverseBytesS (LoadS mem))); 13787 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13788 13789 size(8); 13790 ins_encode %{ 13791 __ lhbrx($dst$$Register, $mem$$Register); 13792 __ extsh($dst$$Register, $dst$$Register); 13793 %} 13794 ins_pipe(pipe_class_default); 13795 %} 13796 13797 // Store Integer reversed byte order 13798 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13799 match(Set mem (StoreI mem (ReverseBytesI src))); 13800 ins_cost(MEMORY_REF_COST); 13801 13802 size(4); 13803 ins_encode %{ 13804 __ stwbrx($src$$Register, $mem$$Register); 13805 %} 13806 ins_pipe(pipe_class_default); 13807 %} 13808 13809 // Store Long reversed byte order 13810 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13811 match(Set mem (StoreL mem (ReverseBytesL src))); 13812 predicate(VM_Version::has_stdbrx()); 13813 ins_cost(MEMORY_REF_COST); 13814 13815 size(4); 13816 ins_encode %{ 13817 __ stdbrx($src$$Register, $mem$$Register); 13818 %} 13819 ins_pipe(pipe_class_default); 13820 %} 13821 13822 // Store unsigned short / char reversed byte order 13823 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13824 match(Set mem (StoreC mem (ReverseBytesUS src))); 13825 ins_cost(MEMORY_REF_COST); 13826 13827 size(4); 13828 ins_encode %{ 13829 __ sthbrx($src$$Register, $mem$$Register); 13830 %} 13831 ins_pipe(pipe_class_default); 13832 %} 13833 13834 // Store short reversed byte order 13835 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13836 match(Set mem (StoreC mem (ReverseBytesS src))); 13837 ins_cost(MEMORY_REF_COST); 13838 13839 size(4); 13840 ins_encode %{ 13841 __ sthbrx($src$$Register, $mem$$Register); 13842 %} 13843 ins_pipe(pipe_class_default); 13844 %} 13845 13846 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13847 effect(DEF temp1, USE src); 13848 13849 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %} 13850 size(4); 13851 ins_encode %{ 13852 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13853 %} 13854 ins_pipe(pipe_class_default); 13855 %} 13856 13857 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13858 effect(DEF dst, USE src, USE imm1); 13859 13860 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %} 13861 size(4); 13862 ins_encode %{ 13863 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13864 %} 13865 ins_pipe(pipe_class_default); 13866 %} 13867 13868 instruct xscvdpspn_regF(vecX dst, regF src) %{ 13869 effect(DEF dst, USE src); 13870 13871 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %} 13872 size(4); 13873 ins_encode %{ 13874 __ xscvdpspn($dst$$VectorSRegister, $src$$FloatRegister->to_vsr()); 13875 %} 13876 ins_pipe(pipe_class_default); 13877 %} 13878 13879 //---------- Replicate Vector Instructions ------------------------------------ 13880 13881 // Insrdi does replicate if src == dst. 13882 instruct repl32(iRegLdst dst) %{ 13883 predicate(false); 13884 effect(USE_DEF dst); 13885 13886 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13887 size(4); 13888 ins_encode %{ 13889 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13890 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13891 %} 13892 ins_pipe(pipe_class_default); 13893 %} 13894 13895 // Insrdi does replicate if src == dst. 13896 instruct repl48(iRegLdst dst) %{ 13897 predicate(false); 13898 effect(USE_DEF dst); 13899 13900 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13901 size(4); 13902 ins_encode %{ 13903 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13904 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13905 %} 13906 ins_pipe(pipe_class_default); 13907 %} 13908 13909 // Insrdi does replicate if src == dst. 13910 instruct repl56(iRegLdst dst) %{ 13911 predicate(false); 13912 effect(USE_DEF dst); 13913 13914 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13915 size(4); 13916 ins_encode %{ 13917 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13918 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 13919 %} 13920 ins_pipe(pipe_class_default); 13921 %} 13922 13923 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13924 match(Set dst (ReplicateB src)); 13925 predicate(n->as_Vector()->length() == 8); 13926 expand %{ 13927 moveReg(dst, src); 13928 repl56(dst); 13929 repl48(dst); 13930 repl32(dst); 13931 %} 13932 %} 13933 13934 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 13935 match(Set dst (ReplicateB zero)); 13936 predicate(n->as_Vector()->length() == 8); 13937 format %{ "LI $dst, #0 \t// replicate8B" %} 13938 size(4); 13939 ins_encode %{ 13940 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13941 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13942 %} 13943 ins_pipe(pipe_class_default); 13944 %} 13945 13946 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13947 match(Set dst (ReplicateB src)); 13948 predicate(n->as_Vector()->length() == 8); 13949 format %{ "LI $dst, #-1 \t// replicate8B" %} 13950 size(4); 13951 ins_encode %{ 13952 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13953 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13954 %} 13955 ins_pipe(pipe_class_default); 13956 %} 13957 13958 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 13959 match(Set dst (ReplicateB src)); 13960 predicate(n->as_Vector()->length() == 16); 13961 13962 expand %{ 13963 iRegLdst tmpL; 13964 vecX tmpV; 13965 immI8 imm1 %{ (int) 1 %} 13966 moveReg(tmpL, src); 13967 repl56(tmpL); 13968 repl48(tmpL); 13969 mtvsrwz(tmpV, tmpL); 13970 xxspltw(dst, tmpV, imm1); 13971 %} 13972 %} 13973 13974 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 13975 match(Set dst (ReplicateB zero)); 13976 predicate(n->as_Vector()->length() == 16); 13977 13978 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 13979 size(4); 13980 ins_encode %{ 13981 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13982 %} 13983 ins_pipe(pipe_class_default); 13984 %} 13985 13986 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 13987 match(Set dst (ReplicateB src)); 13988 predicate(n->as_Vector()->length() == 16); 13989 13990 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13991 size(4); 13992 ins_encode %{ 13993 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13994 %} 13995 ins_pipe(pipe_class_default); 13996 %} 13997 13998 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13999 match(Set dst (ReplicateS src)); 14000 predicate(n->as_Vector()->length() == 4); 14001 expand %{ 14002 moveReg(dst, src); 14003 repl48(dst); 14004 repl32(dst); 14005 %} 14006 %} 14007 14008 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 14009 match(Set dst (ReplicateS zero)); 14010 predicate(n->as_Vector()->length() == 4); 14011 format %{ "LI $dst, #0 \t// replicate4C" %} 14012 size(4); 14013 ins_encode %{ 14014 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14015 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14016 %} 14017 ins_pipe(pipe_class_default); 14018 %} 14019 14020 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14021 match(Set dst (ReplicateS src)); 14022 predicate(n->as_Vector()->length() == 4); 14023 format %{ "LI $dst, -1 \t// replicate4C" %} 14024 size(4); 14025 ins_encode %{ 14026 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14027 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14028 %} 14029 ins_pipe(pipe_class_default); 14030 %} 14031 14032 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 14033 match(Set dst (ReplicateS src)); 14034 predicate(n->as_Vector()->length() == 8); 14035 14036 expand %{ 14037 iRegLdst tmpL; 14038 vecX tmpV; 14039 immI8 zero %{ (int) 0 %} 14040 moveReg(tmpL, src); 14041 repl48(tmpL); 14042 repl32(tmpL); 14043 mtvsrd(tmpV, tmpL); 14044 xxpermdi(dst, tmpV, tmpV, zero); 14045 %} 14046 %} 14047 14048 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 14049 match(Set dst (ReplicateS zero)); 14050 predicate(n->as_Vector()->length() == 8); 14051 14052 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 14053 size(4); 14054 ins_encode %{ 14055 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14056 %} 14057 ins_pipe(pipe_class_default); 14058 %} 14059 14060 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 14061 match(Set dst (ReplicateS src)); 14062 predicate(n->as_Vector()->length() == 8); 14063 14064 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14065 size(4); 14066 ins_encode %{ 14067 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14068 %} 14069 ins_pipe(pipe_class_default); 14070 %} 14071 14072 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14073 match(Set dst (ReplicateI src)); 14074 predicate(n->as_Vector()->length() == 2); 14075 ins_cost(2 * DEFAULT_COST); 14076 expand %{ 14077 moveReg(dst, src); 14078 repl32(dst); 14079 %} 14080 %} 14081 14082 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 14083 match(Set dst (ReplicateI zero)); 14084 predicate(n->as_Vector()->length() == 2); 14085 format %{ "LI $dst, #0 \t// replicate4C" %} 14086 size(4); 14087 ins_encode %{ 14088 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14089 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14090 %} 14091 ins_pipe(pipe_class_default); 14092 %} 14093 14094 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14095 match(Set dst (ReplicateI src)); 14096 predicate(n->as_Vector()->length() == 2); 14097 format %{ "LI $dst, -1 \t// replicate4C" %} 14098 size(4); 14099 ins_encode %{ 14100 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14101 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14102 %} 14103 ins_pipe(pipe_class_default); 14104 %} 14105 14106 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 14107 match(Set dst (ReplicateI src)); 14108 predicate(n->as_Vector()->length() == 4); 14109 ins_cost(2 * DEFAULT_COST); 14110 14111 expand %{ 14112 iRegLdst tmpL; 14113 vecX tmpV; 14114 immI8 zero %{ (int) 0 %} 14115 moveReg(tmpL, src); 14116 repl32(tmpL); 14117 mtvsrd(tmpV, tmpL); 14118 xxpermdi(dst, tmpV, tmpV, zero); 14119 %} 14120 %} 14121 14122 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 14123 match(Set dst (ReplicateI zero)); 14124 predicate(n->as_Vector()->length() == 4); 14125 14126 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 14127 size(4); 14128 ins_encode %{ 14129 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14130 %} 14131 ins_pipe(pipe_class_default); 14132 %} 14133 14134 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 14135 match(Set dst (ReplicateI src)); 14136 predicate(n->as_Vector()->length() == 4); 14137 14138 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 14139 size(4); 14140 ins_encode %{ 14141 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14142 %} 14143 ins_pipe(pipe_class_default); 14144 %} 14145 14146 // Move float to int register via stack, replicate. 14147 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 14148 match(Set dst (ReplicateF src)); 14149 predicate(n->as_Vector()->length() == 2); 14150 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14151 expand %{ 14152 stackSlotL tmpS; 14153 iRegIdst tmpI; 14154 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14155 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14156 moveReg(dst, tmpI); // Move int to long reg. 14157 repl32(dst); // Replicate bitpattern. 14158 %} 14159 %} 14160 14161 // Replicate scalar constant to packed float values in Double register 14162 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 14163 match(Set dst (ReplicateF src)); 14164 predicate(n->as_Vector()->length() == 2); 14165 ins_cost(5 * DEFAULT_COST); 14166 14167 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 14168 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 14169 %} 14170 14171 // Replicate scalar zero constant to packed float values in Double register 14172 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 14173 match(Set dst (ReplicateF zero)); 14174 predicate(n->as_Vector()->length() == 2); 14175 14176 format %{ "LI $dst, #0 \t// replicate2F" %} 14177 ins_encode %{ 14178 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14179 __ li($dst$$Register, 0x0); 14180 %} 14181 ins_pipe(pipe_class_default); 14182 %} 14183 14184 14185 //----------Vector Arithmetic Instructions-------------------------------------- 14186 14187 // Vector Addition Instructions 14188 14189 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{ 14190 match(Set dst (AddVB src1 src2)); 14191 predicate(n->as_Vector()->length() == 16); 14192 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %} 14193 size(4); 14194 ins_encode %{ 14195 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14196 %} 14197 ins_pipe(pipe_class_default); 14198 %} 14199 14200 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{ 14201 match(Set dst (AddVS src1 src2)); 14202 predicate(n->as_Vector()->length() == 8); 14203 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %} 14204 size(4); 14205 ins_encode %{ 14206 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14207 %} 14208 ins_pipe(pipe_class_default); 14209 %} 14210 14211 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{ 14212 match(Set dst (AddVI src1 src2)); 14213 predicate(n->as_Vector()->length() == 4); 14214 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %} 14215 size(4); 14216 ins_encode %{ 14217 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14218 %} 14219 ins_pipe(pipe_class_default); 14220 %} 14221 14222 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{ 14223 match(Set dst (AddVF src1 src2)); 14224 predicate(n->as_Vector()->length() == 4); 14225 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %} 14226 size(4); 14227 ins_encode %{ 14228 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14229 %} 14230 ins_pipe(pipe_class_default); 14231 %} 14232 14233 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{ 14234 match(Set dst (AddVL src1 src2)); 14235 predicate(n->as_Vector()->length() == 2); 14236 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %} 14237 size(4); 14238 ins_encode %{ 14239 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14240 %} 14241 ins_pipe(pipe_class_default); 14242 %} 14243 14244 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{ 14245 match(Set dst (AddVD src1 src2)); 14246 predicate(n->as_Vector()->length() == 2); 14247 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %} 14248 size(4); 14249 ins_encode %{ 14250 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14251 %} 14252 ins_pipe(pipe_class_default); 14253 %} 14254 14255 // Vector Subtraction Instructions 14256 14257 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{ 14258 match(Set dst (SubVB src1 src2)); 14259 predicate(n->as_Vector()->length() == 16); 14260 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %} 14261 size(4); 14262 ins_encode %{ 14263 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14264 %} 14265 ins_pipe(pipe_class_default); 14266 %} 14267 14268 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{ 14269 match(Set dst (SubVS src1 src2)); 14270 predicate(n->as_Vector()->length() == 8); 14271 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %} 14272 size(4); 14273 ins_encode %{ 14274 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14275 %} 14276 ins_pipe(pipe_class_default); 14277 %} 14278 14279 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{ 14280 match(Set dst (SubVI src1 src2)); 14281 predicate(n->as_Vector()->length() == 4); 14282 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %} 14283 size(4); 14284 ins_encode %{ 14285 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14286 %} 14287 ins_pipe(pipe_class_default); 14288 %} 14289 14290 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{ 14291 match(Set dst (SubVF src1 src2)); 14292 predicate(n->as_Vector()->length() == 4); 14293 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %} 14294 size(4); 14295 ins_encode %{ 14296 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14297 %} 14298 ins_pipe(pipe_class_default); 14299 %} 14300 14301 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{ 14302 match(Set dst (SubVL src1 src2)); 14303 predicate(n->as_Vector()->length() == 2); 14304 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %} 14305 size(4); 14306 ins_encode %{ 14307 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14308 %} 14309 ins_pipe(pipe_class_default); 14310 %} 14311 14312 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{ 14313 match(Set dst (SubVD src1 src2)); 14314 predicate(n->as_Vector()->length() == 2); 14315 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %} 14316 size(4); 14317 ins_encode %{ 14318 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14319 %} 14320 ins_pipe(pipe_class_default); 14321 %} 14322 14323 // Vector Multiplication Instructions 14324 14325 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 14326 match(Set dst (MulVS src1 src2)); 14327 predicate(n->as_Vector()->length() == 8); 14328 effect(TEMP tmp); 14329 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %} 14330 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %} 14331 size(8); 14332 ins_encode %{ 14333 __ vspltish($tmp$$VectorSRegister->to_vr(), 0); 14334 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr()); 14335 %} 14336 ins_pipe(pipe_class_default); 14337 %} 14338 14339 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{ 14340 match(Set dst (MulVI src1 src2)); 14341 predicate(n->as_Vector()->length() == 4); 14342 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %} 14343 size(4); 14344 ins_encode %{ 14345 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14346 %} 14347 ins_pipe(pipe_class_default); 14348 %} 14349 14350 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{ 14351 match(Set dst (MulVF src1 src2)); 14352 predicate(n->as_Vector()->length() == 4); 14353 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %} 14354 size(4); 14355 ins_encode %{ 14356 __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14357 %} 14358 ins_pipe(pipe_class_default); 14359 %} 14360 14361 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{ 14362 match(Set dst (MulVD src1 src2)); 14363 predicate(n->as_Vector()->length() == 2); 14364 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %} 14365 size(4); 14366 ins_encode %{ 14367 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14368 %} 14369 ins_pipe(pipe_class_default); 14370 %} 14371 14372 // Vector Division Instructions 14373 14374 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{ 14375 match(Set dst (DivVF src1 src2)); 14376 predicate(n->as_Vector()->length() == 4); 14377 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %} 14378 size(4); 14379 ins_encode %{ 14380 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14381 %} 14382 ins_pipe(pipe_class_default); 14383 %} 14384 14385 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ 14386 match(Set dst (DivVD src1 src2)); 14387 predicate(n->as_Vector()->length() == 2); 14388 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %} 14389 size(4); 14390 ins_encode %{ 14391 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14392 %} 14393 ins_pipe(pipe_class_default); 14394 %} 14395 14396 // Vector Absolute Instructions 14397 14398 instruct vabs4F_reg(vecX dst, vecX src) %{ 14399 match(Set dst (AbsVF src)); 14400 predicate(n->as_Vector()->length() == 4); 14401 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %} 14402 size(4); 14403 ins_encode %{ 14404 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister); 14405 %} 14406 ins_pipe(pipe_class_default); 14407 %} 14408 14409 instruct vabs2D_reg(vecX dst, vecX src) %{ 14410 match(Set dst (AbsVD src)); 14411 predicate(n->as_Vector()->length() == 2); 14412 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %} 14413 size(4); 14414 ins_encode %{ 14415 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister); 14416 %} 14417 ins_pipe(pipe_class_default); 14418 %} 14419 14420 // Vector Negate Instructions 14421 14422 instruct vneg4F_reg(vecX dst, vecX src) %{ 14423 match(Set dst (NegVF src)); 14424 predicate(n->as_Vector()->length() == 4); 14425 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %} 14426 size(4); 14427 ins_encode %{ 14428 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister); 14429 %} 14430 ins_pipe(pipe_class_default); 14431 %} 14432 14433 instruct vneg2D_reg(vecX dst, vecX src) %{ 14434 match(Set dst (NegVD src)); 14435 predicate(n->as_Vector()->length() == 2); 14436 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %} 14437 size(4); 14438 ins_encode %{ 14439 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister); 14440 %} 14441 ins_pipe(pipe_class_default); 14442 %} 14443 14444 // Vector Square Root Instructions 14445 14446 instruct vsqrt4F_reg(vecX dst, vecX src) %{ 14447 match(Set dst (SqrtVF src)); 14448 predicate(n->as_Vector()->length() == 4); 14449 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %} 14450 size(4); 14451 ins_encode %{ 14452 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister); 14453 %} 14454 ins_pipe(pipe_class_default); 14455 %} 14456 14457 instruct vsqrt2D_reg(vecX dst, vecX src) %{ 14458 match(Set dst (SqrtVD src)); 14459 predicate(n->as_Vector()->length() == 2); 14460 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %} 14461 size(4); 14462 ins_encode %{ 14463 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister); 14464 %} 14465 ins_pipe(pipe_class_default); 14466 %} 14467 14468 // Vector Population Count Instructions 14469 14470 instruct vpopcnt4I_reg(vecX dst, vecX src) %{ 14471 match(Set dst (PopCountVI src)); 14472 predicate(n->as_Vector()->length() == 4); 14473 format %{ "VPOPCNTW $dst,$src\t// pop count packed4I" %} 14474 size(4); 14475 ins_encode %{ 14476 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14477 %} 14478 ins_pipe(pipe_class_default); 14479 %} 14480 14481 // --------------------------------- FMA -------------------------------------- 14482 // dst + src1 * src2 14483 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{ 14484 match(Set dst (FmaVF dst (Binary src1 src2))); 14485 predicate(n->as_Vector()->length() == 4); 14486 14487 format %{ "XVMADDASP $dst, $src1, $src2" %} 14488 14489 size(4); 14490 ins_encode %{ 14491 __ xvmaddasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14492 %} 14493 ins_pipe(pipe_class_default); 14494 %} 14495 14496 // dst - src1 * src2 14497 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{ 14498 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 14499 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 14500 predicate(n->as_Vector()->length() == 4); 14501 14502 format %{ "XVNMSUBASP $dst, $src1, $src2" %} 14503 14504 size(4); 14505 ins_encode %{ 14506 __ xvnmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14507 %} 14508 ins_pipe(pipe_class_default); 14509 %} 14510 14511 // - dst + src1 * src2 14512 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{ 14513 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2))); 14514 predicate(n->as_Vector()->length() == 4); 14515 14516 format %{ "XVMSUBASP $dst, $src1, $src2" %} 14517 14518 size(4); 14519 ins_encode %{ 14520 __ xvmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14521 %} 14522 ins_pipe(pipe_class_default); 14523 %} 14524 14525 // dst + src1 * src2 14526 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{ 14527 match(Set dst (FmaVD dst (Binary src1 src2))); 14528 predicate(n->as_Vector()->length() == 2); 14529 14530 format %{ "XVMADDADP $dst, $src1, $src2" %} 14531 14532 size(4); 14533 ins_encode %{ 14534 __ xvmaddadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14535 %} 14536 ins_pipe(pipe_class_default); 14537 %} 14538 14539 // dst - src1 * src2 14540 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{ 14541 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 14542 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 14543 predicate(n->as_Vector()->length() == 2); 14544 14545 format %{ "XVNMSUBADP $dst, $src1, $src2" %} 14546 14547 size(4); 14548 ins_encode %{ 14549 __ xvnmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14550 %} 14551 ins_pipe(pipe_class_default); 14552 %} 14553 14554 // - dst + src1 * src2 14555 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{ 14556 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2))); 14557 predicate(n->as_Vector()->length() == 2); 14558 14559 format %{ "XVMSUBADP $dst, $src1, $src2" %} 14560 14561 size(4); 14562 ins_encode %{ 14563 __ xvmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14564 %} 14565 ins_pipe(pipe_class_default); 14566 %} 14567 14568 //----------Overflow Math Instructions----------------------------------------- 14569 14570 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 14571 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14572 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14573 14574 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14575 match(Set cr0 (OverflowAddL op1 op2)); 14576 14577 format %{ "add_ $op1, $op2\t# overflow check long" %} 14578 ins_encode %{ 14579 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14580 __ li(R0, 0); 14581 __ mtxer(R0); // clear XER.SO 14582 __ addo_(R0, $op1$$Register, $op2$$Register); 14583 %} 14584 ins_pipe(pipe_class_default); 14585 %} 14586 14587 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14588 match(Set cr0 (OverflowSubL op1 op2)); 14589 14590 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14591 ins_encode %{ 14592 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14593 __ li(R0, 0); 14594 __ mtxer(R0); // clear XER.SO 14595 __ subfo_(R0, $op2$$Register, $op1$$Register); 14596 %} 14597 ins_pipe(pipe_class_default); 14598 %} 14599 14600 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14601 match(Set cr0 (OverflowSubL zero op2)); 14602 14603 format %{ "nego_ R0, $op2\t# overflow check long" %} 14604 ins_encode %{ 14605 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14606 __ li(R0, 0); 14607 __ mtxer(R0); // clear XER.SO 14608 __ nego_(R0, $op2$$Register); 14609 %} 14610 ins_pipe(pipe_class_default); 14611 %} 14612 14613 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14614 match(Set cr0 (OverflowMulL op1 op2)); 14615 14616 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14617 ins_encode %{ 14618 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14619 __ li(R0, 0); 14620 __ mtxer(R0); // clear XER.SO 14621 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14622 %} 14623 ins_pipe(pipe_class_default); 14624 %} 14625 14626 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14627 match(Set dst (ReplicateF src)); 14628 predicate(n->as_Vector()->length() == 4); 14629 ins_cost(DEFAULT_COST); 14630 expand %{ 14631 vecX tmpV; 14632 immI8 zero %{ (int) 0 %} 14633 14634 xscvdpspn_regF(tmpV, src); 14635 xxspltw(dst, tmpV, zero); 14636 %} 14637 %} 14638 14639 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14640 match(Set dst (ReplicateF src)); 14641 predicate(n->as_Vector()->length() == 4); 14642 effect(TEMP tmp); 14643 ins_cost(10 * DEFAULT_COST); 14644 14645 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14646 %} 14647 14648 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14649 match(Set dst (ReplicateF zero)); 14650 predicate(n->as_Vector()->length() == 4); 14651 14652 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14653 ins_encode %{ 14654 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14655 %} 14656 ins_pipe(pipe_class_default); 14657 %} 14658 14659 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14660 match(Set dst (ReplicateD src)); 14661 predicate(n->as_Vector()->length() == 2); 14662 14663 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %} 14664 size(4); 14665 ins_encode %{ 14666 __ xxpermdi($dst$$VectorSRegister, $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0); 14667 %} 14668 ins_pipe(pipe_class_default); 14669 %} 14670 14671 instruct repl2D_immI0(vecX dst, immI_0 zero) %{ 14672 match(Set dst (ReplicateD zero)); 14673 predicate(n->as_Vector()->length() == 2); 14674 14675 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14676 size(4); 14677 ins_encode %{ 14678 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14679 %} 14680 ins_pipe(pipe_class_default); 14681 %} 14682 14683 instruct repl2D_immIminus1(vecX dst, immI_minus1 src) %{ 14684 match(Set dst (ReplicateD src)); 14685 predicate(n->as_Vector()->length() == 2); 14686 14687 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14688 size(4); 14689 ins_encode %{ 14690 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14691 %} 14692 ins_pipe(pipe_class_default); 14693 %} 14694 14695 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14696 predicate(false); 14697 effect(DEF dst, USE src); 14698 14699 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %} 14700 size(4); 14701 ins_encode %{ 14702 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14703 %} 14704 ins_pipe(pipe_class_default); 14705 %} 14706 14707 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14708 effect(DEF dst, USE src, USE zero); 14709 14710 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %} 14711 size(4); 14712 ins_encode %{ 14713 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14714 %} 14715 ins_pipe(pipe_class_default); 14716 %} 14717 14718 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14719 effect(DEF dst, USE src1, USE src2, USE zero); 14720 14721 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %} 14722 size(4); 14723 ins_encode %{ 14724 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14725 %} 14726 ins_pipe(pipe_class_default); 14727 %} 14728 14729 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14730 match(Set dst (ReplicateL src)); 14731 predicate(n->as_Vector()->length() == 2); 14732 expand %{ 14733 vecX tmpV; 14734 immI8 zero %{ (int) 0 %} 14735 mtvsrd(tmpV, src); 14736 xxpermdi(dst, tmpV, tmpV, zero); 14737 %} 14738 %} 14739 14740 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14741 match(Set dst (ReplicateL zero)); 14742 predicate(n->as_Vector()->length() == 2); 14743 14744 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14745 size(4); 14746 ins_encode %{ 14747 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14748 %} 14749 ins_pipe(pipe_class_default); 14750 %} 14751 14752 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14753 match(Set dst (ReplicateL src)); 14754 predicate(n->as_Vector()->length() == 2); 14755 14756 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14757 size(4); 14758 ins_encode %{ 14759 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14760 %} 14761 ins_pipe(pipe_class_default); 14762 %} 14763 14764 // ============================================================================ 14765 // Safepoint Instruction 14766 14767 instruct safePoint_poll(iRegPdst poll) %{ 14768 match(SafePoint poll); 14769 14770 // It caused problems to add the effect that r0 is killed, but this 14771 // effect no longer needs to be mentioned, since r0 is not contained 14772 // in a reg_class. 14773 14774 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14775 size(4); 14776 ins_encode( enc_poll(0x0, poll) ); 14777 ins_pipe(pipe_class_default); 14778 %} 14779 14780 // ============================================================================ 14781 // Call Instructions 14782 14783 // Call Java Static Instruction 14784 14785 // Schedulable version of call static node. 14786 instruct CallStaticJavaDirect(method meth) %{ 14787 match(CallStaticJava); 14788 effect(USE meth); 14789 ins_cost(CALL_COST); 14790 14791 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14792 14793 format %{ "CALL,static $meth \t// ==> " %} 14794 size(4); 14795 ins_encode( enc_java_static_call(meth) ); 14796 ins_pipe(pipe_class_call); 14797 %} 14798 14799 // Call Java Dynamic Instruction 14800 14801 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14802 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14803 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14804 // The call destination must still be placed in the constant pool. 14805 instruct CallDynamicJavaDirectSched(method meth) %{ 14806 match(CallDynamicJava); // To get all the data fields we need ... 14807 effect(USE meth); 14808 predicate(false); // ... but never match. 14809 14810 ins_field_load_ic_hi_node(loadConL_hiNode*); 14811 ins_field_load_ic_node(loadConLNode*); 14812 ins_num_consts(1 /* 1 patchable constant: call destination */); 14813 14814 format %{ "BL \t// dynamic $meth ==> " %} 14815 size(4); 14816 ins_encode( enc_java_dynamic_call_sched(meth) ); 14817 ins_pipe(pipe_class_call); 14818 %} 14819 14820 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14821 // We use postalloc expanded calls if we use inline caches 14822 // and do not update method data. 14823 // 14824 // This instruction has two constants: inline cache (IC) and call destination. 14825 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14826 // one constant. 14827 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14828 match(CallDynamicJava); 14829 effect(USE meth); 14830 predicate(UseInlineCaches); 14831 ins_cost(CALL_COST); 14832 14833 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14834 14835 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14836 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14837 %} 14838 14839 // Compound version of call dynamic java 14840 // We use postalloc expanded calls if we use inline caches 14841 // and do not update method data. 14842 instruct CallDynamicJavaDirect(method meth) %{ 14843 match(CallDynamicJava); 14844 effect(USE meth); 14845 predicate(!UseInlineCaches); 14846 ins_cost(CALL_COST); 14847 14848 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14849 ins_num_consts(4); 14850 14851 format %{ "CALL,dynamic $meth \t// ==> " %} 14852 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14853 ins_pipe(pipe_class_call); 14854 %} 14855 14856 // Call Runtime Instruction 14857 14858 instruct CallRuntimeDirect(method meth) %{ 14859 match(CallRuntime); 14860 effect(USE meth); 14861 ins_cost(CALL_COST); 14862 14863 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14864 // env for callee, C-toc. 14865 ins_num_consts(3); 14866 14867 format %{ "CALL,runtime" %} 14868 ins_encode( enc_java_to_runtime_call(meth) ); 14869 ins_pipe(pipe_class_call); 14870 %} 14871 14872 // Call Leaf 14873 14874 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14875 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14876 effect(DEF dst, USE src); 14877 14878 ins_num_consts(1); 14879 14880 format %{ "MTCTR $src" %} 14881 size(4); 14882 ins_encode( enc_leaf_call_mtctr(src) ); 14883 ins_pipe(pipe_class_default); 14884 %} 14885 14886 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 14887 instruct CallLeafDirect(method meth) %{ 14888 match(CallLeaf); // To get the data all the data fields we need ... 14889 effect(USE meth); 14890 predicate(false); // but never match. 14891 14892 format %{ "BCTRL \t// leaf call $meth ==> " %} 14893 size(4); 14894 ins_encode %{ 14895 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 14896 __ bctrl(); 14897 %} 14898 ins_pipe(pipe_class_call); 14899 %} 14900 14901 // postalloc expand of CallLeafDirect. 14902 // Load adress to call from TOC, then bl to it. 14903 instruct CallLeafDirect_Ex(method meth) %{ 14904 match(CallLeaf); 14905 effect(USE meth); 14906 ins_cost(CALL_COST); 14907 14908 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14909 // env for callee, C-toc. 14910 ins_num_consts(3); 14911 14912 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14913 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14914 %} 14915 14916 // Call runtime without safepoint - same as CallLeaf. 14917 // postalloc expand of CallLeafNoFPDirect. 14918 // Load adress to call from TOC, then bl to it. 14919 instruct CallLeafNoFPDirect_Ex(method meth) %{ 14920 match(CallLeafNoFP); 14921 effect(USE meth); 14922 ins_cost(CALL_COST); 14923 14924 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14925 // env for callee, C-toc. 14926 ins_num_consts(3); 14927 14928 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14929 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14930 %} 14931 14932 // Tail Call; Jump from runtime stub to Java code. 14933 // Also known as an 'interprocedural jump'. 14934 // Target of jump will eventually return to caller. 14935 // TailJump below removes the return address. 14936 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 14937 match(TailCall jump_target method_oop); 14938 ins_cost(CALL_COST); 14939 14940 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 14941 "BCTR \t// tail call" %} 14942 size(8); 14943 ins_encode %{ 14944 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14945 __ mtctr($jump_target$$Register); 14946 __ bctr(); 14947 %} 14948 ins_pipe(pipe_class_call); 14949 %} 14950 14951 // Return Instruction 14952 instruct Ret() %{ 14953 match(Return); 14954 format %{ "BLR \t// branch to link register" %} 14955 size(4); 14956 ins_encode %{ 14957 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 14958 // LR is restored in MachEpilogNode. Just do the RET here. 14959 __ blr(); 14960 %} 14961 ins_pipe(pipe_class_default); 14962 %} 14963 14964 // Tail Jump; remove the return address; jump to target. 14965 // TailCall above leaves the return address around. 14966 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14967 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14968 // "restore" before this instruction (in Epilogue), we need to materialize it 14969 // in %i0. 14970 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14971 match(TailJump jump_target ex_oop); 14972 ins_cost(CALL_COST); 14973 14974 format %{ "LD R4_ARG2 = LR\n\t" 14975 "MTCTR $jump_target\n\t" 14976 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14977 size(12); 14978 ins_encode %{ 14979 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14980 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 14981 __ mtctr($jump_target$$Register); 14982 __ bctr(); 14983 %} 14984 ins_pipe(pipe_class_call); 14985 %} 14986 14987 // Create exception oop: created by stack-crawling runtime code. 14988 // Created exception is now available to this handler, and is setup 14989 // just prior to jumping to this handler. No code emitted. 14990 instruct CreateException(rarg1RegP ex_oop) %{ 14991 match(Set ex_oop (CreateEx)); 14992 ins_cost(0); 14993 14994 format %{ " -- \t// exception oop; no code emitted" %} 14995 size(0); 14996 ins_encode( /*empty*/ ); 14997 ins_pipe(pipe_class_default); 14998 %} 14999 15000 // Rethrow exception: The exception oop will come in the first 15001 // argument position. Then JUMP (not call) to the rethrow stub code. 15002 instruct RethrowException() %{ 15003 match(Rethrow); 15004 ins_cost(CALL_COST); 15005 15006 format %{ "Jmp rethrow_stub" %} 15007 ins_encode %{ 15008 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 15009 cbuf.set_insts_mark(); 15010 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 15011 %} 15012 ins_pipe(pipe_class_call); 15013 %} 15014 15015 // Die now. 15016 instruct ShouldNotReachHere() %{ 15017 match(Halt); 15018 ins_cost(CALL_COST); 15019 15020 format %{ "ShouldNotReachHere" %} 15021 size(4); 15022 ins_encode %{ 15023 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 15024 __ trap_should_not_reach_here(); 15025 %} 15026 ins_pipe(pipe_class_default); 15027 %} 15028 15029 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 15030 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 15031 // Get a DEF on threadRegP, no costs, no encoding, use 15032 // 'ins_should_rematerialize(true)' to avoid spilling. 15033 instruct tlsLoadP(threadRegP dst) %{ 15034 match(Set dst (ThreadLocal)); 15035 ins_cost(0); 15036 15037 ins_should_rematerialize(true); 15038 15039 format %{ " -- \t// $dst=Thread::current(), empty" %} 15040 size(0); 15041 ins_encode( /*empty*/ ); 15042 ins_pipe(pipe_class_empty); 15043 %} 15044 15045 //---Some PPC specific nodes--------------------------------------------------- 15046 15047 // Stop a group. 15048 instruct endGroup() %{ 15049 ins_cost(0); 15050 15051 ins_is_nop(true); 15052 15053 format %{ "End Bundle (ori r1, r1, 0)" %} 15054 size(4); 15055 ins_encode %{ 15056 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 15057 __ endgroup(); 15058 %} 15059 ins_pipe(pipe_class_default); 15060 %} 15061 15062 // Nop instructions 15063 15064 instruct fxNop() %{ 15065 ins_cost(0); 15066 15067 ins_is_nop(true); 15068 15069 format %{ "fxNop" %} 15070 size(4); 15071 ins_encode %{ 15072 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15073 __ nop(); 15074 %} 15075 ins_pipe(pipe_class_default); 15076 %} 15077 15078 instruct fpNop0() %{ 15079 ins_cost(0); 15080 15081 ins_is_nop(true); 15082 15083 format %{ "fpNop0" %} 15084 size(4); 15085 ins_encode %{ 15086 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15087 __ fpnop0(); 15088 %} 15089 ins_pipe(pipe_class_default); 15090 %} 15091 15092 instruct fpNop1() %{ 15093 ins_cost(0); 15094 15095 ins_is_nop(true); 15096 15097 format %{ "fpNop1" %} 15098 size(4); 15099 ins_encode %{ 15100 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15101 __ fpnop1(); 15102 %} 15103 ins_pipe(pipe_class_default); 15104 %} 15105 15106 instruct brNop0() %{ 15107 ins_cost(0); 15108 size(4); 15109 format %{ "brNop0" %} 15110 ins_encode %{ 15111 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15112 __ brnop0(); 15113 %} 15114 ins_is_nop(true); 15115 ins_pipe(pipe_class_default); 15116 %} 15117 15118 instruct brNop1() %{ 15119 ins_cost(0); 15120 15121 ins_is_nop(true); 15122 15123 format %{ "brNop1" %} 15124 size(4); 15125 ins_encode %{ 15126 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15127 __ brnop1(); 15128 %} 15129 ins_pipe(pipe_class_default); 15130 %} 15131 15132 instruct brNop2() %{ 15133 ins_cost(0); 15134 15135 ins_is_nop(true); 15136 15137 format %{ "brNop2" %} 15138 size(4); 15139 ins_encode %{ 15140 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15141 __ brnop2(); 15142 %} 15143 ins_pipe(pipe_class_default); 15144 %} 15145 15146 //----------PEEPHOLE RULES----------------------------------------------------- 15147 // These must follow all instruction definitions as they use the names 15148 // defined in the instructions definitions. 15149 // 15150 // peepmatch ( root_instr_name [preceeding_instruction]* ); 15151 // 15152 // peepconstraint %{ 15153 // (instruction_number.operand_name relational_op instruction_number.operand_name 15154 // [, ...] ); 15155 // // instruction numbers are zero-based using left to right order in peepmatch 15156 // 15157 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 15158 // // provide an instruction_number.operand_name for each operand that appears 15159 // // in the replacement instruction's match rule 15160 // 15161 // ---------VM FLAGS--------------------------------------------------------- 15162 // 15163 // All peephole optimizations can be turned off using -XX:-OptoPeephole 15164 // 15165 // Each peephole rule is given an identifying number starting with zero and 15166 // increasing by one in the order seen by the parser. An individual peephole 15167 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 15168 // on the command-line. 15169 // 15170 // ---------CURRENT LIMITATIONS---------------------------------------------- 15171 // 15172 // Only match adjacent instructions in same basic block 15173 // Only equality constraints 15174 // Only constraints between operands, not (0.dest_reg == EAX_enc) 15175 // Only one replacement instruction 15176 // 15177 // ---------EXAMPLE---------------------------------------------------------- 15178 // 15179 // // pertinent parts of existing instructions in architecture description 15180 // instruct movI(eRegI dst, eRegI src) %{ 15181 // match(Set dst (CopyI src)); 15182 // %} 15183 // 15184 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 15185 // match(Set dst (AddI dst src)); 15186 // effect(KILL cr); 15187 // %} 15188 // 15189 // // Change (inc mov) to lea 15190 // peephole %{ 15191 // // increment preceeded by register-register move 15192 // peepmatch ( incI_eReg movI ); 15193 // // require that the destination register of the increment 15194 // // match the destination register of the move 15195 // peepconstraint ( 0.dst == 1.dst ); 15196 // // construct a replacement instruction that sets 15197 // // the destination to ( move's source register + one ) 15198 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15199 // %} 15200 // 15201 // Implementation no longer uses movX instructions since 15202 // machine-independent system no longer uses CopyX nodes. 15203 // 15204 // peephole %{ 15205 // peepmatch ( incI_eReg movI ); 15206 // peepconstraint ( 0.dst == 1.dst ); 15207 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15208 // %} 15209 // 15210 // peephole %{ 15211 // peepmatch ( decI_eReg movI ); 15212 // peepconstraint ( 0.dst == 1.dst ); 15213 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15214 // %} 15215 // 15216 // peephole %{ 15217 // peepmatch ( addI_eReg_imm movI ); 15218 // peepconstraint ( 0.dst == 1.dst ); 15219 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15220 // %} 15221 // 15222 // peephole %{ 15223 // peepmatch ( addP_eReg_imm movP ); 15224 // peepconstraint ( 0.dst == 1.dst ); 15225 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 15226 // %} 15227 15228 // // Change load of spilled value to only a spill 15229 // instruct storeI(memory mem, eRegI src) %{ 15230 // match(Set mem (StoreI mem src)); 15231 // %} 15232 // 15233 // instruct loadI(eRegI dst, memory mem) %{ 15234 // match(Set dst (LoadI mem)); 15235 // %} 15236 // 15237 peephole %{ 15238 peepmatch ( loadI storeI ); 15239 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15240 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 15241 %} 15242 15243 peephole %{ 15244 peepmatch ( loadL storeL ); 15245 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15246 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 15247 %} 15248 15249 peephole %{ 15250 peepmatch ( loadP storeP ); 15251 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 15252 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 15253 %} 15254 15255 //----------SMARTSPILL RULES--------------------------------------------------- 15256 // These must follow all instruction definitions as they use the names 15257 // defined in the instructions definitions.