1 // 2 // Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2017 SAP SE. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // 27 // PPC64 Architecture Description File 28 // 29 30 //----------REGISTER DEFINITION BLOCK------------------------------------------ 31 // This information is used by the matcher and the register allocator to 32 // describe individual registers and classes of registers within the target 33 // architecture. 34 register %{ 35 //----------Architecture Description Register Definitions---------------------- 36 // General Registers 37 // "reg_def" name (register save type, C convention save type, 38 // ideal register type, encoding); 39 // 40 // Register Save Types: 41 // 42 // NS = No-Save: The register allocator assumes that these registers 43 // can be used without saving upon entry to the method, & 44 // that they do not need to be saved at call sites. 45 // 46 // SOC = Save-On-Call: The register allocator assumes that these registers 47 // can be used without saving upon entry to the method, 48 // but that they must be saved at call sites. 49 // These are called "volatiles" on ppc. 50 // 51 // SOE = Save-On-Entry: The register allocator assumes that these registers 52 // must be saved before using them upon entry to the 53 // method, but they do not need to be saved at call 54 // sites. 55 // These are called "nonvolatiles" on ppc. 56 // 57 // AS = Always-Save: The register allocator assumes that these registers 58 // must be saved before using them upon entry to the 59 // method, & that they must be saved at call sites. 60 // 61 // Ideal Register Type is used to determine how to save & restore a 62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 64 // 65 // The encoding number is the actual bit-pattern placed into the opcodes. 66 // 67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI 68 // Supplement Version 1.7 as of 2003-10-29. 69 // 70 // For each 64-bit register we must define two registers: the register 71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half', 72 // e.g. R3_H, which is needed by the allocator, but is not used 73 // for stores, loads, etc. 74 75 // ---------------------------- 76 // Integer/Long Registers 77 // ---------------------------- 78 79 // PPC64 has 32 64-bit integer registers. 80 81 // types: v = volatile, nv = non-volatile, s = system 82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs 83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() ); 84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP 85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() ); 86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC 87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() ); 88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret 89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() ); 90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2 91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() ); 92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3 93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() ); 94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4 95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() ); 96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5 97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() ); 98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6 99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() ); 100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7 101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() ); 102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8 103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next()); 104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch 105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next()); 106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch 107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next()); 108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id 109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next()); 110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv 111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next()); 112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv 113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next()); 114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv 115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next()); 116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv 117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next()); 118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv 119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next()); 120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv 121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next()); 122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv 123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next()); 124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv 125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next()); 126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv 127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next()); 128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv 129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next()); 130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv 131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next()); 132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv 133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next()); 134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv 135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next()); 136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv 137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next()); 138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv 139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next()); 140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv 141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next()); 142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv 143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next()); 144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv 145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next()); 146 147 148 // ---------------------------- 149 // Float/Double Registers 150 // ---------------------------- 151 152 // Double Registers 153 // The rules of ADL require that double registers be defined in pairs. 154 // Each pair must be two 32-bit values, but not necessarily a pair of 155 // single float registers. In each pair, ADLC-assigned register numbers 156 // must be adjacent, with the lower number even. Finally, when the 157 // CPU stores such a register pair to memory, the word associated with 158 // the lower ADLC-assigned number must be stored to the lower address. 159 160 // PPC64 has 32 64-bit floating-point registers. Each can store a single 161 // or double precision floating-point value. 162 163 // types: v = volatile, nv = non-volatile, s = system 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch 165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret 167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2 169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3 171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4 173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5 175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6 177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7 179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8 181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9 183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10 185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next()); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11 187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next()); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12 189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next()); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13 191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next()); 192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv 193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next()); 194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv 195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next()); 196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv 197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next()); 198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv 199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next()); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv 201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next()); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv 203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next()); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv 205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next()); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv 207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next()); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv 209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next()); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv 211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next()); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv 213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next()); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv 215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next()); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv 217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next()); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv 219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next()); 220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv 221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next()); 222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv 223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next()); 224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv 225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next()); 226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv 227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next()); 228 229 // ---------------------------- 230 // Special Registers 231 // ---------------------------- 232 233 // Condition Codes Flag Registers 234 235 // PPC64 has 8 condition code "registers" which are all contained 236 // in the CR register. 237 238 // types: v = volatile, nv = non-volatile, s = system 239 reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v 240 reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v 241 reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv 242 reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv 243 reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv 244 reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v 245 reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v 246 reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg()); // v 247 248 // Special registers of PPC64 249 250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v 251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v 252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v 253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v 254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v 255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v 256 257 // ---------------------------- 258 // Vector-Scalar Registers 259 // ---------------------------- 260 reg_def VSR0 ( SOC, SOC, Op_VecX, 0, NULL); 261 reg_def VSR1 ( SOC, SOC, Op_VecX, 1, NULL); 262 reg_def VSR2 ( SOC, SOC, Op_VecX, 2, NULL); 263 reg_def VSR3 ( SOC, SOC, Op_VecX, 3, NULL); 264 reg_def VSR4 ( SOC, SOC, Op_VecX, 4, NULL); 265 reg_def VSR5 ( SOC, SOC, Op_VecX, 5, NULL); 266 reg_def VSR6 ( SOC, SOC, Op_VecX, 6, NULL); 267 reg_def VSR7 ( SOC, SOC, Op_VecX, 7, NULL); 268 reg_def VSR8 ( SOC, SOC, Op_VecX, 8, NULL); 269 reg_def VSR9 ( SOC, SOC, Op_VecX, 9, NULL); 270 reg_def VSR10 ( SOC, SOC, Op_VecX, 10, NULL); 271 reg_def VSR11 ( SOC, SOC, Op_VecX, 11, NULL); 272 reg_def VSR12 ( SOC, SOC, Op_VecX, 12, NULL); 273 reg_def VSR13 ( SOC, SOC, Op_VecX, 13, NULL); 274 reg_def VSR14 ( SOC, SOC, Op_VecX, 14, NULL); 275 reg_def VSR15 ( SOC, SOC, Op_VecX, 15, NULL); 276 reg_def VSR16 ( SOC, SOC, Op_VecX, 16, NULL); 277 reg_def VSR17 ( SOC, SOC, Op_VecX, 17, NULL); 278 reg_def VSR18 ( SOC, SOC, Op_VecX, 18, NULL); 279 reg_def VSR19 ( SOC, SOC, Op_VecX, 19, NULL); 280 reg_def VSR20 ( SOC, SOC, Op_VecX, 20, NULL); 281 reg_def VSR21 ( SOC, SOC, Op_VecX, 21, NULL); 282 reg_def VSR22 ( SOC, SOC, Op_VecX, 22, NULL); 283 reg_def VSR23 ( SOC, SOC, Op_VecX, 23, NULL); 284 reg_def VSR24 ( SOC, SOC, Op_VecX, 24, NULL); 285 reg_def VSR25 ( SOC, SOC, Op_VecX, 25, NULL); 286 reg_def VSR26 ( SOC, SOC, Op_VecX, 26, NULL); 287 reg_def VSR27 ( SOC, SOC, Op_VecX, 27, NULL); 288 reg_def VSR28 ( SOC, SOC, Op_VecX, 28, NULL); 289 reg_def VSR29 ( SOC, SOC, Op_VecX, 29, NULL); 290 reg_def VSR30 ( SOC, SOC, Op_VecX, 30, NULL); 291 reg_def VSR31 ( SOC, SOC, Op_VecX, 31, NULL); 292 reg_def VSR32 ( SOC, SOC, Op_VecX, 32, NULL); 293 reg_def VSR33 ( SOC, SOC, Op_VecX, 33, NULL); 294 reg_def VSR34 ( SOC, SOC, Op_VecX, 34, NULL); 295 reg_def VSR35 ( SOC, SOC, Op_VecX, 35, NULL); 296 reg_def VSR36 ( SOC, SOC, Op_VecX, 36, NULL); 297 reg_def VSR37 ( SOC, SOC, Op_VecX, 37, NULL); 298 reg_def VSR38 ( SOC, SOC, Op_VecX, 38, NULL); 299 reg_def VSR39 ( SOC, SOC, Op_VecX, 39, NULL); 300 reg_def VSR40 ( SOC, SOC, Op_VecX, 40, NULL); 301 reg_def VSR41 ( SOC, SOC, Op_VecX, 41, NULL); 302 reg_def VSR42 ( SOC, SOC, Op_VecX, 42, NULL); 303 reg_def VSR43 ( SOC, SOC, Op_VecX, 43, NULL); 304 reg_def VSR44 ( SOC, SOC, Op_VecX, 44, NULL); 305 reg_def VSR45 ( SOC, SOC, Op_VecX, 45, NULL); 306 reg_def VSR46 ( SOC, SOC, Op_VecX, 46, NULL); 307 reg_def VSR47 ( SOC, SOC, Op_VecX, 47, NULL); 308 reg_def VSR48 ( SOC, SOC, Op_VecX, 48, NULL); 309 reg_def VSR49 ( SOC, SOC, Op_VecX, 49, NULL); 310 reg_def VSR50 ( SOC, SOC, Op_VecX, 50, NULL); 311 reg_def VSR51 ( SOC, SOC, Op_VecX, 51, NULL); 312 reg_def VSR52 ( SOC, SOC, Op_VecX, 52, NULL); 313 reg_def VSR53 ( SOC, SOC, Op_VecX, 53, NULL); 314 reg_def VSR54 ( SOC, SOC, Op_VecX, 54, NULL); 315 reg_def VSR55 ( SOC, SOC, Op_VecX, 55, NULL); 316 reg_def VSR56 ( SOC, SOC, Op_VecX, 56, NULL); 317 reg_def VSR57 ( SOC, SOC, Op_VecX, 57, NULL); 318 reg_def VSR58 ( SOC, SOC, Op_VecX, 58, NULL); 319 reg_def VSR59 ( SOC, SOC, Op_VecX, 59, NULL); 320 reg_def VSR60 ( SOC, SOC, Op_VecX, 60, NULL); 321 reg_def VSR61 ( SOC, SOC, Op_VecX, 61, NULL); 322 reg_def VSR62 ( SOC, SOC, Op_VecX, 62, NULL); 323 reg_def VSR63 ( SOC, SOC, Op_VecX, 63, NULL); 324 325 // ---------------------------- 326 // Specify priority of register selection within phases of register 327 // allocation. Highest priority is first. A useful heuristic is to 328 // give registers a low priority when they are required by machine 329 // instructions, like EAX and EDX on I486, and choose no-save registers 330 // before save-on-call, & save-on-call before save-on-entry. Registers 331 // which participate in fixed calling sequences should come last. 332 // Registers which are used as pairs must fall on an even boundary. 333 334 // It's worth about 1% on SPEC geomean to get this right. 335 336 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 337 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 338 // R3_num. Therefore, R3_num may not be (and in reality is not) 339 // the same as R3->encoding()! Furthermore, we cannot make any 340 // assumptions on ordering, e.g. R3_num may be less than R2_num. 341 // Additionally, the function 342 // static enum RC rc_class(OptoReg::Name reg ) 343 // maps a given <register>_num value to its chunk type (except for flags) 344 // and its current implementation relies on chunk0 and chunk1 having a 345 // size of 64 each. 346 347 // If you change this allocation class, please have a look at the 348 // default values for the parameters RoundRobinIntegerRegIntervalStart 349 // and RoundRobinFloatRegIntervalStart 350 351 alloc_class chunk0 ( 352 // Chunk0 contains *all* 64 integer registers halves. 353 354 // "non-volatile" registers 355 R14, R14_H, 356 R15, R15_H, 357 R17, R17_H, 358 R18, R18_H, 359 R19, R19_H, 360 R20, R20_H, 361 R21, R21_H, 362 R22, R22_H, 363 R23, R23_H, 364 R24, R24_H, 365 R25, R25_H, 366 R26, R26_H, 367 R27, R27_H, 368 R28, R28_H, 369 R29, R29_H, 370 R30, R30_H, 371 R31, R31_H, 372 373 // scratch/special registers 374 R11, R11_H, 375 R12, R12_H, 376 377 // argument registers 378 R10, R10_H, 379 R9, R9_H, 380 R8, R8_H, 381 R7, R7_H, 382 R6, R6_H, 383 R5, R5_H, 384 R4, R4_H, 385 R3, R3_H, 386 387 // special registers, not available for allocation 388 R16, R16_H, // R16_thread 389 R13, R13_H, // system thread id 390 R2, R2_H, // may be used for TOC 391 R1, R1_H, // SP 392 R0, R0_H // R0 (scratch) 393 ); 394 395 // If you change this allocation class, please have a look at the 396 // default values for the parameters RoundRobinIntegerRegIntervalStart 397 // and RoundRobinFloatRegIntervalStart 398 399 alloc_class chunk1 ( 400 // Chunk1 contains *all* 64 floating-point registers halves. 401 402 // scratch register 403 F0, F0_H, 404 405 // argument registers 406 F13, F13_H, 407 F12, F12_H, 408 F11, F11_H, 409 F10, F10_H, 410 F9, F9_H, 411 F8, F8_H, 412 F7, F7_H, 413 F6, F6_H, 414 F5, F5_H, 415 F4, F4_H, 416 F3, F3_H, 417 F2, F2_H, 418 F1, F1_H, 419 420 // non-volatile registers 421 F14, F14_H, 422 F15, F15_H, 423 F16, F16_H, 424 F17, F17_H, 425 F18, F18_H, 426 F19, F19_H, 427 F20, F20_H, 428 F21, F21_H, 429 F22, F22_H, 430 F23, F23_H, 431 F24, F24_H, 432 F25, F25_H, 433 F26, F26_H, 434 F27, F27_H, 435 F28, F28_H, 436 F29, F29_H, 437 F30, F30_H, 438 F31, F31_H 439 ); 440 441 alloc_class chunk2 ( 442 // Chunk2 contains *all* 8 condition code registers. 443 444 CCR0, 445 CCR1, 446 CCR2, 447 CCR3, 448 CCR4, 449 CCR5, 450 CCR6, 451 CCR7 452 ); 453 454 alloc_class chunk3 ( 455 VSR0, 456 VSR1, 457 VSR2, 458 VSR3, 459 VSR4, 460 VSR5, 461 VSR6, 462 VSR7, 463 VSR8, 464 VSR9, 465 VSR10, 466 VSR11, 467 VSR12, 468 VSR13, 469 VSR14, 470 VSR15, 471 VSR16, 472 VSR17, 473 VSR18, 474 VSR19, 475 VSR20, 476 VSR21, 477 VSR22, 478 VSR23, 479 VSR24, 480 VSR25, 481 VSR26, 482 VSR27, 483 VSR28, 484 VSR29, 485 VSR30, 486 VSR31, 487 VSR32, 488 VSR33, 489 VSR34, 490 VSR35, 491 VSR36, 492 VSR37, 493 VSR38, 494 VSR39, 495 VSR40, 496 VSR41, 497 VSR42, 498 VSR43, 499 VSR44, 500 VSR45, 501 VSR46, 502 VSR47, 503 VSR48, 504 VSR49, 505 VSR50, 506 VSR51, 507 VSR52, 508 VSR53, 509 VSR54, 510 VSR55, 511 VSR56, 512 VSR57, 513 VSR58, 514 VSR59, 515 VSR60, 516 VSR61, 517 VSR62, 518 VSR63 519 ); 520 521 alloc_class chunk4 ( 522 // special registers 523 // These registers are not allocated, but used for nodes generated by postalloc expand. 524 SR_XER, 525 SR_LR, 526 SR_CTR, 527 SR_VRSAVE, 528 SR_SPEFSCR, 529 SR_PPR 530 ); 531 532 //-------Architecture Description Register Classes----------------------- 533 534 // Several register classes are automatically defined based upon 535 // information in this architecture description. 536 537 // 1) reg_class inline_cache_reg ( as defined in frame section ) 538 // 2) reg_class compiler_method_oop_reg ( as defined in frame section ) 539 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 540 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 541 // 542 543 // ---------------------------- 544 // 32 Bit Register Classes 545 // ---------------------------- 546 547 // We specify registers twice, once as read/write, and once read-only. 548 // We use the read-only registers for source operands. With this, we 549 // can include preset read only registers in this class, as a hard-coded 550 // '0'-register. (We used to simulate this on ppc.) 551 552 // 32 bit registers that can be read and written i.e. these registers 553 // can be dest (or src) of normal instructions. 554 reg_class bits32_reg_rw( 555 /*R0*/ // R0 556 /*R1*/ // SP 557 R2, // TOC 558 R3, 559 R4, 560 R5, 561 R6, 562 R7, 563 R8, 564 R9, 565 R10, 566 R11, 567 R12, 568 /*R13*/ // system thread id 569 R14, 570 R15, 571 /*R16*/ // R16_thread 572 R17, 573 R18, 574 R19, 575 R20, 576 R21, 577 R22, 578 R23, 579 R24, 580 R25, 581 R26, 582 R27, 583 R28, 584 /*R29,*/ // global TOC 585 R30, 586 R31 587 ); 588 589 // 32 bit registers that can only be read i.e. these registers can 590 // only be src of all instructions. 591 reg_class bits32_reg_ro( 592 /*R0*/ // R0 593 /*R1*/ // SP 594 R2 // TOC 595 R3, 596 R4, 597 R5, 598 R6, 599 R7, 600 R8, 601 R9, 602 R10, 603 R11, 604 R12, 605 /*R13*/ // system thread id 606 R14, 607 R15, 608 /*R16*/ // R16_thread 609 R17, 610 R18, 611 R19, 612 R20, 613 R21, 614 R22, 615 R23, 616 R24, 617 R25, 618 R26, 619 R27, 620 R28, 621 /*R29,*/ 622 R30, 623 R31 624 ); 625 626 reg_class rscratch1_bits32_reg(R11); 627 reg_class rscratch2_bits32_reg(R12); 628 reg_class rarg1_bits32_reg(R3); 629 reg_class rarg2_bits32_reg(R4); 630 reg_class rarg3_bits32_reg(R5); 631 reg_class rarg4_bits32_reg(R6); 632 633 // ---------------------------- 634 // 64 Bit Register Classes 635 // ---------------------------- 636 // 64-bit build means 64-bit pointers means hi/lo pairs 637 638 reg_class rscratch1_bits64_reg(R11_H, R11); 639 reg_class rscratch2_bits64_reg(R12_H, R12); 640 reg_class rarg1_bits64_reg(R3_H, R3); 641 reg_class rarg2_bits64_reg(R4_H, R4); 642 reg_class rarg3_bits64_reg(R5_H, R5); 643 reg_class rarg4_bits64_reg(R6_H, R6); 644 // Thread register, 'written' by tlsLoadP, see there. 645 reg_class thread_bits64_reg(R16_H, R16); 646 647 reg_class r19_bits64_reg(R19_H, R19); 648 649 // 64 bit registers that can be read and written i.e. these registers 650 // can be dest (or src) of normal instructions. 651 reg_class bits64_reg_rw( 652 /*R0_H, R0*/ // R0 653 /*R1_H, R1*/ // SP 654 R2_H, R2, // TOC 655 R3_H, R3, 656 R4_H, R4, 657 R5_H, R5, 658 R6_H, R6, 659 R7_H, R7, 660 R8_H, R8, 661 R9_H, R9, 662 R10_H, R10, 663 R11_H, R11, 664 R12_H, R12, 665 /*R13_H, R13*/ // system thread id 666 R14_H, R14, 667 R15_H, R15, 668 /*R16_H, R16*/ // R16_thread 669 R17_H, R17, 670 R18_H, R18, 671 R19_H, R19, 672 R20_H, R20, 673 R21_H, R21, 674 R22_H, R22, 675 R23_H, R23, 676 R24_H, R24, 677 R25_H, R25, 678 R26_H, R26, 679 R27_H, R27, 680 R28_H, R28, 681 /*R29_H, R29,*/ 682 R30_H, R30, 683 R31_H, R31 684 ); 685 686 // 64 bit registers used excluding r2, r11 and r12 687 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses 688 // r2, r11 and r12 internally. 689 reg_class bits64_reg_leaf_call( 690 /*R0_H, R0*/ // R0 691 /*R1_H, R1*/ // SP 692 /*R2_H, R2*/ // TOC 693 R3_H, R3, 694 R4_H, R4, 695 R5_H, R5, 696 R6_H, R6, 697 R7_H, R7, 698 R8_H, R8, 699 R9_H, R9, 700 R10_H, R10, 701 /*R11_H, R11*/ 702 /*R12_H, R12*/ 703 /*R13_H, R13*/ // system thread id 704 R14_H, R14, 705 R15_H, R15, 706 /*R16_H, R16*/ // R16_thread 707 R17_H, R17, 708 R18_H, R18, 709 R19_H, R19, 710 R20_H, R20, 711 R21_H, R21, 712 R22_H, R22, 713 R23_H, R23, 714 R24_H, R24, 715 R25_H, R25, 716 R26_H, R26, 717 R27_H, R27, 718 R28_H, R28, 719 /*R29_H, R29,*/ 720 R30_H, R30, 721 R31_H, R31 722 ); 723 724 // Used to hold the TOC to avoid collisions with expanded DynamicCall 725 // which uses r19 as inline cache internally and expanded LeafCall which uses 726 // r2, r11 and r12 internally. 727 reg_class bits64_constant_table_base( 728 /*R0_H, R0*/ // R0 729 /*R1_H, R1*/ // SP 730 /*R2_H, R2*/ // TOC 731 R3_H, R3, 732 R4_H, R4, 733 R5_H, R5, 734 R6_H, R6, 735 R7_H, R7, 736 R8_H, R8, 737 R9_H, R9, 738 R10_H, R10, 739 /*R11_H, R11*/ 740 /*R12_H, R12*/ 741 /*R13_H, R13*/ // system thread id 742 R14_H, R14, 743 R15_H, R15, 744 /*R16_H, R16*/ // R16_thread 745 R17_H, R17, 746 R18_H, R18, 747 /*R19_H, R19*/ 748 R20_H, R20, 749 R21_H, R21, 750 R22_H, R22, 751 R23_H, R23, 752 R24_H, R24, 753 R25_H, R25, 754 R26_H, R26, 755 R27_H, R27, 756 R28_H, R28, 757 /*R29_H, R29,*/ 758 R30_H, R30, 759 R31_H, R31 760 ); 761 762 // 64 bit registers that can only be read i.e. these registers can 763 // only be src of all instructions. 764 reg_class bits64_reg_ro( 765 /*R0_H, R0*/ // R0 766 R1_H, R1, 767 R2_H, R2, // TOC 768 R3_H, R3, 769 R4_H, R4, 770 R5_H, R5, 771 R6_H, R6, 772 R7_H, R7, 773 R8_H, R8, 774 R9_H, R9, 775 R10_H, R10, 776 R11_H, R11, 777 R12_H, R12, 778 /*R13_H, R13*/ // system thread id 779 R14_H, R14, 780 R15_H, R15, 781 R16_H, R16, // R16_thread 782 R17_H, R17, 783 R18_H, R18, 784 R19_H, R19, 785 R20_H, R20, 786 R21_H, R21, 787 R22_H, R22, 788 R23_H, R23, 789 R24_H, R24, 790 R25_H, R25, 791 R26_H, R26, 792 R27_H, R27, 793 R28_H, R28, 794 /*R29_H, R29,*/ // TODO: let allocator handle TOC!! 795 R30_H, R30, 796 R31_H, R31 797 ); 798 799 800 // ---------------------------- 801 // Special Class for Condition Code Flags Register 802 803 reg_class int_flags( 804 /*CCR0*/ // scratch 805 /*CCR1*/ // scratch 806 /*CCR2*/ // nv! 807 /*CCR3*/ // nv! 808 /*CCR4*/ // nv! 809 CCR5, 810 CCR6, 811 CCR7 812 ); 813 814 reg_class int_flags_ro( 815 CCR0, 816 CCR1, 817 CCR2, 818 CCR3, 819 CCR4, 820 CCR5, 821 CCR6, 822 CCR7 823 ); 824 825 reg_class int_flags_CR0(CCR0); 826 reg_class int_flags_CR1(CCR1); 827 reg_class int_flags_CR6(CCR6); 828 reg_class ctr_reg(SR_CTR); 829 830 // ---------------------------- 831 // Float Register Classes 832 // ---------------------------- 833 834 reg_class flt_reg( 835 F0, 836 F1, 837 F2, 838 F3, 839 F4, 840 F5, 841 F6, 842 F7, 843 F8, 844 F9, 845 F10, 846 F11, 847 F12, 848 F13, 849 F14, // nv! 850 F15, // nv! 851 F16, // nv! 852 F17, // nv! 853 F18, // nv! 854 F19, // nv! 855 F20, // nv! 856 F21, // nv! 857 F22, // nv! 858 F23, // nv! 859 F24, // nv! 860 F25, // nv! 861 F26, // nv! 862 F27, // nv! 863 F28, // nv! 864 F29, // nv! 865 F30, // nv! 866 F31 // nv! 867 ); 868 869 // Double precision float registers have virtual `high halves' that 870 // are needed by the allocator. 871 reg_class dbl_reg( 872 F0, F0_H, 873 F1, F1_H, 874 F2, F2_H, 875 F3, F3_H, 876 F4, F4_H, 877 F5, F5_H, 878 F6, F6_H, 879 F7, F7_H, 880 F8, F8_H, 881 F9, F9_H, 882 F10, F10_H, 883 F11, F11_H, 884 F12, F12_H, 885 F13, F13_H, 886 F14, F14_H, // nv! 887 F15, F15_H, // nv! 888 F16, F16_H, // nv! 889 F17, F17_H, // nv! 890 F18, F18_H, // nv! 891 F19, F19_H, // nv! 892 F20, F20_H, // nv! 893 F21, F21_H, // nv! 894 F22, F22_H, // nv! 895 F23, F23_H, // nv! 896 F24, F24_H, // nv! 897 F25, F25_H, // nv! 898 F26, F26_H, // nv! 899 F27, F27_H, // nv! 900 F28, F28_H, // nv! 901 F29, F29_H, // nv! 902 F30, F30_H, // nv! 903 F31, F31_H // nv! 904 ); 905 906 // ---------------------------- 907 // Vector-Scalar Register Class 908 // ---------------------------- 909 910 reg_class vs_reg( 911 // Attention: Only these ones are saved & restored at safepoint by RegisterSaver. 912 VSR32, 913 VSR33, 914 VSR34, 915 VSR35, 916 VSR36, 917 VSR37, 918 VSR38, 919 VSR39, 920 VSR40, 921 VSR41, 922 VSR42, 923 VSR43, 924 VSR44, 925 VSR45, 926 VSR46, 927 VSR47, 928 VSR48, 929 VSR49, 930 VSR50, 931 VSR51 932 // VSR52-VSR63 // nv! 933 ); 934 935 %} 936 937 //----------DEFINITION BLOCK--------------------------------------------------- 938 // Define name --> value mappings to inform the ADLC of an integer valued name 939 // Current support includes integer values in the range [0, 0x7FFFFFFF] 940 // Format: 941 // int_def <name> ( <int_value>, <expression>); 942 // Generated Code in ad_<arch>.hpp 943 // #define <name> (<expression>) 944 // // value == <int_value> 945 // Generated code in ad_<arch>.cpp adlc_verification() 946 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 947 // 948 definitions %{ 949 // The default cost (of an ALU instruction). 950 int_def DEFAULT_COST_LOW ( 30, 30); 951 int_def DEFAULT_COST ( 100, 100); 952 int_def HUGE_COST (1000000, 1000000); 953 954 // Memory refs 955 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 956 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 957 958 // Branches are even more expensive. 959 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 960 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 961 %} 962 963 964 //----------SOURCE BLOCK------------------------------------------------------- 965 // This is a block of C++ code which provides values, functions, and 966 // definitions necessary in the rest of the architecture description. 967 source_hpp %{ 968 // Header information of the source block. 969 // Method declarations/definitions which are used outside 970 // the ad-scope can conveniently be defined here. 971 // 972 // To keep related declarations/definitions/uses close together, 973 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 974 975 // Returns true if Node n is followed by a MemBar node that 976 // will do an acquire. If so, this node must not do the acquire 977 // operation. 978 bool followed_by_acquire(const Node *n); 979 %} 980 981 source %{ 982 983 // Should the Matcher clone shifts on addressing modes, expecting them 984 // to be subsumed into complex addressing expressions or compute them 985 // into registers? 986 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 987 return clone_base_plus_offset_address(m, mstack, address_visited); 988 } 989 990 void Compile::reshape_address(AddPNode* addp) { 991 } 992 993 // Optimize load-acquire. 994 // 995 // Check if acquire is unnecessary due to following operation that does 996 // acquire anyways. 997 // Walk the pattern: 998 // 999 // n: Load.acq 1000 // | 1001 // MemBarAcquire 1002 // | | 1003 // Proj(ctrl) Proj(mem) 1004 // | | 1005 // MemBarRelease/Volatile 1006 // 1007 bool followed_by_acquire(const Node *load) { 1008 assert(load->is_Load(), "So far implemented only for loads."); 1009 1010 // Find MemBarAcquire. 1011 const Node *mba = NULL; 1012 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 1013 const Node *out = load->fast_out(i); 1014 if (out->Opcode() == Op_MemBarAcquire) { 1015 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 1016 mba = out; 1017 break; 1018 } 1019 } 1020 if (!mba) return false; 1021 1022 // Find following MemBar node. 1023 // 1024 // The following node must be reachable by control AND memory 1025 // edge to assure no other operations are in between the two nodes. 1026 // 1027 // So first get the Proj node, mem_proj, to use it to iterate forward. 1028 Node *mem_proj = NULL; 1029 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 1030 mem_proj = mba->fast_out(i); // Runs out of bounds and asserts if Proj not found. 1031 assert(mem_proj->is_Proj(), "only projections here"); 1032 ProjNode *proj = mem_proj->as_Proj(); 1033 if (proj->_con == TypeFunc::Memory && 1034 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 1035 break; 1036 } 1037 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 1038 1039 // Search MemBar behind Proj. If there are other memory operations 1040 // behind the Proj we lost. 1041 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 1042 Node *x = mem_proj->fast_out(j); 1043 // Proj might have an edge to a store or load node which precedes the membar. 1044 if (x->is_Mem()) return false; 1045 1046 // On PPC64 release and volatile are implemented by an instruction 1047 // that also has acquire semantics. I.e. there is no need for an 1048 // acquire before these. 1049 int xop = x->Opcode(); 1050 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 1051 // Make sure we're not missing Call/Phi/MergeMem by checking 1052 // control edges. The control edge must directly lead back 1053 // to the MemBarAcquire 1054 Node *ctrl_proj = x->in(0); 1055 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 1056 return true; 1057 } 1058 } 1059 } 1060 1061 return false; 1062 } 1063 1064 #define __ _masm. 1065 1066 // Tertiary op of a LoadP or StoreP encoding. 1067 #define REGP_OP true 1068 1069 // **************************************************************************** 1070 1071 // REQUIRED FUNCTIONALITY 1072 1073 // !!!!! Special hack to get all type of calls to specify the byte offset 1074 // from the start of the call to the point where the return address 1075 // will point. 1076 1077 // PPC port: Removed use of lazy constant construct. 1078 1079 int MachCallStaticJavaNode::ret_addr_offset() { 1080 // It's only a single branch-and-link instruction. 1081 return 4; 1082 } 1083 1084 int MachCallDynamicJavaNode::ret_addr_offset() { 1085 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 1086 // postalloc expanded calls if we use inline caches and do not update method data. 1087 if (UseInlineCaches) 1088 return 4; 1089 1090 int vtable_index = this->_vtable_index; 1091 if (vtable_index < 0) { 1092 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 1093 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 1094 return 12; 1095 } else { 1096 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 1097 return 24; 1098 } 1099 } 1100 1101 int MachCallRuntimeNode::ret_addr_offset() { 1102 #if defined(ABI_ELFv2) 1103 return 28; 1104 #else 1105 return 40; 1106 #endif 1107 } 1108 1109 //============================================================================= 1110 1111 // condition code conversions 1112 1113 static int cc_to_boint(int cc) { 1114 return Assembler::bcondCRbiIs0 | (cc & 8); 1115 } 1116 1117 static int cc_to_inverse_boint(int cc) { 1118 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 1119 } 1120 1121 static int cc_to_biint(int cc, int flags_reg) { 1122 return (flags_reg << 2) | (cc & 3); 1123 } 1124 1125 //============================================================================= 1126 1127 // Compute padding required for nodes which need alignment. The padding 1128 // is the number of bytes (not instructions) which will be inserted before 1129 // the instruction. The padding must match the size of a NOP instruction. 1130 1131 // Currently not used on this platform. 1132 1133 //============================================================================= 1134 1135 // Indicate if the safepoint node needs the polling page as an input. 1136 bool SafePointNode::needs_polling_address_input() { 1137 // The address is loaded from thread by a seperate node. 1138 return true; 1139 } 1140 1141 //============================================================================= 1142 1143 // Emit an interrupt that is caught by the debugger (for debugging compiler). 1144 void emit_break(CodeBuffer &cbuf) { 1145 MacroAssembler _masm(&cbuf); 1146 __ illtrap(); 1147 } 1148 1149 #ifndef PRODUCT 1150 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1151 st->print("BREAKPOINT"); 1152 } 1153 #endif 1154 1155 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1156 emit_break(cbuf); 1157 } 1158 1159 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1160 return MachNode::size(ra_); 1161 } 1162 1163 //============================================================================= 1164 1165 void emit_nop(CodeBuffer &cbuf) { 1166 MacroAssembler _masm(&cbuf); 1167 __ nop(); 1168 } 1169 1170 static inline void emit_long(CodeBuffer &cbuf, int value) { 1171 *((int*)(cbuf.insts_end())) = value; 1172 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1173 } 1174 1175 //============================================================================= 1176 1177 %} // interrupt source 1178 1179 source_hpp %{ // Header information of the source block. 1180 1181 //-------------------------------------------------------------- 1182 //---< Used for optimization in Compile::Shorten_branches >--- 1183 //-------------------------------------------------------------- 1184 1185 class CallStubImpl { 1186 1187 public: 1188 1189 // Emit call stub, compiled java to interpreter. 1190 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1191 1192 // Size of call trampoline stub. 1193 // This doesn't need to be accurate to the byte, but it 1194 // must be larger than or equal to the real size of the stub. 1195 static uint size_call_trampoline() { 1196 return MacroAssembler::trampoline_stub_size; 1197 } 1198 1199 // number of relocations needed by a call trampoline stub 1200 static uint reloc_call_trampoline() { 1201 return 5; 1202 } 1203 1204 }; 1205 1206 %} // end source_hpp 1207 1208 source %{ 1209 1210 // Emit a trampoline stub for a call to a target which is too far away. 1211 // 1212 // code sequences: 1213 // 1214 // call-site: 1215 // branch-and-link to <destination> or <trampoline stub> 1216 // 1217 // Related trampoline stub for this call-site in the stub section: 1218 // load the call target from the constant pool 1219 // branch via CTR (LR/link still points to the call-site above) 1220 1221 void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1222 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1223 if (stub == NULL) { 1224 ciEnv::current()->record_out_of_memory_failure(); 1225 } 1226 } 1227 1228 //============================================================================= 1229 1230 // Emit an inline branch-and-link call and a related trampoline stub. 1231 // 1232 // code sequences: 1233 // 1234 // call-site: 1235 // branch-and-link to <destination> or <trampoline stub> 1236 // 1237 // Related trampoline stub for this call-site in the stub section: 1238 // load the call target from the constant pool 1239 // branch via CTR (LR/link still points to the call-site above) 1240 // 1241 1242 typedef struct { 1243 int insts_call_instruction_offset; 1244 int ret_addr_offset; 1245 } EmitCallOffsets; 1246 1247 // Emit a branch-and-link instruction that branches to a trampoline. 1248 // - Remember the offset of the branch-and-link instruction. 1249 // - Add a relocation at the branch-and-link instruction. 1250 // - Emit a branch-and-link. 1251 // - Remember the return pc offset. 1252 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1253 EmitCallOffsets offsets = { -1, -1 }; 1254 const int start_offset = __ offset(); 1255 offsets.insts_call_instruction_offset = __ offset(); 1256 1257 // No entry point given, use the current pc. 1258 if (entry_point == NULL) entry_point = __ pc(); 1259 1260 // Put the entry point as a constant into the constant pool. 1261 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1262 if (entry_point_toc_addr == NULL) { 1263 ciEnv::current()->record_out_of_memory_failure(); 1264 return offsets; 1265 } 1266 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1267 1268 // Emit the trampoline stub which will be related to the branch-and-link below. 1269 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1270 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1271 __ relocate(rtype); 1272 1273 // Note: At this point we do not have the address of the trampoline 1274 // stub, and the entry point might be too far away for bl, so __ pc() 1275 // serves as dummy and the bl will be patched later. 1276 __ bl((address) __ pc()); 1277 1278 offsets.ret_addr_offset = __ offset() - start_offset; 1279 1280 return offsets; 1281 } 1282 1283 //============================================================================= 1284 1285 // Factory for creating loadConL* nodes for large/small constant pool. 1286 1287 static inline jlong replicate_immF(float con) { 1288 // Replicate float con 2 times and pack into vector. 1289 int val = *((int*)&con); 1290 jlong lval = val; 1291 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1292 return lval; 1293 } 1294 1295 //============================================================================= 1296 1297 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1298 int Compile::ConstantTable::calculate_table_base_offset() const { 1299 return 0; // absolute addressing, no offset 1300 } 1301 1302 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1303 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1304 iRegPdstOper *op_dst = new iRegPdstOper(); 1305 MachNode *m1 = new loadToc_hiNode(); 1306 MachNode *m2 = new loadToc_loNode(); 1307 1308 m1->add_req(NULL); 1309 m2->add_req(NULL, m1); 1310 m1->_opnds[0] = op_dst; 1311 m2->_opnds[0] = op_dst; 1312 m2->_opnds[1] = op_dst; 1313 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1314 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1315 nodes->push(m1); 1316 nodes->push(m2); 1317 } 1318 1319 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1320 // Is postalloc expanded. 1321 ShouldNotReachHere(); 1322 } 1323 1324 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1325 return 0; 1326 } 1327 1328 #ifndef PRODUCT 1329 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1330 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1331 } 1332 #endif 1333 1334 //============================================================================= 1335 1336 #ifndef PRODUCT 1337 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1338 Compile* C = ra_->C; 1339 const long framesize = C->frame_slots() << LogBytesPerInt; 1340 1341 st->print("PROLOG\n\t"); 1342 if (C->need_stack_bang(framesize)) { 1343 st->print("stack_overflow_check\n\t"); 1344 } 1345 1346 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1347 st->print("save return pc\n\t"); 1348 st->print("push frame %ld\n\t", -framesize); 1349 } 1350 } 1351 #endif 1352 1353 // Macro used instead of the common __ to emulate the pipes of PPC. 1354 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1355 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1356 // still no scheduling of this code is possible, the micro scheduler is aware of the 1357 // code and can update its internal data. The following mechanism is used to achieve this: 1358 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1359 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1360 #if 0 // TODO: PPC port 1361 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1362 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1363 _masm. 1364 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1365 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1366 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1367 C->hb_scheduling()->_pdScheduling->advance_offset 1368 #else 1369 #define ___(op) if (UsePower6SchedulerPPC64) \ 1370 Unimplemented(); \ 1371 _masm. 1372 #define ___stop if (UsePower6SchedulerPPC64) \ 1373 Unimplemented() 1374 #define ___advance if (UsePower6SchedulerPPC64) \ 1375 Unimplemented() 1376 #endif 1377 1378 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1379 Compile* C = ra_->C; 1380 MacroAssembler _masm(&cbuf); 1381 1382 const long framesize = C->frame_size_in_bytes(); 1383 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1384 1385 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1386 1387 const Register return_pc = R20; // Must match return_addr() in frame section. 1388 const Register callers_sp = R21; 1389 const Register push_frame_temp = R22; 1390 const Register toc_temp = R23; 1391 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1392 1393 if (method_is_frameless) { 1394 // Add nop at beginning of all frameless methods to prevent any 1395 // oop instructions from getting overwritten by make_not_entrant 1396 // (patching attempt would fail). 1397 ___(nop) nop(); 1398 } else { 1399 // Get return pc. 1400 ___(mflr) mflr(return_pc); 1401 } 1402 1403 // Calls to C2R adapters often do not accept exceptional returns. 1404 // We require that their callers must bang for them. But be 1405 // careful, because some VM calls (such as call site linkage) can 1406 // use several kilobytes of stack. But the stack safety zone should 1407 // account for that. See bugs 4446381, 4468289, 4497237. 1408 1409 int bangsize = C->bang_size_in_bytes(); 1410 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1411 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1412 // Unfortunately we cannot use the function provided in 1413 // assembler.cpp as we have to emulate the pipes. So I had to 1414 // insert the code of generate_stack_overflow_check(), see 1415 // assembler.cpp for some illuminative comments. 1416 const int page_size = os::vm_page_size(); 1417 int bang_end = JavaThread::stack_shadow_zone_size(); 1418 1419 // This is how far the previous frame's stack banging extended. 1420 const int bang_end_safe = bang_end; 1421 1422 if (bangsize > page_size) { 1423 bang_end += bangsize; 1424 } 1425 1426 int bang_offset = bang_end_safe; 1427 1428 while (bang_offset <= bang_end) { 1429 // Need at least one stack bang at end of shadow zone. 1430 1431 // Again I had to copy code, this time from assembler_ppc.cpp, 1432 // bang_stack_with_offset - see there for comments. 1433 1434 // Stack grows down, caller passes positive offset. 1435 assert(bang_offset > 0, "must bang with positive offset"); 1436 1437 long stdoffset = -bang_offset; 1438 1439 if (Assembler::is_simm(stdoffset, 16)) { 1440 // Signed 16 bit offset, a simple std is ok. 1441 if (UseLoadInstructionsForStackBangingPPC64) { 1442 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1443 } else { 1444 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1445 } 1446 } else if (Assembler::is_simm(stdoffset, 31)) { 1447 // Use largeoffset calculations for addis & ld/std. 1448 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1449 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1450 1451 Register tmp = R11; 1452 ___(addis) addis(tmp, R1_SP, hi); 1453 if (UseLoadInstructionsForStackBangingPPC64) { 1454 ___(ld) ld(R0, lo, tmp); 1455 } else { 1456 ___(std) std(R0, lo, tmp); 1457 } 1458 } else { 1459 ShouldNotReachHere(); 1460 } 1461 1462 bang_offset += page_size; 1463 } 1464 // R11 trashed 1465 } // C->need_stack_bang(framesize) && UseStackBanging 1466 1467 unsigned int bytes = (unsigned int)framesize; 1468 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1469 ciMethod *currMethod = C->method(); 1470 1471 // Optimized version for most common case. 1472 if (UsePower6SchedulerPPC64 && 1473 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1474 !(false /* ConstantsALot TODO: PPC port*/)) { 1475 ___(or) mr(callers_sp, R1_SP); 1476 ___(std) std(return_pc, _abi(lr), R1_SP); 1477 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1478 return; 1479 } 1480 1481 if (!method_is_frameless) { 1482 // Get callers sp. 1483 ___(or) mr(callers_sp, R1_SP); 1484 1485 // Push method's frame, modifies SP. 1486 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1487 // The ABI is already accounted for in 'framesize' via the 1488 // 'out_preserve' area. 1489 Register tmp = push_frame_temp; 1490 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1491 if (Assembler::is_simm(-offset, 16)) { 1492 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1493 } else { 1494 long x = -offset; 1495 // Had to insert load_const(tmp, -offset). 1496 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1497 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1498 ___(rldicr) sldi(tmp, tmp, 32); 1499 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1500 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1501 1502 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1503 } 1504 } 1505 #if 0 // TODO: PPC port 1506 // For testing large constant pools, emit a lot of constants to constant pool. 1507 // "Randomize" const_size. 1508 if (ConstantsALot) { 1509 const int num_consts = const_size(); 1510 for (int i = 0; i < num_consts; i++) { 1511 __ long_constant(0xB0B5B00BBABE); 1512 } 1513 } 1514 #endif 1515 if (!method_is_frameless) { 1516 // Save return pc. 1517 ___(std) std(return_pc, _abi(lr), callers_sp); 1518 } 1519 1520 C->set_frame_complete(cbuf.insts_size()); 1521 } 1522 #undef ___ 1523 #undef ___stop 1524 #undef ___advance 1525 1526 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1527 // Variable size. determine dynamically. 1528 return MachNode::size(ra_); 1529 } 1530 1531 int MachPrologNode::reloc() const { 1532 // Return number of relocatable values contained in this instruction. 1533 return 1; // 1 reloc entry for load_const(toc). 1534 } 1535 1536 //============================================================================= 1537 1538 #ifndef PRODUCT 1539 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1540 Compile* C = ra_->C; 1541 1542 st->print("EPILOG\n\t"); 1543 st->print("restore return pc\n\t"); 1544 st->print("pop frame\n\t"); 1545 1546 if (do_polling() && C->is_method_compilation()) { 1547 st->print("touch polling page\n\t"); 1548 } 1549 } 1550 #endif 1551 1552 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1553 Compile* C = ra_->C; 1554 MacroAssembler _masm(&cbuf); 1555 1556 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1557 assert(framesize >= 0, "negative frame-size?"); 1558 1559 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1560 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1561 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1562 const Register polling_page = R12; 1563 1564 if (!method_is_frameless) { 1565 // Restore return pc relative to callers' sp. 1566 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1567 } 1568 1569 if (method_needs_polling) { 1570 if (SafepointMechanism::uses_thread_local_poll()) { 1571 __ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread); 1572 } else { 1573 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); 1574 } 1575 } 1576 1577 if (!method_is_frameless) { 1578 // Move return pc to LR. 1579 __ mtlr(return_pc); 1580 // Pop frame (fixed frame-size). 1581 __ addi(R1_SP, R1_SP, (int)framesize); 1582 } 1583 1584 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1585 __ reserved_stack_check(return_pc); 1586 } 1587 1588 if (method_needs_polling) { 1589 // We need to mark the code position where the load from the safepoint 1590 // polling page was emitted as relocInfo::poll_return_type here. 1591 __ relocate(relocInfo::poll_return_type); 1592 __ load_from_polling_page(polling_page); 1593 } 1594 } 1595 1596 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1597 // Variable size. Determine dynamically. 1598 return MachNode::size(ra_); 1599 } 1600 1601 int MachEpilogNode::reloc() const { 1602 // Return number of relocatable values contained in this instruction. 1603 return 1; // 1 for load_from_polling_page. 1604 } 1605 1606 const Pipeline * MachEpilogNode::pipeline() const { 1607 return MachNode::pipeline_class(); 1608 } 1609 1610 // This method seems to be obsolete. It is declared in machnode.hpp 1611 // and defined in all *.ad files, but it is never called. Should we 1612 // get rid of it? 1613 int MachEpilogNode::safepoint_offset() const { 1614 assert(do_polling(), "no return for this epilog node"); 1615 return 0; 1616 } 1617 1618 #if 0 // TODO: PPC port 1619 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1620 MacroAssembler _masm(&cbuf); 1621 if (LoadPollAddressFromThread) { 1622 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1623 } else { 1624 _masm.nop(); 1625 } 1626 } 1627 1628 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1629 if (LoadPollAddressFromThread) { 1630 return 4; 1631 } else { 1632 return 4; 1633 } 1634 } 1635 1636 #ifndef PRODUCT 1637 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1638 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1639 } 1640 #endif 1641 1642 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1643 return RSCRATCH1_BITS64_REG_mask(); 1644 } 1645 #endif // PPC port 1646 1647 // ============================================================================= 1648 1649 // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or 1650 // rc_stack. 1651 enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack }; 1652 1653 static enum RC rc_class(OptoReg::Name reg) { 1654 // Return the register class for the given register. The given register 1655 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1656 // enumeration in adGlobals_ppc.hpp. 1657 1658 if (reg == OptoReg::Bad) return rc_bad; 1659 1660 // We have 64 integer register halves, starting at index 0. 1661 if (reg < 64) return rc_int; 1662 1663 // We have 64 floating-point register halves, starting at index 64. 1664 if (reg < 64+64) return rc_float; 1665 1666 // We have 64 vector-scalar registers, starting at index 128. 1667 if (reg < 64+64+64) return rc_vs; 1668 1669 // Between float regs & stack are the flags regs. 1670 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1671 1672 return rc_stack; 1673 } 1674 1675 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1676 bool do_print, Compile* C, outputStream *st) { 1677 1678 assert(opcode == Assembler::LD_OPCODE || 1679 opcode == Assembler::STD_OPCODE || 1680 opcode == Assembler::LWZ_OPCODE || 1681 opcode == Assembler::STW_OPCODE || 1682 opcode == Assembler::LFD_OPCODE || 1683 opcode == Assembler::STFD_OPCODE || 1684 opcode == Assembler::LFS_OPCODE || 1685 opcode == Assembler::STFS_OPCODE, 1686 "opcode not supported"); 1687 1688 if (cbuf) { 1689 int d = 1690 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1691 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1692 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1693 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1694 } 1695 #ifndef PRODUCT 1696 else if (do_print) { 1697 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1698 op_str, 1699 Matcher::regName[reg], 1700 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1701 } 1702 #endif 1703 return 4; // size 1704 } 1705 1706 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1707 Compile* C = ra_->C; 1708 1709 // Get registers to move. 1710 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1711 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1712 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1713 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1714 1715 enum RC src_hi_rc = rc_class(src_hi); 1716 enum RC src_lo_rc = rc_class(src_lo); 1717 enum RC dst_hi_rc = rc_class(dst_hi); 1718 enum RC dst_lo_rc = rc_class(dst_lo); 1719 1720 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1721 if (src_hi != OptoReg::Bad) 1722 assert((src_lo&1)==0 && src_lo+1==src_hi && 1723 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1724 "expected aligned-adjacent pairs"); 1725 // Generate spill code! 1726 int size = 0; 1727 1728 if (src_lo == dst_lo && src_hi == dst_hi) 1729 return size; // Self copy, no move. 1730 1731 if (bottom_type()->isa_vect() != NULL && ideal_reg() == Op_VecX) { 1732 // Memory->Memory Spill. 1733 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1734 int src_offset = ra_->reg2offset(src_lo); 1735 int dst_offset = ra_->reg2offset(dst_lo); 1736 if (cbuf) { 1737 MacroAssembler _masm(cbuf); 1738 __ ld(R0, src_offset, R1_SP); 1739 __ std(R0, dst_offset, R1_SP); 1740 __ ld(R0, src_offset+8, R1_SP); 1741 __ std(R0, dst_offset+8, R1_SP); 1742 } 1743 size += 16; 1744 } 1745 // VectorSRegister->Memory Spill. 1746 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) { 1747 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1748 int dst_offset = ra_->reg2offset(dst_lo); 1749 if (cbuf) { 1750 MacroAssembler _masm(cbuf); 1751 __ addi(R0, R1_SP, dst_offset); 1752 __ stxvd2x(Rsrc, R0); 1753 } 1754 size += 8; 1755 } 1756 // Memory->VectorSRegister Spill. 1757 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) { 1758 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1759 int src_offset = ra_->reg2offset(src_lo); 1760 if (cbuf) { 1761 MacroAssembler _masm(cbuf); 1762 __ addi(R0, R1_SP, src_offset); 1763 __ lxvd2x(Rdst, R0); 1764 } 1765 size += 8; 1766 } 1767 // VectorSRegister->VectorSRegister. 1768 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) { 1769 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1770 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1771 if (cbuf) { 1772 MacroAssembler _masm(cbuf); 1773 __ xxlor(Rdst, Rsrc, Rsrc); 1774 } 1775 size += 4; 1776 } 1777 else { 1778 ShouldNotReachHere(); // No VSR spill. 1779 } 1780 return size; 1781 } 1782 1783 // -------------------------------------- 1784 // Memory->Memory Spill. Use R0 to hold the value. 1785 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1786 int src_offset = ra_->reg2offset(src_lo); 1787 int dst_offset = ra_->reg2offset(dst_lo); 1788 if (src_hi != OptoReg::Bad) { 1789 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1790 "expected same type of move for high parts"); 1791 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1792 if (!cbuf && !do_size) st->print("\n\t"); 1793 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1794 } else { 1795 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1796 if (!cbuf && !do_size) st->print("\n\t"); 1797 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1798 } 1799 return size; 1800 } 1801 1802 // -------------------------------------- 1803 // Check for float->int copy; requires a trip through memory. 1804 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1805 Unimplemented(); 1806 } 1807 1808 // -------------------------------------- 1809 // Check for integer reg-reg copy. 1810 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1811 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1812 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1813 size = (Rsrc != Rdst) ? 4 : 0; 1814 1815 if (cbuf) { 1816 MacroAssembler _masm(cbuf); 1817 if (size) { 1818 __ mr(Rdst, Rsrc); 1819 } 1820 } 1821 #ifndef PRODUCT 1822 else if (!do_size) { 1823 if (size) { 1824 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1825 } else { 1826 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1827 } 1828 } 1829 #endif 1830 return size; 1831 } 1832 1833 // Check for integer store. 1834 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1835 int dst_offset = ra_->reg2offset(dst_lo); 1836 if (src_hi != OptoReg::Bad) { 1837 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1838 "expected same type of move for high parts"); 1839 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1840 } else { 1841 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1842 } 1843 return size; 1844 } 1845 1846 // Check for integer load. 1847 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1848 int src_offset = ra_->reg2offset(src_lo); 1849 if (src_hi != OptoReg::Bad) { 1850 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1851 "expected same type of move for high parts"); 1852 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1853 } else { 1854 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1855 } 1856 return size; 1857 } 1858 1859 // Check for float reg-reg copy. 1860 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1861 if (cbuf) { 1862 MacroAssembler _masm(cbuf); 1863 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1864 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1865 __ fmr(Rdst, Rsrc); 1866 } 1867 #ifndef PRODUCT 1868 else if (!do_size) { 1869 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1870 } 1871 #endif 1872 return 4; 1873 } 1874 1875 // Check for float store. 1876 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1877 int dst_offset = ra_->reg2offset(dst_lo); 1878 if (src_hi != OptoReg::Bad) { 1879 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1880 "expected same type of move for high parts"); 1881 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1882 } else { 1883 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1884 } 1885 return size; 1886 } 1887 1888 // Check for float load. 1889 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1890 int src_offset = ra_->reg2offset(src_lo); 1891 if (src_hi != OptoReg::Bad) { 1892 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1893 "expected same type of move for high parts"); 1894 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1895 } else { 1896 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1897 } 1898 return size; 1899 } 1900 1901 // -------------------------------------------------------------------- 1902 // Check for hi bits still needing moving. Only happens for misaligned 1903 // arguments to native calls. 1904 if (src_hi == dst_hi) 1905 return size; // Self copy; no move. 1906 1907 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1908 ShouldNotReachHere(); // Unimplemented 1909 return 0; 1910 } 1911 1912 #ifndef PRODUCT 1913 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1914 if (!ra_) 1915 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1916 else 1917 implementation(NULL, ra_, false, st); 1918 } 1919 #endif 1920 1921 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1922 implementation(&cbuf, ra_, false, NULL); 1923 } 1924 1925 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1926 return implementation(NULL, ra_, true, NULL); 1927 } 1928 1929 #if 0 // TODO: PPC port 1930 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1931 #ifndef PRODUCT 1932 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1933 #endif 1934 assert(ra_->node_regs_max_index() != 0, ""); 1935 1936 // Get registers to move. 1937 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1938 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1939 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1940 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1941 1942 enum RC src_lo_rc = rc_class(src_lo); 1943 enum RC dst_lo_rc = rc_class(dst_lo); 1944 1945 if (src_lo == dst_lo && src_hi == dst_hi) 1946 return ppc64Opcode_none; // Self copy, no move. 1947 1948 // -------------------------------------- 1949 // Memory->Memory Spill. Use R0 to hold the value. 1950 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1951 return ppc64Opcode_compound; 1952 } 1953 1954 // -------------------------------------- 1955 // Check for float->int copy; requires a trip through memory. 1956 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1957 Unimplemented(); 1958 } 1959 1960 // -------------------------------------- 1961 // Check for integer reg-reg copy. 1962 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1963 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1964 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1965 if (Rsrc == Rdst) { 1966 return ppc64Opcode_none; 1967 } else { 1968 return ppc64Opcode_or; 1969 } 1970 } 1971 1972 // Check for integer store. 1973 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1974 if (src_hi != OptoReg::Bad) { 1975 return ppc64Opcode_std; 1976 } else { 1977 return ppc64Opcode_stw; 1978 } 1979 } 1980 1981 // Check for integer load. 1982 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1983 if (src_hi != OptoReg::Bad) { 1984 return ppc64Opcode_ld; 1985 } else { 1986 return ppc64Opcode_lwz; 1987 } 1988 } 1989 1990 // Check for float reg-reg copy. 1991 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1992 return ppc64Opcode_fmr; 1993 } 1994 1995 // Check for float store. 1996 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1997 if (src_hi != OptoReg::Bad) { 1998 return ppc64Opcode_stfd; 1999 } else { 2000 return ppc64Opcode_stfs; 2001 } 2002 } 2003 2004 // Check for float load. 2005 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 2006 if (src_hi != OptoReg::Bad) { 2007 return ppc64Opcode_lfd; 2008 } else { 2009 return ppc64Opcode_lfs; 2010 } 2011 } 2012 2013 // -------------------------------------------------------------------- 2014 // Check for hi bits still needing moving. Only happens for misaligned 2015 // arguments to native calls. 2016 if (src_hi == dst_hi) { 2017 return ppc64Opcode_none; // Self copy; no move. 2018 } 2019 2020 ShouldNotReachHere(); 2021 return ppc64Opcode_undefined; 2022 } 2023 #endif // PPC port 2024 2025 #ifndef PRODUCT 2026 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2027 st->print("NOP \t// %d nops to pad for loops.", _count); 2028 } 2029 #endif 2030 2031 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 2032 MacroAssembler _masm(&cbuf); 2033 // _count contains the number of nops needed for padding. 2034 for (int i = 0; i < _count; i++) { 2035 __ nop(); 2036 } 2037 } 2038 2039 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 2040 return _count * 4; 2041 } 2042 2043 #ifndef PRODUCT 2044 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2045 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2046 char reg_str[128]; 2047 ra_->dump_register(this, reg_str); 2048 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 2049 } 2050 #endif 2051 2052 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2053 MacroAssembler _masm(&cbuf); 2054 2055 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2056 int reg = ra_->get_encode(this); 2057 2058 if (Assembler::is_simm(offset, 16)) { 2059 __ addi(as_Register(reg), R1, offset); 2060 } else { 2061 ShouldNotReachHere(); 2062 } 2063 } 2064 2065 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2066 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2067 return 4; 2068 } 2069 2070 #ifndef PRODUCT 2071 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2072 st->print_cr("---- MachUEPNode ----"); 2073 st->print_cr("..."); 2074 } 2075 #endif 2076 2077 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2078 // This is the unverified entry point. 2079 MacroAssembler _masm(&cbuf); 2080 2081 // Inline_cache contains a klass. 2082 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 2083 Register receiver_klass = R12_scratch2; // tmp 2084 2085 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 2086 assert(R11_scratch1 == R11, "need prologue scratch register"); 2087 2088 // Check for NULL argument if we don't have implicit null checks. 2089 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 2090 if (TrapBasedNullChecks) { 2091 __ trap_null_check(R3_ARG1); 2092 } else { 2093 Label valid; 2094 __ cmpdi(CCR0, R3_ARG1, 0); 2095 __ bne_predict_taken(CCR0, valid); 2096 // We have a null argument, branch to ic_miss_stub. 2097 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2098 relocInfo::runtime_call_type); 2099 __ bind(valid); 2100 } 2101 } 2102 // Assume argument is not NULL, load klass from receiver. 2103 __ load_klass(receiver_klass, R3_ARG1); 2104 2105 if (TrapBasedICMissChecks) { 2106 __ trap_ic_miss_check(receiver_klass, ic_klass); 2107 } else { 2108 Label valid; 2109 __ cmpd(CCR0, receiver_klass, ic_klass); 2110 __ beq_predict_taken(CCR0, valid); 2111 // We have an unexpected klass, branch to ic_miss_stub. 2112 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2113 relocInfo::runtime_call_type); 2114 __ bind(valid); 2115 } 2116 2117 // Argument is valid and klass is as expected, continue. 2118 } 2119 2120 #if 0 // TODO: PPC port 2121 // Optimize UEP code on z (save a load_const() call in main path). 2122 int MachUEPNode::ep_offset() { 2123 return 0; 2124 } 2125 #endif 2126 2127 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2128 // Variable size. Determine dynamically. 2129 return MachNode::size(ra_); 2130 } 2131 2132 //============================================================================= 2133 2134 %} // interrupt source 2135 2136 source_hpp %{ // Header information of the source block. 2137 2138 class HandlerImpl { 2139 2140 public: 2141 2142 static int emit_exception_handler(CodeBuffer &cbuf); 2143 static int emit_deopt_handler(CodeBuffer& cbuf); 2144 2145 static uint size_exception_handler() { 2146 // The exception_handler is a b64_patchable. 2147 return MacroAssembler::b64_patchable_size; 2148 } 2149 2150 static uint size_deopt_handler() { 2151 // The deopt_handler is a bl64_patchable. 2152 return MacroAssembler::bl64_patchable_size; 2153 } 2154 2155 }; 2156 2157 %} // end source_hpp 2158 2159 source %{ 2160 2161 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2162 MacroAssembler _masm(&cbuf); 2163 2164 address base = __ start_a_stub(size_exception_handler()); 2165 if (base == NULL) return 0; // CodeBuffer::expand failed 2166 2167 int offset = __ offset(); 2168 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2169 relocInfo::runtime_call_type); 2170 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2171 __ end_a_stub(); 2172 2173 return offset; 2174 } 2175 2176 // The deopt_handler is like the exception handler, but it calls to 2177 // the deoptimization blob instead of jumping to the exception blob. 2178 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2179 MacroAssembler _masm(&cbuf); 2180 2181 address base = __ start_a_stub(size_deopt_handler()); 2182 if (base == NULL) return 0; // CodeBuffer::expand failed 2183 2184 int offset = __ offset(); 2185 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2186 relocInfo::runtime_call_type); 2187 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2188 __ end_a_stub(); 2189 2190 return offset; 2191 } 2192 2193 //============================================================================= 2194 2195 // Use a frame slots bias for frameless methods if accessing the stack. 2196 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2197 if (as_Register(reg_enc) == R1_SP) { 2198 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2199 } 2200 return 0; 2201 } 2202 2203 const bool Matcher::match_rule_supported(int opcode) { 2204 if (!has_match_rule(opcode)) 2205 return false; 2206 2207 switch (opcode) { 2208 case Op_SqrtD: 2209 return VM_Version::has_fsqrt(); 2210 case Op_CountLeadingZerosI: 2211 case Op_CountLeadingZerosL: 2212 case Op_CountTrailingZerosI: 2213 case Op_CountTrailingZerosL: 2214 if (!UseCountLeadingZerosInstructionsPPC64) 2215 return false; 2216 break; 2217 2218 case Op_PopCountI: 2219 case Op_PopCountL: 2220 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2221 2222 case Op_StrComp: 2223 return SpecialStringCompareTo; 2224 case Op_StrEquals: 2225 return SpecialStringEquals; 2226 case Op_StrIndexOf: 2227 case Op_StrIndexOfChar: 2228 return SpecialStringIndexOf; 2229 case Op_AddVB: 2230 case Op_AddVS: 2231 case Op_AddVI: 2232 case Op_AddVF: 2233 case Op_AddVD: 2234 case Op_SubVB: 2235 case Op_SubVS: 2236 case Op_SubVI: 2237 case Op_SubVF: 2238 case Op_SubVD: 2239 case Op_MulVS: 2240 case Op_MulVF: 2241 case Op_MulVD: 2242 case Op_DivVF: 2243 case Op_DivVD: 2244 case Op_AbsVF: 2245 case Op_AbsVD: 2246 case Op_NegVF: 2247 case Op_NegVD: 2248 case Op_SqrtVF: 2249 case Op_SqrtVD: 2250 case Op_AddVL: 2251 case Op_SubVL: 2252 case Op_MulVI: 2253 return SuperwordUseVSX; 2254 case Op_PopCountVI: 2255 return (SuperwordUseVSX && UsePopCountInstruction); 2256 case Op_DigitC: 2257 case Op_LowerCaseC: 2258 case Op_UpperCaseC: 2259 case Op_WhitespaceC: 2260 return VM_Version::has_darn(); 2261 } 2262 2263 return true; // Per default match rules are supported. 2264 } 2265 2266 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2267 2268 // TODO 2269 // identify extra cases that we might want to provide match rules for 2270 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2271 bool ret_value = match_rule_supported(opcode); 2272 // Add rules here. 2273 2274 return ret_value; // Per default match rules are supported. 2275 } 2276 2277 const bool Matcher::has_predicated_vectors(void) { 2278 return false; 2279 } 2280 2281 const int Matcher::float_pressure(int default_pressure_threshold) { 2282 return default_pressure_threshold; 2283 } 2284 2285 int Matcher::regnum_to_fpu_offset(int regnum) { 2286 // No user for this method? 2287 Unimplemented(); 2288 return 999; 2289 } 2290 2291 const bool Matcher::convL2FSupported(void) { 2292 // fcfids can do the conversion (>= Power7). 2293 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2294 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2295 } 2296 2297 // Vector width in bytes. 2298 const int Matcher::vector_width_in_bytes(BasicType bt) { 2299 if (SuperwordUseVSX) { 2300 assert(MaxVectorSize == 16, ""); 2301 return 16; 2302 } else { 2303 assert(MaxVectorSize == 8, ""); 2304 return 8; 2305 } 2306 } 2307 2308 // Vector ideal reg. 2309 const uint Matcher::vector_ideal_reg(int size) { 2310 if (SuperwordUseVSX) { 2311 assert(MaxVectorSize == 16 && size == 16, ""); 2312 return Op_VecX; 2313 } else { 2314 assert(MaxVectorSize == 8 && size == 8, ""); 2315 return Op_RegL; 2316 } 2317 } 2318 2319 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2320 fatal("vector shift is not supported"); 2321 return Node::NotAMachineReg; 2322 } 2323 2324 // Limits on vector size (number of elements) loaded into vector. 2325 const int Matcher::max_vector_size(const BasicType bt) { 2326 assert(is_java_primitive(bt), "only primitive type vectors"); 2327 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2328 } 2329 2330 const int Matcher::min_vector_size(const BasicType bt) { 2331 return max_vector_size(bt); // Same as max. 2332 } 2333 2334 // PPC doesn't support misaligned vectors store/load. 2335 const bool Matcher::misaligned_vectors_ok() { 2336 return !AlignVector; // can be changed by flag 2337 } 2338 2339 // PPC AES support not yet implemented 2340 const bool Matcher::pass_original_key_for_aes() { 2341 return false; 2342 } 2343 2344 // RETURNS: whether this branch offset is short enough that a short 2345 // branch can be used. 2346 // 2347 // If the platform does not provide any short branch variants, then 2348 // this method should return `false' for offset 0. 2349 // 2350 // `Compile::Fill_buffer' will decide on basis of this information 2351 // whether to do the pass `Compile::Shorten_branches' at all. 2352 // 2353 // And `Compile::Shorten_branches' will decide on basis of this 2354 // information whether to replace particular branch sites by short 2355 // ones. 2356 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2357 // Is the offset within the range of a ppc64 pc relative branch? 2358 bool b; 2359 2360 const int safety_zone = 3 * BytesPerInstWord; 2361 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2362 29 - 16 + 1 + 2); 2363 return b; 2364 } 2365 2366 const bool Matcher::isSimpleConstant64(jlong value) { 2367 // Probably always true, even if a temp register is required. 2368 return true; 2369 } 2370 /* TODO: PPC port 2371 // Make a new machine dependent decode node (with its operands). 2372 MachTypeNode *Matcher::make_decode_node() { 2373 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2374 "This method is only implemented for unscaled cOops mode so far"); 2375 MachTypeNode *decode = new decodeN_unscaledNode(); 2376 decode->set_opnd_array(0, new iRegPdstOper()); 2377 decode->set_opnd_array(1, new iRegNsrcOper()); 2378 return decode; 2379 } 2380 */ 2381 2382 // false => size gets scaled to BytesPerLong, ok. 2383 const bool Matcher::init_array_count_is_in_bytes = false; 2384 2385 // Use conditional move (CMOVL) on Power7. 2386 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2387 2388 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2389 // fsel doesn't accept a condition register as input, so this would be slightly different. 2390 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2391 2392 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2393 const bool Matcher::require_postalloc_expand = true; 2394 2395 // Do we need to mask the count passed to shift instructions or does 2396 // the cpu only look at the lower 5/6 bits anyway? 2397 // PowerPC requires masked shift counts. 2398 const bool Matcher::need_masked_shift_count = true; 2399 2400 // This affects two different things: 2401 // - how Decode nodes are matched 2402 // - how ImplicitNullCheck opportunities are recognized 2403 // If true, the matcher will try to remove all Decodes and match them 2404 // (as operands) into nodes. NullChecks are not prepared to deal with 2405 // Decodes by final_graph_reshaping(). 2406 // If false, final_graph_reshaping() forces the decode behind the Cmp 2407 // for a NullCheck. The matcher matches the Decode node into a register. 2408 // Implicit_null_check optimization moves the Decode along with the 2409 // memory operation back up before the NullCheck. 2410 bool Matcher::narrow_oop_use_complex_address() { 2411 // TODO: PPC port if (MatchDecodeNodes) return true; 2412 return false; 2413 } 2414 2415 bool Matcher::narrow_klass_use_complex_address() { 2416 NOT_LP64(ShouldNotCallThis()); 2417 assert(UseCompressedClassPointers, "only for compressed klass code"); 2418 // TODO: PPC port if (MatchDecodeNodes) return true; 2419 return false; 2420 } 2421 2422 bool Matcher::const_oop_prefer_decode() { 2423 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2424 return Universe::narrow_oop_base() == NULL; 2425 } 2426 2427 bool Matcher::const_klass_prefer_decode() { 2428 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2429 return Universe::narrow_klass_base() == NULL; 2430 } 2431 2432 // Is it better to copy float constants, or load them directly from memory? 2433 // Intel can load a float constant from a direct address, requiring no 2434 // extra registers. Most RISCs will have to materialize an address into a 2435 // register first, so they would do better to copy the constant from stack. 2436 const bool Matcher::rematerialize_float_constants = false; 2437 2438 // If CPU can load and store mis-aligned doubles directly then no fixup is 2439 // needed. Else we split the double into 2 integer pieces and move it 2440 // piece-by-piece. Only happens when passing doubles into C code as the 2441 // Java calling convention forces doubles to be aligned. 2442 const bool Matcher::misaligned_doubles_ok = true; 2443 2444 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2445 Unimplemented(); 2446 } 2447 2448 // Advertise here if the CPU requires explicit rounding operations 2449 // to implement the UseStrictFP mode. 2450 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2451 2452 // Do floats take an entire double register or just half? 2453 // 2454 // A float occupies a ppc64 double register. For the allocator, a 2455 // ppc64 double register appears as a pair of float registers. 2456 bool Matcher::float_in_double() { return true; } 2457 2458 // Do ints take an entire long register or just half? 2459 // The relevant question is how the int is callee-saved: 2460 // the whole long is written but de-opt'ing will have to extract 2461 // the relevant 32 bits. 2462 const bool Matcher::int_in_long = true; 2463 2464 // Constants for c2c and c calling conventions. 2465 2466 const MachRegisterNumbers iarg_reg[8] = { 2467 R3_num, R4_num, R5_num, R6_num, 2468 R7_num, R8_num, R9_num, R10_num 2469 }; 2470 2471 const MachRegisterNumbers farg_reg[13] = { 2472 F1_num, F2_num, F3_num, F4_num, 2473 F5_num, F6_num, F7_num, F8_num, 2474 F9_num, F10_num, F11_num, F12_num, 2475 F13_num 2476 }; 2477 2478 const MachRegisterNumbers vsarg_reg[64] = { 2479 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2480 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2481 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2482 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2483 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2484 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2485 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2486 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2487 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2488 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2489 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2490 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2491 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2492 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2493 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2494 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2495 }; 2496 2497 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2498 2499 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2500 2501 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2502 2503 // Return whether or not this register is ever used as an argument. This 2504 // function is used on startup to build the trampoline stubs in generateOptoStub. 2505 // Registers not mentioned will be killed by the VM call in the trampoline, and 2506 // arguments in those registers not be available to the callee. 2507 bool Matcher::can_be_java_arg(int reg) { 2508 // We return true for all registers contained in iarg_reg[] and 2509 // farg_reg[] and their virtual halves. 2510 // We must include the virtual halves in order to get STDs and LDs 2511 // instead of STWs and LWs in the trampoline stubs. 2512 2513 if ( reg == R3_num || reg == R3_H_num 2514 || reg == R4_num || reg == R4_H_num 2515 || reg == R5_num || reg == R5_H_num 2516 || reg == R6_num || reg == R6_H_num 2517 || reg == R7_num || reg == R7_H_num 2518 || reg == R8_num || reg == R8_H_num 2519 || reg == R9_num || reg == R9_H_num 2520 || reg == R10_num || reg == R10_H_num) 2521 return true; 2522 2523 if ( reg == F1_num || reg == F1_H_num 2524 || reg == F2_num || reg == F2_H_num 2525 || reg == F3_num || reg == F3_H_num 2526 || reg == F4_num || reg == F4_H_num 2527 || reg == F5_num || reg == F5_H_num 2528 || reg == F6_num || reg == F6_H_num 2529 || reg == F7_num || reg == F7_H_num 2530 || reg == F8_num || reg == F8_H_num 2531 || reg == F9_num || reg == F9_H_num 2532 || reg == F10_num || reg == F10_H_num 2533 || reg == F11_num || reg == F11_H_num 2534 || reg == F12_num || reg == F12_H_num 2535 || reg == F13_num || reg == F13_H_num) 2536 return true; 2537 2538 return false; 2539 } 2540 2541 bool Matcher::is_spillable_arg(int reg) { 2542 return can_be_java_arg(reg); 2543 } 2544 2545 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2546 return false; 2547 } 2548 2549 // Register for DIVI projection of divmodI. 2550 RegMask Matcher::divI_proj_mask() { 2551 ShouldNotReachHere(); 2552 return RegMask(); 2553 } 2554 2555 // Register for MODI projection of divmodI. 2556 RegMask Matcher::modI_proj_mask() { 2557 ShouldNotReachHere(); 2558 return RegMask(); 2559 } 2560 2561 // Register for DIVL projection of divmodL. 2562 RegMask Matcher::divL_proj_mask() { 2563 ShouldNotReachHere(); 2564 return RegMask(); 2565 } 2566 2567 // Register for MODL projection of divmodL. 2568 RegMask Matcher::modL_proj_mask() { 2569 ShouldNotReachHere(); 2570 return RegMask(); 2571 } 2572 2573 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2574 return RegMask(); 2575 } 2576 2577 const bool Matcher::convi2l_type_required = true; 2578 2579 %} 2580 2581 //----------ENCODING BLOCK----------------------------------------------------- 2582 // This block specifies the encoding classes used by the compiler to output 2583 // byte streams. Encoding classes are parameterized macros used by 2584 // Machine Instruction Nodes in order to generate the bit encoding of the 2585 // instruction. Operands specify their base encoding interface with the 2586 // interface keyword. There are currently supported four interfaces, 2587 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2588 // operand to generate a function which returns its register number when 2589 // queried. CONST_INTER causes an operand to generate a function which 2590 // returns the value of the constant when queried. MEMORY_INTER causes an 2591 // operand to generate four functions which return the Base Register, the 2592 // Index Register, the Scale Value, and the Offset Value of the operand when 2593 // queried. COND_INTER causes an operand to generate six functions which 2594 // return the encoding code (ie - encoding bits for the instruction) 2595 // associated with each basic boolean condition for a conditional instruction. 2596 // 2597 // Instructions specify two basic values for encoding. Again, a function 2598 // is available to check if the constant displacement is an oop. They use the 2599 // ins_encode keyword to specify their encoding classes (which must be 2600 // a sequence of enc_class names, and their parameters, specified in 2601 // the encoding block), and they use the 2602 // opcode keyword to specify, in order, their primary, secondary, and 2603 // tertiary opcode. Only the opcode sections which a particular instruction 2604 // needs for encoding need to be specified. 2605 encode %{ 2606 enc_class enc_unimplemented %{ 2607 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2608 MacroAssembler _masm(&cbuf); 2609 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2610 %} 2611 2612 enc_class enc_untested %{ 2613 #ifdef ASSERT 2614 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2615 MacroAssembler _masm(&cbuf); 2616 __ untested("Untested mach node encoding in AD file."); 2617 #else 2618 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2619 #endif 2620 %} 2621 2622 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2623 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2624 MacroAssembler _masm(&cbuf); 2625 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2626 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2627 %} 2628 2629 // Load acquire. 2630 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2631 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2632 MacroAssembler _masm(&cbuf); 2633 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2634 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2635 __ twi_0($dst$$Register); 2636 __ isync(); 2637 %} 2638 2639 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2640 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2641 2642 MacroAssembler _masm(&cbuf); 2643 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2644 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2645 %} 2646 2647 // Load acquire. 2648 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2649 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2650 2651 MacroAssembler _masm(&cbuf); 2652 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2653 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2654 __ twi_0($dst$$Register); 2655 __ isync(); 2656 %} 2657 2658 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2659 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2660 2661 MacroAssembler _masm(&cbuf); 2662 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2663 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2664 %} 2665 2666 // Load acquire. 2667 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2668 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2669 2670 MacroAssembler _masm(&cbuf); 2671 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2672 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2673 __ twi_0($dst$$Register); 2674 __ isync(); 2675 %} 2676 2677 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2678 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2679 MacroAssembler _masm(&cbuf); 2680 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2681 // Operand 'ds' requires 4-alignment. 2682 assert((Idisp & 0x3) == 0, "unaligned offset"); 2683 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2684 %} 2685 2686 // Load acquire. 2687 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2688 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2689 MacroAssembler _masm(&cbuf); 2690 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2691 // Operand 'ds' requires 4-alignment. 2692 assert((Idisp & 0x3) == 0, "unaligned offset"); 2693 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2694 __ twi_0($dst$$Register); 2695 __ isync(); 2696 %} 2697 2698 enc_class enc_lfd(RegF dst, memory mem) %{ 2699 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2700 MacroAssembler _masm(&cbuf); 2701 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2702 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2703 %} 2704 2705 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2706 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2707 2708 MacroAssembler _masm(&cbuf); 2709 int toc_offset = 0; 2710 2711 address const_toc_addr; 2712 // Create a non-oop constant, no relocation needed. 2713 // If it is an IC, it has a virtual_call_Relocation. 2714 const_toc_addr = __ long_constant((jlong)$src$$constant); 2715 if (const_toc_addr == NULL) { 2716 ciEnv::current()->record_out_of_memory_failure(); 2717 return; 2718 } 2719 2720 // Get the constant's TOC offset. 2721 toc_offset = __ offset_to_method_toc(const_toc_addr); 2722 2723 // Keep the current instruction offset in mind. 2724 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2725 2726 __ ld($dst$$Register, toc_offset, $toc$$Register); 2727 %} 2728 2729 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2730 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2731 2732 MacroAssembler _masm(&cbuf); 2733 2734 if (!ra_->C->in_scratch_emit_size()) { 2735 address const_toc_addr; 2736 // Create a non-oop constant, no relocation needed. 2737 // If it is an IC, it has a virtual_call_Relocation. 2738 const_toc_addr = __ long_constant((jlong)$src$$constant); 2739 if (const_toc_addr == NULL) { 2740 ciEnv::current()->record_out_of_memory_failure(); 2741 return; 2742 } 2743 2744 // Get the constant's TOC offset. 2745 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2746 // Store the toc offset of the constant. 2747 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2748 2749 // Also keep the current instruction offset in mind. 2750 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2751 } 2752 2753 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2754 %} 2755 2756 %} // encode 2757 2758 source %{ 2759 2760 typedef struct { 2761 loadConL_hiNode *_large_hi; 2762 loadConL_loNode *_large_lo; 2763 loadConLNode *_small; 2764 MachNode *_last; 2765 } loadConLNodesTuple; 2766 2767 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2768 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2769 loadConLNodesTuple nodes; 2770 2771 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2772 if (large_constant_pool) { 2773 // Create new nodes. 2774 loadConL_hiNode *m1 = new loadConL_hiNode(); 2775 loadConL_loNode *m2 = new loadConL_loNode(); 2776 2777 // inputs for new nodes 2778 m1->add_req(NULL, toc); 2779 m2->add_req(NULL, m1); 2780 2781 // operands for new nodes 2782 m1->_opnds[0] = new iRegLdstOper(); // dst 2783 m1->_opnds[1] = immSrc; // src 2784 m1->_opnds[2] = new iRegPdstOper(); // toc 2785 m2->_opnds[0] = new iRegLdstOper(); // dst 2786 m2->_opnds[1] = immSrc; // src 2787 m2->_opnds[2] = new iRegLdstOper(); // base 2788 2789 // Initialize ins_attrib TOC fields. 2790 m1->_const_toc_offset = -1; 2791 m2->_const_toc_offset_hi_node = m1; 2792 2793 // Initialize ins_attrib instruction offset. 2794 m1->_cbuf_insts_offset = -1; 2795 2796 // register allocation for new nodes 2797 ra_->set_pair(m1->_idx, reg_second, reg_first); 2798 ra_->set_pair(m2->_idx, reg_second, reg_first); 2799 2800 // Create result. 2801 nodes._large_hi = m1; 2802 nodes._large_lo = m2; 2803 nodes._small = NULL; 2804 nodes._last = nodes._large_lo; 2805 assert(m2->bottom_type()->isa_long(), "must be long"); 2806 } else { 2807 loadConLNode *m2 = new loadConLNode(); 2808 2809 // inputs for new nodes 2810 m2->add_req(NULL, toc); 2811 2812 // operands for new nodes 2813 m2->_opnds[0] = new iRegLdstOper(); // dst 2814 m2->_opnds[1] = immSrc; // src 2815 m2->_opnds[2] = new iRegPdstOper(); // toc 2816 2817 // Initialize ins_attrib instruction offset. 2818 m2->_cbuf_insts_offset = -1; 2819 2820 // register allocation for new nodes 2821 ra_->set_pair(m2->_idx, reg_second, reg_first); 2822 2823 // Create result. 2824 nodes._large_hi = NULL; 2825 nodes._large_lo = NULL; 2826 nodes._small = m2; 2827 nodes._last = nodes._small; 2828 assert(m2->bottom_type()->isa_long(), "must be long"); 2829 } 2830 2831 return nodes; 2832 } 2833 2834 typedef struct { 2835 loadConL_hiNode *_large_hi; 2836 loadConL_loNode *_large_lo; 2837 mtvsrdNode *_moved; 2838 xxspltdNode *_replicated; 2839 loadConLNode *_small; 2840 MachNode *_last; 2841 } loadConLReplicatedNodesTuple; 2842 2843 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2844 vecXOper *dst, immI_0Oper *zero, 2845 OptoReg::Name reg_second, OptoReg::Name reg_first, 2846 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2847 loadConLReplicatedNodesTuple nodes; 2848 2849 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2850 if (large_constant_pool) { 2851 // Create new nodes. 2852 loadConL_hiNode *m1 = new loadConL_hiNode(); 2853 loadConL_loNode *m2 = new loadConL_loNode(); 2854 mtvsrdNode *m3 = new mtvsrdNode(); 2855 xxspltdNode *m4 = new xxspltdNode(); 2856 2857 // inputs for new nodes 2858 m1->add_req(NULL, toc); 2859 m2->add_req(NULL, m1); 2860 m3->add_req(NULL, m2); 2861 m4->add_req(NULL, m3); 2862 2863 // operands for new nodes 2864 m1->_opnds[0] = new iRegLdstOper(); // dst 2865 m1->_opnds[1] = immSrc; // src 2866 m1->_opnds[2] = new iRegPdstOper(); // toc 2867 2868 m2->_opnds[0] = new iRegLdstOper(); // dst 2869 m2->_opnds[1] = immSrc; // src 2870 m2->_opnds[2] = new iRegLdstOper(); // base 2871 2872 m3->_opnds[0] = new vecXOper(); // dst 2873 m3->_opnds[1] = new iRegLdstOper(); // src 2874 2875 m4->_opnds[0] = new vecXOper(); // dst 2876 m4->_opnds[1] = new vecXOper(); // src 2877 m4->_opnds[2] = zero; 2878 2879 // Initialize ins_attrib TOC fields. 2880 m1->_const_toc_offset = -1; 2881 m2->_const_toc_offset_hi_node = m1; 2882 2883 // Initialize ins_attrib instruction offset. 2884 m1->_cbuf_insts_offset = -1; 2885 2886 // register allocation for new nodes 2887 ra_->set_pair(m1->_idx, reg_second, reg_first); 2888 ra_->set_pair(m2->_idx, reg_second, reg_first); 2889 ra_->set1(m3->_idx, reg_second); 2890 ra_->set2(m3->_idx, reg_vec_first); 2891 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2892 2893 // Create result. 2894 nodes._large_hi = m1; 2895 nodes._large_lo = m2; 2896 nodes._moved = m3; 2897 nodes._replicated = m4; 2898 nodes._small = NULL; 2899 nodes._last = nodes._replicated; 2900 assert(m2->bottom_type()->isa_long(), "must be long"); 2901 } else { 2902 loadConLNode *m2 = new loadConLNode(); 2903 mtvsrdNode *m3 = new mtvsrdNode(); 2904 xxspltdNode *m4 = new xxspltdNode(); 2905 2906 // inputs for new nodes 2907 m2->add_req(NULL, toc); 2908 2909 // operands for new nodes 2910 m2->_opnds[0] = new iRegLdstOper(); // dst 2911 m2->_opnds[1] = immSrc; // src 2912 m2->_opnds[2] = new iRegPdstOper(); // toc 2913 2914 m3->_opnds[0] = new vecXOper(); // dst 2915 m3->_opnds[1] = new iRegLdstOper(); // src 2916 2917 m4->_opnds[0] = new vecXOper(); // dst 2918 m4->_opnds[1] = new vecXOper(); // src 2919 m4->_opnds[2] = zero; 2920 2921 // Initialize ins_attrib instruction offset. 2922 m2->_cbuf_insts_offset = -1; 2923 ra_->set1(m3->_idx, reg_second); 2924 ra_->set2(m3->_idx, reg_vec_first); 2925 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2926 2927 // register allocation for new nodes 2928 ra_->set_pair(m2->_idx, reg_second, reg_first); 2929 2930 // Create result. 2931 nodes._large_hi = NULL; 2932 nodes._large_lo = NULL; 2933 nodes._small = m2; 2934 nodes._moved = m3; 2935 nodes._replicated = m4; 2936 nodes._last = nodes._replicated; 2937 assert(m2->bottom_type()->isa_long(), "must be long"); 2938 } 2939 2940 return nodes; 2941 } 2942 2943 %} // source 2944 2945 encode %{ 2946 // Postalloc expand emitter for loading a long constant from the method's TOC. 2947 // Enc_class needed as consttanttablebase is not supported by postalloc 2948 // expand. 2949 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2950 // Create new nodes. 2951 loadConLNodesTuple loadConLNodes = 2952 loadConLNodesTuple_create(ra_, n_toc, op_src, 2953 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2954 2955 // Push new nodes. 2956 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2957 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2958 2959 // some asserts 2960 assert(nodes->length() >= 1, "must have created at least 1 node"); 2961 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2962 %} 2963 2964 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2965 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2966 2967 MacroAssembler _masm(&cbuf); 2968 int toc_offset = 0; 2969 2970 intptr_t val = $src$$constant; 2971 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2972 address const_toc_addr; 2973 if (constant_reloc == relocInfo::oop_type) { 2974 // Create an oop constant and a corresponding relocation. 2975 AddressLiteral a = __ allocate_oop_address((jobject)val); 2976 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2977 __ relocate(a.rspec()); 2978 } else if (constant_reloc == relocInfo::metadata_type) { 2979 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2980 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2981 __ relocate(a.rspec()); 2982 } else { 2983 // Create a non-oop constant, no relocation needed. 2984 const_toc_addr = __ long_constant((jlong)$src$$constant); 2985 } 2986 2987 if (const_toc_addr == NULL) { 2988 ciEnv::current()->record_out_of_memory_failure(); 2989 return; 2990 } 2991 // Get the constant's TOC offset. 2992 toc_offset = __ offset_to_method_toc(const_toc_addr); 2993 2994 __ ld($dst$$Register, toc_offset, $toc$$Register); 2995 %} 2996 2997 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2998 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2999 3000 MacroAssembler _masm(&cbuf); 3001 if (!ra_->C->in_scratch_emit_size()) { 3002 intptr_t val = $src$$constant; 3003 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 3004 address const_toc_addr; 3005 if (constant_reloc == relocInfo::oop_type) { 3006 // Create an oop constant and a corresponding relocation. 3007 AddressLiteral a = __ allocate_oop_address((jobject)val); 3008 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3009 __ relocate(a.rspec()); 3010 } else if (constant_reloc == relocInfo::metadata_type) { 3011 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 3012 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3013 __ relocate(a.rspec()); 3014 } else { // non-oop pointers, e.g. card mark base, heap top 3015 // Create a non-oop constant, no relocation needed. 3016 const_toc_addr = __ long_constant((jlong)$src$$constant); 3017 } 3018 3019 if (const_toc_addr == NULL) { 3020 ciEnv::current()->record_out_of_memory_failure(); 3021 return; 3022 } 3023 // Get the constant's TOC offset. 3024 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 3025 // Store the toc offset of the constant. 3026 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 3027 } 3028 3029 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 3030 %} 3031 3032 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 3033 // Enc_class needed as consttanttablebase is not supported by postalloc 3034 // expand. 3035 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 3036 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3037 if (large_constant_pool) { 3038 // Create new nodes. 3039 loadConP_hiNode *m1 = new loadConP_hiNode(); 3040 loadConP_loNode *m2 = new loadConP_loNode(); 3041 3042 // inputs for new nodes 3043 m1->add_req(NULL, n_toc); 3044 m2->add_req(NULL, m1); 3045 3046 // operands for new nodes 3047 m1->_opnds[0] = new iRegPdstOper(); // dst 3048 m1->_opnds[1] = op_src; // src 3049 m1->_opnds[2] = new iRegPdstOper(); // toc 3050 m2->_opnds[0] = new iRegPdstOper(); // dst 3051 m2->_opnds[1] = op_src; // src 3052 m2->_opnds[2] = new iRegLdstOper(); // base 3053 3054 // Initialize ins_attrib TOC fields. 3055 m1->_const_toc_offset = -1; 3056 m2->_const_toc_offset_hi_node = m1; 3057 3058 // Register allocation for new nodes. 3059 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3060 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3061 3062 nodes->push(m1); 3063 nodes->push(m2); 3064 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3065 } else { 3066 loadConPNode *m2 = new loadConPNode(); 3067 3068 // inputs for new nodes 3069 m2->add_req(NULL, n_toc); 3070 3071 // operands for new nodes 3072 m2->_opnds[0] = new iRegPdstOper(); // dst 3073 m2->_opnds[1] = op_src; // src 3074 m2->_opnds[2] = new iRegPdstOper(); // toc 3075 3076 // Register allocation for new nodes. 3077 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3078 3079 nodes->push(m2); 3080 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3081 } 3082 %} 3083 3084 // Enc_class needed as consttanttablebase is not supported by postalloc 3085 // expand. 3086 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3087 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3088 3089 MachNode *m2; 3090 if (large_constant_pool) { 3091 m2 = new loadConFCompNode(); 3092 } else { 3093 m2 = new loadConFNode(); 3094 } 3095 // inputs for new nodes 3096 m2->add_req(NULL, n_toc); 3097 3098 // operands for new nodes 3099 m2->_opnds[0] = op_dst; 3100 m2->_opnds[1] = op_src; 3101 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3102 3103 // register allocation for new nodes 3104 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3105 nodes->push(m2); 3106 %} 3107 3108 // Enc_class needed as consttanttablebase is not supported by postalloc 3109 // expand. 3110 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3111 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3112 3113 MachNode *m2; 3114 if (large_constant_pool) { 3115 m2 = new loadConDCompNode(); 3116 } else { 3117 m2 = new loadConDNode(); 3118 } 3119 // inputs for new nodes 3120 m2->add_req(NULL, n_toc); 3121 3122 // operands for new nodes 3123 m2->_opnds[0] = op_dst; 3124 m2->_opnds[1] = op_src; 3125 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3126 3127 // register allocation for new nodes 3128 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3129 nodes->push(m2); 3130 %} 3131 3132 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3133 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3134 MacroAssembler _masm(&cbuf); 3135 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3136 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3137 %} 3138 3139 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3140 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3141 MacroAssembler _masm(&cbuf); 3142 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3143 // Operand 'ds' requires 4-alignment. 3144 assert((Idisp & 0x3) == 0, "unaligned offset"); 3145 __ std($src$$Register, Idisp, $mem$$base$$Register); 3146 %} 3147 3148 enc_class enc_stfs(RegF src, memory mem) %{ 3149 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3150 MacroAssembler _masm(&cbuf); 3151 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3152 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3153 %} 3154 3155 enc_class enc_stfd(RegF src, memory mem) %{ 3156 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3157 MacroAssembler _masm(&cbuf); 3158 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3159 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3160 %} 3161 3162 // Use release_store for card-marking to ensure that previous 3163 // oop-stores are visible before the card-mark change. 3164 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3165 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3166 // FIXME: Implement this as a cmove and use a fixed condition code 3167 // register which is written on every transition to compiled code, 3168 // e.g. in call-stub and when returning from runtime stubs. 3169 // 3170 // Proposed code sequence for the cmove implementation: 3171 // 3172 // Label skip_release; 3173 // __ beq(CCRfixed, skip_release); 3174 // __ release(); 3175 // __ bind(skip_release); 3176 // __ stb(card mark); 3177 3178 MacroAssembler _masm(&cbuf); 3179 Label skip_storestore; 3180 3181 #if 0 // TODO: PPC port 3182 // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the 3183 // StoreStore barrier conditionally. 3184 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3185 __ cmpwi($crx$$CondRegister, R0, 0); 3186 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3187 #endif 3188 __ li(R0, 0); 3189 __ membar(Assembler::StoreStore); 3190 #if 0 // TODO: PPC port 3191 __ bind(skip_storestore); 3192 #endif 3193 3194 // Do the store. 3195 if ($mem$$index == 0) { 3196 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3197 } else { 3198 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3199 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3200 } 3201 %} 3202 3203 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3204 3205 if (VM_Version::has_isel()) { 3206 // use isel instruction with Power 7 3207 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3208 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3209 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3210 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3211 3212 n_compare->add_req(n_region, n_src); 3213 n_compare->_opnds[0] = op_crx; 3214 n_compare->_opnds[1] = op_src; 3215 n_compare->_opnds[2] = new immL16Oper(0); 3216 3217 n_sub_base->add_req(n_region, n_src); 3218 n_sub_base->_opnds[0] = op_dst; 3219 n_sub_base->_opnds[1] = op_src; 3220 n_sub_base->_bottom_type = _bottom_type; 3221 3222 n_shift->add_req(n_region, n_sub_base); 3223 n_shift->_opnds[0] = op_dst; 3224 n_shift->_opnds[1] = op_dst; 3225 n_shift->_bottom_type = _bottom_type; 3226 3227 n_cond_set->add_req(n_region, n_compare, n_shift); 3228 n_cond_set->_opnds[0] = op_dst; 3229 n_cond_set->_opnds[1] = op_crx; 3230 n_cond_set->_opnds[2] = op_dst; 3231 n_cond_set->_bottom_type = _bottom_type; 3232 3233 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3234 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3235 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3236 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3237 3238 nodes->push(n_compare); 3239 nodes->push(n_sub_base); 3240 nodes->push(n_shift); 3241 nodes->push(n_cond_set); 3242 3243 } else { 3244 // before Power 7 3245 moveRegNode *n_move = new moveRegNode(); 3246 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3247 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3248 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3249 3250 n_move->add_req(n_region, n_src); 3251 n_move->_opnds[0] = op_dst; 3252 n_move->_opnds[1] = op_src; 3253 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3254 3255 n_compare->add_req(n_region, n_src); 3256 n_compare->add_prec(n_move); 3257 3258 n_compare->_opnds[0] = op_crx; 3259 n_compare->_opnds[1] = op_src; 3260 n_compare->_opnds[2] = new immL16Oper(0); 3261 3262 n_sub_base->add_req(n_region, n_compare, n_src); 3263 n_sub_base->_opnds[0] = op_dst; 3264 n_sub_base->_opnds[1] = op_crx; 3265 n_sub_base->_opnds[2] = op_src; 3266 n_sub_base->_bottom_type = _bottom_type; 3267 3268 n_shift->add_req(n_region, n_sub_base); 3269 n_shift->_opnds[0] = op_dst; 3270 n_shift->_opnds[1] = op_dst; 3271 n_shift->_bottom_type = _bottom_type; 3272 3273 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3274 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3275 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3276 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3277 3278 nodes->push(n_move); 3279 nodes->push(n_compare); 3280 nodes->push(n_sub_base); 3281 nodes->push(n_shift); 3282 } 3283 3284 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3285 %} 3286 3287 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3288 3289 encodeP_subNode *n1 = new encodeP_subNode(); 3290 n1->add_req(n_region, n_src); 3291 n1->_opnds[0] = op_dst; 3292 n1->_opnds[1] = op_src; 3293 n1->_bottom_type = _bottom_type; 3294 3295 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3296 n2->add_req(n_region, n1); 3297 n2->_opnds[0] = op_dst; 3298 n2->_opnds[1] = op_dst; 3299 n2->_bottom_type = _bottom_type; 3300 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3301 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3302 3303 nodes->push(n1); 3304 nodes->push(n2); 3305 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3306 %} 3307 3308 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3309 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3310 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3311 3312 n_compare->add_req(n_region, n_src); 3313 n_compare->_opnds[0] = op_crx; 3314 n_compare->_opnds[1] = op_src; 3315 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3316 3317 n_shift->add_req(n_region, n_src); 3318 n_shift->_opnds[0] = op_dst; 3319 n_shift->_opnds[1] = op_src; 3320 n_shift->_bottom_type = _bottom_type; 3321 3322 if (VM_Version::has_isel()) { 3323 // use isel instruction with Power 7 3324 3325 decodeN_addNode *n_add_base = new decodeN_addNode(); 3326 n_add_base->add_req(n_region, n_shift); 3327 n_add_base->_opnds[0] = op_dst; 3328 n_add_base->_opnds[1] = op_dst; 3329 n_add_base->_bottom_type = _bottom_type; 3330 3331 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3332 n_cond_set->add_req(n_region, n_compare, n_add_base); 3333 n_cond_set->_opnds[0] = op_dst; 3334 n_cond_set->_opnds[1] = op_crx; 3335 n_cond_set->_opnds[2] = op_dst; 3336 n_cond_set->_bottom_type = _bottom_type; 3337 3338 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3339 ra_->set_oop(n_cond_set, true); 3340 3341 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3342 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3343 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3344 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3345 3346 nodes->push(n_compare); 3347 nodes->push(n_shift); 3348 nodes->push(n_add_base); 3349 nodes->push(n_cond_set); 3350 3351 } else { 3352 // before Power 7 3353 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3354 3355 n_add_base->add_req(n_region, n_compare, n_shift); 3356 n_add_base->_opnds[0] = op_dst; 3357 n_add_base->_opnds[1] = op_crx; 3358 n_add_base->_opnds[2] = op_dst; 3359 n_add_base->_bottom_type = _bottom_type; 3360 3361 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3362 ra_->set_oop(n_add_base, true); 3363 3364 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3365 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3366 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3367 3368 nodes->push(n_compare); 3369 nodes->push(n_shift); 3370 nodes->push(n_add_base); 3371 } 3372 %} 3373 3374 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3375 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3376 n1->add_req(n_region, n_src); 3377 n1->_opnds[0] = op_dst; 3378 n1->_opnds[1] = op_src; 3379 n1->_bottom_type = _bottom_type; 3380 3381 decodeN_addNode *n2 = new decodeN_addNode(); 3382 n2->add_req(n_region, n1); 3383 n2->_opnds[0] = op_dst; 3384 n2->_opnds[1] = op_dst; 3385 n2->_bottom_type = _bottom_type; 3386 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3387 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3388 3389 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3390 ra_->set_oop(n2, true); 3391 3392 nodes->push(n1); 3393 nodes->push(n2); 3394 %} 3395 3396 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3397 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3398 3399 MacroAssembler _masm(&cbuf); 3400 int cc = $cmp$$cmpcode; 3401 int flags_reg = $crx$$reg; 3402 Label done; 3403 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3404 // Branch if not (cmp crx). 3405 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3406 __ mr($dst$$Register, $src$$Register); 3407 // TODO PPC port __ endgroup_if_needed(_size == 12); 3408 __ bind(done); 3409 %} 3410 3411 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3412 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3413 3414 MacroAssembler _masm(&cbuf); 3415 Label done; 3416 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3417 // Branch if not (cmp crx). 3418 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3419 __ li($dst$$Register, $src$$constant); 3420 // TODO PPC port __ endgroup_if_needed(_size == 12); 3421 __ bind(done); 3422 %} 3423 3424 // This enc_class is needed so that scheduler gets proper 3425 // input mapping for latency computation. 3426 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3427 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3428 MacroAssembler _masm(&cbuf); 3429 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3430 %} 3431 3432 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3433 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3434 3435 MacroAssembler _masm(&cbuf); 3436 3437 Label done; 3438 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3439 __ li($dst$$Register, $zero$$constant); 3440 __ beq($crx$$CondRegister, done); 3441 __ li($dst$$Register, $notzero$$constant); 3442 __ bind(done); 3443 %} 3444 3445 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3446 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3447 3448 MacroAssembler _masm(&cbuf); 3449 3450 Label done; 3451 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3452 __ li($dst$$Register, $zero$$constant); 3453 __ beq($crx$$CondRegister, done); 3454 __ li($dst$$Register, $notzero$$constant); 3455 __ bind(done); 3456 %} 3457 3458 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3459 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3460 3461 MacroAssembler _masm(&cbuf); 3462 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3463 Label done; 3464 __ bso($crx$$CondRegister, done); 3465 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3466 // TODO PPC port __ endgroup_if_needed(_size == 12); 3467 __ bind(done); 3468 %} 3469 3470 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3471 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3472 3473 MacroAssembler _masm(&cbuf); 3474 Label done; 3475 __ bso($crx$$CondRegister, done); 3476 __ mffprd($dst$$Register, $src$$FloatRegister); 3477 // TODO PPC port __ endgroup_if_needed(_size == 12); 3478 __ bind(done); 3479 %} 3480 3481 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3482 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3483 3484 MacroAssembler _masm(&cbuf); 3485 Label d; // dummy 3486 __ bind(d); 3487 Label* p = ($lbl$$label); 3488 // `p' is `NULL' when this encoding class is used only to 3489 // determine the size of the encoded instruction. 3490 Label& l = (NULL == p)? d : *(p); 3491 int cc = $cmp$$cmpcode; 3492 int flags_reg = $crx$$reg; 3493 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3494 int bhint = Assembler::bhintNoHint; 3495 3496 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3497 if (_prob <= PROB_NEVER) { 3498 bhint = Assembler::bhintIsNotTaken; 3499 } else if (_prob >= PROB_ALWAYS) { 3500 bhint = Assembler::bhintIsTaken; 3501 } 3502 } 3503 3504 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3505 cc_to_biint(cc, flags_reg), 3506 l); 3507 %} 3508 3509 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3510 // The scheduler doesn't know about branch shortening, so we set the opcode 3511 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3512 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3513 3514 MacroAssembler _masm(&cbuf); 3515 Label d; // dummy 3516 __ bind(d); 3517 Label* p = ($lbl$$label); 3518 // `p' is `NULL' when this encoding class is used only to 3519 // determine the size of the encoded instruction. 3520 Label& l = (NULL == p)? d : *(p); 3521 int cc = $cmp$$cmpcode; 3522 int flags_reg = $crx$$reg; 3523 int bhint = Assembler::bhintNoHint; 3524 3525 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3526 if (_prob <= PROB_NEVER) { 3527 bhint = Assembler::bhintIsNotTaken; 3528 } else if (_prob >= PROB_ALWAYS) { 3529 bhint = Assembler::bhintIsTaken; 3530 } 3531 } 3532 3533 // Tell the conditional far branch to optimize itself when being relocated. 3534 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3535 cc_to_biint(cc, flags_reg), 3536 l, 3537 MacroAssembler::bc_far_optimize_on_relocate); 3538 %} 3539 3540 // Branch used with Power6 scheduling (can be shortened without changing the node). 3541 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3542 // The scheduler doesn't know about branch shortening, so we set the opcode 3543 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3544 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3545 3546 MacroAssembler _masm(&cbuf); 3547 Label d; // dummy 3548 __ bind(d); 3549 Label* p = ($lbl$$label); 3550 // `p' is `NULL' when this encoding class is used only to 3551 // determine the size of the encoded instruction. 3552 Label& l = (NULL == p)? d : *(p); 3553 int cc = $cmp$$cmpcode; 3554 int flags_reg = $crx$$reg; 3555 int bhint = Assembler::bhintNoHint; 3556 3557 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3558 if (_prob <= PROB_NEVER) { 3559 bhint = Assembler::bhintIsNotTaken; 3560 } else if (_prob >= PROB_ALWAYS) { 3561 bhint = Assembler::bhintIsTaken; 3562 } 3563 } 3564 3565 #if 0 // TODO: PPC port 3566 if (_size == 8) { 3567 // Tell the conditional far branch to optimize itself when being relocated. 3568 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3569 cc_to_biint(cc, flags_reg), 3570 l, 3571 MacroAssembler::bc_far_optimize_on_relocate); 3572 } else { 3573 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3574 cc_to_biint(cc, flags_reg), 3575 l); 3576 } 3577 #endif 3578 Unimplemented(); 3579 %} 3580 3581 // Postalloc expand emitter for loading a replicatef float constant from 3582 // the method's TOC. 3583 // Enc_class needed as consttanttablebase is not supported by postalloc 3584 // expand. 3585 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3586 // Create new nodes. 3587 3588 // Make an operand with the bit pattern to load as float. 3589 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3590 3591 loadConLNodesTuple loadConLNodes = 3592 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3593 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3594 3595 // Push new nodes. 3596 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3597 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3598 3599 assert(nodes->length() >= 1, "must have created at least 1 node"); 3600 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3601 %} 3602 3603 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3604 // Create new nodes. 3605 3606 // Make an operand with the bit pattern to load as float. 3607 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3608 immI_0Oper *op_zero = new immI_0Oper(0); 3609 3610 loadConLReplicatedNodesTuple loadConLNodes = 3611 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3612 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3613 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3614 3615 // Push new nodes. 3616 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3617 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3618 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3619 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3620 3621 assert(nodes->length() >= 1, "must have created at least 1 node"); 3622 %} 3623 3624 // This enc_class is needed so that scheduler gets proper 3625 // input mapping for latency computation. 3626 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3627 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3628 // Fake operand dst needed for PPC scheduler. 3629 assert($dst$$constant == 0x0, "dst must be 0x0"); 3630 3631 MacroAssembler _masm(&cbuf); 3632 // Mark the code position where the load from the safepoint 3633 // polling page was emitted as relocInfo::poll_type. 3634 __ relocate(relocInfo::poll_type); 3635 __ load_from_polling_page($poll$$Register); 3636 %} 3637 3638 // A Java static call or a runtime call. 3639 // 3640 // Branch-and-link relative to a trampoline. 3641 // The trampoline loads the target address and does a long branch to there. 3642 // In case we call java, the trampoline branches to a interpreter_stub 3643 // which loads the inline cache and the real call target from the constant pool. 3644 // 3645 // This basically looks like this: 3646 // 3647 // >>>> consts -+ -+ 3648 // | |- offset1 3649 // [call target1] | <-+ 3650 // [IC cache] |- offset2 3651 // [call target2] <--+ 3652 // 3653 // <<<< consts 3654 // >>>> insts 3655 // 3656 // bl offset16 -+ -+ ??? // How many bits available? 3657 // | | 3658 // <<<< insts | | 3659 // >>>> stubs | | 3660 // | |- trampoline_stub_Reloc 3661 // trampoline stub: | <-+ 3662 // r2 = toc | 3663 // r2 = [r2 + offset1] | // Load call target1 from const section 3664 // mtctr r2 | 3665 // bctr |- static_stub_Reloc 3666 // comp_to_interp_stub: <---+ 3667 // r1 = toc 3668 // ICreg = [r1 + IC_offset] // Load IC from const section 3669 // r1 = [r1 + offset2] // Load call target2 from const section 3670 // mtctr r1 3671 // bctr 3672 // 3673 // <<<< stubs 3674 // 3675 // The call instruction in the code either 3676 // - Branches directly to a compiled method if the offset is encodable in instruction. 3677 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3678 // - Branches to the compiled_to_interp stub if the target is interpreted. 3679 // 3680 // Further there are three relocations from the loads to the constants in 3681 // the constant section. 3682 // 3683 // Usage of r1 and r2 in the stubs allows to distinguish them. 3684 enc_class enc_java_static_call(method meth) %{ 3685 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3686 3687 MacroAssembler _masm(&cbuf); 3688 address entry_point = (address)$meth$$method; 3689 3690 if (!_method) { 3691 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3692 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3693 } else { 3694 // Remember the offset not the address. 3695 const int start_offset = __ offset(); 3696 3697 // The trampoline stub. 3698 // No entry point given, use the current pc. 3699 // Make sure branch fits into 3700 if (entry_point == 0) entry_point = __ pc(); 3701 3702 // Put the entry point as a constant into the constant pool. 3703 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3704 if (entry_point_toc_addr == NULL) { 3705 ciEnv::current()->record_out_of_memory_failure(); 3706 return; 3707 } 3708 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3709 3710 // Emit the trampoline stub which will be related to the branch-and-link below. 3711 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3712 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3713 int method_index = resolved_method_index(cbuf); 3714 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3715 : static_call_Relocation::spec(method_index)); 3716 3717 // The real call. 3718 // Note: At this point we do not have the address of the trampoline 3719 // stub, and the entry point might be too far away for bl, so __ pc() 3720 // serves as dummy and the bl will be patched later. 3721 cbuf.set_insts_mark(); 3722 __ bl(__ pc()); // Emits a relocation. 3723 3724 // The stub for call to interpreter. 3725 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3726 if (stub == NULL) { 3727 ciEnv::current()->record_failure("CodeCache is full"); 3728 return; 3729 } 3730 } 3731 %} 3732 3733 // Second node of expanded dynamic call - the call. 3734 enc_class enc_java_dynamic_call_sched(method meth) %{ 3735 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3736 3737 MacroAssembler _masm(&cbuf); 3738 3739 if (!ra_->C->in_scratch_emit_size()) { 3740 // Create a call trampoline stub for the given method. 3741 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3742 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3743 if (entry_point_const == NULL) { 3744 ciEnv::current()->record_out_of_memory_failure(); 3745 return; 3746 } 3747 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3748 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3749 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3750 3751 // Build relocation at call site with ic position as data. 3752 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3753 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3754 "must have one, but can't have both"); 3755 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3756 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3757 "must contain instruction offset"); 3758 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3759 ? _load_ic_hi_node->_cbuf_insts_offset 3760 : _load_ic_node->_cbuf_insts_offset; 3761 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3762 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3763 "should be load from TOC"); 3764 int method_index = resolved_method_index(cbuf); 3765 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3766 } 3767 3768 // At this point I do not have the address of the trampoline stub, 3769 // and the entry point might be too far away for bl. Pc() serves 3770 // as dummy and bl will be patched later. 3771 __ bl((address) __ pc()); 3772 %} 3773 3774 // postalloc expand emitter for virtual calls. 3775 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3776 3777 // Create the nodes for loading the IC from the TOC. 3778 loadConLNodesTuple loadConLNodes_IC = 3779 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3780 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3781 3782 // Create the call node. 3783 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3784 call->_method_handle_invoke = _method_handle_invoke; 3785 call->_vtable_index = _vtable_index; 3786 call->_method = _method; 3787 call->_bci = _bci; 3788 call->_optimized_virtual = _optimized_virtual; 3789 call->_tf = _tf; 3790 call->_entry_point = _entry_point; 3791 call->_cnt = _cnt; 3792 call->_argsize = _argsize; 3793 call->_oop_map = _oop_map; 3794 call->_jvms = _jvms; 3795 call->_jvmadj = _jvmadj; 3796 call->_in_rms = _in_rms; 3797 call->_nesting = _nesting; 3798 call->_override_symbolic_info = _override_symbolic_info; 3799 3800 // New call needs all inputs of old call. 3801 // Req... 3802 for (uint i = 0; i < req(); ++i) { 3803 // The expanded node does not need toc any more. 3804 // Add the inline cache constant here instead. This expresses the 3805 // register of the inline cache must be live at the call. 3806 // Else we would have to adapt JVMState by -1. 3807 if (i == mach_constant_base_node_input()) { 3808 call->add_req(loadConLNodes_IC._last); 3809 } else { 3810 call->add_req(in(i)); 3811 } 3812 } 3813 // ...as well as prec 3814 for (uint i = req(); i < len(); ++i) { 3815 call->add_prec(in(i)); 3816 } 3817 3818 // Remember nodes loading the inline cache into r19. 3819 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3820 call->_load_ic_node = loadConLNodes_IC._small; 3821 3822 // Operands for new nodes. 3823 call->_opnds[0] = _opnds[0]; 3824 call->_opnds[1] = _opnds[1]; 3825 3826 // Only the inline cache is associated with a register. 3827 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3828 3829 // Push new nodes. 3830 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3831 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3832 nodes->push(call); 3833 %} 3834 3835 // Compound version of call dynamic 3836 // Toc is only passed so that it can be used in ins_encode statement. 3837 // In the code we have to use $constanttablebase. 3838 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3839 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3840 MacroAssembler _masm(&cbuf); 3841 int start_offset = __ offset(); 3842 3843 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3844 #if 0 3845 int vtable_index = this->_vtable_index; 3846 if (_vtable_index < 0) { 3847 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3848 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3849 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3850 3851 // Virtual call relocation will point to ic load. 3852 address virtual_call_meta_addr = __ pc(); 3853 // Load a clear inline cache. 3854 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3855 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3856 if (!success) { 3857 ciEnv::current()->record_out_of_memory_failure(); 3858 return; 3859 } 3860 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3861 // to determine who we intended to call. 3862 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3863 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3864 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3865 "Fix constant in ret_addr_offset()"); 3866 } else { 3867 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3868 // Go thru the vtable. Get receiver klass. Receiver already 3869 // checked for non-null. If we'll go thru a C2I adapter, the 3870 // interpreter expects method in R19_method. 3871 3872 __ load_klass(R11_scratch1, R3); 3873 3874 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3875 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3876 __ li(R19_method, v_off); 3877 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3878 // NOTE: for vtable dispatches, the vtable entry will never be 3879 // null. However it may very well end up in handle_wrong_method 3880 // if the method is abstract for the particular class. 3881 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3882 // Call target. Either compiled code or C2I adapter. 3883 __ mtctr(R11_scratch1); 3884 __ bctrl(); 3885 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3886 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3887 } 3888 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3889 "Fix constant in ret_addr_offset()"); 3890 } 3891 #endif 3892 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3893 %} 3894 3895 // a runtime call 3896 enc_class enc_java_to_runtime_call (method meth) %{ 3897 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3898 3899 MacroAssembler _masm(&cbuf); 3900 const address start_pc = __ pc(); 3901 3902 #if defined(ABI_ELFv2) 3903 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3904 __ call_c(entry, relocInfo::runtime_call_type); 3905 #else 3906 // The function we're going to call. 3907 FunctionDescriptor fdtemp; 3908 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3909 3910 Register Rtoc = R12_scratch2; 3911 // Calculate the method's TOC. 3912 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3913 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3914 // pool entries; call_c_using_toc will optimize the call. 3915 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3916 if (!success) { 3917 ciEnv::current()->record_out_of_memory_failure(); 3918 return; 3919 } 3920 #endif 3921 3922 // Check the ret_addr_offset. 3923 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3924 "Fix constant in ret_addr_offset()"); 3925 %} 3926 3927 // Move to ctr for leaf call. 3928 // This enc_class is needed so that scheduler gets proper 3929 // input mapping for latency computation. 3930 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3931 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3932 MacroAssembler _masm(&cbuf); 3933 __ mtctr($src$$Register); 3934 %} 3935 3936 // Postalloc expand emitter for runtime leaf calls. 3937 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3938 loadConLNodesTuple loadConLNodes_Entry; 3939 #if defined(ABI_ELFv2) 3940 jlong entry_address = (jlong) this->entry_point(); 3941 assert(entry_address, "need address here"); 3942 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3943 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3944 #else 3945 // Get the struct that describes the function we are about to call. 3946 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3947 assert(fd, "need fd here"); 3948 jlong entry_address = (jlong) fd->entry(); 3949 // new nodes 3950 loadConLNodesTuple loadConLNodes_Env; 3951 loadConLNodesTuple loadConLNodes_Toc; 3952 3953 // Create nodes and operands for loading the entry point. 3954 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3955 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3956 3957 3958 // Create nodes and operands for loading the env pointer. 3959 if (fd->env() != NULL) { 3960 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3961 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3962 } else { 3963 loadConLNodes_Env._large_hi = NULL; 3964 loadConLNodes_Env._large_lo = NULL; 3965 loadConLNodes_Env._small = NULL; 3966 loadConLNodes_Env._last = new loadConL16Node(); 3967 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3968 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3969 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3970 } 3971 3972 // Create nodes and operands for loading the Toc point. 3973 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3974 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3975 #endif // ABI_ELFv2 3976 // mtctr node 3977 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3978 3979 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3980 mtctr->add_req(0, loadConLNodes_Entry._last); 3981 3982 mtctr->_opnds[0] = new iRegLdstOper(); 3983 mtctr->_opnds[1] = new iRegLdstOper(); 3984 3985 // call node 3986 MachCallLeafNode *call = new CallLeafDirectNode(); 3987 3988 call->_opnds[0] = _opnds[0]; 3989 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3990 3991 // Make the new call node look like the old one. 3992 call->_name = _name; 3993 call->_tf = _tf; 3994 call->_entry_point = _entry_point; 3995 call->_cnt = _cnt; 3996 call->_argsize = _argsize; 3997 call->_oop_map = _oop_map; 3998 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3999 call->_jvms = NULL; 4000 call->_jvmadj = _jvmadj; 4001 call->_in_rms = _in_rms; 4002 call->_nesting = _nesting; 4003 4004 4005 // New call needs all inputs of old call. 4006 // Req... 4007 for (uint i = 0; i < req(); ++i) { 4008 if (i != mach_constant_base_node_input()) { 4009 call->add_req(in(i)); 4010 } 4011 } 4012 4013 // These must be reqired edges, as the registers are live up to 4014 // the call. Else the constants are handled as kills. 4015 call->add_req(mtctr); 4016 #if !defined(ABI_ELFv2) 4017 call->add_req(loadConLNodes_Env._last); 4018 call->add_req(loadConLNodes_Toc._last); 4019 #endif 4020 4021 // ...as well as prec 4022 for (uint i = req(); i < len(); ++i) { 4023 call->add_prec(in(i)); 4024 } 4025 4026 // registers 4027 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 4028 4029 // Insert the new nodes. 4030 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 4031 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 4032 #if !defined(ABI_ELFv2) 4033 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 4034 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 4035 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 4036 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 4037 #endif 4038 nodes->push(mtctr); 4039 nodes->push(call); 4040 %} 4041 %} 4042 4043 //----------FRAME-------------------------------------------------------------- 4044 // Definition of frame structure and management information. 4045 4046 frame %{ 4047 // What direction does stack grow in (assumed to be same for native & Java). 4048 stack_direction(TOWARDS_LOW); 4049 4050 // These two registers define part of the calling convention between 4051 // compiled code and the interpreter. 4052 4053 // Inline Cache Register or method for I2C. 4054 inline_cache_reg(R19); // R19_method 4055 4056 // Method Oop Register when calling interpreter. 4057 interpreter_method_oop_reg(R19); // R19_method 4058 4059 // Optional: name the operand used by cisc-spilling to access 4060 // [stack_pointer + offset]. 4061 cisc_spilling_operand_name(indOffset); 4062 4063 // Number of stack slots consumed by a Monitor enter. 4064 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 4065 4066 // Compiled code's Frame Pointer. 4067 frame_pointer(R1); // R1_SP 4068 4069 // Interpreter stores its frame pointer in a register which is 4070 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 4071 // interpreted java to compiled java. 4072 // 4073 // R14_state holds pointer to caller's cInterpreter. 4074 interpreter_frame_pointer(R14); // R14_state 4075 4076 stack_alignment(frame::alignment_in_bytes); 4077 4078 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4079 4080 // Number of outgoing stack slots killed above the 4081 // out_preserve_stack_slots for calls to C. Supports the var-args 4082 // backing area for register parms. 4083 // 4084 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4085 4086 // The after-PROLOG location of the return address. Location of 4087 // return address specifies a type (REG or STACK) and a number 4088 // representing the register number (i.e. - use a register name) or 4089 // stack slot. 4090 // 4091 // A: Link register is stored in stack slot ... 4092 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4093 // J: Therefore, we make sure that the link register is also in R11_scratch1 4094 // at the end of the prolog. 4095 // B: We use R20, now. 4096 //return_addr(REG R20); 4097 4098 // G: After reading the comments made by all the luminaries on their 4099 // failure to tell the compiler where the return address really is, 4100 // I hardly dare to try myself. However, I'm convinced it's in slot 4101 // 4 what apparently works and saves us some spills. 4102 return_addr(STACK 4); 4103 4104 // This is the body of the function 4105 // 4106 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4107 // uint length, // length of array 4108 // bool is_outgoing) 4109 // 4110 // The `sig' array is to be updated. sig[j] represents the location 4111 // of the j-th argument, either a register or a stack slot. 4112 4113 // Comment taken from i486.ad: 4114 // Body of function which returns an integer array locating 4115 // arguments either in registers or in stack slots. Passed an array 4116 // of ideal registers called "sig" and a "length" count. Stack-slot 4117 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4118 // arguments for a CALLEE. Incoming stack arguments are 4119 // automatically biased by the preserve_stack_slots field above. 4120 calling_convention %{ 4121 // No difference between ingoing/outgoing. Just pass false. 4122 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4123 %} 4124 4125 // Comment taken from i486.ad: 4126 // Body of function which returns an integer array locating 4127 // arguments either in registers or in stack slots. Passed an array 4128 // of ideal registers called "sig" and a "length" count. Stack-slot 4129 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4130 // arguments for a CALLEE. Incoming stack arguments are 4131 // automatically biased by the preserve_stack_slots field above. 4132 c_calling_convention %{ 4133 // This is obviously always outgoing. 4134 // C argument in register AND stack slot. 4135 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4136 %} 4137 4138 // Location of native (C/C++) and interpreter return values. This 4139 // is specified to be the same as Java. In the 32-bit VM, long 4140 // values are actually returned from native calls in O0:O1 and 4141 // returned to the interpreter in I0:I1. The copying to and from 4142 // the register pairs is done by the appropriate call and epilog 4143 // opcodes. This simplifies the register allocator. 4144 c_return_value %{ 4145 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4146 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4147 "only return normal values"); 4148 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4149 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4150 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4151 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4152 %} 4153 4154 // Location of compiled Java return values. Same as C 4155 return_value %{ 4156 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4157 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4158 "only return normal values"); 4159 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4160 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4161 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4162 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4163 %} 4164 %} 4165 4166 4167 //----------ATTRIBUTES--------------------------------------------------------- 4168 4169 //----------Operand Attributes------------------------------------------------- 4170 op_attrib op_cost(1); // Required cost attribute. 4171 4172 //----------Instruction Attributes--------------------------------------------- 4173 4174 // Cost attribute. required. 4175 ins_attrib ins_cost(DEFAULT_COST); 4176 4177 // Is this instruction a non-matching short branch variant of some 4178 // long branch? Not required. 4179 ins_attrib ins_short_branch(0); 4180 4181 ins_attrib ins_is_TrapBasedCheckNode(true); 4182 4183 // Number of constants. 4184 // This instruction uses the given number of constants 4185 // (optional attribute). 4186 // This is needed to determine in time whether the constant pool will 4187 // exceed 4000 entries. Before postalloc_expand the overall number of constants 4188 // is determined. It's also used to compute the constant pool size 4189 // in Output(). 4190 ins_attrib ins_num_consts(0); 4191 4192 // Required alignment attribute (must be a power of 2) specifies the 4193 // alignment that some part of the instruction (not necessarily the 4194 // start) requires. If > 1, a compute_padding() function must be 4195 // provided for the instruction. 4196 ins_attrib ins_alignment(1); 4197 4198 // Enforce/prohibit rematerializations. 4199 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4200 // then rematerialization of that instruction is prohibited and the 4201 // instruction's value will be spilled if necessary. 4202 // Causes that MachNode::rematerialize() returns false. 4203 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 4204 // then rematerialization should be enforced and a copy of the instruction 4205 // should be inserted if possible; rematerialization is not guaranteed. 4206 // Note: this may result in rematerializations in front of every use. 4207 // Causes that MachNode::rematerialize() can return true. 4208 // (optional attribute) 4209 ins_attrib ins_cannot_rematerialize(false); 4210 ins_attrib ins_should_rematerialize(false); 4211 4212 // Instruction has variable size depending on alignment. 4213 ins_attrib ins_variable_size_depending_on_alignment(false); 4214 4215 // Instruction is a nop. 4216 ins_attrib ins_is_nop(false); 4217 4218 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4219 ins_attrib ins_use_mach_if_fast_lock_node(false); 4220 4221 // Field for the toc offset of a constant. 4222 // 4223 // This is needed if the toc offset is not encodable as an immediate in 4224 // the PPC load instruction. If so, the upper (hi) bits of the offset are 4225 // added to the toc, and from this a load with immediate is performed. 4226 // With postalloc expand, we get two nodes that require the same offset 4227 // but which don't know about each other. The offset is only known 4228 // when the constant is added to the constant pool during emitting. 4229 // It is generated in the 'hi'-node adding the upper bits, and saved 4230 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 4231 // the offset from there when it gets encoded. 4232 ins_attrib ins_field_const_toc_offset(0); 4233 ins_attrib ins_field_const_toc_offset_hi_node(0); 4234 4235 // A field that can hold the instructions offset in the code buffer. 4236 // Set in the nodes emitter. 4237 ins_attrib ins_field_cbuf_insts_offset(-1); 4238 4239 // Fields for referencing a call's load-IC-node. 4240 // If the toc offset can not be encoded as an immediate in a load, we 4241 // use two nodes. 4242 ins_attrib ins_field_load_ic_hi_node(0); 4243 ins_attrib ins_field_load_ic_node(0); 4244 4245 //----------OPERANDS----------------------------------------------------------- 4246 // Operand definitions must precede instruction definitions for correct 4247 // parsing in the ADLC because operands constitute user defined types 4248 // which are used in instruction definitions. 4249 // 4250 // Formats are generated automatically for constants and base registers. 4251 4252 operand vecX() %{ 4253 constraint(ALLOC_IN_RC(vs_reg)); 4254 match(VecX); 4255 4256 format %{ %} 4257 interface(REG_INTER); 4258 %} 4259 4260 //----------Simple Operands---------------------------------------------------- 4261 // Immediate Operands 4262 4263 // Integer Immediate: 32-bit 4264 operand immI() %{ 4265 match(ConI); 4266 op_cost(40); 4267 format %{ %} 4268 interface(CONST_INTER); 4269 %} 4270 4271 operand immI8() %{ 4272 predicate(Assembler::is_simm(n->get_int(), 8)); 4273 op_cost(0); 4274 match(ConI); 4275 format %{ %} 4276 interface(CONST_INTER); 4277 %} 4278 4279 // Integer Immediate: 16-bit 4280 operand immI16() %{ 4281 predicate(Assembler::is_simm(n->get_int(), 16)); 4282 op_cost(0); 4283 match(ConI); 4284 format %{ %} 4285 interface(CONST_INTER); 4286 %} 4287 4288 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4289 operand immIhi16() %{ 4290 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4291 match(ConI); 4292 op_cost(0); 4293 format %{ %} 4294 interface(CONST_INTER); 4295 %} 4296 4297 operand immInegpow2() %{ 4298 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 4299 match(ConI); 4300 op_cost(0); 4301 format %{ %} 4302 interface(CONST_INTER); 4303 %} 4304 4305 operand immIpow2minus1() %{ 4306 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 4307 match(ConI); 4308 op_cost(0); 4309 format %{ %} 4310 interface(CONST_INTER); 4311 %} 4312 4313 operand immIpowerOf2() %{ 4314 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 4315 match(ConI); 4316 op_cost(0); 4317 format %{ %} 4318 interface(CONST_INTER); 4319 %} 4320 4321 // Unsigned Integer Immediate: the values 0-31 4322 operand uimmI5() %{ 4323 predicate(Assembler::is_uimm(n->get_int(), 5)); 4324 match(ConI); 4325 op_cost(0); 4326 format %{ %} 4327 interface(CONST_INTER); 4328 %} 4329 4330 // Unsigned Integer Immediate: 6-bit 4331 operand uimmI6() %{ 4332 predicate(Assembler::is_uimm(n->get_int(), 6)); 4333 match(ConI); 4334 op_cost(0); 4335 format %{ %} 4336 interface(CONST_INTER); 4337 %} 4338 4339 // Unsigned Integer Immediate: 6-bit int, greater than 32 4340 operand uimmI6_ge32() %{ 4341 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4342 match(ConI); 4343 op_cost(0); 4344 format %{ %} 4345 interface(CONST_INTER); 4346 %} 4347 4348 // Unsigned Integer Immediate: 15-bit 4349 operand uimmI15() %{ 4350 predicate(Assembler::is_uimm(n->get_int(), 15)); 4351 match(ConI); 4352 op_cost(0); 4353 format %{ %} 4354 interface(CONST_INTER); 4355 %} 4356 4357 // Unsigned Integer Immediate: 16-bit 4358 operand uimmI16() %{ 4359 predicate(Assembler::is_uimm(n->get_int(), 16)); 4360 match(ConI); 4361 op_cost(0); 4362 format %{ %} 4363 interface(CONST_INTER); 4364 %} 4365 4366 // constant 'int 0'. 4367 operand immI_0() %{ 4368 predicate(n->get_int() == 0); 4369 match(ConI); 4370 op_cost(0); 4371 format %{ %} 4372 interface(CONST_INTER); 4373 %} 4374 4375 // constant 'int 1'. 4376 operand immI_1() %{ 4377 predicate(n->get_int() == 1); 4378 match(ConI); 4379 op_cost(0); 4380 format %{ %} 4381 interface(CONST_INTER); 4382 %} 4383 4384 // constant 'int -1'. 4385 operand immI_minus1() %{ 4386 predicate(n->get_int() == -1); 4387 match(ConI); 4388 op_cost(0); 4389 format %{ %} 4390 interface(CONST_INTER); 4391 %} 4392 4393 // int value 16. 4394 operand immI_16() %{ 4395 predicate(n->get_int() == 16); 4396 match(ConI); 4397 op_cost(0); 4398 format %{ %} 4399 interface(CONST_INTER); 4400 %} 4401 4402 // int value 24. 4403 operand immI_24() %{ 4404 predicate(n->get_int() == 24); 4405 match(ConI); 4406 op_cost(0); 4407 format %{ %} 4408 interface(CONST_INTER); 4409 %} 4410 4411 // Compressed oops constants 4412 // Pointer Immediate 4413 operand immN() %{ 4414 match(ConN); 4415 4416 op_cost(10); 4417 format %{ %} 4418 interface(CONST_INTER); 4419 %} 4420 4421 // NULL Pointer Immediate 4422 operand immN_0() %{ 4423 predicate(n->get_narrowcon() == 0); 4424 match(ConN); 4425 4426 op_cost(0); 4427 format %{ %} 4428 interface(CONST_INTER); 4429 %} 4430 4431 // Compressed klass constants 4432 operand immNKlass() %{ 4433 match(ConNKlass); 4434 4435 op_cost(0); 4436 format %{ %} 4437 interface(CONST_INTER); 4438 %} 4439 4440 // This operand can be used to avoid matching of an instruct 4441 // with chain rule. 4442 operand immNKlass_NM() %{ 4443 match(ConNKlass); 4444 predicate(false); 4445 op_cost(0); 4446 format %{ %} 4447 interface(CONST_INTER); 4448 %} 4449 4450 // Pointer Immediate: 64-bit 4451 operand immP() %{ 4452 match(ConP); 4453 op_cost(0); 4454 format %{ %} 4455 interface(CONST_INTER); 4456 %} 4457 4458 // Operand to avoid match of loadConP. 4459 // This operand can be used to avoid matching of an instruct 4460 // with chain rule. 4461 operand immP_NM() %{ 4462 match(ConP); 4463 predicate(false); 4464 op_cost(0); 4465 format %{ %} 4466 interface(CONST_INTER); 4467 %} 4468 4469 // costant 'pointer 0'. 4470 operand immP_0() %{ 4471 predicate(n->get_ptr() == 0); 4472 match(ConP); 4473 op_cost(0); 4474 format %{ %} 4475 interface(CONST_INTER); 4476 %} 4477 4478 // pointer 0x0 or 0x1 4479 operand immP_0or1() %{ 4480 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4481 match(ConP); 4482 op_cost(0); 4483 format %{ %} 4484 interface(CONST_INTER); 4485 %} 4486 4487 operand immL() %{ 4488 match(ConL); 4489 op_cost(40); 4490 format %{ %} 4491 interface(CONST_INTER); 4492 %} 4493 4494 operand immLmax30() %{ 4495 predicate((n->get_long() <= 30)); 4496 match(ConL); 4497 op_cost(0); 4498 format %{ %} 4499 interface(CONST_INTER); 4500 %} 4501 4502 // Long Immediate: 16-bit 4503 operand immL16() %{ 4504 predicate(Assembler::is_simm(n->get_long(), 16)); 4505 match(ConL); 4506 op_cost(0); 4507 format %{ %} 4508 interface(CONST_INTER); 4509 %} 4510 4511 // Long Immediate: 16-bit, 4-aligned 4512 operand immL16Alg4() %{ 4513 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4514 match(ConL); 4515 op_cost(0); 4516 format %{ %} 4517 interface(CONST_INTER); 4518 %} 4519 4520 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4521 operand immL32hi16() %{ 4522 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4523 match(ConL); 4524 op_cost(0); 4525 format %{ %} 4526 interface(CONST_INTER); 4527 %} 4528 4529 // Long Immediate: 32-bit 4530 operand immL32() %{ 4531 predicate(Assembler::is_simm(n->get_long(), 32)); 4532 match(ConL); 4533 op_cost(0); 4534 format %{ %} 4535 interface(CONST_INTER); 4536 %} 4537 4538 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4539 operand immLhighest16() %{ 4540 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4541 match(ConL); 4542 op_cost(0); 4543 format %{ %} 4544 interface(CONST_INTER); 4545 %} 4546 4547 operand immLnegpow2() %{ 4548 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4549 match(ConL); 4550 op_cost(0); 4551 format %{ %} 4552 interface(CONST_INTER); 4553 %} 4554 4555 operand immLpow2minus1() %{ 4556 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4557 (n->get_long() != (jlong)0xffffffffffffffffL)); 4558 match(ConL); 4559 op_cost(0); 4560 format %{ %} 4561 interface(CONST_INTER); 4562 %} 4563 4564 // constant 'long 0'. 4565 operand immL_0() %{ 4566 predicate(n->get_long() == 0L); 4567 match(ConL); 4568 op_cost(0); 4569 format %{ %} 4570 interface(CONST_INTER); 4571 %} 4572 4573 // constat ' long -1'. 4574 operand immL_minus1() %{ 4575 predicate(n->get_long() == -1L); 4576 match(ConL); 4577 op_cost(0); 4578 format %{ %} 4579 interface(CONST_INTER); 4580 %} 4581 4582 // Long Immediate: low 32-bit mask 4583 operand immL_32bits() %{ 4584 predicate(n->get_long() == 0xFFFFFFFFL); 4585 match(ConL); 4586 op_cost(0); 4587 format %{ %} 4588 interface(CONST_INTER); 4589 %} 4590 4591 // Unsigned Long Immediate: 16-bit 4592 operand uimmL16() %{ 4593 predicate(Assembler::is_uimm(n->get_long(), 16)); 4594 match(ConL); 4595 op_cost(0); 4596 format %{ %} 4597 interface(CONST_INTER); 4598 %} 4599 4600 // Float Immediate 4601 operand immF() %{ 4602 match(ConF); 4603 op_cost(40); 4604 format %{ %} 4605 interface(CONST_INTER); 4606 %} 4607 4608 // Float Immediate: +0.0f. 4609 operand immF_0() %{ 4610 predicate(jint_cast(n->getf()) == 0); 4611 match(ConF); 4612 4613 op_cost(0); 4614 format %{ %} 4615 interface(CONST_INTER); 4616 %} 4617 4618 // Double Immediate 4619 operand immD() %{ 4620 match(ConD); 4621 op_cost(40); 4622 format %{ %} 4623 interface(CONST_INTER); 4624 %} 4625 4626 // Integer Register Operands 4627 // Integer Destination Register 4628 // See definition of reg_class bits32_reg_rw. 4629 operand iRegIdst() %{ 4630 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4631 match(RegI); 4632 match(rscratch1RegI); 4633 match(rscratch2RegI); 4634 match(rarg1RegI); 4635 match(rarg2RegI); 4636 match(rarg3RegI); 4637 match(rarg4RegI); 4638 format %{ %} 4639 interface(REG_INTER); 4640 %} 4641 4642 // Integer Source Register 4643 // See definition of reg_class bits32_reg_ro. 4644 operand iRegIsrc() %{ 4645 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4646 match(RegI); 4647 match(rscratch1RegI); 4648 match(rscratch2RegI); 4649 match(rarg1RegI); 4650 match(rarg2RegI); 4651 match(rarg3RegI); 4652 match(rarg4RegI); 4653 format %{ %} 4654 interface(REG_INTER); 4655 %} 4656 4657 operand rscratch1RegI() %{ 4658 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4659 match(iRegIdst); 4660 format %{ %} 4661 interface(REG_INTER); 4662 %} 4663 4664 operand rscratch2RegI() %{ 4665 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4666 match(iRegIdst); 4667 format %{ %} 4668 interface(REG_INTER); 4669 %} 4670 4671 operand rarg1RegI() %{ 4672 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4673 match(iRegIdst); 4674 format %{ %} 4675 interface(REG_INTER); 4676 %} 4677 4678 operand rarg2RegI() %{ 4679 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4680 match(iRegIdst); 4681 format %{ %} 4682 interface(REG_INTER); 4683 %} 4684 4685 operand rarg3RegI() %{ 4686 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4687 match(iRegIdst); 4688 format %{ %} 4689 interface(REG_INTER); 4690 %} 4691 4692 operand rarg4RegI() %{ 4693 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4694 match(iRegIdst); 4695 format %{ %} 4696 interface(REG_INTER); 4697 %} 4698 4699 operand rarg1RegL() %{ 4700 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4701 match(iRegLdst); 4702 format %{ %} 4703 interface(REG_INTER); 4704 %} 4705 4706 operand rarg2RegL() %{ 4707 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4708 match(iRegLdst); 4709 format %{ %} 4710 interface(REG_INTER); 4711 %} 4712 4713 operand rarg3RegL() %{ 4714 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4715 match(iRegLdst); 4716 format %{ %} 4717 interface(REG_INTER); 4718 %} 4719 4720 operand rarg4RegL() %{ 4721 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4722 match(iRegLdst); 4723 format %{ %} 4724 interface(REG_INTER); 4725 %} 4726 4727 // Pointer Destination Register 4728 // See definition of reg_class bits64_reg_rw. 4729 operand iRegPdst() %{ 4730 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4731 match(RegP); 4732 match(rscratch1RegP); 4733 match(rscratch2RegP); 4734 match(rarg1RegP); 4735 match(rarg2RegP); 4736 match(rarg3RegP); 4737 match(rarg4RegP); 4738 format %{ %} 4739 interface(REG_INTER); 4740 %} 4741 4742 // Pointer Destination Register 4743 // Operand not using r11 and r12 (killed in epilog). 4744 operand iRegPdstNoScratch() %{ 4745 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4746 match(RegP); 4747 match(rarg1RegP); 4748 match(rarg2RegP); 4749 match(rarg3RegP); 4750 match(rarg4RegP); 4751 format %{ %} 4752 interface(REG_INTER); 4753 %} 4754 4755 // Pointer Source Register 4756 // See definition of reg_class bits64_reg_ro. 4757 operand iRegPsrc() %{ 4758 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4759 match(RegP); 4760 match(iRegPdst); 4761 match(rscratch1RegP); 4762 match(rscratch2RegP); 4763 match(rarg1RegP); 4764 match(rarg2RegP); 4765 match(rarg3RegP); 4766 match(rarg4RegP); 4767 match(threadRegP); 4768 format %{ %} 4769 interface(REG_INTER); 4770 %} 4771 4772 // Thread operand. 4773 operand threadRegP() %{ 4774 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4775 match(iRegPdst); 4776 format %{ "R16" %} 4777 interface(REG_INTER); 4778 %} 4779 4780 operand rscratch1RegP() %{ 4781 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4782 match(iRegPdst); 4783 format %{ "R11" %} 4784 interface(REG_INTER); 4785 %} 4786 4787 operand rscratch2RegP() %{ 4788 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4789 match(iRegPdst); 4790 format %{ %} 4791 interface(REG_INTER); 4792 %} 4793 4794 operand rarg1RegP() %{ 4795 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4796 match(iRegPdst); 4797 format %{ %} 4798 interface(REG_INTER); 4799 %} 4800 4801 operand rarg2RegP() %{ 4802 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4803 match(iRegPdst); 4804 format %{ %} 4805 interface(REG_INTER); 4806 %} 4807 4808 operand rarg3RegP() %{ 4809 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4810 match(iRegPdst); 4811 format %{ %} 4812 interface(REG_INTER); 4813 %} 4814 4815 operand rarg4RegP() %{ 4816 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4817 match(iRegPdst); 4818 format %{ %} 4819 interface(REG_INTER); 4820 %} 4821 4822 operand iRegNsrc() %{ 4823 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4824 match(RegN); 4825 match(iRegNdst); 4826 4827 format %{ %} 4828 interface(REG_INTER); 4829 %} 4830 4831 operand iRegNdst() %{ 4832 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4833 match(RegN); 4834 4835 format %{ %} 4836 interface(REG_INTER); 4837 %} 4838 4839 // Long Destination Register 4840 // See definition of reg_class bits64_reg_rw. 4841 operand iRegLdst() %{ 4842 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4843 match(RegL); 4844 match(rscratch1RegL); 4845 match(rscratch2RegL); 4846 format %{ %} 4847 interface(REG_INTER); 4848 %} 4849 4850 // Long Source Register 4851 // See definition of reg_class bits64_reg_ro. 4852 operand iRegLsrc() %{ 4853 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4854 match(RegL); 4855 match(iRegLdst); 4856 match(rscratch1RegL); 4857 match(rscratch2RegL); 4858 format %{ %} 4859 interface(REG_INTER); 4860 %} 4861 4862 // Special operand for ConvL2I. 4863 operand iRegL2Isrc(iRegLsrc reg) %{ 4864 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4865 match(ConvL2I reg); 4866 format %{ "ConvL2I($reg)" %} 4867 interface(REG_INTER) 4868 %} 4869 4870 operand rscratch1RegL() %{ 4871 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4872 match(RegL); 4873 format %{ %} 4874 interface(REG_INTER); 4875 %} 4876 4877 operand rscratch2RegL() %{ 4878 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4879 match(RegL); 4880 format %{ %} 4881 interface(REG_INTER); 4882 %} 4883 4884 // Condition Code Flag Registers 4885 operand flagsReg() %{ 4886 constraint(ALLOC_IN_RC(int_flags)); 4887 match(RegFlags); 4888 format %{ %} 4889 interface(REG_INTER); 4890 %} 4891 4892 operand flagsRegSrc() %{ 4893 constraint(ALLOC_IN_RC(int_flags_ro)); 4894 match(RegFlags); 4895 match(flagsReg); 4896 match(flagsRegCR0); 4897 format %{ %} 4898 interface(REG_INTER); 4899 %} 4900 4901 // Condition Code Flag Register CR0 4902 operand flagsRegCR0() %{ 4903 constraint(ALLOC_IN_RC(int_flags_CR0)); 4904 match(RegFlags); 4905 format %{ "CR0" %} 4906 interface(REG_INTER); 4907 %} 4908 4909 operand flagsRegCR1() %{ 4910 constraint(ALLOC_IN_RC(int_flags_CR1)); 4911 match(RegFlags); 4912 format %{ "CR1" %} 4913 interface(REG_INTER); 4914 %} 4915 4916 operand flagsRegCR6() %{ 4917 constraint(ALLOC_IN_RC(int_flags_CR6)); 4918 match(RegFlags); 4919 format %{ "CR6" %} 4920 interface(REG_INTER); 4921 %} 4922 4923 operand regCTR() %{ 4924 constraint(ALLOC_IN_RC(ctr_reg)); 4925 // RegFlags should work. Introducing a RegSpecial type would cause a 4926 // lot of changes. 4927 match(RegFlags); 4928 format %{"SR_CTR" %} 4929 interface(REG_INTER); 4930 %} 4931 4932 operand regD() %{ 4933 constraint(ALLOC_IN_RC(dbl_reg)); 4934 match(RegD); 4935 format %{ %} 4936 interface(REG_INTER); 4937 %} 4938 4939 operand regF() %{ 4940 constraint(ALLOC_IN_RC(flt_reg)); 4941 match(RegF); 4942 format %{ %} 4943 interface(REG_INTER); 4944 %} 4945 4946 // Special Registers 4947 4948 // Method Register 4949 operand inline_cache_regP(iRegPdst reg) %{ 4950 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4951 match(reg); 4952 format %{ %} 4953 interface(REG_INTER); 4954 %} 4955 4956 operand compiler_method_oop_regP(iRegPdst reg) %{ 4957 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4958 match(reg); 4959 format %{ %} 4960 interface(REG_INTER); 4961 %} 4962 4963 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4964 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4965 match(reg); 4966 format %{ %} 4967 interface(REG_INTER); 4968 %} 4969 4970 // Operands to remove register moves in unscaled mode. 4971 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4972 operand iRegP2N(iRegPsrc reg) %{ 4973 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4974 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4975 match(EncodeP reg); 4976 format %{ "$reg" %} 4977 interface(REG_INTER) 4978 %} 4979 4980 operand iRegN2P(iRegNsrc reg) %{ 4981 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4982 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4983 match(DecodeN reg); 4984 format %{ "$reg" %} 4985 interface(REG_INTER) 4986 %} 4987 4988 operand iRegN2P_klass(iRegNsrc reg) %{ 4989 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4990 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4991 match(DecodeNKlass reg); 4992 format %{ "$reg" %} 4993 interface(REG_INTER) 4994 %} 4995 4996 //----------Complex Operands--------------------------------------------------- 4997 // Indirect Memory Reference 4998 operand indirect(iRegPsrc reg) %{ 4999 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5000 match(reg); 5001 op_cost(100); 5002 format %{ "[$reg]" %} 5003 interface(MEMORY_INTER) %{ 5004 base($reg); 5005 index(0x0); 5006 scale(0x0); 5007 disp(0x0); 5008 %} 5009 %} 5010 5011 // Indirect with Offset 5012 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 5013 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5014 match(AddP reg offset); 5015 op_cost(100); 5016 format %{ "[$reg + $offset]" %} 5017 interface(MEMORY_INTER) %{ 5018 base($reg); 5019 index(0x0); 5020 scale(0x0); 5021 disp($offset); 5022 %} 5023 %} 5024 5025 // Indirect with 4-aligned Offset 5026 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 5027 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5028 match(AddP reg offset); 5029 op_cost(100); 5030 format %{ "[$reg + $offset]" %} 5031 interface(MEMORY_INTER) %{ 5032 base($reg); 5033 index(0x0); 5034 scale(0x0); 5035 disp($offset); 5036 %} 5037 %} 5038 5039 //----------Complex Operands for Compressed OOPs------------------------------- 5040 // Compressed OOPs with narrow_oop_shift == 0. 5041 5042 // Indirect Memory Reference, compressed OOP 5043 operand indirectNarrow(iRegNsrc reg) %{ 5044 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5045 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5046 match(DecodeN reg); 5047 op_cost(100); 5048 format %{ "[$reg]" %} 5049 interface(MEMORY_INTER) %{ 5050 base($reg); 5051 index(0x0); 5052 scale(0x0); 5053 disp(0x0); 5054 %} 5055 %} 5056 5057 operand indirectNarrow_klass(iRegNsrc reg) %{ 5058 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5059 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5060 match(DecodeNKlass reg); 5061 op_cost(100); 5062 format %{ "[$reg]" %} 5063 interface(MEMORY_INTER) %{ 5064 base($reg); 5065 index(0x0); 5066 scale(0x0); 5067 disp(0x0); 5068 %} 5069 %} 5070 5071 // Indirect with Offset, compressed OOP 5072 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 5073 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5074 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5075 match(AddP (DecodeN reg) offset); 5076 op_cost(100); 5077 format %{ "[$reg + $offset]" %} 5078 interface(MEMORY_INTER) %{ 5079 base($reg); 5080 index(0x0); 5081 scale(0x0); 5082 disp($offset); 5083 %} 5084 %} 5085 5086 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5087 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5088 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5089 match(AddP (DecodeNKlass reg) offset); 5090 op_cost(100); 5091 format %{ "[$reg + $offset]" %} 5092 interface(MEMORY_INTER) %{ 5093 base($reg); 5094 index(0x0); 5095 scale(0x0); 5096 disp($offset); 5097 %} 5098 %} 5099 5100 // Indirect with 4-aligned Offset, compressed OOP 5101 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 5102 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5103 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5104 match(AddP (DecodeN reg) offset); 5105 op_cost(100); 5106 format %{ "[$reg + $offset]" %} 5107 interface(MEMORY_INTER) %{ 5108 base($reg); 5109 index(0x0); 5110 scale(0x0); 5111 disp($offset); 5112 %} 5113 %} 5114 5115 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5116 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5117 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5118 match(AddP (DecodeNKlass reg) offset); 5119 op_cost(100); 5120 format %{ "[$reg + $offset]" %} 5121 interface(MEMORY_INTER) %{ 5122 base($reg); 5123 index(0x0); 5124 scale(0x0); 5125 disp($offset); 5126 %} 5127 %} 5128 5129 //----------Special Memory Operands-------------------------------------------- 5130 // Stack Slot Operand 5131 // 5132 // This operand is used for loading and storing temporary values on 5133 // the stack where a match requires a value to flow through memory. 5134 operand stackSlotI(sRegI reg) %{ 5135 constraint(ALLOC_IN_RC(stack_slots)); 5136 op_cost(100); 5137 //match(RegI); 5138 format %{ "[sp+$reg]" %} 5139 interface(MEMORY_INTER) %{ 5140 base(0x1); // R1_SP 5141 index(0x0); 5142 scale(0x0); 5143 disp($reg); // Stack Offset 5144 %} 5145 %} 5146 5147 operand stackSlotL(sRegL reg) %{ 5148 constraint(ALLOC_IN_RC(stack_slots)); 5149 op_cost(100); 5150 //match(RegL); 5151 format %{ "[sp+$reg]" %} 5152 interface(MEMORY_INTER) %{ 5153 base(0x1); // R1_SP 5154 index(0x0); 5155 scale(0x0); 5156 disp($reg); // Stack Offset 5157 %} 5158 %} 5159 5160 operand stackSlotP(sRegP reg) %{ 5161 constraint(ALLOC_IN_RC(stack_slots)); 5162 op_cost(100); 5163 //match(RegP); 5164 format %{ "[sp+$reg]" %} 5165 interface(MEMORY_INTER) %{ 5166 base(0x1); // R1_SP 5167 index(0x0); 5168 scale(0x0); 5169 disp($reg); // Stack Offset 5170 %} 5171 %} 5172 5173 operand stackSlotF(sRegF reg) %{ 5174 constraint(ALLOC_IN_RC(stack_slots)); 5175 op_cost(100); 5176 //match(RegF); 5177 format %{ "[sp+$reg]" %} 5178 interface(MEMORY_INTER) %{ 5179 base(0x1); // R1_SP 5180 index(0x0); 5181 scale(0x0); 5182 disp($reg); // Stack Offset 5183 %} 5184 %} 5185 5186 operand stackSlotD(sRegD reg) %{ 5187 constraint(ALLOC_IN_RC(stack_slots)); 5188 op_cost(100); 5189 //match(RegD); 5190 format %{ "[sp+$reg]" %} 5191 interface(MEMORY_INTER) %{ 5192 base(0x1); // R1_SP 5193 index(0x0); 5194 scale(0x0); 5195 disp($reg); // Stack Offset 5196 %} 5197 %} 5198 5199 // Operands for expressing Control Flow 5200 // NOTE: Label is a predefined operand which should not be redefined in 5201 // the AD file. It is generically handled within the ADLC. 5202 5203 //----------Conditional Branch Operands---------------------------------------- 5204 // Comparison Op 5205 // 5206 // This is the operation of the comparison, and is limited to the 5207 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5208 // (!=). 5209 // 5210 // Other attributes of the comparison, such as unsignedness, are specified 5211 // by the comparison instruction that sets a condition code flags register. 5212 // That result is represented by a flags operand whose subtype is appropriate 5213 // to the unsignedness (etc.) of the comparison. 5214 // 5215 // Later, the instruction which matches both the Comparison Op (a Bool) and 5216 // the flags (produced by the Cmp) specifies the coding of the comparison op 5217 // by matching a specific subtype of Bool operand below. 5218 5219 // When used for floating point comparisons: unordered same as less. 5220 operand cmpOp() %{ 5221 match(Bool); 5222 format %{ "" %} 5223 interface(COND_INTER) %{ 5224 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5225 // BO & BI 5226 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5227 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5228 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5229 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5230 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5231 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5232 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5233 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5234 %} 5235 %} 5236 5237 //----------OPERAND CLASSES---------------------------------------------------- 5238 // Operand Classes are groups of operands that are used to simplify 5239 // instruction definitions by not requiring the AD writer to specify 5240 // seperate instructions for every form of operand when the 5241 // instruction accepts multiple operand types with the same basic 5242 // encoding and format. The classic case of this is memory operands. 5243 // Indirect is not included since its use is limited to Compare & Swap. 5244 5245 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5246 // Memory operand where offsets are 4-aligned. Required for ld, std. 5247 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5248 opclass indirectMemory(indirect, indirectNarrow); 5249 5250 // Special opclass for I and ConvL2I. 5251 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5252 5253 // Operand classes to match encode and decode. iRegN_P2N is only used 5254 // for storeN. I have never seen an encode node elsewhere. 5255 opclass iRegN_P2N(iRegNsrc, iRegP2N); 5256 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5257 5258 //----------PIPELINE----------------------------------------------------------- 5259 5260 pipeline %{ 5261 5262 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5263 // J. Res. & Dev., No. 1, Jan. 2002. 5264 5265 //----------ATTRIBUTES--------------------------------------------------------- 5266 attributes %{ 5267 5268 // Power4 instructions are of fixed length. 5269 fixed_size_instructions; 5270 5271 // TODO: if `bundle' means number of instructions fetched 5272 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5273 // max instructions issued per cycle, this is 5. 5274 max_instructions_per_bundle = 8; 5275 5276 // A Power4 instruction is 4 bytes long. 5277 instruction_unit_size = 4; 5278 5279 // The Power4 processor fetches 64 bytes... 5280 instruction_fetch_unit_size = 64; 5281 5282 // ...in one line 5283 instruction_fetch_units = 1 5284 5285 // Unused, list one so that array generated by adlc is not empty. 5286 // Aix compiler chokes if _nop_count = 0. 5287 nops(fxNop); 5288 %} 5289 5290 //----------RESOURCES---------------------------------------------------------- 5291 // Resources are the functional units available to the machine 5292 resources( 5293 PPC_BR, // branch unit 5294 PPC_CR, // condition unit 5295 PPC_FX1, // integer arithmetic unit 1 5296 PPC_FX2, // integer arithmetic unit 2 5297 PPC_LDST1, // load/store unit 1 5298 PPC_LDST2, // load/store unit 2 5299 PPC_FP1, // float arithmetic unit 1 5300 PPC_FP2, // float arithmetic unit 2 5301 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5302 PPC_FX = PPC_FX1 | PPC_FX2, 5303 PPC_FP = PPC_FP1 | PPC_FP2 5304 ); 5305 5306 //----------PIPELINE DESCRIPTION----------------------------------------------- 5307 // Pipeline Description specifies the stages in the machine's pipeline 5308 pipe_desc( 5309 // Power4 longest pipeline path 5310 PPC_IF, // instruction fetch 5311 PPC_IC, 5312 //PPC_BP, // branch prediction 5313 PPC_D0, // decode 5314 PPC_D1, // decode 5315 PPC_D2, // decode 5316 PPC_D3, // decode 5317 PPC_Xfer1, 5318 PPC_GD, // group definition 5319 PPC_MP, // map 5320 PPC_ISS, // issue 5321 PPC_RF, // resource fetch 5322 PPC_EX1, // execute (all units) 5323 PPC_EX2, // execute (FP, LDST) 5324 PPC_EX3, // execute (FP, LDST) 5325 PPC_EX4, // execute (FP) 5326 PPC_EX5, // execute (FP) 5327 PPC_EX6, // execute (FP) 5328 PPC_WB, // write back 5329 PPC_Xfer2, 5330 PPC_CP 5331 ); 5332 5333 //----------PIPELINE CLASSES--------------------------------------------------- 5334 // Pipeline Classes describe the stages in which input and output are 5335 // referenced by the hardware pipeline. 5336 5337 // Simple pipeline classes. 5338 5339 // Default pipeline class. 5340 pipe_class pipe_class_default() %{ 5341 single_instruction; 5342 fixed_latency(2); 5343 %} 5344 5345 // Pipeline class for empty instructions. 5346 pipe_class pipe_class_empty() %{ 5347 single_instruction; 5348 fixed_latency(0); 5349 %} 5350 5351 // Pipeline class for compares. 5352 pipe_class pipe_class_compare() %{ 5353 single_instruction; 5354 fixed_latency(16); 5355 %} 5356 5357 // Pipeline class for traps. 5358 pipe_class pipe_class_trap() %{ 5359 single_instruction; 5360 fixed_latency(100); 5361 %} 5362 5363 // Pipeline class for memory operations. 5364 pipe_class pipe_class_memory() %{ 5365 single_instruction; 5366 fixed_latency(16); 5367 %} 5368 5369 // Pipeline class for call. 5370 pipe_class pipe_class_call() %{ 5371 single_instruction; 5372 fixed_latency(100); 5373 %} 5374 5375 // Define the class for the Nop node. 5376 define %{ 5377 MachNop = pipe_class_default; 5378 %} 5379 5380 %} 5381 5382 //----------INSTRUCTIONS------------------------------------------------------- 5383 5384 // Naming of instructions: 5385 // opA_operB / opA_operB_operC: 5386 // Operation 'op' with one or two source operands 'oper'. Result 5387 // type is A, source operand types are B and C. 5388 // Iff A == B == C, B and C are left out. 5389 // 5390 // The instructions are ordered according to the following scheme: 5391 // - loads 5392 // - load constants 5393 // - prefetch 5394 // - store 5395 // - encode/decode 5396 // - membar 5397 // - conditional moves 5398 // - compare & swap 5399 // - arithmetic and logic operations 5400 // * int: Add, Sub, Mul, Div, Mod 5401 // * int: lShift, arShift, urShift, rot 5402 // * float: Add, Sub, Mul, Div 5403 // * and, or, xor ... 5404 // - register moves: float <-> int, reg <-> stack, repl 5405 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5406 // - conv (low level type cast requiring bit changes (sign extend etc) 5407 // - compares, range & zero checks. 5408 // - branches 5409 // - complex operations, intrinsics, min, max, replicate 5410 // - lock 5411 // - Calls 5412 // 5413 // If there are similar instructions with different types they are sorted: 5414 // int before float 5415 // small before big 5416 // signed before unsigned 5417 // e.g., loadS before loadUS before loadI before loadF. 5418 5419 5420 //----------Load/Store Instructions-------------------------------------------- 5421 5422 //----------Load Instructions-------------------------------------------------- 5423 5424 // Converts byte to int. 5425 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5426 // reuses the 'amount' operand, but adlc expects that operand specification 5427 // and operands in match rule are equivalent. 5428 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5429 effect(DEF dst, USE src); 5430 format %{ "EXTSB $dst, $src \t// byte->int" %} 5431 size(4); 5432 ins_encode %{ 5433 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5434 __ extsb($dst$$Register, $src$$Register); 5435 %} 5436 ins_pipe(pipe_class_default); 5437 %} 5438 5439 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5440 // match-rule, false predicate 5441 match(Set dst (LoadB mem)); 5442 predicate(false); 5443 5444 format %{ "LBZ $dst, $mem" %} 5445 size(4); 5446 ins_encode( enc_lbz(dst, mem) ); 5447 ins_pipe(pipe_class_memory); 5448 %} 5449 5450 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5451 // match-rule, false predicate 5452 match(Set dst (LoadB mem)); 5453 predicate(false); 5454 5455 format %{ "LBZ $dst, $mem\n\t" 5456 "TWI $dst\n\t" 5457 "ISYNC" %} 5458 size(12); 5459 ins_encode( enc_lbz_ac(dst, mem) ); 5460 ins_pipe(pipe_class_memory); 5461 %} 5462 5463 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5464 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5465 match(Set dst (LoadB mem)); 5466 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5467 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5468 expand %{ 5469 iRegIdst tmp; 5470 loadUB_indirect(tmp, mem); 5471 convB2I_reg_2(dst, tmp); 5472 %} 5473 %} 5474 5475 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5476 match(Set dst (LoadB mem)); 5477 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5478 expand %{ 5479 iRegIdst tmp; 5480 loadUB_indirect_ac(tmp, mem); 5481 convB2I_reg_2(dst, tmp); 5482 %} 5483 %} 5484 5485 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5486 // match-rule, false predicate 5487 match(Set dst (LoadB mem)); 5488 predicate(false); 5489 5490 format %{ "LBZ $dst, $mem" %} 5491 size(4); 5492 ins_encode( enc_lbz(dst, mem) ); 5493 ins_pipe(pipe_class_memory); 5494 %} 5495 5496 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5497 // match-rule, false predicate 5498 match(Set dst (LoadB mem)); 5499 predicate(false); 5500 5501 format %{ "LBZ $dst, $mem\n\t" 5502 "TWI $dst\n\t" 5503 "ISYNC" %} 5504 size(12); 5505 ins_encode( enc_lbz_ac(dst, mem) ); 5506 ins_pipe(pipe_class_memory); 5507 %} 5508 5509 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5510 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5511 match(Set dst (LoadB mem)); 5512 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5513 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5514 5515 expand %{ 5516 iRegIdst tmp; 5517 loadUB_indOffset16(tmp, mem); 5518 convB2I_reg_2(dst, tmp); 5519 %} 5520 %} 5521 5522 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5523 match(Set dst (LoadB mem)); 5524 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5525 5526 expand %{ 5527 iRegIdst tmp; 5528 loadUB_indOffset16_ac(tmp, mem); 5529 convB2I_reg_2(dst, tmp); 5530 %} 5531 %} 5532 5533 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5534 instruct loadUB(iRegIdst dst, memory mem) %{ 5535 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5536 match(Set dst (LoadUB mem)); 5537 ins_cost(MEMORY_REF_COST); 5538 5539 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5540 size(4); 5541 ins_encode( enc_lbz(dst, mem) ); 5542 ins_pipe(pipe_class_memory); 5543 %} 5544 5545 // Load Unsigned Byte (8bit UNsigned) acquire. 5546 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5547 match(Set dst (LoadUB mem)); 5548 ins_cost(3*MEMORY_REF_COST); 5549 5550 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5551 "TWI $dst\n\t" 5552 "ISYNC" %} 5553 size(12); 5554 ins_encode( enc_lbz_ac(dst, mem) ); 5555 ins_pipe(pipe_class_memory); 5556 %} 5557 5558 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5559 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5560 match(Set dst (ConvI2L (LoadUB mem))); 5561 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5562 ins_cost(MEMORY_REF_COST); 5563 5564 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5565 size(4); 5566 ins_encode( enc_lbz(dst, mem) ); 5567 ins_pipe(pipe_class_memory); 5568 %} 5569 5570 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5571 match(Set dst (ConvI2L (LoadUB mem))); 5572 ins_cost(3*MEMORY_REF_COST); 5573 5574 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5575 "TWI $dst\n\t" 5576 "ISYNC" %} 5577 size(12); 5578 ins_encode( enc_lbz_ac(dst, mem) ); 5579 ins_pipe(pipe_class_memory); 5580 %} 5581 5582 // Load Short (16bit signed) 5583 instruct loadS(iRegIdst dst, memory mem) %{ 5584 match(Set dst (LoadS mem)); 5585 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5586 ins_cost(MEMORY_REF_COST); 5587 5588 format %{ "LHA $dst, $mem" %} 5589 size(4); 5590 ins_encode %{ 5591 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5592 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5593 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5594 %} 5595 ins_pipe(pipe_class_memory); 5596 %} 5597 5598 // Load Short (16bit signed) acquire. 5599 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5600 match(Set dst (LoadS mem)); 5601 ins_cost(3*MEMORY_REF_COST); 5602 5603 format %{ "LHA $dst, $mem\t acquire\n\t" 5604 "TWI $dst\n\t" 5605 "ISYNC" %} 5606 size(12); 5607 ins_encode %{ 5608 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5609 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5610 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5611 __ twi_0($dst$$Register); 5612 __ isync(); 5613 %} 5614 ins_pipe(pipe_class_memory); 5615 %} 5616 5617 // Load Char (16bit unsigned) 5618 instruct loadUS(iRegIdst dst, memory mem) %{ 5619 match(Set dst (LoadUS mem)); 5620 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5621 ins_cost(MEMORY_REF_COST); 5622 5623 format %{ "LHZ $dst, $mem" %} 5624 size(4); 5625 ins_encode( enc_lhz(dst, mem) ); 5626 ins_pipe(pipe_class_memory); 5627 %} 5628 5629 // Load Char (16bit unsigned) acquire. 5630 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5631 match(Set dst (LoadUS mem)); 5632 ins_cost(3*MEMORY_REF_COST); 5633 5634 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5635 "TWI $dst\n\t" 5636 "ISYNC" %} 5637 size(12); 5638 ins_encode( enc_lhz_ac(dst, mem) ); 5639 ins_pipe(pipe_class_memory); 5640 %} 5641 5642 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5643 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5644 match(Set dst (ConvI2L (LoadUS mem))); 5645 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5646 ins_cost(MEMORY_REF_COST); 5647 5648 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5649 size(4); 5650 ins_encode( enc_lhz(dst, mem) ); 5651 ins_pipe(pipe_class_memory); 5652 %} 5653 5654 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5655 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5656 match(Set dst (ConvI2L (LoadUS mem))); 5657 ins_cost(3*MEMORY_REF_COST); 5658 5659 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5660 "TWI $dst\n\t" 5661 "ISYNC" %} 5662 size(12); 5663 ins_encode( enc_lhz_ac(dst, mem) ); 5664 ins_pipe(pipe_class_memory); 5665 %} 5666 5667 // Load Integer. 5668 instruct loadI(iRegIdst dst, memory mem) %{ 5669 match(Set dst (LoadI mem)); 5670 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5671 ins_cost(MEMORY_REF_COST); 5672 5673 format %{ "LWZ $dst, $mem" %} 5674 size(4); 5675 ins_encode( enc_lwz(dst, mem) ); 5676 ins_pipe(pipe_class_memory); 5677 %} 5678 5679 // Load Integer acquire. 5680 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5681 match(Set dst (LoadI mem)); 5682 ins_cost(3*MEMORY_REF_COST); 5683 5684 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5685 "TWI $dst\n\t" 5686 "ISYNC" %} 5687 size(12); 5688 ins_encode( enc_lwz_ac(dst, mem) ); 5689 ins_pipe(pipe_class_memory); 5690 %} 5691 5692 // Match loading integer and casting it to unsigned int in 5693 // long register. 5694 // LoadI + ConvI2L + AndL 0xffffffff. 5695 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5696 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5697 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5698 ins_cost(MEMORY_REF_COST); 5699 5700 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5701 size(4); 5702 ins_encode( enc_lwz(dst, mem) ); 5703 ins_pipe(pipe_class_memory); 5704 %} 5705 5706 // Match loading integer and casting it to long. 5707 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5708 match(Set dst (ConvI2L (LoadI mem))); 5709 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5710 ins_cost(MEMORY_REF_COST); 5711 5712 format %{ "LWA $dst, $mem \t// loadI2L" %} 5713 size(4); 5714 ins_encode %{ 5715 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5716 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5717 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5718 %} 5719 ins_pipe(pipe_class_memory); 5720 %} 5721 5722 // Match loading integer and casting it to long - acquire. 5723 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5724 match(Set dst (ConvI2L (LoadI mem))); 5725 ins_cost(3*MEMORY_REF_COST); 5726 5727 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5728 "TWI $dst\n\t" 5729 "ISYNC" %} 5730 size(12); 5731 ins_encode %{ 5732 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5733 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5734 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5735 __ twi_0($dst$$Register); 5736 __ isync(); 5737 %} 5738 ins_pipe(pipe_class_memory); 5739 %} 5740 5741 // Load Long - aligned 5742 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5743 match(Set dst (LoadL mem)); 5744 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5745 ins_cost(MEMORY_REF_COST); 5746 5747 format %{ "LD $dst, $mem \t// long" %} 5748 size(4); 5749 ins_encode( enc_ld(dst, mem) ); 5750 ins_pipe(pipe_class_memory); 5751 %} 5752 5753 // Load Long - aligned acquire. 5754 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5755 match(Set dst (LoadL mem)); 5756 ins_cost(3*MEMORY_REF_COST); 5757 5758 format %{ "LD $dst, $mem \t// long acquire\n\t" 5759 "TWI $dst\n\t" 5760 "ISYNC" %} 5761 size(12); 5762 ins_encode( enc_ld_ac(dst, mem) ); 5763 ins_pipe(pipe_class_memory); 5764 %} 5765 5766 // Load Long - UNaligned 5767 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5768 match(Set dst (LoadL_unaligned mem)); 5769 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5770 ins_cost(MEMORY_REF_COST); 5771 5772 format %{ "LD $dst, $mem \t// unaligned long" %} 5773 size(4); 5774 ins_encode( enc_ld(dst, mem) ); 5775 ins_pipe(pipe_class_memory); 5776 %} 5777 5778 // Load nodes for superwords 5779 5780 // Load Aligned Packed Byte 5781 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5782 predicate(n->as_LoadVector()->memory_size() == 8); 5783 match(Set dst (LoadVector mem)); 5784 ins_cost(MEMORY_REF_COST); 5785 5786 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5787 size(4); 5788 ins_encode( enc_ld(dst, mem) ); 5789 ins_pipe(pipe_class_memory); 5790 %} 5791 5792 // Load Aligned Packed Byte 5793 instruct loadV16(vecX dst, indirect mem) %{ 5794 predicate(n->as_LoadVector()->memory_size() == 16); 5795 match(Set dst (LoadVector mem)); 5796 ins_cost(MEMORY_REF_COST); 5797 5798 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5799 size(4); 5800 ins_encode %{ 5801 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5802 %} 5803 ins_pipe(pipe_class_default); 5804 %} 5805 5806 // Load Range, range = array length (=jint) 5807 instruct loadRange(iRegIdst dst, memory mem) %{ 5808 match(Set dst (LoadRange mem)); 5809 ins_cost(MEMORY_REF_COST); 5810 5811 format %{ "LWZ $dst, $mem \t// range" %} 5812 size(4); 5813 ins_encode( enc_lwz(dst, mem) ); 5814 ins_pipe(pipe_class_memory); 5815 %} 5816 5817 // Load Compressed Pointer 5818 instruct loadN(iRegNdst dst, memory mem) %{ 5819 match(Set dst (LoadN mem)); 5820 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5821 ins_cost(MEMORY_REF_COST); 5822 5823 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5824 size(4); 5825 ins_encode( enc_lwz(dst, mem) ); 5826 ins_pipe(pipe_class_memory); 5827 %} 5828 5829 // Load Compressed Pointer acquire. 5830 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5831 match(Set dst (LoadN mem)); 5832 ins_cost(3*MEMORY_REF_COST); 5833 5834 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5835 "TWI $dst\n\t" 5836 "ISYNC" %} 5837 size(12); 5838 ins_encode( enc_lwz_ac(dst, mem) ); 5839 ins_pipe(pipe_class_memory); 5840 %} 5841 5842 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5843 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5844 match(Set dst (DecodeN (LoadN mem))); 5845 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5846 ins_cost(MEMORY_REF_COST); 5847 5848 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5849 size(4); 5850 ins_encode( enc_lwz(dst, mem) ); 5851 ins_pipe(pipe_class_memory); 5852 %} 5853 5854 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5855 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5856 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5857 _kids[0]->_leaf->as_Load()->is_unordered()); 5858 ins_cost(MEMORY_REF_COST); 5859 5860 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5861 size(4); 5862 ins_encode( enc_lwz(dst, mem) ); 5863 ins_pipe(pipe_class_memory); 5864 %} 5865 5866 // Load Pointer 5867 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5868 match(Set dst (LoadP mem)); 5869 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5870 ins_cost(MEMORY_REF_COST); 5871 5872 format %{ "LD $dst, $mem \t// ptr" %} 5873 size(4); 5874 ins_encode( enc_ld(dst, mem) ); 5875 ins_pipe(pipe_class_memory); 5876 %} 5877 5878 // Load Pointer acquire. 5879 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5880 match(Set dst (LoadP mem)); 5881 ins_cost(3*MEMORY_REF_COST); 5882 5883 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5884 "TWI $dst\n\t" 5885 "ISYNC" %} 5886 size(12); 5887 ins_encode( enc_ld_ac(dst, mem) ); 5888 ins_pipe(pipe_class_memory); 5889 %} 5890 5891 // LoadP + CastP2L 5892 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5893 match(Set dst (CastP2X (LoadP mem))); 5894 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5895 ins_cost(MEMORY_REF_COST); 5896 5897 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5898 size(4); 5899 ins_encode( enc_ld(dst, mem) ); 5900 ins_pipe(pipe_class_memory); 5901 %} 5902 5903 // Load compressed klass pointer. 5904 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5905 match(Set dst (LoadNKlass mem)); 5906 ins_cost(MEMORY_REF_COST); 5907 5908 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5909 size(4); 5910 ins_encode( enc_lwz(dst, mem) ); 5911 ins_pipe(pipe_class_memory); 5912 %} 5913 5914 // Load Klass Pointer 5915 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5916 match(Set dst (LoadKlass mem)); 5917 ins_cost(MEMORY_REF_COST); 5918 5919 format %{ "LD $dst, $mem \t// klass ptr" %} 5920 size(4); 5921 ins_encode( enc_ld(dst, mem) ); 5922 ins_pipe(pipe_class_memory); 5923 %} 5924 5925 // Load Float 5926 instruct loadF(regF dst, memory mem) %{ 5927 match(Set dst (LoadF mem)); 5928 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5929 ins_cost(MEMORY_REF_COST); 5930 5931 format %{ "LFS $dst, $mem" %} 5932 size(4); 5933 ins_encode %{ 5934 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5935 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5936 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5937 %} 5938 ins_pipe(pipe_class_memory); 5939 %} 5940 5941 // Load Float acquire. 5942 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5943 match(Set dst (LoadF mem)); 5944 effect(TEMP cr0); 5945 ins_cost(3*MEMORY_REF_COST); 5946 5947 format %{ "LFS $dst, $mem \t// acquire\n\t" 5948 "FCMPU cr0, $dst, $dst\n\t" 5949 "BNE cr0, next\n" 5950 "next:\n\t" 5951 "ISYNC" %} 5952 size(16); 5953 ins_encode %{ 5954 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5955 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5956 Label next; 5957 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5958 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5959 __ bne(CCR0, next); 5960 __ bind(next); 5961 __ isync(); 5962 %} 5963 ins_pipe(pipe_class_memory); 5964 %} 5965 5966 // Load Double - aligned 5967 instruct loadD(regD dst, memory mem) %{ 5968 match(Set dst (LoadD mem)); 5969 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5970 ins_cost(MEMORY_REF_COST); 5971 5972 format %{ "LFD $dst, $mem" %} 5973 size(4); 5974 ins_encode( enc_lfd(dst, mem) ); 5975 ins_pipe(pipe_class_memory); 5976 %} 5977 5978 // Load Double - aligned acquire. 5979 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5980 match(Set dst (LoadD mem)); 5981 effect(TEMP cr0); 5982 ins_cost(3*MEMORY_REF_COST); 5983 5984 format %{ "LFD $dst, $mem \t// acquire\n\t" 5985 "FCMPU cr0, $dst, $dst\n\t" 5986 "BNE cr0, next\n" 5987 "next:\n\t" 5988 "ISYNC" %} 5989 size(16); 5990 ins_encode %{ 5991 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5992 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5993 Label next; 5994 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5995 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5996 __ bne(CCR0, next); 5997 __ bind(next); 5998 __ isync(); 5999 %} 6000 ins_pipe(pipe_class_memory); 6001 %} 6002 6003 // Load Double - UNaligned 6004 instruct loadD_unaligned(regD dst, memory mem) %{ 6005 match(Set dst (LoadD_unaligned mem)); 6006 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 6007 ins_cost(MEMORY_REF_COST); 6008 6009 format %{ "LFD $dst, $mem" %} 6010 size(4); 6011 ins_encode( enc_lfd(dst, mem) ); 6012 ins_pipe(pipe_class_memory); 6013 %} 6014 6015 //----------Constants-------------------------------------------------------- 6016 6017 // Load MachConstantTableBase: add hi offset to global toc. 6018 // TODO: Handle hidden register r29 in bundler! 6019 instruct loadToc_hi(iRegLdst dst) %{ 6020 effect(DEF dst); 6021 ins_cost(DEFAULT_COST); 6022 6023 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 6024 size(4); 6025 ins_encode %{ 6026 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6027 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 6028 %} 6029 ins_pipe(pipe_class_default); 6030 %} 6031 6032 // Load MachConstantTableBase: add lo offset to global toc. 6033 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 6034 effect(DEF dst, USE src); 6035 ins_cost(DEFAULT_COST); 6036 6037 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 6038 size(4); 6039 ins_encode %{ 6040 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6041 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 6042 %} 6043 ins_pipe(pipe_class_default); 6044 %} 6045 6046 // Load 16-bit integer constant 0xssss???? 6047 instruct loadConI16(iRegIdst dst, immI16 src) %{ 6048 match(Set dst src); 6049 6050 format %{ "LI $dst, $src" %} 6051 size(4); 6052 ins_encode %{ 6053 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6054 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6055 %} 6056 ins_pipe(pipe_class_default); 6057 %} 6058 6059 // Load integer constant 0x????0000 6060 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 6061 match(Set dst src); 6062 ins_cost(DEFAULT_COST); 6063 6064 format %{ "LIS $dst, $src.hi" %} 6065 size(4); 6066 ins_encode %{ 6067 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6068 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 6069 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6070 %} 6071 ins_pipe(pipe_class_default); 6072 %} 6073 6074 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 6075 // and sign extended), this adds the low 16 bits. 6076 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6077 // no match-rule, false predicate 6078 effect(DEF dst, USE src1, USE src2); 6079 predicate(false); 6080 6081 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6082 size(4); 6083 ins_encode %{ 6084 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6085 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6086 %} 6087 ins_pipe(pipe_class_default); 6088 %} 6089 6090 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6091 match(Set dst src); 6092 ins_cost(DEFAULT_COST*2); 6093 6094 expand %{ 6095 // Would like to use $src$$constant. 6096 immI16 srcLo %{ _opnds[1]->constant() %} 6097 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6098 immIhi16 srcHi %{ _opnds[1]->constant() %} 6099 iRegIdst tmpI; 6100 loadConIhi16(tmpI, srcHi); 6101 loadConI32_lo16(dst, tmpI, srcLo); 6102 %} 6103 %} 6104 6105 // No constant pool entries required. 6106 instruct loadConL16(iRegLdst dst, immL16 src) %{ 6107 match(Set dst src); 6108 6109 format %{ "LI $dst, $src \t// long" %} 6110 size(4); 6111 ins_encode %{ 6112 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6113 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6114 %} 6115 ins_pipe(pipe_class_default); 6116 %} 6117 6118 // Load long constant 0xssssssss????0000 6119 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6120 match(Set dst src); 6121 ins_cost(DEFAULT_COST); 6122 6123 format %{ "LIS $dst, $src.hi \t// long" %} 6124 size(4); 6125 ins_encode %{ 6126 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6127 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6128 %} 6129 ins_pipe(pipe_class_default); 6130 %} 6131 6132 // To load a 32 bit constant: merge lower 16 bits into already loaded 6133 // high 16 bits. 6134 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6135 // no match-rule, false predicate 6136 effect(DEF dst, USE src1, USE src2); 6137 predicate(false); 6138 6139 format %{ "ORI $dst, $src1, $src2.lo" %} 6140 size(4); 6141 ins_encode %{ 6142 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6143 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6144 %} 6145 ins_pipe(pipe_class_default); 6146 %} 6147 6148 // Load 32-bit long constant 6149 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6150 match(Set dst src); 6151 ins_cost(DEFAULT_COST*2); 6152 6153 expand %{ 6154 // Would like to use $src$$constant. 6155 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6156 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6157 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6158 iRegLdst tmpL; 6159 loadConL32hi16(tmpL, srcHi); 6160 loadConL32_lo16(dst, tmpL, srcLo); 6161 %} 6162 %} 6163 6164 // Load long constant 0x????000000000000. 6165 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6166 match(Set dst src); 6167 ins_cost(DEFAULT_COST); 6168 6169 expand %{ 6170 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6171 immI shift32 %{ 32 %} 6172 iRegLdst tmpL; 6173 loadConL32hi16(tmpL, srcHi); 6174 lshiftL_regL_immI(dst, tmpL, shift32); 6175 %} 6176 %} 6177 6178 // Expand node for constant pool load: small offset. 6179 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6180 effect(DEF dst, USE src, USE toc); 6181 ins_cost(MEMORY_REF_COST); 6182 6183 ins_num_consts(1); 6184 // Needed so that CallDynamicJavaDirect can compute the address of this 6185 // instruction for relocation. 6186 ins_field_cbuf_insts_offset(int); 6187 6188 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6189 size(4); 6190 ins_encode( enc_load_long_constL(dst, src, toc) ); 6191 ins_pipe(pipe_class_memory); 6192 %} 6193 6194 // Expand node for constant pool load: large offset. 6195 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6196 effect(DEF dst, USE src, USE toc); 6197 predicate(false); 6198 6199 ins_num_consts(1); 6200 ins_field_const_toc_offset(int); 6201 // Needed so that CallDynamicJavaDirect can compute the address of this 6202 // instruction for relocation. 6203 ins_field_cbuf_insts_offset(int); 6204 6205 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6206 size(4); 6207 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6208 ins_pipe(pipe_class_default); 6209 %} 6210 6211 // Expand node for constant pool load: large offset. 6212 // No constant pool entries required. 6213 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6214 effect(DEF dst, USE src, USE base); 6215 predicate(false); 6216 6217 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6218 6219 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6220 size(4); 6221 ins_encode %{ 6222 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6223 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6224 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6225 %} 6226 ins_pipe(pipe_class_memory); 6227 %} 6228 6229 // Load long constant from constant table. Expand in case of 6230 // offset > 16 bit is needed. 6231 // Adlc adds toc node MachConstantTableBase. 6232 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6233 match(Set dst src); 6234 ins_cost(MEMORY_REF_COST); 6235 6236 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6237 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6238 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6239 %} 6240 6241 // Load NULL as compressed oop. 6242 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6243 match(Set dst src); 6244 ins_cost(DEFAULT_COST); 6245 6246 format %{ "LI $dst, $src \t// compressed ptr" %} 6247 size(4); 6248 ins_encode %{ 6249 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6250 __ li($dst$$Register, 0); 6251 %} 6252 ins_pipe(pipe_class_default); 6253 %} 6254 6255 // Load hi part of compressed oop constant. 6256 instruct loadConN_hi(iRegNdst dst, immN src) %{ 6257 effect(DEF dst, USE src); 6258 ins_cost(DEFAULT_COST); 6259 6260 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6261 size(4); 6262 ins_encode %{ 6263 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6264 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6265 %} 6266 ins_pipe(pipe_class_default); 6267 %} 6268 6269 // Add lo part of compressed oop constant to already loaded hi part. 6270 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6271 effect(DEF dst, USE src1, USE src2); 6272 ins_cost(DEFAULT_COST); 6273 6274 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6275 size(4); 6276 ins_encode %{ 6277 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6278 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6279 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6280 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6281 __ relocate(rspec, 1); 6282 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6283 %} 6284 ins_pipe(pipe_class_default); 6285 %} 6286 6287 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6288 effect(DEF dst, USE src, USE shift, USE mask_begin); 6289 6290 size(4); 6291 ins_encode %{ 6292 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6293 %} 6294 ins_pipe(pipe_class_default); 6295 %} 6296 6297 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6298 // leaving the upper 32 bits with sign-extension bits. 6299 // This clears these bits: dst = src & 0xFFFFFFFF. 6300 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6301 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6302 effect(DEF dst, USE src); 6303 predicate(false); 6304 6305 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6306 size(4); 6307 ins_encode %{ 6308 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6309 __ clrldi($dst$$Register, $src$$Register, 0x20); 6310 %} 6311 ins_pipe(pipe_class_default); 6312 %} 6313 6314 // Optimize DecodeN for disjoint base. 6315 // Load base of compressed oops into a register 6316 instruct loadBase(iRegLdst dst) %{ 6317 effect(DEF dst); 6318 6319 format %{ "LoadConst $dst, heapbase" %} 6320 ins_encode %{ 6321 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6322 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 6323 %} 6324 ins_pipe(pipe_class_default); 6325 %} 6326 6327 // Loading ConN must be postalloc expanded so that edges between 6328 // the nodes are safe. They may not interfere with a safepoint. 6329 // GL TODO: This needs three instructions: better put this into the constant pool. 6330 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6331 match(Set dst src); 6332 ins_cost(DEFAULT_COST*2); 6333 6334 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6335 postalloc_expand %{ 6336 MachNode *m1 = new loadConN_hiNode(); 6337 MachNode *m2 = new loadConN_loNode(); 6338 MachNode *m3 = new clearMs32bNode(); 6339 m1->add_req(NULL); 6340 m2->add_req(NULL, m1); 6341 m3->add_req(NULL, m2); 6342 m1->_opnds[0] = op_dst; 6343 m1->_opnds[1] = op_src; 6344 m2->_opnds[0] = op_dst; 6345 m2->_opnds[1] = op_dst; 6346 m2->_opnds[2] = op_src; 6347 m3->_opnds[0] = op_dst; 6348 m3->_opnds[1] = op_dst; 6349 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6350 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6351 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6352 nodes->push(m1); 6353 nodes->push(m2); 6354 nodes->push(m3); 6355 %} 6356 %} 6357 6358 // We have seen a safepoint between the hi and lo parts, and this node was handled 6359 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6360 // not a narrow oop. 6361 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6362 match(Set dst src); 6363 effect(DEF dst, USE src); 6364 ins_cost(DEFAULT_COST); 6365 6366 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6367 size(4); 6368 ins_encode %{ 6369 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6370 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 6371 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6372 %} 6373 ins_pipe(pipe_class_default); 6374 %} 6375 6376 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6377 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6378 match(Set dst src1); 6379 effect(TEMP src2); 6380 ins_cost(DEFAULT_COST); 6381 6382 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6383 size(4); 6384 ins_encode %{ 6385 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6386 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6387 %} 6388 ins_pipe(pipe_class_default); 6389 %} 6390 6391 // This needs a match rule so that build_oop_map knows this is 6392 // not a narrow oop. 6393 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6394 match(Set dst src1); 6395 effect(TEMP src2); 6396 ins_cost(DEFAULT_COST); 6397 6398 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6399 size(4); 6400 ins_encode %{ 6401 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6402 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 6403 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6404 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6405 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6406 6407 __ relocate(rspec, 1); 6408 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6409 %} 6410 ins_pipe(pipe_class_default); 6411 %} 6412 6413 // Loading ConNKlass must be postalloc expanded so that edges between 6414 // the nodes are safe. They may not interfere with a safepoint. 6415 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6416 match(Set dst src); 6417 ins_cost(DEFAULT_COST*2); 6418 6419 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6420 postalloc_expand %{ 6421 // Load high bits into register. Sign extended. 6422 MachNode *m1 = new loadConNKlass_hiNode(); 6423 m1->add_req(NULL); 6424 m1->_opnds[0] = op_dst; 6425 m1->_opnds[1] = op_src; 6426 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6427 nodes->push(m1); 6428 6429 MachNode *m2 = m1; 6430 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 6431 // Value might be 1-extended. Mask out these bits. 6432 m2 = new loadConNKlass_maskNode(); 6433 m2->add_req(NULL, m1); 6434 m2->_opnds[0] = op_dst; 6435 m2->_opnds[1] = op_src; 6436 m2->_opnds[2] = op_dst; 6437 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6438 nodes->push(m2); 6439 } 6440 6441 MachNode *m3 = new loadConNKlass_loNode(); 6442 m3->add_req(NULL, m2); 6443 m3->_opnds[0] = op_dst; 6444 m3->_opnds[1] = op_src; 6445 m3->_opnds[2] = op_dst; 6446 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6447 nodes->push(m3); 6448 %} 6449 %} 6450 6451 // 0x1 is used in object initialization (initial object header). 6452 // No constant pool entries required. 6453 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6454 match(Set dst src); 6455 6456 format %{ "LI $dst, $src \t// ptr" %} 6457 size(4); 6458 ins_encode %{ 6459 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6460 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6461 %} 6462 ins_pipe(pipe_class_default); 6463 %} 6464 6465 // Expand node for constant pool load: small offset. 6466 // The match rule is needed to generate the correct bottom_type(), 6467 // however this node should never match. The use of predicate is not 6468 // possible since ADLC forbids predicates for chain rules. The higher 6469 // costs do not prevent matching in this case. For that reason the 6470 // operand immP_NM with predicate(false) is used. 6471 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6472 match(Set dst src); 6473 effect(TEMP toc); 6474 6475 ins_num_consts(1); 6476 6477 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6478 size(4); 6479 ins_encode( enc_load_long_constP(dst, src, toc) ); 6480 ins_pipe(pipe_class_memory); 6481 %} 6482 6483 // Expand node for constant pool load: large offset. 6484 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6485 effect(DEF dst, USE src, USE toc); 6486 predicate(false); 6487 6488 ins_num_consts(1); 6489 ins_field_const_toc_offset(int); 6490 6491 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6492 size(4); 6493 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6494 ins_pipe(pipe_class_default); 6495 %} 6496 6497 // Expand node for constant pool load: large offset. 6498 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6499 match(Set dst src); 6500 effect(TEMP base); 6501 6502 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6503 6504 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6505 size(4); 6506 ins_encode %{ 6507 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6508 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6509 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6510 %} 6511 ins_pipe(pipe_class_memory); 6512 %} 6513 6514 // Load pointer constant from constant table. Expand in case an 6515 // offset > 16 bit is needed. 6516 // Adlc adds toc node MachConstantTableBase. 6517 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6518 match(Set dst src); 6519 ins_cost(MEMORY_REF_COST); 6520 6521 // This rule does not use "expand" because then 6522 // the result type is not known to be an Oop. An ADLC 6523 // enhancement will be needed to make that work - not worth it! 6524 6525 // If this instruction rematerializes, it prolongs the live range 6526 // of the toc node, causing illegal graphs. 6527 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6528 ins_cannot_rematerialize(true); 6529 6530 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6531 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6532 %} 6533 6534 // Expand node for constant pool load: small offset. 6535 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6536 effect(DEF dst, USE src, USE toc); 6537 ins_cost(MEMORY_REF_COST); 6538 6539 ins_num_consts(1); 6540 6541 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6542 size(4); 6543 ins_encode %{ 6544 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6545 address float_address = __ float_constant($src$$constant); 6546 if (float_address == NULL) { 6547 ciEnv::current()->record_out_of_memory_failure(); 6548 return; 6549 } 6550 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6551 %} 6552 ins_pipe(pipe_class_memory); 6553 %} 6554 6555 // Expand node for constant pool load: large offset. 6556 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6557 effect(DEF dst, USE src, USE toc); 6558 ins_cost(MEMORY_REF_COST); 6559 6560 ins_num_consts(1); 6561 6562 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6563 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6564 "ADDIS $toc, $toc, -offset_hi"%} 6565 size(12); 6566 ins_encode %{ 6567 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6568 FloatRegister Rdst = $dst$$FloatRegister; 6569 Register Rtoc = $toc$$Register; 6570 address float_address = __ float_constant($src$$constant); 6571 if (float_address == NULL) { 6572 ciEnv::current()->record_out_of_memory_failure(); 6573 return; 6574 } 6575 int offset = __ offset_to_method_toc(float_address); 6576 int hi = (offset + (1<<15))>>16; 6577 int lo = offset - hi * (1<<16); 6578 6579 __ addis(Rtoc, Rtoc, hi); 6580 __ lfs(Rdst, lo, Rtoc); 6581 __ addis(Rtoc, Rtoc, -hi); 6582 %} 6583 ins_pipe(pipe_class_memory); 6584 %} 6585 6586 // Adlc adds toc node MachConstantTableBase. 6587 instruct loadConF_Ex(regF dst, immF src) %{ 6588 match(Set dst src); 6589 ins_cost(MEMORY_REF_COST); 6590 6591 // See loadConP. 6592 ins_cannot_rematerialize(true); 6593 6594 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6595 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6596 %} 6597 6598 // Expand node for constant pool load: small offset. 6599 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6600 effect(DEF dst, USE src, USE toc); 6601 ins_cost(MEMORY_REF_COST); 6602 6603 ins_num_consts(1); 6604 6605 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6606 size(4); 6607 ins_encode %{ 6608 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6609 address float_address = __ double_constant($src$$constant); 6610 if (float_address == NULL) { 6611 ciEnv::current()->record_out_of_memory_failure(); 6612 return; 6613 } 6614 int offset = __ offset_to_method_toc(float_address); 6615 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6616 %} 6617 ins_pipe(pipe_class_memory); 6618 %} 6619 6620 // Expand node for constant pool load: large offset. 6621 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6622 effect(DEF dst, USE src, USE toc); 6623 ins_cost(MEMORY_REF_COST); 6624 6625 ins_num_consts(1); 6626 6627 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6628 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6629 "ADDIS $toc, $toc, -offset_hi" %} 6630 size(12); 6631 ins_encode %{ 6632 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6633 FloatRegister Rdst = $dst$$FloatRegister; 6634 Register Rtoc = $toc$$Register; 6635 address float_address = __ double_constant($src$$constant); 6636 if (float_address == NULL) { 6637 ciEnv::current()->record_out_of_memory_failure(); 6638 return; 6639 } 6640 int offset = __ offset_to_method_toc(float_address); 6641 int hi = (offset + (1<<15))>>16; 6642 int lo = offset - hi * (1<<16); 6643 6644 __ addis(Rtoc, Rtoc, hi); 6645 __ lfd(Rdst, lo, Rtoc); 6646 __ addis(Rtoc, Rtoc, -hi); 6647 %} 6648 ins_pipe(pipe_class_memory); 6649 %} 6650 6651 // Adlc adds toc node MachConstantTableBase. 6652 instruct loadConD_Ex(regD dst, immD src) %{ 6653 match(Set dst src); 6654 ins_cost(MEMORY_REF_COST); 6655 6656 // See loadConP. 6657 ins_cannot_rematerialize(true); 6658 6659 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6660 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6661 %} 6662 6663 // Prefetch instructions. 6664 // Must be safe to execute with invalid address (cannot fault). 6665 6666 // Special prefetch versions which use the dcbz instruction. 6667 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6668 match(PrefetchAllocation (AddP mem src)); 6669 predicate(AllocatePrefetchStyle == 3); 6670 ins_cost(MEMORY_REF_COST); 6671 6672 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6673 size(4); 6674 ins_encode %{ 6675 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6676 __ dcbz($src$$Register, $mem$$base$$Register); 6677 %} 6678 ins_pipe(pipe_class_memory); 6679 %} 6680 6681 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6682 match(PrefetchAllocation mem); 6683 predicate(AllocatePrefetchStyle == 3); 6684 ins_cost(MEMORY_REF_COST); 6685 6686 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6687 size(4); 6688 ins_encode %{ 6689 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6690 __ dcbz($mem$$base$$Register); 6691 %} 6692 ins_pipe(pipe_class_memory); 6693 %} 6694 6695 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6696 match(PrefetchAllocation (AddP mem src)); 6697 predicate(AllocatePrefetchStyle != 3); 6698 ins_cost(MEMORY_REF_COST); 6699 6700 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6701 size(4); 6702 ins_encode %{ 6703 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6704 __ dcbtst($src$$Register, $mem$$base$$Register); 6705 %} 6706 ins_pipe(pipe_class_memory); 6707 %} 6708 6709 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6710 match(PrefetchAllocation mem); 6711 predicate(AllocatePrefetchStyle != 3); 6712 ins_cost(MEMORY_REF_COST); 6713 6714 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6715 size(4); 6716 ins_encode %{ 6717 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6718 __ dcbtst($mem$$base$$Register); 6719 %} 6720 ins_pipe(pipe_class_memory); 6721 %} 6722 6723 //----------Store Instructions------------------------------------------------- 6724 6725 // Store Byte 6726 instruct storeB(memory mem, iRegIsrc src) %{ 6727 match(Set mem (StoreB mem src)); 6728 ins_cost(MEMORY_REF_COST); 6729 6730 format %{ "STB $src, $mem \t// byte" %} 6731 size(4); 6732 ins_encode %{ 6733 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6734 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6735 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6736 %} 6737 ins_pipe(pipe_class_memory); 6738 %} 6739 6740 // Store Char/Short 6741 instruct storeC(memory mem, iRegIsrc src) %{ 6742 match(Set mem (StoreC mem src)); 6743 ins_cost(MEMORY_REF_COST); 6744 6745 format %{ "STH $src, $mem \t// short" %} 6746 size(4); 6747 ins_encode %{ 6748 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6749 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6750 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6751 %} 6752 ins_pipe(pipe_class_memory); 6753 %} 6754 6755 // Store Integer 6756 instruct storeI(memory mem, iRegIsrc src) %{ 6757 match(Set mem (StoreI mem src)); 6758 ins_cost(MEMORY_REF_COST); 6759 6760 format %{ "STW $src, $mem" %} 6761 size(4); 6762 ins_encode( enc_stw(src, mem) ); 6763 ins_pipe(pipe_class_memory); 6764 %} 6765 6766 // ConvL2I + StoreI. 6767 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6768 match(Set mem (StoreI mem (ConvL2I src))); 6769 ins_cost(MEMORY_REF_COST); 6770 6771 format %{ "STW l2i($src), $mem" %} 6772 size(4); 6773 ins_encode( enc_stw(src, mem) ); 6774 ins_pipe(pipe_class_memory); 6775 %} 6776 6777 // Store Long 6778 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6779 match(Set mem (StoreL mem src)); 6780 ins_cost(MEMORY_REF_COST); 6781 6782 format %{ "STD $src, $mem \t// long" %} 6783 size(4); 6784 ins_encode( enc_std(src, mem) ); 6785 ins_pipe(pipe_class_memory); 6786 %} 6787 6788 // Store super word nodes. 6789 6790 // Store Aligned Packed Byte long register to memory 6791 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6792 predicate(n->as_StoreVector()->memory_size() == 8); 6793 match(Set mem (StoreVector mem src)); 6794 ins_cost(MEMORY_REF_COST); 6795 6796 format %{ "STD $mem, $src \t// packed8B" %} 6797 size(4); 6798 ins_encode( enc_std(src, mem) ); 6799 ins_pipe(pipe_class_memory); 6800 %} 6801 6802 // Store Packed Byte long register to memory 6803 instruct storeV16(indirect mem, vecX src) %{ 6804 predicate(n->as_StoreVector()->memory_size() == 16); 6805 match(Set mem (StoreVector mem src)); 6806 ins_cost(MEMORY_REF_COST); 6807 6808 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6809 size(4); 6810 ins_encode %{ 6811 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6812 %} 6813 ins_pipe(pipe_class_default); 6814 %} 6815 6816 // Store Compressed Oop 6817 instruct storeN(memory dst, iRegN_P2N src) %{ 6818 match(Set dst (StoreN dst src)); 6819 ins_cost(MEMORY_REF_COST); 6820 6821 format %{ "STW $src, $dst \t// compressed oop" %} 6822 size(4); 6823 ins_encode( enc_stw(src, dst) ); 6824 ins_pipe(pipe_class_memory); 6825 %} 6826 6827 // Store Compressed KLass 6828 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6829 match(Set dst (StoreNKlass dst src)); 6830 ins_cost(MEMORY_REF_COST); 6831 6832 format %{ "STW $src, $dst \t// compressed klass" %} 6833 size(4); 6834 ins_encode( enc_stw(src, dst) ); 6835 ins_pipe(pipe_class_memory); 6836 %} 6837 6838 // Store Pointer 6839 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6840 match(Set dst (StoreP dst src)); 6841 ins_cost(MEMORY_REF_COST); 6842 6843 format %{ "STD $src, $dst \t// ptr" %} 6844 size(4); 6845 ins_encode( enc_std(src, dst) ); 6846 ins_pipe(pipe_class_memory); 6847 %} 6848 6849 // Store Float 6850 instruct storeF(memory mem, regF src) %{ 6851 match(Set mem (StoreF mem src)); 6852 ins_cost(MEMORY_REF_COST); 6853 6854 format %{ "STFS $src, $mem" %} 6855 size(4); 6856 ins_encode( enc_stfs(src, mem) ); 6857 ins_pipe(pipe_class_memory); 6858 %} 6859 6860 // Store Double 6861 instruct storeD(memory mem, regD src) %{ 6862 match(Set mem (StoreD mem src)); 6863 ins_cost(MEMORY_REF_COST); 6864 6865 format %{ "STFD $src, $mem" %} 6866 size(4); 6867 ins_encode( enc_stfd(src, mem) ); 6868 ins_pipe(pipe_class_memory); 6869 %} 6870 6871 //----------Store Instructions With Zeros-------------------------------------- 6872 6873 // Card-mark for CMS garbage collection. 6874 // This cardmark does an optimization so that it must not always 6875 // do a releasing store. For this, it gets the address of 6876 // CMSCollectorCardTableBarrierSetBSExt::_requires_release as input. 6877 // (Using releaseFieldAddr in the match rule is a hack.) 6878 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6879 match(Set mem (StoreCM mem releaseFieldAddr)); 6880 effect(TEMP crx); 6881 predicate(false); 6882 ins_cost(MEMORY_REF_COST); 6883 6884 // See loadConP. 6885 ins_cannot_rematerialize(true); 6886 6887 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6888 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6889 ins_pipe(pipe_class_memory); 6890 %} 6891 6892 // Card-mark for CMS garbage collection. 6893 // This cardmark does an optimization so that it must not always 6894 // do a releasing store. For this, it needs the constant address of 6895 // CMSCollectorCardTableBarrierSetBSExt::_requires_release. 6896 // This constant address is split off here by expand so we can use 6897 // adlc / matcher functionality to load it from the constant section. 6898 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6899 match(Set mem (StoreCM mem zero)); 6900 predicate(UseConcMarkSweepGC); 6901 6902 expand %{ 6903 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableBarrierSetBSExt::requires_release_address() */ %} 6904 iRegLdst releaseFieldAddress; 6905 flagsReg crx; 6906 loadConL_Ex(releaseFieldAddress, baseImm); 6907 storeCM_CMS(mem, releaseFieldAddress, crx); 6908 %} 6909 %} 6910 6911 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6912 match(Set mem (StoreCM mem zero)); 6913 predicate(UseG1GC); 6914 ins_cost(MEMORY_REF_COST); 6915 6916 ins_cannot_rematerialize(true); 6917 6918 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6919 size(8); 6920 ins_encode %{ 6921 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6922 __ li(R0, 0); 6923 //__ release(); // G1: oops are allowed to get visible after dirty marking 6924 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6925 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6926 %} 6927 ins_pipe(pipe_class_memory); 6928 %} 6929 6930 // Convert oop pointer into compressed form. 6931 6932 // Nodes for postalloc expand. 6933 6934 // Shift node for expand. 6935 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6936 // The match rule is needed to make it a 'MachTypeNode'! 6937 match(Set dst (EncodeP src)); 6938 predicate(false); 6939 6940 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6941 size(4); 6942 ins_encode %{ 6943 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6944 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6945 %} 6946 ins_pipe(pipe_class_default); 6947 %} 6948 6949 // Add node for expand. 6950 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6951 // The match rule is needed to make it a 'MachTypeNode'! 6952 match(Set dst (EncodeP src)); 6953 predicate(false); 6954 6955 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6956 ins_encode %{ 6957 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6958 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6959 %} 6960 ins_pipe(pipe_class_default); 6961 %} 6962 6963 // Conditional sub base. 6964 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6965 // The match rule is needed to make it a 'MachTypeNode'! 6966 match(Set dst (EncodeP (Binary crx src1))); 6967 predicate(false); 6968 6969 format %{ "BEQ $crx, done\n\t" 6970 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6971 "done:" %} 6972 ins_encode %{ 6973 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6974 Label done; 6975 __ beq($crx$$CondRegister, done); 6976 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6977 __ bind(done); 6978 %} 6979 ins_pipe(pipe_class_default); 6980 %} 6981 6982 // Power 7 can use isel instruction 6983 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6984 // The match rule is needed to make it a 'MachTypeNode'! 6985 match(Set dst (EncodeP (Binary crx src1))); 6986 predicate(false); 6987 6988 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6989 size(4); 6990 ins_encode %{ 6991 // This is a Power7 instruction for which no machine description exists. 6992 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6993 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6994 %} 6995 ins_pipe(pipe_class_default); 6996 %} 6997 6998 // Disjoint narrow oop base. 6999 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7000 match(Set dst (EncodeP src)); 7001 predicate(Universe::narrow_oop_base_disjoint()); 7002 7003 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7004 size(4); 7005 ins_encode %{ 7006 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7007 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 7008 %} 7009 ins_pipe(pipe_class_default); 7010 %} 7011 7012 // shift != 0, base != 0 7013 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 7014 match(Set dst (EncodeP src)); 7015 effect(TEMP crx); 7016 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 7017 Universe::narrow_oop_shift() != 0 && 7018 Universe::narrow_oop_base_overlaps()); 7019 7020 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 7021 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 7022 %} 7023 7024 // shift != 0, base != 0 7025 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 7026 match(Set dst (EncodeP src)); 7027 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 7028 Universe::narrow_oop_shift() != 0 && 7029 Universe::narrow_oop_base_overlaps()); 7030 7031 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 7032 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 7033 %} 7034 7035 // shift != 0, base == 0 7036 // TODO: This is the same as encodeP_shift. Merge! 7037 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 7038 match(Set dst (EncodeP src)); 7039 predicate(Universe::narrow_oop_shift() != 0 && 7040 Universe::narrow_oop_base() ==0); 7041 7042 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 7043 size(4); 7044 ins_encode %{ 7045 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7046 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 7047 %} 7048 ins_pipe(pipe_class_default); 7049 %} 7050 7051 // Compressed OOPs with narrow_oop_shift == 0. 7052 // shift == 0, base == 0 7053 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 7054 match(Set dst (EncodeP src)); 7055 predicate(Universe::narrow_oop_shift() == 0); 7056 7057 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 7058 // variable size, 0 or 4. 7059 ins_encode %{ 7060 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7061 __ mr_if_needed($dst$$Register, $src$$Register); 7062 %} 7063 ins_pipe(pipe_class_default); 7064 %} 7065 7066 // Decode nodes. 7067 7068 // Shift node for expand. 7069 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 7070 // The match rule is needed to make it a 'MachTypeNode'! 7071 match(Set dst (DecodeN src)); 7072 predicate(false); 7073 7074 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 7075 size(4); 7076 ins_encode %{ 7077 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7078 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7079 %} 7080 ins_pipe(pipe_class_default); 7081 %} 7082 7083 // Add node for expand. 7084 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7085 // The match rule is needed to make it a 'MachTypeNode'! 7086 match(Set dst (DecodeN src)); 7087 predicate(false); 7088 7089 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7090 ins_encode %{ 7091 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7092 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7093 %} 7094 ins_pipe(pipe_class_default); 7095 %} 7096 7097 // conditianal add base for expand 7098 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7099 // The match rule is needed to make it a 'MachTypeNode'! 7100 // NOTICE that the rule is nonsense - we just have to make sure that: 7101 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7102 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7103 match(Set dst (DecodeN (Binary crx src))); 7104 predicate(false); 7105 7106 format %{ "BEQ $crx, done\n\t" 7107 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7108 "done:" %} 7109 ins_encode %{ 7110 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7111 Label done; 7112 __ beq($crx$$CondRegister, done); 7113 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7114 __ bind(done); 7115 %} 7116 ins_pipe(pipe_class_default); 7117 %} 7118 7119 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7120 // The match rule is needed to make it a 'MachTypeNode'! 7121 // NOTICE that the rule is nonsense - we just have to make sure that: 7122 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7123 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7124 match(Set dst (DecodeN (Binary crx src1))); 7125 predicate(false); 7126 7127 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7128 size(4); 7129 ins_encode %{ 7130 // This is a Power7 instruction for which no machine description exists. 7131 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7132 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7133 %} 7134 ins_pipe(pipe_class_default); 7135 %} 7136 7137 // shift != 0, base != 0 7138 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7139 match(Set dst (DecodeN src)); 7140 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7141 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7142 Universe::narrow_oop_shift() != 0 && 7143 Universe::narrow_oop_base() != 0); 7144 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7145 effect(TEMP crx); 7146 7147 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7148 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7149 %} 7150 7151 // shift != 0, base == 0 7152 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7153 match(Set dst (DecodeN src)); 7154 predicate(Universe::narrow_oop_shift() != 0 && 7155 Universe::narrow_oop_base() == 0); 7156 7157 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7158 size(4); 7159 ins_encode %{ 7160 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7161 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7162 %} 7163 ins_pipe(pipe_class_default); 7164 %} 7165 7166 // Optimize DecodeN for disjoint base. 7167 // Shift narrow oop and or it into register that already contains the heap base. 7168 // Base == dst must hold, and is assured by construction in postaloc_expand. 7169 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7170 match(Set dst (DecodeN src)); 7171 effect(TEMP base); 7172 predicate(false); 7173 7174 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7175 size(4); 7176 ins_encode %{ 7177 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7178 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 7179 %} 7180 ins_pipe(pipe_class_default); 7181 %} 7182 7183 // Optimize DecodeN for disjoint base. 7184 // This node requires only one cycle on the critical path. 7185 // We must postalloc_expand as we can not express use_def effects where 7186 // the used register is L and the def'ed register P. 7187 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7188 match(Set dst (DecodeN src)); 7189 effect(TEMP_DEF dst); 7190 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7191 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7192 Universe::narrow_oop_base_disjoint()); 7193 ins_cost(DEFAULT_COST); 7194 7195 format %{ "MOV $dst, heapbase \t\n" 7196 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7197 postalloc_expand %{ 7198 loadBaseNode *n1 = new loadBaseNode(); 7199 n1->add_req(NULL); 7200 n1->_opnds[0] = op_dst; 7201 7202 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7203 n2->add_req(n_region, n_src, n1); 7204 n2->_opnds[0] = op_dst; 7205 n2->_opnds[1] = op_src; 7206 n2->_opnds[2] = op_dst; 7207 n2->_bottom_type = _bottom_type; 7208 7209 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7210 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7211 7212 nodes->push(n1); 7213 nodes->push(n2); 7214 %} 7215 %} 7216 7217 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7218 match(Set dst (DecodeN src)); 7219 effect(TEMP_DEF dst, TEMP crx); 7220 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7221 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7222 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 7223 ins_cost(3 * DEFAULT_COST); 7224 7225 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7226 postalloc_expand %{ 7227 loadBaseNode *n1 = new loadBaseNode(); 7228 n1->add_req(NULL); 7229 n1->_opnds[0] = op_dst; 7230 7231 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7232 n_compare->add_req(n_region, n_src); 7233 n_compare->_opnds[0] = op_crx; 7234 n_compare->_opnds[1] = op_src; 7235 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7236 7237 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7238 n2->add_req(n_region, n_src, n1); 7239 n2->_opnds[0] = op_dst; 7240 n2->_opnds[1] = op_src; 7241 n2->_opnds[2] = op_dst; 7242 n2->_bottom_type = _bottom_type; 7243 7244 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7245 n_cond_set->add_req(n_region, n_compare, n2); 7246 n_cond_set->_opnds[0] = op_dst; 7247 n_cond_set->_opnds[1] = op_crx; 7248 n_cond_set->_opnds[2] = op_dst; 7249 n_cond_set->_bottom_type = _bottom_type; 7250 7251 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7252 ra_->set_oop(n_cond_set, true); 7253 7254 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7255 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7256 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7257 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7258 7259 nodes->push(n1); 7260 nodes->push(n_compare); 7261 nodes->push(n2); 7262 nodes->push(n_cond_set); 7263 %} 7264 %} 7265 7266 // src != 0, shift != 0, base != 0 7267 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7268 match(Set dst (DecodeN src)); 7269 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7270 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7271 Universe::narrow_oop_shift() != 0 && 7272 Universe::narrow_oop_base() != 0); 7273 ins_cost(2 * DEFAULT_COST); 7274 7275 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7276 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7277 %} 7278 7279 // Compressed OOPs with narrow_oop_shift == 0. 7280 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7281 match(Set dst (DecodeN src)); 7282 predicate(Universe::narrow_oop_shift() == 0); 7283 ins_cost(DEFAULT_COST); 7284 7285 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7286 // variable size, 0 or 4. 7287 ins_encode %{ 7288 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7289 __ mr_if_needed($dst$$Register, $src$$Register); 7290 %} 7291 ins_pipe(pipe_class_default); 7292 %} 7293 7294 // Convert compressed oop into int for vectors alignment masking. 7295 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7296 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7297 predicate(Universe::narrow_oop_shift() == 0); 7298 ins_cost(DEFAULT_COST); 7299 7300 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7301 // variable size, 0 or 4. 7302 ins_encode %{ 7303 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7304 __ mr_if_needed($dst$$Register, $src$$Register); 7305 %} 7306 ins_pipe(pipe_class_default); 7307 %} 7308 7309 // Convert klass pointer into compressed form. 7310 7311 // Nodes for postalloc expand. 7312 7313 // Shift node for expand. 7314 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7315 // The match rule is needed to make it a 'MachTypeNode'! 7316 match(Set dst (EncodePKlass src)); 7317 predicate(false); 7318 7319 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7320 size(4); 7321 ins_encode %{ 7322 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7323 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7324 %} 7325 ins_pipe(pipe_class_default); 7326 %} 7327 7328 // Add node for expand. 7329 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7330 // The match rule is needed to make it a 'MachTypeNode'! 7331 match(Set dst (EncodePKlass (Binary base src))); 7332 predicate(false); 7333 7334 format %{ "SUB $dst, $base, $src \t// encode" %} 7335 size(4); 7336 ins_encode %{ 7337 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7338 __ subf($dst$$Register, $base$$Register, $src$$Register); 7339 %} 7340 ins_pipe(pipe_class_default); 7341 %} 7342 7343 // Disjoint narrow oop base. 7344 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7345 match(Set dst (EncodePKlass src)); 7346 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 7347 7348 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7349 size(4); 7350 ins_encode %{ 7351 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7352 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 7353 %} 7354 ins_pipe(pipe_class_default); 7355 %} 7356 7357 // shift != 0, base != 0 7358 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7359 match(Set dst (EncodePKlass (Binary base src))); 7360 predicate(false); 7361 7362 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7363 postalloc_expand %{ 7364 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7365 n1->add_req(n_region, n_base, n_src); 7366 n1->_opnds[0] = op_dst; 7367 n1->_opnds[1] = op_base; 7368 n1->_opnds[2] = op_src; 7369 n1->_bottom_type = _bottom_type; 7370 7371 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7372 n2->add_req(n_region, n1); 7373 n2->_opnds[0] = op_dst; 7374 n2->_opnds[1] = op_dst; 7375 n2->_bottom_type = _bottom_type; 7376 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7377 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7378 7379 nodes->push(n1); 7380 nodes->push(n2); 7381 %} 7382 %} 7383 7384 // shift != 0, base != 0 7385 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7386 match(Set dst (EncodePKlass src)); 7387 //predicate(Universe::narrow_klass_shift() != 0 && 7388 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 7389 7390 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7391 ins_cost(DEFAULT_COST*2); // Don't count constant. 7392 expand %{ 7393 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 7394 iRegLdst base; 7395 loadConL_Ex(base, baseImm); 7396 encodePKlass_not_null_Ex(dst, base, src); 7397 %} 7398 %} 7399 7400 // Decode nodes. 7401 7402 // Shift node for expand. 7403 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7404 // The match rule is needed to make it a 'MachTypeNode'! 7405 match(Set dst (DecodeNKlass src)); 7406 predicate(false); 7407 7408 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7409 size(4); 7410 ins_encode %{ 7411 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7412 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7413 %} 7414 ins_pipe(pipe_class_default); 7415 %} 7416 7417 // Add node for expand. 7418 7419 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7420 // The match rule is needed to make it a 'MachTypeNode'! 7421 match(Set dst (DecodeNKlass (Binary base src))); 7422 predicate(false); 7423 7424 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7425 size(4); 7426 ins_encode %{ 7427 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7428 __ add($dst$$Register, $base$$Register, $src$$Register); 7429 %} 7430 ins_pipe(pipe_class_default); 7431 %} 7432 7433 // src != 0, shift != 0, base != 0 7434 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7435 match(Set dst (DecodeNKlass (Binary base src))); 7436 //effect(kill src); // We need a register for the immediate result after shifting. 7437 predicate(false); 7438 7439 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7440 postalloc_expand %{ 7441 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7442 n1->add_req(n_region, n_base, n_src); 7443 n1->_opnds[0] = op_dst; 7444 n1->_opnds[1] = op_base; 7445 n1->_opnds[2] = op_src; 7446 n1->_bottom_type = _bottom_type; 7447 7448 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7449 n2->add_req(n_region, n1); 7450 n2->_opnds[0] = op_dst; 7451 n2->_opnds[1] = op_dst; 7452 n2->_bottom_type = _bottom_type; 7453 7454 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7455 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7456 7457 nodes->push(n1); 7458 nodes->push(n2); 7459 %} 7460 %} 7461 7462 // src != 0, shift != 0, base != 0 7463 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7464 match(Set dst (DecodeNKlass src)); 7465 // predicate(Universe::narrow_klass_shift() != 0 && 7466 // Universe::narrow_klass_base() != 0); 7467 7468 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7469 7470 ins_cost(DEFAULT_COST*2); // Don't count constant. 7471 expand %{ 7472 // We add first, then we shift. Like this, we can get along with one register less. 7473 // But we have to load the base pre-shifted. 7474 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7475 iRegLdst base; 7476 loadConL_Ex(base, baseImm); 7477 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7478 %} 7479 %} 7480 7481 //----------MemBar Instructions----------------------------------------------- 7482 // Memory barrier flavors 7483 7484 instruct membar_acquire() %{ 7485 match(LoadFence); 7486 ins_cost(4*MEMORY_REF_COST); 7487 7488 format %{ "MEMBAR-acquire" %} 7489 size(4); 7490 ins_encode %{ 7491 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7492 __ acquire(); 7493 %} 7494 ins_pipe(pipe_class_default); 7495 %} 7496 7497 instruct unnecessary_membar_acquire() %{ 7498 match(MemBarAcquire); 7499 ins_cost(0); 7500 7501 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7502 size(0); 7503 ins_encode( /*empty*/ ); 7504 ins_pipe(pipe_class_default); 7505 %} 7506 7507 instruct membar_acquire_lock() %{ 7508 match(MemBarAcquireLock); 7509 ins_cost(0); 7510 7511 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7512 size(0); 7513 ins_encode( /*empty*/ ); 7514 ins_pipe(pipe_class_default); 7515 %} 7516 7517 instruct membar_release() %{ 7518 match(MemBarRelease); 7519 match(StoreFence); 7520 ins_cost(4*MEMORY_REF_COST); 7521 7522 format %{ "MEMBAR-release" %} 7523 size(4); 7524 ins_encode %{ 7525 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7526 __ release(); 7527 %} 7528 ins_pipe(pipe_class_default); 7529 %} 7530 7531 instruct membar_storestore() %{ 7532 match(MemBarStoreStore); 7533 ins_cost(4*MEMORY_REF_COST); 7534 7535 format %{ "MEMBAR-store-store" %} 7536 size(4); 7537 ins_encode %{ 7538 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7539 __ membar(Assembler::StoreStore); 7540 %} 7541 ins_pipe(pipe_class_default); 7542 %} 7543 7544 instruct membar_release_lock() %{ 7545 match(MemBarReleaseLock); 7546 ins_cost(0); 7547 7548 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7549 size(0); 7550 ins_encode( /*empty*/ ); 7551 ins_pipe(pipe_class_default); 7552 %} 7553 7554 instruct membar_volatile() %{ 7555 match(MemBarVolatile); 7556 ins_cost(4*MEMORY_REF_COST); 7557 7558 format %{ "MEMBAR-volatile" %} 7559 size(4); 7560 ins_encode %{ 7561 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7562 __ fence(); 7563 %} 7564 ins_pipe(pipe_class_default); 7565 %} 7566 7567 // This optimization is wrong on PPC. The following pattern is not supported: 7568 // MemBarVolatile 7569 // ^ ^ 7570 // | | 7571 // CtrlProj MemProj 7572 // ^ ^ 7573 // | | 7574 // | Load 7575 // | 7576 // MemBarVolatile 7577 // 7578 // The first MemBarVolatile could get optimized out! According to 7579 // Vladimir, this pattern can not occur on Oracle platforms. 7580 // However, it does occur on PPC64 (because of membars in 7581 // inline_unsafe_load_store). 7582 // 7583 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7584 // Don't forget to look at the implementation of post_store_load_barrier again, 7585 // we did other fixes in that method. 7586 //instruct unnecessary_membar_volatile() %{ 7587 // match(MemBarVolatile); 7588 // predicate(Matcher::post_store_load_barrier(n)); 7589 // ins_cost(0); 7590 // 7591 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7592 // size(0); 7593 // ins_encode( /*empty*/ ); 7594 // ins_pipe(pipe_class_default); 7595 //%} 7596 7597 instruct membar_CPUOrder() %{ 7598 match(MemBarCPUOrder); 7599 ins_cost(0); 7600 7601 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7602 size(0); 7603 ins_encode( /*empty*/ ); 7604 ins_pipe(pipe_class_default); 7605 %} 7606 7607 //----------Conditional Move--------------------------------------------------- 7608 7609 // Cmove using isel. 7610 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7611 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7612 predicate(VM_Version::has_isel()); 7613 ins_cost(DEFAULT_COST); 7614 7615 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7616 size(4); 7617 ins_encode %{ 7618 // This is a Power7 instruction for which no machine description 7619 // exists. Anyways, the scheduler should be off on Power7. 7620 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7621 int cc = $cmp$$cmpcode; 7622 __ isel($dst$$Register, $crx$$CondRegister, 7623 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7624 %} 7625 ins_pipe(pipe_class_default); 7626 %} 7627 7628 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7629 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7630 predicate(!VM_Version::has_isel()); 7631 ins_cost(DEFAULT_COST+BRANCH_COST); 7632 7633 ins_variable_size_depending_on_alignment(true); 7634 7635 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7636 // Worst case is branch + move + stop, no stop without scheduler 7637 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7638 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7639 ins_pipe(pipe_class_default); 7640 %} 7641 7642 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7643 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7644 ins_cost(DEFAULT_COST+BRANCH_COST); 7645 7646 ins_variable_size_depending_on_alignment(true); 7647 7648 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7649 // Worst case is branch + move + stop, no stop without scheduler 7650 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7651 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7652 ins_pipe(pipe_class_default); 7653 %} 7654 7655 // Cmove using isel. 7656 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7657 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7658 predicate(VM_Version::has_isel()); 7659 ins_cost(DEFAULT_COST); 7660 7661 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7662 size(4); 7663 ins_encode %{ 7664 // This is a Power7 instruction for which no machine description 7665 // exists. Anyways, the scheduler should be off on Power7. 7666 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7667 int cc = $cmp$$cmpcode; 7668 __ isel($dst$$Register, $crx$$CondRegister, 7669 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7670 %} 7671 ins_pipe(pipe_class_default); 7672 %} 7673 7674 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7675 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7676 predicate(!VM_Version::has_isel()); 7677 ins_cost(DEFAULT_COST+BRANCH_COST); 7678 7679 ins_variable_size_depending_on_alignment(true); 7680 7681 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7682 // Worst case is branch + move + stop, no stop without scheduler. 7683 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7684 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7685 ins_pipe(pipe_class_default); 7686 %} 7687 7688 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7689 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7690 ins_cost(DEFAULT_COST+BRANCH_COST); 7691 7692 ins_variable_size_depending_on_alignment(true); 7693 7694 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7695 // Worst case is branch + move + stop, no stop without scheduler. 7696 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7697 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7698 ins_pipe(pipe_class_default); 7699 %} 7700 7701 // Cmove using isel. 7702 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7703 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7704 predicate(VM_Version::has_isel()); 7705 ins_cost(DEFAULT_COST); 7706 7707 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7708 size(4); 7709 ins_encode %{ 7710 // This is a Power7 instruction for which no machine description 7711 // exists. Anyways, the scheduler should be off on Power7. 7712 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7713 int cc = $cmp$$cmpcode; 7714 __ isel($dst$$Register, $crx$$CondRegister, 7715 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7716 %} 7717 ins_pipe(pipe_class_default); 7718 %} 7719 7720 // Conditional move for RegN. Only cmov(reg, reg). 7721 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7722 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7723 predicate(!VM_Version::has_isel()); 7724 ins_cost(DEFAULT_COST+BRANCH_COST); 7725 7726 ins_variable_size_depending_on_alignment(true); 7727 7728 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7729 // Worst case is branch + move + stop, no stop without scheduler. 7730 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7731 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7732 ins_pipe(pipe_class_default); 7733 %} 7734 7735 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7736 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7737 ins_cost(DEFAULT_COST+BRANCH_COST); 7738 7739 ins_variable_size_depending_on_alignment(true); 7740 7741 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7742 // Worst case is branch + move + stop, no stop without scheduler. 7743 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7744 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7745 ins_pipe(pipe_class_default); 7746 %} 7747 7748 // Cmove using isel. 7749 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7750 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7751 predicate(VM_Version::has_isel()); 7752 ins_cost(DEFAULT_COST); 7753 7754 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7755 size(4); 7756 ins_encode %{ 7757 // This is a Power7 instruction for which no machine description 7758 // exists. Anyways, the scheduler should be off on Power7. 7759 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7760 int cc = $cmp$$cmpcode; 7761 __ isel($dst$$Register, $crx$$CondRegister, 7762 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7763 %} 7764 ins_pipe(pipe_class_default); 7765 %} 7766 7767 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7768 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7769 predicate(!VM_Version::has_isel()); 7770 ins_cost(DEFAULT_COST+BRANCH_COST); 7771 7772 ins_variable_size_depending_on_alignment(true); 7773 7774 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7775 // Worst case is branch + move + stop, no stop without scheduler. 7776 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7777 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7778 ins_pipe(pipe_class_default); 7779 %} 7780 7781 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7782 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7783 ins_cost(DEFAULT_COST+BRANCH_COST); 7784 7785 ins_variable_size_depending_on_alignment(true); 7786 7787 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7788 // Worst case is branch + move + stop, no stop without scheduler. 7789 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7790 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7791 ins_pipe(pipe_class_default); 7792 %} 7793 7794 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7795 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7796 ins_cost(DEFAULT_COST+BRANCH_COST); 7797 7798 ins_variable_size_depending_on_alignment(true); 7799 7800 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7801 // Worst case is branch + move + stop, no stop without scheduler. 7802 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7803 ins_encode %{ 7804 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7805 Label done; 7806 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7807 // Branch if not (cmp crx). 7808 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7809 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7810 // TODO PPC port __ endgroup_if_needed(_size == 12); 7811 __ bind(done); 7812 %} 7813 ins_pipe(pipe_class_default); 7814 %} 7815 7816 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7817 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7818 ins_cost(DEFAULT_COST+BRANCH_COST); 7819 7820 ins_variable_size_depending_on_alignment(true); 7821 7822 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7823 // Worst case is branch + move + stop, no stop without scheduler. 7824 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7825 ins_encode %{ 7826 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7827 Label done; 7828 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7829 // Branch if not (cmp crx). 7830 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7831 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7832 // TODO PPC port __ endgroup_if_needed(_size == 12); 7833 __ bind(done); 7834 %} 7835 ins_pipe(pipe_class_default); 7836 %} 7837 7838 //----------Conditional_store-------------------------------------------------- 7839 // Conditional-store of the updated heap-top. 7840 // Used during allocation of the shared heap. 7841 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7842 7843 // As compareAndSwapL, but return flag register instead of boolean value in 7844 // int register. 7845 // Used by sun/misc/AtomicLongCSImpl.java. 7846 // Mem_ptr must be a memory operand, else this node does not get 7847 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7848 // can be rematerialized which leads to errors. 7849 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7850 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7851 effect(TEMP cr0); 7852 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7853 ins_encode %{ 7854 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7855 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7856 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7857 noreg, NULL, true); 7858 %} 7859 ins_pipe(pipe_class_default); 7860 %} 7861 7862 // As compareAndSwapP, but return flag register instead of boolean value in 7863 // int register. 7864 // This instruction is matched if UseTLAB is off. 7865 // Mem_ptr must be a memory operand, else this node does not get 7866 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7867 // can be rematerialized which leads to errors. 7868 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7869 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7870 ins_cost(2*MEMORY_REF_COST); 7871 7872 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7873 ins_encode %{ 7874 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7875 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7876 %} 7877 ins_pipe(pipe_class_memory); 7878 %} 7879 7880 // Implement LoadPLocked. Must be ordered against changes of the memory location 7881 // by storePConditional. 7882 // Don't know whether this is ever used. 7883 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7884 match(Set dst (LoadPLocked mem)); 7885 ins_cost(2*MEMORY_REF_COST); 7886 7887 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7888 size(4); 7889 ins_encode %{ 7890 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7891 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7892 %} 7893 ins_pipe(pipe_class_memory); 7894 %} 7895 7896 //----------Compare-And-Swap--------------------------------------------------- 7897 7898 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7899 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7900 // matched. 7901 7902 // Strong versions: 7903 7904 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7905 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7906 predicate(VM_Version::has_lqarx()); 7907 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7908 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7909 ins_encode %{ 7910 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7911 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7912 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7913 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7914 $res$$Register, true); 7915 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7916 __ isync(); 7917 } else { 7918 __ sync(); 7919 } 7920 %} 7921 ins_pipe(pipe_class_default); 7922 %} 7923 7924 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7925 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7926 predicate(!VM_Version::has_lqarx()); 7927 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7928 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7929 ins_encode %{ 7930 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7931 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7932 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7933 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7934 $res$$Register, true); 7935 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7936 __ isync(); 7937 } else { 7938 __ sync(); 7939 } 7940 %} 7941 ins_pipe(pipe_class_default); 7942 %} 7943 7944 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7945 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7946 predicate(VM_Version::has_lqarx()); 7947 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7948 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7949 ins_encode %{ 7950 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7951 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7952 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7953 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7954 $res$$Register, true); 7955 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7956 __ isync(); 7957 } else { 7958 __ sync(); 7959 } 7960 %} 7961 ins_pipe(pipe_class_default); 7962 %} 7963 7964 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7965 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7966 predicate(!VM_Version::has_lqarx()); 7967 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7968 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7969 ins_encode %{ 7970 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7971 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7972 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7973 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7974 $res$$Register, true); 7975 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7976 __ isync(); 7977 } else { 7978 __ sync(); 7979 } 7980 %} 7981 ins_pipe(pipe_class_default); 7982 %} 7983 7984 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7985 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7986 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7987 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7988 ins_encode %{ 7989 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7990 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7991 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7992 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7993 $res$$Register, true); 7994 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7995 __ isync(); 7996 } else { 7997 __ sync(); 7998 } 7999 %} 8000 ins_pipe(pipe_class_default); 8001 %} 8002 8003 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8004 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 8005 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8006 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8007 ins_encode %{ 8008 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8009 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8010 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8011 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8012 $res$$Register, true); 8013 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8014 __ isync(); 8015 } else { 8016 __ sync(); 8017 } 8018 %} 8019 ins_pipe(pipe_class_default); 8020 %} 8021 8022 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8023 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 8024 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8025 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8026 ins_encode %{ 8027 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8028 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8029 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8030 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8031 $res$$Register, NULL, true); 8032 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8033 __ isync(); 8034 } else { 8035 __ sync(); 8036 } 8037 %} 8038 ins_pipe(pipe_class_default); 8039 %} 8040 8041 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8042 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 8043 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8044 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8045 ins_encode %{ 8046 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8047 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8048 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8049 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8050 $res$$Register, NULL, true); 8051 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8052 __ isync(); 8053 } else { 8054 __ sync(); 8055 } 8056 %} 8057 ins_pipe(pipe_class_default); 8058 %} 8059 8060 // Weak versions: 8061 8062 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8063 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8064 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8065 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8066 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8067 ins_encode %{ 8068 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8069 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8070 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8071 MacroAssembler::MemBarNone, 8072 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8073 %} 8074 ins_pipe(pipe_class_default); 8075 %} 8076 8077 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8078 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8079 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8080 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8081 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8082 ins_encode %{ 8083 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8084 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8085 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8086 MacroAssembler::MemBarNone, 8087 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8088 %} 8089 ins_pipe(pipe_class_default); 8090 %} 8091 8092 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8093 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8094 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8095 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8096 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8097 ins_encode %{ 8098 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8099 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8100 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8101 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8102 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8103 %} 8104 ins_pipe(pipe_class_default); 8105 %} 8106 8107 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8108 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8109 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8110 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8111 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8112 ins_encode %{ 8113 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8114 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8115 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8116 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8117 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8118 %} 8119 ins_pipe(pipe_class_default); 8120 %} 8121 8122 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8123 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8124 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8125 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8126 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8127 ins_encode %{ 8128 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8129 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8130 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8131 MacroAssembler::MemBarNone, 8132 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8133 %} 8134 ins_pipe(pipe_class_default); 8135 %} 8136 8137 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8138 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8139 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8140 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8141 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8142 ins_encode %{ 8143 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8144 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8145 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8146 MacroAssembler::MemBarNone, 8147 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8148 %} 8149 ins_pipe(pipe_class_default); 8150 %} 8151 8152 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8153 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8154 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8155 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8156 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8157 ins_encode %{ 8158 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8159 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8160 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8161 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8162 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8163 %} 8164 ins_pipe(pipe_class_default); 8165 %} 8166 8167 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8168 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8169 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8170 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8171 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8172 ins_encode %{ 8173 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8174 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8175 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8176 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8177 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8178 %} 8179 ins_pipe(pipe_class_default); 8180 %} 8181 8182 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8183 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8184 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8185 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8186 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8187 ins_encode %{ 8188 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8189 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8190 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8191 MacroAssembler::MemBarNone, 8192 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8193 %} 8194 ins_pipe(pipe_class_default); 8195 %} 8196 8197 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8198 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8199 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8200 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8201 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8202 ins_encode %{ 8203 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8204 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8205 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8206 // value is never passed to caller. 8207 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8208 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8209 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8210 %} 8211 ins_pipe(pipe_class_default); 8212 %} 8213 8214 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8215 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8216 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8217 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8218 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8219 ins_encode %{ 8220 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8221 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8222 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8223 MacroAssembler::MemBarNone, 8224 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8225 %} 8226 ins_pipe(pipe_class_default); 8227 %} 8228 8229 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8230 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8231 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8232 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8233 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8234 ins_encode %{ 8235 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8236 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8237 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8238 // value is never passed to caller. 8239 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8240 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8241 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8242 %} 8243 ins_pipe(pipe_class_default); 8244 %} 8245 8246 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8247 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8248 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8249 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8250 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8251 ins_encode %{ 8252 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8253 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8254 // value is never passed to caller. 8255 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8256 MacroAssembler::MemBarNone, 8257 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8258 %} 8259 ins_pipe(pipe_class_default); 8260 %} 8261 8262 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8263 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8264 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8265 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8266 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 8267 ins_encode %{ 8268 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8269 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8270 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8271 // value is never passed to caller. 8272 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8273 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8274 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8275 %} 8276 ins_pipe(pipe_class_default); 8277 %} 8278 8279 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8280 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8281 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8282 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8283 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8284 ins_encode %{ 8285 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8286 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8287 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8288 MacroAssembler::MemBarNone, 8289 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8290 %} 8291 ins_pipe(pipe_class_default); 8292 %} 8293 8294 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8295 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8296 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8297 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8298 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8299 ins_encode %{ 8300 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8301 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8302 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8303 // value is never passed to caller. 8304 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8305 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8306 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8307 %} 8308 ins_pipe(pipe_class_default); 8309 %} 8310 8311 // CompareAndExchange 8312 8313 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8314 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8315 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8316 effect(TEMP_DEF res, TEMP cr0); 8317 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8318 ins_encode %{ 8319 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8320 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8321 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8322 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8323 noreg, true); 8324 %} 8325 ins_pipe(pipe_class_default); 8326 %} 8327 8328 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8329 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8330 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8331 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8332 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8333 ins_encode %{ 8334 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8335 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8336 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8337 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8338 noreg, true); 8339 %} 8340 ins_pipe(pipe_class_default); 8341 %} 8342 8343 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8344 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8345 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8346 effect(TEMP_DEF res, TEMP cr0); 8347 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8348 ins_encode %{ 8349 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8350 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8351 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8352 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8353 noreg, true); 8354 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8355 __ isync(); 8356 } else { 8357 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8358 __ sync(); 8359 } 8360 %} 8361 ins_pipe(pipe_class_default); 8362 %} 8363 8364 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8365 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8366 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8367 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8368 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8369 ins_encode %{ 8370 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8371 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8372 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8373 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8374 noreg, true); 8375 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8376 __ isync(); 8377 } else { 8378 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8379 __ sync(); 8380 } 8381 %} 8382 ins_pipe(pipe_class_default); 8383 %} 8384 8385 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8386 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8387 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8388 effect(TEMP_DEF res, TEMP cr0); 8389 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8390 ins_encode %{ 8391 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8392 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8393 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8394 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8395 noreg, true); 8396 %} 8397 ins_pipe(pipe_class_default); 8398 %} 8399 8400 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8401 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8402 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8403 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8404 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8405 ins_encode %{ 8406 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8407 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8408 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8409 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8410 noreg, true); 8411 %} 8412 ins_pipe(pipe_class_default); 8413 %} 8414 8415 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8416 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8417 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8418 effect(TEMP_DEF res, TEMP cr0); 8419 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8420 ins_encode %{ 8421 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8422 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8423 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8424 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8425 noreg, true); 8426 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8427 __ isync(); 8428 } else { 8429 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8430 __ sync(); 8431 } 8432 %} 8433 ins_pipe(pipe_class_default); 8434 %} 8435 8436 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8437 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8438 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8439 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8440 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8441 ins_encode %{ 8442 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8443 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8444 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8445 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8446 noreg, true); 8447 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8448 __ isync(); 8449 } else { 8450 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8451 __ sync(); 8452 } 8453 %} 8454 ins_pipe(pipe_class_default); 8455 %} 8456 8457 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8458 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8459 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8460 effect(TEMP_DEF res, TEMP cr0); 8461 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8462 ins_encode %{ 8463 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8464 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8465 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8466 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8467 noreg, true); 8468 %} 8469 ins_pipe(pipe_class_default); 8470 %} 8471 8472 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8473 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8474 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8475 effect(TEMP_DEF res, TEMP cr0); 8476 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8477 ins_encode %{ 8478 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8479 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8480 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8481 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8482 noreg, true); 8483 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8484 __ isync(); 8485 } else { 8486 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8487 __ sync(); 8488 } 8489 %} 8490 ins_pipe(pipe_class_default); 8491 %} 8492 8493 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8494 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8495 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8496 effect(TEMP_DEF res, TEMP cr0); 8497 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8498 ins_encode %{ 8499 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8500 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8501 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8502 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8503 noreg, true); 8504 %} 8505 ins_pipe(pipe_class_default); 8506 %} 8507 8508 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8509 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8510 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8511 effect(TEMP_DEF res, TEMP cr0); 8512 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8513 ins_encode %{ 8514 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8515 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8516 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8517 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8518 noreg, true); 8519 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8520 __ isync(); 8521 } else { 8522 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8523 __ sync(); 8524 } 8525 %} 8526 ins_pipe(pipe_class_default); 8527 %} 8528 8529 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8530 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8531 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8532 effect(TEMP_DEF res, TEMP cr0); 8533 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8534 ins_encode %{ 8535 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8536 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8537 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8538 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8539 noreg, NULL, true); 8540 %} 8541 ins_pipe(pipe_class_default); 8542 %} 8543 8544 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8545 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8546 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8547 effect(TEMP_DEF res, TEMP cr0); 8548 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8549 ins_encode %{ 8550 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8551 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8552 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8553 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8554 noreg, NULL, true); 8555 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8556 __ isync(); 8557 } else { 8558 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8559 __ sync(); 8560 } 8561 %} 8562 ins_pipe(pipe_class_default); 8563 %} 8564 8565 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8566 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8567 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8568 effect(TEMP_DEF res, TEMP cr0); 8569 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8570 ins_encode %{ 8571 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8572 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8573 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8574 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8575 noreg, NULL, true); 8576 %} 8577 ins_pipe(pipe_class_default); 8578 %} 8579 8580 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8581 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8582 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8583 effect(TEMP_DEF res, TEMP cr0); 8584 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8585 ins_encode %{ 8586 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8587 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8588 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8589 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8590 noreg, NULL, true); 8591 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8592 __ isync(); 8593 } else { 8594 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8595 __ sync(); 8596 } 8597 %} 8598 ins_pipe(pipe_class_default); 8599 %} 8600 8601 // Special RMW 8602 8603 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8604 match(Set res (GetAndAddB mem_ptr src)); 8605 predicate(VM_Version::has_lqarx()); 8606 effect(TEMP_DEF res, TEMP cr0); 8607 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8608 ins_encode %{ 8609 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8610 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8611 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8612 __ isync(); 8613 } else { 8614 __ sync(); 8615 } 8616 %} 8617 ins_pipe(pipe_class_default); 8618 %} 8619 8620 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8621 match(Set res (GetAndAddB mem_ptr src)); 8622 predicate(!VM_Version::has_lqarx()); 8623 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8624 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8625 ins_encode %{ 8626 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8627 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8628 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8629 __ isync(); 8630 } else { 8631 __ sync(); 8632 } 8633 %} 8634 ins_pipe(pipe_class_default); 8635 %} 8636 8637 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8638 match(Set res (GetAndAddS mem_ptr src)); 8639 predicate(VM_Version::has_lqarx()); 8640 effect(TEMP_DEF res, TEMP cr0); 8641 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8642 ins_encode %{ 8643 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8644 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8645 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8646 __ isync(); 8647 } else { 8648 __ sync(); 8649 } 8650 %} 8651 ins_pipe(pipe_class_default); 8652 %} 8653 8654 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8655 match(Set res (GetAndAddS mem_ptr src)); 8656 predicate(!VM_Version::has_lqarx()); 8657 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8658 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8659 ins_encode %{ 8660 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8661 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8662 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8663 __ isync(); 8664 } else { 8665 __ sync(); 8666 } 8667 %} 8668 ins_pipe(pipe_class_default); 8669 %} 8670 8671 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8672 match(Set res (GetAndAddI mem_ptr src)); 8673 effect(TEMP_DEF res, TEMP cr0); 8674 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8675 ins_encode %{ 8676 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8677 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8678 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8679 __ isync(); 8680 } else { 8681 __ sync(); 8682 } 8683 %} 8684 ins_pipe(pipe_class_default); 8685 %} 8686 8687 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8688 match(Set res (GetAndAddL mem_ptr src)); 8689 effect(TEMP_DEF res, TEMP cr0); 8690 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8691 ins_encode %{ 8692 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8693 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8694 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8695 __ isync(); 8696 } else { 8697 __ sync(); 8698 } 8699 %} 8700 ins_pipe(pipe_class_default); 8701 %} 8702 8703 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8704 match(Set res (GetAndSetB mem_ptr src)); 8705 predicate(VM_Version::has_lqarx()); 8706 effect(TEMP_DEF res, TEMP cr0); 8707 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8708 ins_encode %{ 8709 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8710 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8711 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8712 __ isync(); 8713 } else { 8714 __ sync(); 8715 } 8716 %} 8717 ins_pipe(pipe_class_default); 8718 %} 8719 8720 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8721 match(Set res (GetAndSetB mem_ptr src)); 8722 predicate(!VM_Version::has_lqarx()); 8723 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8724 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8725 ins_encode %{ 8726 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8727 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8728 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8729 __ isync(); 8730 } else { 8731 __ sync(); 8732 } 8733 %} 8734 ins_pipe(pipe_class_default); 8735 %} 8736 8737 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8738 match(Set res (GetAndSetS mem_ptr src)); 8739 predicate(VM_Version::has_lqarx()); 8740 effect(TEMP_DEF res, TEMP cr0); 8741 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8742 ins_encode %{ 8743 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8744 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8745 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8746 __ isync(); 8747 } else { 8748 __ sync(); 8749 } 8750 %} 8751 ins_pipe(pipe_class_default); 8752 %} 8753 8754 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8755 match(Set res (GetAndSetS mem_ptr src)); 8756 predicate(!VM_Version::has_lqarx()); 8757 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8758 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8759 ins_encode %{ 8760 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8761 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8762 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8763 __ isync(); 8764 } else { 8765 __ sync(); 8766 } 8767 %} 8768 ins_pipe(pipe_class_default); 8769 %} 8770 8771 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8772 match(Set res (GetAndSetI mem_ptr src)); 8773 effect(TEMP_DEF res, TEMP cr0); 8774 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8775 ins_encode %{ 8776 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8777 MacroAssembler::cmpxchgx_hint_atomic_update()); 8778 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8779 __ isync(); 8780 } else { 8781 __ sync(); 8782 } 8783 %} 8784 ins_pipe(pipe_class_default); 8785 %} 8786 8787 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8788 match(Set res (GetAndSetL mem_ptr src)); 8789 effect(TEMP_DEF res, TEMP cr0); 8790 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8791 ins_encode %{ 8792 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8793 MacroAssembler::cmpxchgx_hint_atomic_update()); 8794 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8795 __ isync(); 8796 } else { 8797 __ sync(); 8798 } 8799 %} 8800 ins_pipe(pipe_class_default); 8801 %} 8802 8803 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8804 match(Set res (GetAndSetP mem_ptr src)); 8805 effect(TEMP_DEF res, TEMP cr0); 8806 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8807 ins_encode %{ 8808 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8809 MacroAssembler::cmpxchgx_hint_atomic_update()); 8810 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8811 __ isync(); 8812 } else { 8813 __ sync(); 8814 } 8815 %} 8816 ins_pipe(pipe_class_default); 8817 %} 8818 8819 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8820 match(Set res (GetAndSetN mem_ptr src)); 8821 effect(TEMP_DEF res, TEMP cr0); 8822 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8823 ins_encode %{ 8824 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8825 MacroAssembler::cmpxchgx_hint_atomic_update()); 8826 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8827 __ isync(); 8828 } else { 8829 __ sync(); 8830 } 8831 %} 8832 ins_pipe(pipe_class_default); 8833 %} 8834 8835 //----------Arithmetic Instructions-------------------------------------------- 8836 // Addition Instructions 8837 8838 // Register Addition 8839 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8840 match(Set dst (AddI src1 src2)); 8841 format %{ "ADD $dst, $src1, $src2" %} 8842 size(4); 8843 ins_encode %{ 8844 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8845 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8846 %} 8847 ins_pipe(pipe_class_default); 8848 %} 8849 8850 // Expand does not work with above instruct. (??) 8851 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8852 // no match-rule 8853 effect(DEF dst, USE src1, USE src2); 8854 format %{ "ADD $dst, $src1, $src2" %} 8855 size(4); 8856 ins_encode %{ 8857 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8858 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8859 %} 8860 ins_pipe(pipe_class_default); 8861 %} 8862 8863 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8864 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8865 ins_cost(DEFAULT_COST*3); 8866 8867 expand %{ 8868 // FIXME: we should do this in the ideal world. 8869 iRegIdst tmp1; 8870 iRegIdst tmp2; 8871 addI_reg_reg(tmp1, src1, src2); 8872 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8873 addI_reg_reg(dst, tmp1, tmp2); 8874 %} 8875 %} 8876 8877 // Immediate Addition 8878 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8879 match(Set dst (AddI src1 src2)); 8880 format %{ "ADDI $dst, $src1, $src2" %} 8881 size(4); 8882 ins_encode %{ 8883 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8884 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8885 %} 8886 ins_pipe(pipe_class_default); 8887 %} 8888 8889 // Immediate Addition with 16-bit shifted operand 8890 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8891 match(Set dst (AddI src1 src2)); 8892 format %{ "ADDIS $dst, $src1, $src2" %} 8893 size(4); 8894 ins_encode %{ 8895 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8896 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8897 %} 8898 ins_pipe(pipe_class_default); 8899 %} 8900 8901 // Long Addition 8902 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8903 match(Set dst (AddL src1 src2)); 8904 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8905 size(4); 8906 ins_encode %{ 8907 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8908 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8909 %} 8910 ins_pipe(pipe_class_default); 8911 %} 8912 8913 // Expand does not work with above instruct. (??) 8914 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8915 // no match-rule 8916 effect(DEF dst, USE src1, USE src2); 8917 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8918 size(4); 8919 ins_encode %{ 8920 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8921 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8922 %} 8923 ins_pipe(pipe_class_default); 8924 %} 8925 8926 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8927 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8928 ins_cost(DEFAULT_COST*3); 8929 8930 expand %{ 8931 // FIXME: we should do this in the ideal world. 8932 iRegLdst tmp1; 8933 iRegLdst tmp2; 8934 addL_reg_reg(tmp1, src1, src2); 8935 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8936 addL_reg_reg(dst, tmp1, tmp2); 8937 %} 8938 %} 8939 8940 // AddL + ConvL2I. 8941 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8942 match(Set dst (ConvL2I (AddL src1 src2))); 8943 8944 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8945 size(4); 8946 ins_encode %{ 8947 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8948 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8949 %} 8950 ins_pipe(pipe_class_default); 8951 %} 8952 8953 // No constant pool entries required. 8954 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8955 match(Set dst (AddL src1 src2)); 8956 8957 format %{ "ADDI $dst, $src1, $src2" %} 8958 size(4); 8959 ins_encode %{ 8960 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8961 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8962 %} 8963 ins_pipe(pipe_class_default); 8964 %} 8965 8966 // Long Immediate Addition with 16-bit shifted operand. 8967 // No constant pool entries required. 8968 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8969 match(Set dst (AddL src1 src2)); 8970 8971 format %{ "ADDIS $dst, $src1, $src2" %} 8972 size(4); 8973 ins_encode %{ 8974 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8975 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8976 %} 8977 ins_pipe(pipe_class_default); 8978 %} 8979 8980 // Pointer Register Addition 8981 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8982 match(Set dst (AddP src1 src2)); 8983 format %{ "ADD $dst, $src1, $src2" %} 8984 size(4); 8985 ins_encode %{ 8986 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8987 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8988 %} 8989 ins_pipe(pipe_class_default); 8990 %} 8991 8992 // Pointer Immediate Addition 8993 // No constant pool entries required. 8994 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8995 match(Set dst (AddP src1 src2)); 8996 8997 format %{ "ADDI $dst, $src1, $src2" %} 8998 size(4); 8999 ins_encode %{ 9000 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 9001 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 9002 %} 9003 ins_pipe(pipe_class_default); 9004 %} 9005 9006 // Pointer Immediate Addition with 16-bit shifted operand. 9007 // No constant pool entries required. 9008 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 9009 match(Set dst (AddP src1 src2)); 9010 9011 format %{ "ADDIS $dst, $src1, $src2" %} 9012 size(4); 9013 ins_encode %{ 9014 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 9015 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 9016 %} 9017 ins_pipe(pipe_class_default); 9018 %} 9019 9020 //--------------------- 9021 // Subtraction Instructions 9022 9023 // Register Subtraction 9024 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9025 match(Set dst (SubI src1 src2)); 9026 format %{ "SUBF $dst, $src2, $src1" %} 9027 size(4); 9028 ins_encode %{ 9029 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9030 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9031 %} 9032 ins_pipe(pipe_class_default); 9033 %} 9034 9035 // Immediate Subtraction 9036 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 9037 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 9038 9039 // SubI from constant (using subfic). 9040 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 9041 match(Set dst (SubI src1 src2)); 9042 format %{ "SUBI $dst, $src1, $src2" %} 9043 9044 size(4); 9045 ins_encode %{ 9046 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 9047 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 9048 %} 9049 ins_pipe(pipe_class_default); 9050 %} 9051 9052 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 9053 // positive integers and 0xF...F for negative ones. 9054 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 9055 // no match-rule, false predicate 9056 effect(DEF dst, USE src); 9057 predicate(false); 9058 9059 format %{ "SRAWI $dst, $src, #31" %} 9060 size(4); 9061 ins_encode %{ 9062 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9063 __ srawi($dst$$Register, $src$$Register, 0x1f); 9064 %} 9065 ins_pipe(pipe_class_default); 9066 %} 9067 9068 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 9069 match(Set dst (AbsI src)); 9070 ins_cost(DEFAULT_COST*3); 9071 9072 expand %{ 9073 iRegIdst tmp1; 9074 iRegIdst tmp2; 9075 signmask32I_regI(tmp1, src); 9076 xorI_reg_reg(tmp2, tmp1, src); 9077 subI_reg_reg(dst, tmp2, tmp1); 9078 %} 9079 %} 9080 9081 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9082 match(Set dst (SubI zero src2)); 9083 format %{ "NEG $dst, $src2" %} 9084 size(4); 9085 ins_encode %{ 9086 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9087 __ neg($dst$$Register, $src2$$Register); 9088 %} 9089 ins_pipe(pipe_class_default); 9090 %} 9091 9092 // Long subtraction 9093 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9094 match(Set dst (SubL src1 src2)); 9095 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9096 size(4); 9097 ins_encode %{ 9098 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9099 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9100 %} 9101 ins_pipe(pipe_class_default); 9102 %} 9103 9104 // SubL + convL2I. 9105 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9106 match(Set dst (ConvL2I (SubL src1 src2))); 9107 9108 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9109 size(4); 9110 ins_encode %{ 9111 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9112 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9113 %} 9114 ins_pipe(pipe_class_default); 9115 %} 9116 9117 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9118 // positive longs and 0xF...F for negative ones. 9119 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9120 // no match-rule, false predicate 9121 effect(DEF dst, USE src); 9122 predicate(false); 9123 9124 format %{ "SRADI $dst, $src, #63" %} 9125 size(4); 9126 ins_encode %{ 9127 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9128 __ sradi($dst$$Register, $src$$Register, 0x3f); 9129 %} 9130 ins_pipe(pipe_class_default); 9131 %} 9132 9133 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9134 // positive longs and 0xF...F for negative ones. 9135 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9136 // no match-rule, false predicate 9137 effect(DEF dst, USE src); 9138 predicate(false); 9139 9140 format %{ "SRADI $dst, $src, #63" %} 9141 size(4); 9142 ins_encode %{ 9143 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9144 __ sradi($dst$$Register, $src$$Register, 0x3f); 9145 %} 9146 ins_pipe(pipe_class_default); 9147 %} 9148 9149 // Long negation 9150 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9151 match(Set dst (SubL zero src2)); 9152 format %{ "NEG $dst, $src2 \t// long" %} 9153 size(4); 9154 ins_encode %{ 9155 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9156 __ neg($dst$$Register, $src2$$Register); 9157 %} 9158 ins_pipe(pipe_class_default); 9159 %} 9160 9161 // NegL + ConvL2I. 9162 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9163 match(Set dst (ConvL2I (SubL zero src2))); 9164 9165 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9166 size(4); 9167 ins_encode %{ 9168 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9169 __ neg($dst$$Register, $src2$$Register); 9170 %} 9171 ins_pipe(pipe_class_default); 9172 %} 9173 9174 // Multiplication Instructions 9175 // Integer Multiplication 9176 9177 // Register Multiplication 9178 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9179 match(Set dst (MulI src1 src2)); 9180 ins_cost(DEFAULT_COST); 9181 9182 format %{ "MULLW $dst, $src1, $src2" %} 9183 size(4); 9184 ins_encode %{ 9185 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9186 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9187 %} 9188 ins_pipe(pipe_class_default); 9189 %} 9190 9191 // Immediate Multiplication 9192 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9193 match(Set dst (MulI src1 src2)); 9194 ins_cost(DEFAULT_COST); 9195 9196 format %{ "MULLI $dst, $src1, $src2" %} 9197 size(4); 9198 ins_encode %{ 9199 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9200 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9201 %} 9202 ins_pipe(pipe_class_default); 9203 %} 9204 9205 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9206 match(Set dst (MulL src1 src2)); 9207 ins_cost(DEFAULT_COST); 9208 9209 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9210 size(4); 9211 ins_encode %{ 9212 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9213 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9214 %} 9215 ins_pipe(pipe_class_default); 9216 %} 9217 9218 // Multiply high for optimized long division by constant. 9219 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9220 match(Set dst (MulHiL src1 src2)); 9221 ins_cost(DEFAULT_COST); 9222 9223 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9224 size(4); 9225 ins_encode %{ 9226 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9227 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9228 %} 9229 ins_pipe(pipe_class_default); 9230 %} 9231 9232 // Immediate Multiplication 9233 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9234 match(Set dst (MulL src1 src2)); 9235 ins_cost(DEFAULT_COST); 9236 9237 format %{ "MULLI $dst, $src1, $src2" %} 9238 size(4); 9239 ins_encode %{ 9240 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9241 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9242 %} 9243 ins_pipe(pipe_class_default); 9244 %} 9245 9246 // Integer Division with Immediate -1: Negate. 9247 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9248 match(Set dst (DivI src1 src2)); 9249 ins_cost(DEFAULT_COST); 9250 9251 format %{ "NEG $dst, $src1 \t// /-1" %} 9252 size(4); 9253 ins_encode %{ 9254 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9255 __ neg($dst$$Register, $src1$$Register); 9256 %} 9257 ins_pipe(pipe_class_default); 9258 %} 9259 9260 // Integer Division with constant, but not -1. 9261 // We should be able to improve this by checking the type of src2. 9262 // It might well be that src2 is known to be positive. 9263 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9264 match(Set dst (DivI src1 src2)); 9265 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9266 ins_cost(2*DEFAULT_COST); 9267 9268 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9269 size(4); 9270 ins_encode %{ 9271 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9272 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9273 %} 9274 ins_pipe(pipe_class_default); 9275 %} 9276 9277 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9278 effect(USE_DEF dst, USE src1, USE crx); 9279 predicate(false); 9280 9281 ins_variable_size_depending_on_alignment(true); 9282 9283 format %{ "CMOVE $dst, neg($src1), $crx" %} 9284 // Worst case is branch + move + stop, no stop without scheduler. 9285 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9286 ins_encode %{ 9287 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9288 Label done; 9289 __ bne($crx$$CondRegister, done); 9290 __ neg($dst$$Register, $src1$$Register); 9291 // TODO PPC port __ endgroup_if_needed(_size == 12); 9292 __ bind(done); 9293 %} 9294 ins_pipe(pipe_class_default); 9295 %} 9296 9297 // Integer Division with Registers not containing constants. 9298 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9299 match(Set dst (DivI src1 src2)); 9300 ins_cost(10*DEFAULT_COST); 9301 9302 expand %{ 9303 immI16 imm %{ (int)-1 %} 9304 flagsReg tmp1; 9305 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9306 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9307 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9308 %} 9309 %} 9310 9311 // Long Division with Immediate -1: Negate. 9312 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9313 match(Set dst (DivL src1 src2)); 9314 ins_cost(DEFAULT_COST); 9315 9316 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9317 size(4); 9318 ins_encode %{ 9319 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9320 __ neg($dst$$Register, $src1$$Register); 9321 %} 9322 ins_pipe(pipe_class_default); 9323 %} 9324 9325 // Long Division with constant, but not -1. 9326 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9327 match(Set dst (DivL src1 src2)); 9328 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9329 ins_cost(2*DEFAULT_COST); 9330 9331 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9332 size(4); 9333 ins_encode %{ 9334 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9335 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9336 %} 9337 ins_pipe(pipe_class_default); 9338 %} 9339 9340 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9341 effect(USE_DEF dst, USE src1, USE crx); 9342 predicate(false); 9343 9344 ins_variable_size_depending_on_alignment(true); 9345 9346 format %{ "CMOVE $dst, neg($src1), $crx" %} 9347 // Worst case is branch + move + stop, no stop without scheduler. 9348 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9349 ins_encode %{ 9350 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9351 Label done; 9352 __ bne($crx$$CondRegister, done); 9353 __ neg($dst$$Register, $src1$$Register); 9354 // TODO PPC port __ endgroup_if_needed(_size == 12); 9355 __ bind(done); 9356 %} 9357 ins_pipe(pipe_class_default); 9358 %} 9359 9360 // Long Division with Registers not containing constants. 9361 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9362 match(Set dst (DivL src1 src2)); 9363 ins_cost(10*DEFAULT_COST); 9364 9365 expand %{ 9366 immL16 imm %{ (int)-1 %} 9367 flagsReg tmp1; 9368 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9369 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9370 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9371 %} 9372 %} 9373 9374 // Integer Remainder with registers. 9375 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9376 match(Set dst (ModI src1 src2)); 9377 ins_cost(10*DEFAULT_COST); 9378 9379 expand %{ 9380 immI16 imm %{ (int)-1 %} 9381 flagsReg tmp1; 9382 iRegIdst tmp2; 9383 iRegIdst tmp3; 9384 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9385 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9386 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9387 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9388 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9389 %} 9390 %} 9391 9392 // Long Remainder with registers 9393 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9394 match(Set dst (ModL src1 src2)); 9395 ins_cost(10*DEFAULT_COST); 9396 9397 expand %{ 9398 immL16 imm %{ (int)-1 %} 9399 flagsReg tmp1; 9400 iRegLdst tmp2; 9401 iRegLdst tmp3; 9402 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9403 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9404 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9405 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9406 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9407 %} 9408 %} 9409 9410 // Integer Shift Instructions 9411 9412 // Register Shift Left 9413 9414 // Clear all but the lowest #mask bits. 9415 // Used to normalize shift amounts in registers. 9416 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9417 // no match-rule, false predicate 9418 effect(DEF dst, USE src, USE mask); 9419 predicate(false); 9420 9421 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9422 size(4); 9423 ins_encode %{ 9424 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9425 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9426 %} 9427 ins_pipe(pipe_class_default); 9428 %} 9429 9430 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9431 // no match-rule, false predicate 9432 effect(DEF dst, USE src1, USE src2); 9433 predicate(false); 9434 9435 format %{ "SLW $dst, $src1, $src2" %} 9436 size(4); 9437 ins_encode %{ 9438 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9439 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9440 %} 9441 ins_pipe(pipe_class_default); 9442 %} 9443 9444 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9445 match(Set dst (LShiftI src1 src2)); 9446 ins_cost(DEFAULT_COST*2); 9447 expand %{ 9448 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9449 iRegIdst tmpI; 9450 maskI_reg_imm(tmpI, src2, mask); 9451 lShiftI_reg_reg(dst, src1, tmpI); 9452 %} 9453 %} 9454 9455 // Register Shift Left Immediate 9456 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9457 match(Set dst (LShiftI src1 src2)); 9458 9459 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9460 size(4); 9461 ins_encode %{ 9462 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9463 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9464 %} 9465 ins_pipe(pipe_class_default); 9466 %} 9467 9468 // AndI with negpow2-constant + LShiftI 9469 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9470 match(Set dst (LShiftI (AndI src1 src2) src3)); 9471 predicate(UseRotateAndMaskInstructionsPPC64); 9472 9473 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9474 size(4); 9475 ins_encode %{ 9476 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9477 long src2 = $src2$$constant; 9478 long src3 = $src3$$constant; 9479 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9480 if (maskbits >= 32) { 9481 __ li($dst$$Register, 0); // addi 9482 } else { 9483 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9484 } 9485 %} 9486 ins_pipe(pipe_class_default); 9487 %} 9488 9489 // RShiftI + AndI with negpow2-constant + LShiftI 9490 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9491 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9492 predicate(UseRotateAndMaskInstructionsPPC64); 9493 9494 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9495 size(4); 9496 ins_encode %{ 9497 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9498 long src2 = $src2$$constant; 9499 long src3 = $src3$$constant; 9500 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9501 if (maskbits >= 32) { 9502 __ li($dst$$Register, 0); // addi 9503 } else { 9504 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9505 } 9506 %} 9507 ins_pipe(pipe_class_default); 9508 %} 9509 9510 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9511 // no match-rule, false predicate 9512 effect(DEF dst, USE src1, USE src2); 9513 predicate(false); 9514 9515 format %{ "SLD $dst, $src1, $src2" %} 9516 size(4); 9517 ins_encode %{ 9518 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9519 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9520 %} 9521 ins_pipe(pipe_class_default); 9522 %} 9523 9524 // Register Shift Left 9525 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9526 match(Set dst (LShiftL src1 src2)); 9527 ins_cost(DEFAULT_COST*2); 9528 expand %{ 9529 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9530 iRegIdst tmpI; 9531 maskI_reg_imm(tmpI, src2, mask); 9532 lShiftL_regL_regI(dst, src1, tmpI); 9533 %} 9534 %} 9535 9536 // Register Shift Left Immediate 9537 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9538 match(Set dst (LShiftL src1 src2)); 9539 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9540 size(4); 9541 ins_encode %{ 9542 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9543 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9544 %} 9545 ins_pipe(pipe_class_default); 9546 %} 9547 9548 // If we shift more than 32 bits, we need not convert I2L. 9549 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9550 match(Set dst (LShiftL (ConvI2L src1) src2)); 9551 ins_cost(DEFAULT_COST); 9552 9553 size(4); 9554 format %{ "SLDI $dst, i2l($src1), $src2" %} 9555 ins_encode %{ 9556 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9557 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9558 %} 9559 ins_pipe(pipe_class_default); 9560 %} 9561 9562 // Shift a postivie int to the left. 9563 // Clrlsldi clears the upper 32 bits and shifts. 9564 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9565 match(Set dst (LShiftL (ConvI2L src1) src2)); 9566 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9567 9568 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9569 size(4); 9570 ins_encode %{ 9571 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9572 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9573 %} 9574 ins_pipe(pipe_class_default); 9575 %} 9576 9577 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9578 // no match-rule, false predicate 9579 effect(DEF dst, USE src1, USE src2); 9580 predicate(false); 9581 9582 format %{ "SRAW $dst, $src1, $src2" %} 9583 size(4); 9584 ins_encode %{ 9585 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9586 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9587 %} 9588 ins_pipe(pipe_class_default); 9589 %} 9590 9591 // Register Arithmetic Shift Right 9592 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9593 match(Set dst (RShiftI src1 src2)); 9594 ins_cost(DEFAULT_COST*2); 9595 expand %{ 9596 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9597 iRegIdst tmpI; 9598 maskI_reg_imm(tmpI, src2, mask); 9599 arShiftI_reg_reg(dst, src1, tmpI); 9600 %} 9601 %} 9602 9603 // Register Arithmetic Shift Right Immediate 9604 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9605 match(Set dst (RShiftI src1 src2)); 9606 9607 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9608 size(4); 9609 ins_encode %{ 9610 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9611 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9612 %} 9613 ins_pipe(pipe_class_default); 9614 %} 9615 9616 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9617 // no match-rule, false predicate 9618 effect(DEF dst, USE src1, USE src2); 9619 predicate(false); 9620 9621 format %{ "SRAD $dst, $src1, $src2" %} 9622 size(4); 9623 ins_encode %{ 9624 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9625 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9626 %} 9627 ins_pipe(pipe_class_default); 9628 %} 9629 9630 // Register Shift Right Arithmetic Long 9631 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9632 match(Set dst (RShiftL src1 src2)); 9633 ins_cost(DEFAULT_COST*2); 9634 9635 expand %{ 9636 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9637 iRegIdst tmpI; 9638 maskI_reg_imm(tmpI, src2, mask); 9639 arShiftL_regL_regI(dst, src1, tmpI); 9640 %} 9641 %} 9642 9643 // Register Shift Right Immediate 9644 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9645 match(Set dst (RShiftL src1 src2)); 9646 9647 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9648 size(4); 9649 ins_encode %{ 9650 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9651 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9652 %} 9653 ins_pipe(pipe_class_default); 9654 %} 9655 9656 // RShiftL + ConvL2I 9657 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9658 match(Set dst (ConvL2I (RShiftL src1 src2))); 9659 9660 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9661 size(4); 9662 ins_encode %{ 9663 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9664 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9665 %} 9666 ins_pipe(pipe_class_default); 9667 %} 9668 9669 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9670 // no match-rule, false predicate 9671 effect(DEF dst, USE src1, USE src2); 9672 predicate(false); 9673 9674 format %{ "SRW $dst, $src1, $src2" %} 9675 size(4); 9676 ins_encode %{ 9677 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9678 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9679 %} 9680 ins_pipe(pipe_class_default); 9681 %} 9682 9683 // Register Shift Right 9684 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9685 match(Set dst (URShiftI src1 src2)); 9686 ins_cost(DEFAULT_COST*2); 9687 9688 expand %{ 9689 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9690 iRegIdst tmpI; 9691 maskI_reg_imm(tmpI, src2, mask); 9692 urShiftI_reg_reg(dst, src1, tmpI); 9693 %} 9694 %} 9695 9696 // Register Shift Right Immediate 9697 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9698 match(Set dst (URShiftI src1 src2)); 9699 9700 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9701 size(4); 9702 ins_encode %{ 9703 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9704 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9705 %} 9706 ins_pipe(pipe_class_default); 9707 %} 9708 9709 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9710 // no match-rule, false predicate 9711 effect(DEF dst, USE src1, USE src2); 9712 predicate(false); 9713 9714 format %{ "SRD $dst, $src1, $src2" %} 9715 size(4); 9716 ins_encode %{ 9717 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9718 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9719 %} 9720 ins_pipe(pipe_class_default); 9721 %} 9722 9723 // Register Shift Right 9724 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9725 match(Set dst (URShiftL src1 src2)); 9726 ins_cost(DEFAULT_COST*2); 9727 9728 expand %{ 9729 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9730 iRegIdst tmpI; 9731 maskI_reg_imm(tmpI, src2, mask); 9732 urShiftL_regL_regI(dst, src1, tmpI); 9733 %} 9734 %} 9735 9736 // Register Shift Right Immediate 9737 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9738 match(Set dst (URShiftL src1 src2)); 9739 9740 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9741 size(4); 9742 ins_encode %{ 9743 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9744 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9745 %} 9746 ins_pipe(pipe_class_default); 9747 %} 9748 9749 // URShiftL + ConvL2I. 9750 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9751 match(Set dst (ConvL2I (URShiftL src1 src2))); 9752 9753 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9754 size(4); 9755 ins_encode %{ 9756 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9757 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9758 %} 9759 ins_pipe(pipe_class_default); 9760 %} 9761 9762 // Register Shift Right Immediate with a CastP2X 9763 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9764 match(Set dst (URShiftL (CastP2X src1) src2)); 9765 9766 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9767 size(4); 9768 ins_encode %{ 9769 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9770 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9771 %} 9772 ins_pipe(pipe_class_default); 9773 %} 9774 9775 // Bitfield Extract: URShiftI + AndI 9776 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9777 match(Set dst (AndI (URShiftI src1 src2) src3)); 9778 9779 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9780 size(4); 9781 ins_encode %{ 9782 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9783 int rshift = ($src2$$constant) & 0x1f; 9784 int length = log2_long(((jlong) $src3$$constant) + 1); 9785 if (rshift + length > 32) { 9786 // if necessary, adjust mask to omit rotated bits. 9787 length = 32 - rshift; 9788 } 9789 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9790 %} 9791 ins_pipe(pipe_class_default); 9792 %} 9793 9794 // Bitfield Extract: URShiftL + AndL 9795 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9796 match(Set dst (AndL (URShiftL src1 src2) src3)); 9797 9798 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9799 size(4); 9800 ins_encode %{ 9801 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9802 int rshift = ($src2$$constant) & 0x3f; 9803 int length = log2_long(((jlong) $src3$$constant) + 1); 9804 if (rshift + length > 64) { 9805 // if necessary, adjust mask to omit rotated bits. 9806 length = 64 - rshift; 9807 } 9808 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9809 %} 9810 ins_pipe(pipe_class_default); 9811 %} 9812 9813 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9814 match(Set dst (ConvL2I (ConvI2L src))); 9815 9816 format %{ "EXTSW $dst, $src \t// int->int" %} 9817 size(4); 9818 ins_encode %{ 9819 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9820 __ extsw($dst$$Register, $src$$Register); 9821 %} 9822 ins_pipe(pipe_class_default); 9823 %} 9824 9825 //----------Rotate Instructions------------------------------------------------ 9826 9827 // Rotate Left by 8-bit immediate 9828 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9829 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9830 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9831 9832 format %{ "ROTLWI $dst, $src, $lshift" %} 9833 size(4); 9834 ins_encode %{ 9835 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9836 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9837 %} 9838 ins_pipe(pipe_class_default); 9839 %} 9840 9841 // Rotate Right by 8-bit immediate 9842 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9843 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9844 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9845 9846 format %{ "ROTRWI $dst, $rshift" %} 9847 size(4); 9848 ins_encode %{ 9849 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9850 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9851 %} 9852 ins_pipe(pipe_class_default); 9853 %} 9854 9855 //----------Floating Point Arithmetic Instructions----------------------------- 9856 9857 // Add float single precision 9858 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9859 match(Set dst (AddF src1 src2)); 9860 9861 format %{ "FADDS $dst, $src1, $src2" %} 9862 size(4); 9863 ins_encode %{ 9864 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9865 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9866 %} 9867 ins_pipe(pipe_class_default); 9868 %} 9869 9870 // Add float double precision 9871 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9872 match(Set dst (AddD src1 src2)); 9873 9874 format %{ "FADD $dst, $src1, $src2" %} 9875 size(4); 9876 ins_encode %{ 9877 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9878 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9879 %} 9880 ins_pipe(pipe_class_default); 9881 %} 9882 9883 // Sub float single precision 9884 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9885 match(Set dst (SubF src1 src2)); 9886 9887 format %{ "FSUBS $dst, $src1, $src2" %} 9888 size(4); 9889 ins_encode %{ 9890 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9891 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9892 %} 9893 ins_pipe(pipe_class_default); 9894 %} 9895 9896 // Sub float double precision 9897 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9898 match(Set dst (SubD src1 src2)); 9899 format %{ "FSUB $dst, $src1, $src2" %} 9900 size(4); 9901 ins_encode %{ 9902 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9903 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9904 %} 9905 ins_pipe(pipe_class_default); 9906 %} 9907 9908 // Mul float single precision 9909 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9910 match(Set dst (MulF src1 src2)); 9911 format %{ "FMULS $dst, $src1, $src2" %} 9912 size(4); 9913 ins_encode %{ 9914 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9915 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9916 %} 9917 ins_pipe(pipe_class_default); 9918 %} 9919 9920 // Mul float double precision 9921 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9922 match(Set dst (MulD src1 src2)); 9923 format %{ "FMUL $dst, $src1, $src2" %} 9924 size(4); 9925 ins_encode %{ 9926 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9927 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9928 %} 9929 ins_pipe(pipe_class_default); 9930 %} 9931 9932 // Div float single precision 9933 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9934 match(Set dst (DivF src1 src2)); 9935 format %{ "FDIVS $dst, $src1, $src2" %} 9936 size(4); 9937 ins_encode %{ 9938 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9939 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9940 %} 9941 ins_pipe(pipe_class_default); 9942 %} 9943 9944 // Div float double precision 9945 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9946 match(Set dst (DivD src1 src2)); 9947 format %{ "FDIV $dst, $src1, $src2" %} 9948 size(4); 9949 ins_encode %{ 9950 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9951 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9952 %} 9953 ins_pipe(pipe_class_default); 9954 %} 9955 9956 // Absolute float single precision 9957 instruct absF_reg(regF dst, regF src) %{ 9958 match(Set dst (AbsF src)); 9959 format %{ "FABS $dst, $src \t// float" %} 9960 size(4); 9961 ins_encode %{ 9962 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9963 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9964 %} 9965 ins_pipe(pipe_class_default); 9966 %} 9967 9968 // Absolute float double precision 9969 instruct absD_reg(regD dst, regD src) %{ 9970 match(Set dst (AbsD src)); 9971 format %{ "FABS $dst, $src \t// double" %} 9972 size(4); 9973 ins_encode %{ 9974 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9975 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9976 %} 9977 ins_pipe(pipe_class_default); 9978 %} 9979 9980 instruct negF_reg(regF dst, regF src) %{ 9981 match(Set dst (NegF src)); 9982 format %{ "FNEG $dst, $src \t// float" %} 9983 size(4); 9984 ins_encode %{ 9985 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9986 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9987 %} 9988 ins_pipe(pipe_class_default); 9989 %} 9990 9991 instruct negD_reg(regD dst, regD src) %{ 9992 match(Set dst (NegD src)); 9993 format %{ "FNEG $dst, $src \t// double" %} 9994 size(4); 9995 ins_encode %{ 9996 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9997 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9998 %} 9999 ins_pipe(pipe_class_default); 10000 %} 10001 10002 // AbsF + NegF. 10003 instruct negF_absF_reg(regF dst, regF src) %{ 10004 match(Set dst (NegF (AbsF src))); 10005 format %{ "FNABS $dst, $src \t// float" %} 10006 size(4); 10007 ins_encode %{ 10008 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10009 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10010 %} 10011 ins_pipe(pipe_class_default); 10012 %} 10013 10014 // AbsD + NegD. 10015 instruct negD_absD_reg(regD dst, regD src) %{ 10016 match(Set dst (NegD (AbsD src))); 10017 format %{ "FNABS $dst, $src \t// double" %} 10018 size(4); 10019 ins_encode %{ 10020 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10021 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10022 %} 10023 ins_pipe(pipe_class_default); 10024 %} 10025 10026 // VM_Version::has_fsqrt() decides if this node will be used. 10027 // Sqrt float double precision 10028 instruct sqrtD_reg(regD dst, regD src) %{ 10029 match(Set dst (SqrtD src)); 10030 format %{ "FSQRT $dst, $src" %} 10031 size(4); 10032 ins_encode %{ 10033 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 10034 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 10035 %} 10036 ins_pipe(pipe_class_default); 10037 %} 10038 10039 // Single-precision sqrt. 10040 instruct sqrtF_reg(regF dst, regF src) %{ 10041 match(Set dst (SqrtF src)); 10042 predicate(VM_Version::has_fsqrts()); 10043 ins_cost(DEFAULT_COST); 10044 10045 format %{ "FSQRTS $dst, $src" %} 10046 size(4); 10047 ins_encode %{ 10048 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 10049 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 10050 %} 10051 ins_pipe(pipe_class_default); 10052 %} 10053 10054 instruct roundDouble_nop(regD dst) %{ 10055 match(Set dst (RoundDouble dst)); 10056 ins_cost(0); 10057 10058 format %{ " -- \t// RoundDouble not needed - empty" %} 10059 size(0); 10060 // PPC results are already "rounded" (i.e., normal-format IEEE). 10061 ins_encode( /*empty*/ ); 10062 ins_pipe(pipe_class_default); 10063 %} 10064 10065 instruct roundFloat_nop(regF dst) %{ 10066 match(Set dst (RoundFloat dst)); 10067 ins_cost(0); 10068 10069 format %{ " -- \t// RoundFloat not needed - empty" %} 10070 size(0); 10071 // PPC results are already "rounded" (i.e., normal-format IEEE). 10072 ins_encode( /*empty*/ ); 10073 ins_pipe(pipe_class_default); 10074 %} 10075 10076 10077 // Multiply-Accumulate 10078 // src1 * src2 + src3 10079 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10080 match(Set dst (FmaF src3 (Binary src1 src2))); 10081 10082 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10083 size(4); 10084 ins_encode %{ 10085 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10086 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10087 %} 10088 ins_pipe(pipe_class_default); 10089 %} 10090 10091 // src1 * src2 + src3 10092 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10093 match(Set dst (FmaD src3 (Binary src1 src2))); 10094 10095 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10096 size(4); 10097 ins_encode %{ 10098 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10099 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10100 %} 10101 ins_pipe(pipe_class_default); 10102 %} 10103 10104 // -src1 * src2 + src3 = -(src1*src2-src3) 10105 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10106 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10107 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10108 10109 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10110 size(4); 10111 ins_encode %{ 10112 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10113 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10114 %} 10115 ins_pipe(pipe_class_default); 10116 %} 10117 10118 // -src1 * src2 + src3 = -(src1*src2-src3) 10119 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10120 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10121 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10122 10123 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10124 size(4); 10125 ins_encode %{ 10126 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10127 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10128 %} 10129 ins_pipe(pipe_class_default); 10130 %} 10131 10132 // -src1 * src2 - src3 = -(src1*src2+src3) 10133 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10134 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10135 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10136 10137 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10138 size(4); 10139 ins_encode %{ 10140 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10141 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10142 %} 10143 ins_pipe(pipe_class_default); 10144 %} 10145 10146 // -src1 * src2 - src3 = -(src1*src2+src3) 10147 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10148 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10149 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10150 10151 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10152 size(4); 10153 ins_encode %{ 10154 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10155 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10156 %} 10157 ins_pipe(pipe_class_default); 10158 %} 10159 10160 // src1 * src2 - src3 10161 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10162 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10163 10164 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10165 size(4); 10166 ins_encode %{ 10167 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10168 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10169 %} 10170 ins_pipe(pipe_class_default); 10171 %} 10172 10173 // src1 * src2 - src3 10174 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10175 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10176 10177 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10178 size(4); 10179 ins_encode %{ 10180 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10181 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10182 %} 10183 ins_pipe(pipe_class_default); 10184 %} 10185 10186 10187 //----------Logical Instructions----------------------------------------------- 10188 10189 // And Instructions 10190 10191 // Register And 10192 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10193 match(Set dst (AndI src1 src2)); 10194 format %{ "AND $dst, $src1, $src2" %} 10195 size(4); 10196 ins_encode %{ 10197 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10198 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10199 %} 10200 ins_pipe(pipe_class_default); 10201 %} 10202 10203 // Left shifted Immediate And 10204 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10205 match(Set dst (AndI src1 src2)); 10206 effect(KILL cr0); 10207 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10208 size(4); 10209 ins_encode %{ 10210 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10211 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10212 %} 10213 ins_pipe(pipe_class_default); 10214 %} 10215 10216 // Immediate And 10217 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10218 match(Set dst (AndI src1 src2)); 10219 effect(KILL cr0); 10220 10221 format %{ "ANDI $dst, $src1, $src2" %} 10222 size(4); 10223 ins_encode %{ 10224 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10225 // FIXME: avoid andi_ ? 10226 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10227 %} 10228 ins_pipe(pipe_class_default); 10229 %} 10230 10231 // Immediate And where the immediate is a negative power of 2. 10232 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10233 match(Set dst (AndI src1 src2)); 10234 format %{ "ANDWI $dst, $src1, $src2" %} 10235 size(4); 10236 ins_encode %{ 10237 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10238 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10239 %} 10240 ins_pipe(pipe_class_default); 10241 %} 10242 10243 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10244 match(Set dst (AndI src1 src2)); 10245 format %{ "ANDWI $dst, $src1, $src2" %} 10246 size(4); 10247 ins_encode %{ 10248 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10249 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10250 %} 10251 ins_pipe(pipe_class_default); 10252 %} 10253 10254 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10255 match(Set dst (AndI src1 src2)); 10256 predicate(UseRotateAndMaskInstructionsPPC64); 10257 format %{ "ANDWI $dst, $src1, $src2" %} 10258 size(4); 10259 ins_encode %{ 10260 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10261 __ rlwinm($dst$$Register, $src1$$Register, 0, 10262 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10263 %} 10264 ins_pipe(pipe_class_default); 10265 %} 10266 10267 // Register And Long 10268 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10269 match(Set dst (AndL src1 src2)); 10270 ins_cost(DEFAULT_COST); 10271 10272 format %{ "AND $dst, $src1, $src2 \t// long" %} 10273 size(4); 10274 ins_encode %{ 10275 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10276 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10277 %} 10278 ins_pipe(pipe_class_default); 10279 %} 10280 10281 // Immediate And long 10282 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10283 match(Set dst (AndL src1 src2)); 10284 effect(KILL cr0); 10285 10286 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10287 size(4); 10288 ins_encode %{ 10289 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10290 // FIXME: avoid andi_ ? 10291 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10292 %} 10293 ins_pipe(pipe_class_default); 10294 %} 10295 10296 // Immediate And Long where the immediate is a negative power of 2. 10297 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10298 match(Set dst (AndL src1 src2)); 10299 format %{ "ANDDI $dst, $src1, $src2" %} 10300 size(4); 10301 ins_encode %{ 10302 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10303 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10304 %} 10305 ins_pipe(pipe_class_default); 10306 %} 10307 10308 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10309 match(Set dst (AndL src1 src2)); 10310 format %{ "ANDDI $dst, $src1, $src2" %} 10311 size(4); 10312 ins_encode %{ 10313 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10314 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10315 %} 10316 ins_pipe(pipe_class_default); 10317 %} 10318 10319 // AndL + ConvL2I. 10320 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10321 match(Set dst (ConvL2I (AndL src1 src2))); 10322 ins_cost(DEFAULT_COST); 10323 10324 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10325 size(4); 10326 ins_encode %{ 10327 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10328 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10329 %} 10330 ins_pipe(pipe_class_default); 10331 %} 10332 10333 // Or Instructions 10334 10335 // Register Or 10336 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10337 match(Set dst (OrI src1 src2)); 10338 format %{ "OR $dst, $src1, $src2" %} 10339 size(4); 10340 ins_encode %{ 10341 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10342 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10343 %} 10344 ins_pipe(pipe_class_default); 10345 %} 10346 10347 // Expand does not work with above instruct. (??) 10348 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10349 // no match-rule 10350 effect(DEF dst, USE src1, USE src2); 10351 format %{ "OR $dst, $src1, $src2" %} 10352 size(4); 10353 ins_encode %{ 10354 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10355 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10356 %} 10357 ins_pipe(pipe_class_default); 10358 %} 10359 10360 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10361 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10362 ins_cost(DEFAULT_COST*3); 10363 10364 expand %{ 10365 // FIXME: we should do this in the ideal world. 10366 iRegIdst tmp1; 10367 iRegIdst tmp2; 10368 orI_reg_reg(tmp1, src1, src2); 10369 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10370 orI_reg_reg(dst, tmp1, tmp2); 10371 %} 10372 %} 10373 10374 // Immediate Or 10375 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10376 match(Set dst (OrI src1 src2)); 10377 format %{ "ORI $dst, $src1, $src2" %} 10378 size(4); 10379 ins_encode %{ 10380 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10381 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10382 %} 10383 ins_pipe(pipe_class_default); 10384 %} 10385 10386 // Register Or Long 10387 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10388 match(Set dst (OrL src1 src2)); 10389 ins_cost(DEFAULT_COST); 10390 10391 size(4); 10392 format %{ "OR $dst, $src1, $src2 \t// long" %} 10393 ins_encode %{ 10394 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10395 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10396 %} 10397 ins_pipe(pipe_class_default); 10398 %} 10399 10400 // OrL + ConvL2I. 10401 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10402 match(Set dst (ConvL2I (OrL src1 src2))); 10403 ins_cost(DEFAULT_COST); 10404 10405 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10406 size(4); 10407 ins_encode %{ 10408 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10409 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10410 %} 10411 ins_pipe(pipe_class_default); 10412 %} 10413 10414 // Immediate Or long 10415 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10416 match(Set dst (OrL src1 con)); 10417 ins_cost(DEFAULT_COST); 10418 10419 format %{ "ORI $dst, $src1, $con \t// long" %} 10420 size(4); 10421 ins_encode %{ 10422 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10423 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10424 %} 10425 ins_pipe(pipe_class_default); 10426 %} 10427 10428 // Xor Instructions 10429 10430 // Register Xor 10431 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10432 match(Set dst (XorI src1 src2)); 10433 format %{ "XOR $dst, $src1, $src2" %} 10434 size(4); 10435 ins_encode %{ 10436 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10437 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10438 %} 10439 ins_pipe(pipe_class_default); 10440 %} 10441 10442 // Expand does not work with above instruct. (??) 10443 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10444 // no match-rule 10445 effect(DEF dst, USE src1, USE src2); 10446 format %{ "XOR $dst, $src1, $src2" %} 10447 size(4); 10448 ins_encode %{ 10449 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10450 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10451 %} 10452 ins_pipe(pipe_class_default); 10453 %} 10454 10455 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10456 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10457 ins_cost(DEFAULT_COST*3); 10458 10459 expand %{ 10460 // FIXME: we should do this in the ideal world. 10461 iRegIdst tmp1; 10462 iRegIdst tmp2; 10463 xorI_reg_reg(tmp1, src1, src2); 10464 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10465 xorI_reg_reg(dst, tmp1, tmp2); 10466 %} 10467 %} 10468 10469 // Immediate Xor 10470 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10471 match(Set dst (XorI src1 src2)); 10472 format %{ "XORI $dst, $src1, $src2" %} 10473 size(4); 10474 ins_encode %{ 10475 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10476 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10477 %} 10478 ins_pipe(pipe_class_default); 10479 %} 10480 10481 // Register Xor Long 10482 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10483 match(Set dst (XorL src1 src2)); 10484 ins_cost(DEFAULT_COST); 10485 10486 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10487 size(4); 10488 ins_encode %{ 10489 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10490 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10491 %} 10492 ins_pipe(pipe_class_default); 10493 %} 10494 10495 // XorL + ConvL2I. 10496 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10497 match(Set dst (ConvL2I (XorL src1 src2))); 10498 ins_cost(DEFAULT_COST); 10499 10500 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10501 size(4); 10502 ins_encode %{ 10503 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10504 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10505 %} 10506 ins_pipe(pipe_class_default); 10507 %} 10508 10509 // Immediate Xor Long 10510 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10511 match(Set dst (XorL src1 src2)); 10512 ins_cost(DEFAULT_COST); 10513 10514 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10515 size(4); 10516 ins_encode %{ 10517 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10518 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10519 %} 10520 ins_pipe(pipe_class_default); 10521 %} 10522 10523 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10524 match(Set dst (XorI src1 src2)); 10525 ins_cost(DEFAULT_COST); 10526 10527 format %{ "NOT $dst, $src1 ($src2)" %} 10528 size(4); 10529 ins_encode %{ 10530 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10531 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10532 %} 10533 ins_pipe(pipe_class_default); 10534 %} 10535 10536 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10537 match(Set dst (XorL src1 src2)); 10538 ins_cost(DEFAULT_COST); 10539 10540 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10541 size(4); 10542 ins_encode %{ 10543 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10544 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10545 %} 10546 ins_pipe(pipe_class_default); 10547 %} 10548 10549 // And-complement 10550 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10551 match(Set dst (AndI (XorI src1 src2) src3)); 10552 ins_cost(DEFAULT_COST); 10553 10554 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10555 size(4); 10556 ins_encode( enc_andc(dst, src3, src1) ); 10557 ins_pipe(pipe_class_default); 10558 %} 10559 10560 // And-complement 10561 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10562 // no match-rule, false predicate 10563 effect(DEF dst, USE src1, USE src2); 10564 predicate(false); 10565 10566 format %{ "ANDC $dst, $src1, $src2" %} 10567 size(4); 10568 ins_encode %{ 10569 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10570 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10571 %} 10572 ins_pipe(pipe_class_default); 10573 %} 10574 10575 //----------Moves between int/long and float/double---------------------------- 10576 // 10577 // The following rules move values from int/long registers/stack-locations 10578 // to float/double registers/stack-locations and vice versa, without doing any 10579 // conversions. These rules are used to implement the bit-conversion methods 10580 // of java.lang.Float etc., e.g. 10581 // int floatToIntBits(float value) 10582 // float intBitsToFloat(int bits) 10583 // 10584 // Notes on the implementation on ppc64: 10585 // For Power7 and earlier, the rules are limited to those which move between a 10586 // register and a stack-location, because we always have to go through memory 10587 // when moving between a float register and an integer register. 10588 // This restriction is removed in Power8 with the introduction of the mtfprd 10589 // and mffprd instructions. 10590 10591 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10592 match(Set dst (MoveL2D src)); 10593 predicate(VM_Version::has_mtfprd()); 10594 10595 format %{ "MTFPRD $dst, $src" %} 10596 size(4); 10597 ins_encode %{ 10598 __ mtfprd($dst$$FloatRegister, $src$$Register); 10599 %} 10600 ins_pipe(pipe_class_default); 10601 %} 10602 10603 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10604 // no match-rule, false predicate 10605 effect(DEF dst, USE src); 10606 predicate(false); 10607 10608 format %{ "MTFPRWA $dst, $src" %} 10609 size(4); 10610 ins_encode %{ 10611 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10612 %} 10613 ins_pipe(pipe_class_default); 10614 %} 10615 10616 //---------- Chain stack slots between similar types -------- 10617 10618 // These are needed so that the rules below can match. 10619 10620 // Load integer from stack slot 10621 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10622 match(Set dst src); 10623 ins_cost(MEMORY_REF_COST); 10624 10625 format %{ "LWZ $dst, $src" %} 10626 size(4); 10627 ins_encode( enc_lwz(dst, src) ); 10628 ins_pipe(pipe_class_memory); 10629 %} 10630 10631 // Store integer to stack slot 10632 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10633 match(Set dst src); 10634 ins_cost(MEMORY_REF_COST); 10635 10636 format %{ "STW $src, $dst \t// stk" %} 10637 size(4); 10638 ins_encode( enc_stw(src, dst) ); // rs=rt 10639 ins_pipe(pipe_class_memory); 10640 %} 10641 10642 // Load long from stack slot 10643 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10644 match(Set dst src); 10645 ins_cost(MEMORY_REF_COST); 10646 10647 format %{ "LD $dst, $src \t// long" %} 10648 size(4); 10649 ins_encode( enc_ld(dst, src) ); 10650 ins_pipe(pipe_class_memory); 10651 %} 10652 10653 // Store long to stack slot 10654 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10655 match(Set dst src); 10656 ins_cost(MEMORY_REF_COST); 10657 10658 format %{ "STD $src, $dst \t// long" %} 10659 size(4); 10660 ins_encode( enc_std(src, dst) ); // rs=rt 10661 ins_pipe(pipe_class_memory); 10662 %} 10663 10664 //----------Moves between int and float 10665 10666 // Move float value from float stack-location to integer register. 10667 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10668 match(Set dst (MoveF2I src)); 10669 ins_cost(MEMORY_REF_COST); 10670 10671 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10672 size(4); 10673 ins_encode( enc_lwz(dst, src) ); 10674 ins_pipe(pipe_class_memory); 10675 %} 10676 10677 // Move float value from float register to integer stack-location. 10678 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10679 match(Set dst (MoveF2I src)); 10680 ins_cost(MEMORY_REF_COST); 10681 10682 format %{ "STFS $src, $dst \t// MoveF2I" %} 10683 size(4); 10684 ins_encode( enc_stfs(src, dst) ); 10685 ins_pipe(pipe_class_memory); 10686 %} 10687 10688 // Move integer value from integer stack-location to float register. 10689 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10690 match(Set dst (MoveI2F src)); 10691 ins_cost(MEMORY_REF_COST); 10692 10693 format %{ "LFS $dst, $src \t// MoveI2F" %} 10694 size(4); 10695 ins_encode %{ 10696 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10697 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10698 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10699 %} 10700 ins_pipe(pipe_class_memory); 10701 %} 10702 10703 // Move integer value from integer register to float stack-location. 10704 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10705 match(Set dst (MoveI2F src)); 10706 ins_cost(MEMORY_REF_COST); 10707 10708 format %{ "STW $src, $dst \t// MoveI2F" %} 10709 size(4); 10710 ins_encode( enc_stw(src, dst) ); 10711 ins_pipe(pipe_class_memory); 10712 %} 10713 10714 //----------Moves between long and float 10715 10716 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10717 // no match-rule, false predicate 10718 effect(DEF dst, USE src); 10719 predicate(false); 10720 10721 format %{ "storeD $src, $dst \t// STACK" %} 10722 size(4); 10723 ins_encode( enc_stfd(src, dst) ); 10724 ins_pipe(pipe_class_default); 10725 %} 10726 10727 //----------Moves between long and double 10728 10729 // Move double value from double stack-location to long register. 10730 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10731 match(Set dst (MoveD2L src)); 10732 ins_cost(MEMORY_REF_COST); 10733 size(4); 10734 format %{ "LD $dst, $src \t// MoveD2L" %} 10735 ins_encode( enc_ld(dst, src) ); 10736 ins_pipe(pipe_class_memory); 10737 %} 10738 10739 // Move double value from double register to long stack-location. 10740 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10741 match(Set dst (MoveD2L src)); 10742 effect(DEF dst, USE src); 10743 ins_cost(MEMORY_REF_COST); 10744 10745 format %{ "STFD $src, $dst \t// MoveD2L" %} 10746 size(4); 10747 ins_encode( enc_stfd(src, dst) ); 10748 ins_pipe(pipe_class_memory); 10749 %} 10750 10751 // Move long value from long stack-location to double register. 10752 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10753 match(Set dst (MoveL2D src)); 10754 ins_cost(MEMORY_REF_COST); 10755 10756 format %{ "LFD $dst, $src \t// MoveL2D" %} 10757 size(4); 10758 ins_encode( enc_lfd(dst, src) ); 10759 ins_pipe(pipe_class_memory); 10760 %} 10761 10762 // Move long value from long register to double stack-location. 10763 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10764 match(Set dst (MoveL2D src)); 10765 ins_cost(MEMORY_REF_COST); 10766 10767 format %{ "STD $src, $dst \t// MoveL2D" %} 10768 size(4); 10769 ins_encode( enc_std(src, dst) ); 10770 ins_pipe(pipe_class_memory); 10771 %} 10772 10773 //----------Register Move Instructions----------------------------------------- 10774 10775 // Replicate for Superword 10776 10777 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10778 predicate(false); 10779 effect(DEF dst, USE src); 10780 10781 format %{ "MR $dst, $src \t// replicate " %} 10782 // variable size, 0 or 4. 10783 ins_encode %{ 10784 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10785 __ mr_if_needed($dst$$Register, $src$$Register); 10786 %} 10787 ins_pipe(pipe_class_default); 10788 %} 10789 10790 //----------Cast instructions (Java-level type cast)--------------------------- 10791 10792 // Cast Long to Pointer for unsafe natives. 10793 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10794 match(Set dst (CastX2P src)); 10795 10796 format %{ "MR $dst, $src \t// Long->Ptr" %} 10797 // variable size, 0 or 4. 10798 ins_encode %{ 10799 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10800 __ mr_if_needed($dst$$Register, $src$$Register); 10801 %} 10802 ins_pipe(pipe_class_default); 10803 %} 10804 10805 // Cast Pointer to Long for unsafe natives. 10806 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10807 match(Set dst (CastP2X src)); 10808 10809 format %{ "MR $dst, $src \t// Ptr->Long" %} 10810 // variable size, 0 or 4. 10811 ins_encode %{ 10812 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10813 __ mr_if_needed($dst$$Register, $src$$Register); 10814 %} 10815 ins_pipe(pipe_class_default); 10816 %} 10817 10818 instruct castPP(iRegPdst dst) %{ 10819 match(Set dst (CastPP dst)); 10820 format %{ " -- \t// castPP of $dst" %} 10821 size(0); 10822 ins_encode( /*empty*/ ); 10823 ins_pipe(pipe_class_default); 10824 %} 10825 10826 instruct castII(iRegIdst dst) %{ 10827 match(Set dst (CastII dst)); 10828 format %{ " -- \t// castII of $dst" %} 10829 size(0); 10830 ins_encode( /*empty*/ ); 10831 ins_pipe(pipe_class_default); 10832 %} 10833 10834 instruct checkCastPP(iRegPdst dst) %{ 10835 match(Set dst (CheckCastPP dst)); 10836 format %{ " -- \t// checkcastPP of $dst" %} 10837 size(0); 10838 ins_encode( /*empty*/ ); 10839 ins_pipe(pipe_class_default); 10840 %} 10841 10842 //----------Convert instructions----------------------------------------------- 10843 10844 // Convert to boolean. 10845 10846 // int_to_bool(src) : { 1 if src != 0 10847 // { 0 else 10848 // 10849 // strategy: 10850 // 1) Count leading zeros of 32 bit-value src, 10851 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10852 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10853 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10854 10855 // convI2Bool 10856 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10857 match(Set dst (Conv2B src)); 10858 predicate(UseCountLeadingZerosInstructionsPPC64); 10859 ins_cost(DEFAULT_COST); 10860 10861 expand %{ 10862 immI shiftAmount %{ 0x5 %} 10863 uimmI16 mask %{ 0x1 %} 10864 iRegIdst tmp1; 10865 iRegIdst tmp2; 10866 countLeadingZerosI(tmp1, src); 10867 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10868 xorI_reg_uimm16(dst, tmp2, mask); 10869 %} 10870 %} 10871 10872 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10873 match(Set dst (Conv2B src)); 10874 effect(TEMP crx); 10875 predicate(!UseCountLeadingZerosInstructionsPPC64); 10876 ins_cost(DEFAULT_COST); 10877 10878 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10879 "LI $dst, #0\n\t" 10880 "BEQ $crx, done\n\t" 10881 "LI $dst, #1\n" 10882 "done:" %} 10883 size(16); 10884 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10885 ins_pipe(pipe_class_compare); 10886 %} 10887 10888 // ConvI2B + XorI 10889 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10890 match(Set dst (XorI (Conv2B src) mask)); 10891 predicate(UseCountLeadingZerosInstructionsPPC64); 10892 ins_cost(DEFAULT_COST); 10893 10894 expand %{ 10895 immI shiftAmount %{ 0x5 %} 10896 iRegIdst tmp1; 10897 countLeadingZerosI(tmp1, src); 10898 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10899 %} 10900 %} 10901 10902 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10903 match(Set dst (XorI (Conv2B src) mask)); 10904 effect(TEMP crx); 10905 predicate(!UseCountLeadingZerosInstructionsPPC64); 10906 ins_cost(DEFAULT_COST); 10907 10908 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10909 "LI $dst, #1\n\t" 10910 "BEQ $crx, done\n\t" 10911 "LI $dst, #0\n" 10912 "done:" %} 10913 size(16); 10914 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10915 ins_pipe(pipe_class_compare); 10916 %} 10917 10918 // AndI 0b0..010..0 + ConvI2B 10919 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10920 match(Set dst (Conv2B (AndI src mask))); 10921 predicate(UseRotateAndMaskInstructionsPPC64); 10922 ins_cost(DEFAULT_COST); 10923 10924 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10925 size(4); 10926 ins_encode %{ 10927 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10928 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10929 %} 10930 ins_pipe(pipe_class_default); 10931 %} 10932 10933 // Convert pointer to boolean. 10934 // 10935 // ptr_to_bool(src) : { 1 if src != 0 10936 // { 0 else 10937 // 10938 // strategy: 10939 // 1) Count leading zeros of 64 bit-value src, 10940 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10941 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10942 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10943 10944 // ConvP2B 10945 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10946 match(Set dst (Conv2B src)); 10947 predicate(UseCountLeadingZerosInstructionsPPC64); 10948 ins_cost(DEFAULT_COST); 10949 10950 expand %{ 10951 immI shiftAmount %{ 0x6 %} 10952 uimmI16 mask %{ 0x1 %} 10953 iRegIdst tmp1; 10954 iRegIdst tmp2; 10955 countLeadingZerosP(tmp1, src); 10956 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10957 xorI_reg_uimm16(dst, tmp2, mask); 10958 %} 10959 %} 10960 10961 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10962 match(Set dst (Conv2B src)); 10963 effect(TEMP crx); 10964 predicate(!UseCountLeadingZerosInstructionsPPC64); 10965 ins_cost(DEFAULT_COST); 10966 10967 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10968 "LI $dst, #0\n\t" 10969 "BEQ $crx, done\n\t" 10970 "LI $dst, #1\n" 10971 "done:" %} 10972 size(16); 10973 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10974 ins_pipe(pipe_class_compare); 10975 %} 10976 10977 // ConvP2B + XorI 10978 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10979 match(Set dst (XorI (Conv2B src) mask)); 10980 predicate(UseCountLeadingZerosInstructionsPPC64); 10981 ins_cost(DEFAULT_COST); 10982 10983 expand %{ 10984 immI shiftAmount %{ 0x6 %} 10985 iRegIdst tmp1; 10986 countLeadingZerosP(tmp1, src); 10987 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10988 %} 10989 %} 10990 10991 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10992 match(Set dst (XorI (Conv2B src) mask)); 10993 effect(TEMP crx); 10994 predicate(!UseCountLeadingZerosInstructionsPPC64); 10995 ins_cost(DEFAULT_COST); 10996 10997 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10998 "LI $dst, #1\n\t" 10999 "BEQ $crx, done\n\t" 11000 "LI $dst, #0\n" 11001 "done:" %} 11002 size(16); 11003 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 11004 ins_pipe(pipe_class_compare); 11005 %} 11006 11007 // if src1 < src2, return -1 else return 0 11008 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 11009 match(Set dst (CmpLTMask src1 src2)); 11010 ins_cost(DEFAULT_COST*4); 11011 11012 expand %{ 11013 iRegLdst src1s; 11014 iRegLdst src2s; 11015 iRegLdst diff; 11016 convI2L_reg(src1s, src1); // Ensure proper sign extension. 11017 convI2L_reg(src2s, src2); // Ensure proper sign extension. 11018 subL_reg_reg(diff, src1s, src2s); 11019 // Need to consider >=33 bit result, therefore we need signmaskL. 11020 signmask64I_regL(dst, diff); 11021 %} 11022 %} 11023 11024 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 11025 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 11026 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 11027 size(4); 11028 ins_encode %{ 11029 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 11030 __ srawi($dst$$Register, $src1$$Register, 0x1f); 11031 %} 11032 ins_pipe(pipe_class_default); 11033 %} 11034 11035 //----------Arithmetic Conversion Instructions--------------------------------- 11036 11037 // Convert to Byte -- nop 11038 // Convert to Short -- nop 11039 11040 // Convert to Int 11041 11042 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 11043 match(Set dst (RShiftI (LShiftI src amount) amount)); 11044 format %{ "EXTSB $dst, $src \t// byte->int" %} 11045 size(4); 11046 ins_encode %{ 11047 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 11048 __ extsb($dst$$Register, $src$$Register); 11049 %} 11050 ins_pipe(pipe_class_default); 11051 %} 11052 11053 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 11054 effect(DEF dst, USE src); 11055 11056 size(4); 11057 ins_encode %{ 11058 __ extsh($dst$$Register, $src$$Register); 11059 %} 11060 ins_pipe(pipe_class_default); 11061 %} 11062 11063 // LShiftI 16 + RShiftI 16 converts short to int. 11064 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 11065 match(Set dst (RShiftI (LShiftI src amount) amount)); 11066 format %{ "EXTSH $dst, $src \t// short->int" %} 11067 size(4); 11068 ins_encode %{ 11069 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 11070 __ extsh($dst$$Register, $src$$Register); 11071 %} 11072 ins_pipe(pipe_class_default); 11073 %} 11074 11075 // ConvL2I + ConvI2L: Sign extend int in long register. 11076 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11077 match(Set dst (ConvI2L (ConvL2I src))); 11078 11079 format %{ "EXTSW $dst, $src \t// long->long" %} 11080 size(4); 11081 ins_encode %{ 11082 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11083 __ extsw($dst$$Register, $src$$Register); 11084 %} 11085 ins_pipe(pipe_class_default); 11086 %} 11087 11088 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11089 match(Set dst (ConvL2I src)); 11090 format %{ "MR $dst, $src \t// long->int" %} 11091 // variable size, 0 or 4 11092 ins_encode %{ 11093 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11094 __ mr_if_needed($dst$$Register, $src$$Register); 11095 %} 11096 ins_pipe(pipe_class_default); 11097 %} 11098 11099 instruct convD2IRaw_regD(regD dst, regD src) %{ 11100 // no match-rule, false predicate 11101 effect(DEF dst, USE src); 11102 predicate(false); 11103 11104 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11105 size(4); 11106 ins_encode %{ 11107 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11108 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11109 %} 11110 ins_pipe(pipe_class_default); 11111 %} 11112 11113 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 11114 // no match-rule, false predicate 11115 effect(DEF dst, USE crx, USE src); 11116 predicate(false); 11117 11118 ins_variable_size_depending_on_alignment(true); 11119 11120 format %{ "cmovI $crx, $dst, $src" %} 11121 // Worst case is branch + move + stop, no stop without scheduler. 11122 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11123 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11124 ins_pipe(pipe_class_default); 11125 %} 11126 11127 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11128 // no match-rule, false predicate 11129 effect(DEF dst, USE crx, USE src); 11130 predicate(false); 11131 11132 ins_variable_size_depending_on_alignment(true); 11133 11134 format %{ "cmovI $crx, $dst, $src" %} 11135 // Worst case is branch + move + stop, no stop without scheduler. 11136 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11137 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11138 ins_pipe(pipe_class_default); 11139 %} 11140 11141 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11142 // no match-rule, false predicate 11143 effect(DEF dst, USE crx, USE mem); 11144 predicate(false); 11145 11146 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11147 postalloc_expand %{ 11148 // 11149 // replaces 11150 // 11151 // region dst crx mem 11152 // \ | | / 11153 // dst=cmovI_bso_stackSlotL_conLvalue0 11154 // 11155 // with 11156 // 11157 // region dst 11158 // \ / 11159 // dst=loadConI16(0) 11160 // | 11161 // ^ region dst crx mem 11162 // | \ | | / 11163 // dst=cmovI_bso_stackSlotL 11164 // 11165 11166 // Create new nodes. 11167 MachNode *m1 = new loadConI16Node(); 11168 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11169 11170 // inputs for new nodes 11171 m1->add_req(n_region); 11172 m2->add_req(n_region, n_crx, n_mem); 11173 11174 // precedences for new nodes 11175 m2->add_prec(m1); 11176 11177 // operands for new nodes 11178 m1->_opnds[0] = op_dst; 11179 m1->_opnds[1] = new immI16Oper(0); 11180 11181 m2->_opnds[0] = op_dst; 11182 m2->_opnds[1] = op_crx; 11183 m2->_opnds[2] = op_mem; 11184 11185 // registers for new nodes 11186 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11187 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11188 11189 // Insert new nodes. 11190 nodes->push(m1); 11191 nodes->push(m2); 11192 %} 11193 %} 11194 11195 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11196 // no match-rule, false predicate 11197 effect(DEF dst, USE crx, USE src); 11198 predicate(false); 11199 11200 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11201 postalloc_expand %{ 11202 // 11203 // replaces 11204 // 11205 // region dst crx src 11206 // \ | | / 11207 // dst=cmovI_bso_reg_conLvalue0 11208 // 11209 // with 11210 // 11211 // region dst 11212 // \ / 11213 // dst=loadConI16(0) 11214 // | 11215 // ^ region dst crx src 11216 // | \ | | / 11217 // dst=cmovI_bso_reg 11218 // 11219 11220 // Create new nodes. 11221 MachNode *m1 = new loadConI16Node(); 11222 MachNode *m2 = new cmovI_bso_regNode(); 11223 11224 // inputs for new nodes 11225 m1->add_req(n_region); 11226 m2->add_req(n_region, n_crx, n_src); 11227 11228 // precedences for new nodes 11229 m2->add_prec(m1); 11230 11231 // operands for new nodes 11232 m1->_opnds[0] = op_dst; 11233 m1->_opnds[1] = new immI16Oper(0); 11234 11235 m2->_opnds[0] = op_dst; 11236 m2->_opnds[1] = op_crx; 11237 m2->_opnds[2] = op_src; 11238 11239 // registers for new nodes 11240 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11241 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11242 11243 // Insert new nodes. 11244 nodes->push(m1); 11245 nodes->push(m2); 11246 %} 11247 %} 11248 11249 // Double to Int conversion, NaN is mapped to 0. 11250 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11251 match(Set dst (ConvD2I src)); 11252 predicate(!VM_Version::has_mtfprd()); 11253 ins_cost(DEFAULT_COST); 11254 11255 expand %{ 11256 regD tmpD; 11257 stackSlotL tmpS; 11258 flagsReg crx; 11259 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11260 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11261 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11262 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11263 %} 11264 %} 11265 11266 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11267 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11268 match(Set dst (ConvD2I src)); 11269 predicate(VM_Version::has_mtfprd()); 11270 ins_cost(DEFAULT_COST); 11271 11272 expand %{ 11273 regD tmpD; 11274 flagsReg crx; 11275 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11276 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11277 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11278 %} 11279 %} 11280 11281 instruct convF2IRaw_regF(regF dst, regF src) %{ 11282 // no match-rule, false predicate 11283 effect(DEF dst, USE src); 11284 predicate(false); 11285 11286 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11287 size(4); 11288 ins_encode %{ 11289 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11290 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11291 %} 11292 ins_pipe(pipe_class_default); 11293 %} 11294 11295 // Float to Int conversion, NaN is mapped to 0. 11296 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11297 match(Set dst (ConvF2I src)); 11298 predicate(!VM_Version::has_mtfprd()); 11299 ins_cost(DEFAULT_COST); 11300 11301 expand %{ 11302 regF tmpF; 11303 stackSlotL tmpS; 11304 flagsReg crx; 11305 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11306 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11307 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11308 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11309 %} 11310 %} 11311 11312 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11313 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11314 match(Set dst (ConvF2I src)); 11315 predicate(VM_Version::has_mtfprd()); 11316 ins_cost(DEFAULT_COST); 11317 11318 expand %{ 11319 regF tmpF; 11320 flagsReg crx; 11321 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11322 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11323 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11324 %} 11325 %} 11326 11327 // Convert to Long 11328 11329 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11330 match(Set dst (ConvI2L src)); 11331 format %{ "EXTSW $dst, $src \t// int->long" %} 11332 size(4); 11333 ins_encode %{ 11334 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11335 __ extsw($dst$$Register, $src$$Register); 11336 %} 11337 ins_pipe(pipe_class_default); 11338 %} 11339 11340 // Zero-extend: convert unsigned int to long (convUI2L). 11341 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11342 match(Set dst (AndL (ConvI2L src) mask)); 11343 ins_cost(DEFAULT_COST); 11344 11345 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11346 size(4); 11347 ins_encode %{ 11348 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11349 __ clrldi($dst$$Register, $src$$Register, 32); 11350 %} 11351 ins_pipe(pipe_class_default); 11352 %} 11353 11354 // Zero-extend: convert unsigned int to long in long register. 11355 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11356 match(Set dst (AndL src mask)); 11357 ins_cost(DEFAULT_COST); 11358 11359 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11360 size(4); 11361 ins_encode %{ 11362 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11363 __ clrldi($dst$$Register, $src$$Register, 32); 11364 %} 11365 ins_pipe(pipe_class_default); 11366 %} 11367 11368 instruct convF2LRaw_regF(regF dst, regF src) %{ 11369 // no match-rule, false predicate 11370 effect(DEF dst, USE src); 11371 predicate(false); 11372 11373 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11374 size(4); 11375 ins_encode %{ 11376 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11377 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11378 %} 11379 ins_pipe(pipe_class_default); 11380 %} 11381 11382 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 11383 // no match-rule, false predicate 11384 effect(DEF dst, USE crx, USE src); 11385 predicate(false); 11386 11387 ins_variable_size_depending_on_alignment(true); 11388 11389 format %{ "cmovL $crx, $dst, $src" %} 11390 // Worst case is branch + move + stop, no stop without scheduler. 11391 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11392 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11393 ins_pipe(pipe_class_default); 11394 %} 11395 11396 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11397 // no match-rule, false predicate 11398 effect(DEF dst, USE crx, USE src); 11399 predicate(false); 11400 11401 ins_variable_size_depending_on_alignment(true); 11402 11403 format %{ "cmovL $crx, $dst, $src" %} 11404 // Worst case is branch + move + stop, no stop without scheduler. 11405 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11406 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11407 ins_pipe(pipe_class_default); 11408 %} 11409 11410 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11411 // no match-rule, false predicate 11412 effect(DEF dst, USE crx, USE mem); 11413 predicate(false); 11414 11415 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11416 postalloc_expand %{ 11417 // 11418 // replaces 11419 // 11420 // region dst crx mem 11421 // \ | | / 11422 // dst=cmovL_bso_stackSlotL_conLvalue0 11423 // 11424 // with 11425 // 11426 // region dst 11427 // \ / 11428 // dst=loadConL16(0) 11429 // | 11430 // ^ region dst crx mem 11431 // | \ | | / 11432 // dst=cmovL_bso_stackSlotL 11433 // 11434 11435 // Create new nodes. 11436 MachNode *m1 = new loadConL16Node(); 11437 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11438 11439 // inputs for new nodes 11440 m1->add_req(n_region); 11441 m2->add_req(n_region, n_crx, n_mem); 11442 m2->add_prec(m1); 11443 11444 // operands for new nodes 11445 m1->_opnds[0] = op_dst; 11446 m1->_opnds[1] = new immL16Oper(0); 11447 m2->_opnds[0] = op_dst; 11448 m2->_opnds[1] = op_crx; 11449 m2->_opnds[2] = op_mem; 11450 11451 // registers for new nodes 11452 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11453 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11454 11455 // Insert new nodes. 11456 nodes->push(m1); 11457 nodes->push(m2); 11458 %} 11459 %} 11460 11461 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11462 // no match-rule, false predicate 11463 effect(DEF dst, USE crx, USE src); 11464 predicate(false); 11465 11466 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11467 postalloc_expand %{ 11468 // 11469 // replaces 11470 // 11471 // region dst crx src 11472 // \ | | / 11473 // dst=cmovL_bso_reg_conLvalue0 11474 // 11475 // with 11476 // 11477 // region dst 11478 // \ / 11479 // dst=loadConL16(0) 11480 // | 11481 // ^ region dst crx src 11482 // | \ | | / 11483 // dst=cmovL_bso_reg 11484 // 11485 11486 // Create new nodes. 11487 MachNode *m1 = new loadConL16Node(); 11488 MachNode *m2 = new cmovL_bso_regNode(); 11489 11490 // inputs for new nodes 11491 m1->add_req(n_region); 11492 m2->add_req(n_region, n_crx, n_src); 11493 m2->add_prec(m1); 11494 11495 // operands for new nodes 11496 m1->_opnds[0] = op_dst; 11497 m1->_opnds[1] = new immL16Oper(0); 11498 m2->_opnds[0] = op_dst; 11499 m2->_opnds[1] = op_crx; 11500 m2->_opnds[2] = op_src; 11501 11502 // registers for new nodes 11503 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11504 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11505 11506 // Insert new nodes. 11507 nodes->push(m1); 11508 nodes->push(m2); 11509 %} 11510 %} 11511 11512 // Float to Long conversion, NaN is mapped to 0. 11513 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11514 match(Set dst (ConvF2L src)); 11515 predicate(!VM_Version::has_mtfprd()); 11516 ins_cost(DEFAULT_COST); 11517 11518 expand %{ 11519 regF tmpF; 11520 stackSlotL tmpS; 11521 flagsReg crx; 11522 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11523 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11524 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11525 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11526 %} 11527 %} 11528 11529 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11530 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11531 match(Set dst (ConvF2L src)); 11532 predicate(VM_Version::has_mtfprd()); 11533 ins_cost(DEFAULT_COST); 11534 11535 expand %{ 11536 regF tmpF; 11537 flagsReg crx; 11538 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11539 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11540 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11541 %} 11542 %} 11543 11544 instruct convD2LRaw_regD(regD dst, regD src) %{ 11545 // no match-rule, false predicate 11546 effect(DEF dst, USE src); 11547 predicate(false); 11548 11549 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11550 size(4); 11551 ins_encode %{ 11552 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11553 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11554 %} 11555 ins_pipe(pipe_class_default); 11556 %} 11557 11558 // Double to Long conversion, NaN is mapped to 0. 11559 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11560 match(Set dst (ConvD2L src)); 11561 predicate(!VM_Version::has_mtfprd()); 11562 ins_cost(DEFAULT_COST); 11563 11564 expand %{ 11565 regD tmpD; 11566 stackSlotL tmpS; 11567 flagsReg crx; 11568 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11569 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11570 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11571 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11572 %} 11573 %} 11574 11575 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11576 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11577 match(Set dst (ConvD2L src)); 11578 predicate(VM_Version::has_mtfprd()); 11579 ins_cost(DEFAULT_COST); 11580 11581 expand %{ 11582 regD tmpD; 11583 flagsReg crx; 11584 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11585 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11586 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11587 %} 11588 %} 11589 11590 // Convert to Float 11591 11592 // Placed here as needed in expand. 11593 instruct convL2DRaw_regD(regD dst, regD src) %{ 11594 // no match-rule, false predicate 11595 effect(DEF dst, USE src); 11596 predicate(false); 11597 11598 format %{ "FCFID $dst, $src \t// convL2D" %} 11599 size(4); 11600 ins_encode %{ 11601 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11602 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11603 %} 11604 ins_pipe(pipe_class_default); 11605 %} 11606 11607 // Placed here as needed in expand. 11608 instruct convD2F_reg(regF dst, regD src) %{ 11609 match(Set dst (ConvD2F src)); 11610 format %{ "FRSP $dst, $src \t// convD2F" %} 11611 size(4); 11612 ins_encode %{ 11613 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11614 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11615 %} 11616 ins_pipe(pipe_class_default); 11617 %} 11618 11619 // Integer to Float conversion. 11620 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11621 match(Set dst (ConvI2F src)); 11622 predicate(!VM_Version::has_fcfids()); 11623 ins_cost(DEFAULT_COST); 11624 11625 expand %{ 11626 iRegLdst tmpL; 11627 stackSlotL tmpS; 11628 regD tmpD; 11629 regD tmpD2; 11630 convI2L_reg(tmpL, src); // Sign-extension int to long. 11631 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11632 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11633 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11634 convD2F_reg(dst, tmpD2); // Convert double to float. 11635 %} 11636 %} 11637 11638 instruct convL2FRaw_regF(regF dst, regD src) %{ 11639 // no match-rule, false predicate 11640 effect(DEF dst, USE src); 11641 predicate(false); 11642 11643 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11644 size(4); 11645 ins_encode %{ 11646 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11647 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11648 %} 11649 ins_pipe(pipe_class_default); 11650 %} 11651 11652 // Integer to Float conversion. Special version for Power7. 11653 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11654 match(Set dst (ConvI2F src)); 11655 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11656 ins_cost(DEFAULT_COST); 11657 11658 expand %{ 11659 iRegLdst tmpL; 11660 stackSlotL tmpS; 11661 regD tmpD; 11662 convI2L_reg(tmpL, src); // Sign-extension int to long. 11663 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11664 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11665 convL2FRaw_regF(dst, tmpD); // Convert to float. 11666 %} 11667 %} 11668 11669 // Integer to Float conversion. Special version for Power8. 11670 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11671 match(Set dst (ConvI2F src)); 11672 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11673 ins_cost(DEFAULT_COST); 11674 11675 expand %{ 11676 regD tmpD; 11677 moveI2D_reg(tmpD, src); 11678 convL2FRaw_regF(dst, tmpD); // Convert to float. 11679 %} 11680 %} 11681 11682 // L2F to avoid runtime call. 11683 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11684 match(Set dst (ConvL2F src)); 11685 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11686 ins_cost(DEFAULT_COST); 11687 11688 expand %{ 11689 stackSlotL tmpS; 11690 regD tmpD; 11691 regL_to_stkL(tmpS, src); // Store long to stack. 11692 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11693 convL2FRaw_regF(dst, tmpD); // Convert to float. 11694 %} 11695 %} 11696 11697 // L2F to avoid runtime call. Special version for Power8. 11698 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11699 match(Set dst (ConvL2F src)); 11700 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11701 ins_cost(DEFAULT_COST); 11702 11703 expand %{ 11704 regD tmpD; 11705 moveL2D_reg(tmpD, src); 11706 convL2FRaw_regF(dst, tmpD); // Convert to float. 11707 %} 11708 %} 11709 11710 // Moved up as used in expand. 11711 //instruct convD2F_reg(regF dst, regD src) %{%} 11712 11713 // Convert to Double 11714 11715 // Integer to Double conversion. 11716 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11717 match(Set dst (ConvI2D src)); 11718 predicate(!VM_Version::has_mtfprd()); 11719 ins_cost(DEFAULT_COST); 11720 11721 expand %{ 11722 iRegLdst tmpL; 11723 stackSlotL tmpS; 11724 regD tmpD; 11725 convI2L_reg(tmpL, src); // Sign-extension int to long. 11726 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11727 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11728 convL2DRaw_regD(dst, tmpD); // Convert to double. 11729 %} 11730 %} 11731 11732 // Integer to Double conversion. Special version for Power8. 11733 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11734 match(Set dst (ConvI2D src)); 11735 predicate(VM_Version::has_mtfprd()); 11736 ins_cost(DEFAULT_COST); 11737 11738 expand %{ 11739 regD tmpD; 11740 moveI2D_reg(tmpD, src); 11741 convL2DRaw_regD(dst, tmpD); // Convert to double. 11742 %} 11743 %} 11744 11745 // Long to Double conversion 11746 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11747 match(Set dst (ConvL2D src)); 11748 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11749 11750 expand %{ 11751 regD tmpD; 11752 moveL2D_stack_reg(tmpD, src); 11753 convL2DRaw_regD(dst, tmpD); 11754 %} 11755 %} 11756 11757 // Long to Double conversion. Special version for Power8. 11758 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11759 match(Set dst (ConvL2D src)); 11760 predicate(VM_Version::has_mtfprd()); 11761 ins_cost(DEFAULT_COST); 11762 11763 expand %{ 11764 regD tmpD; 11765 moveL2D_reg(tmpD, src); 11766 convL2DRaw_regD(dst, tmpD); // Convert to double. 11767 %} 11768 %} 11769 11770 instruct convF2D_reg(regD dst, regF src) %{ 11771 match(Set dst (ConvF2D src)); 11772 format %{ "FMR $dst, $src \t// float->double" %} 11773 // variable size, 0 or 4 11774 ins_encode %{ 11775 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11776 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11777 %} 11778 ins_pipe(pipe_class_default); 11779 %} 11780 11781 //----------Control Flow Instructions------------------------------------------ 11782 // Compare Instructions 11783 11784 // Compare Integers 11785 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11786 match(Set crx (CmpI src1 src2)); 11787 size(4); 11788 format %{ "CMPW $crx, $src1, $src2" %} 11789 ins_encode %{ 11790 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11791 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11792 %} 11793 ins_pipe(pipe_class_compare); 11794 %} 11795 11796 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11797 match(Set crx (CmpI src1 src2)); 11798 format %{ "CMPWI $crx, $src1, $src2" %} 11799 size(4); 11800 ins_encode %{ 11801 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11802 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11803 %} 11804 ins_pipe(pipe_class_compare); 11805 %} 11806 11807 // (src1 & src2) == 0? 11808 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11809 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11810 // r0 is killed 11811 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11812 size(4); 11813 ins_encode %{ 11814 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11815 __ andi_(R0, $src1$$Register, $src2$$constant); 11816 %} 11817 ins_pipe(pipe_class_compare); 11818 %} 11819 11820 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11821 match(Set crx (CmpL src1 src2)); 11822 format %{ "CMPD $crx, $src1, $src2" %} 11823 size(4); 11824 ins_encode %{ 11825 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11826 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11827 %} 11828 ins_pipe(pipe_class_compare); 11829 %} 11830 11831 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11832 match(Set crx (CmpL src1 src2)); 11833 format %{ "CMPDI $crx, $src1, $src2" %} 11834 size(4); 11835 ins_encode %{ 11836 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11837 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11838 %} 11839 ins_pipe(pipe_class_compare); 11840 %} 11841 11842 // Added CmpUL for LoopPredicate. 11843 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11844 match(Set crx (CmpUL src1 src2)); 11845 format %{ "CMPLD $crx, $src1, $src2" %} 11846 size(4); 11847 ins_encode %{ 11848 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11849 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11850 %} 11851 ins_pipe(pipe_class_compare); 11852 %} 11853 11854 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11855 match(Set crx (CmpUL src1 src2)); 11856 format %{ "CMPLDI $crx, $src1, $src2" %} 11857 size(4); 11858 ins_encode %{ 11859 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11860 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11861 %} 11862 ins_pipe(pipe_class_compare); 11863 %} 11864 11865 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11866 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11867 // r0 is killed 11868 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11869 size(4); 11870 ins_encode %{ 11871 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11872 __ and_(R0, $src1$$Register, $src2$$Register); 11873 %} 11874 ins_pipe(pipe_class_compare); 11875 %} 11876 11877 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11878 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11879 // r0 is killed 11880 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11881 size(4); 11882 ins_encode %{ 11883 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11884 __ andi_(R0, $src1$$Register, $src2$$constant); 11885 %} 11886 ins_pipe(pipe_class_compare); 11887 %} 11888 11889 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11890 // no match-rule, false predicate 11891 effect(DEF dst, USE crx); 11892 predicate(false); 11893 11894 ins_variable_size_depending_on_alignment(true); 11895 11896 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11897 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11898 size((false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16)); 11899 ins_encode %{ 11900 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11901 Label done; 11902 // li(Rdst, 0); // equal -> 0 11903 __ beq($crx$$CondRegister, done); 11904 __ li($dst$$Register, 1); // greater -> +1 11905 __ bgt($crx$$CondRegister, done); 11906 __ li($dst$$Register, -1); // unordered or less -> -1 11907 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11908 __ bind(done); 11909 %} 11910 ins_pipe(pipe_class_compare); 11911 %} 11912 11913 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11914 // no match-rule, false predicate 11915 effect(DEF dst, USE crx); 11916 predicate(false); 11917 11918 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11919 postalloc_expand %{ 11920 // 11921 // replaces 11922 // 11923 // region crx 11924 // \ | 11925 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11926 // 11927 // with 11928 // 11929 // region 11930 // \ 11931 // dst=loadConI16(0) 11932 // | 11933 // ^ region crx 11934 // | \ | 11935 // dst=cmovI_conIvalueMinus1_conIvalue1 11936 // 11937 11938 // Create new nodes. 11939 MachNode *m1 = new loadConI16Node(); 11940 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11941 11942 // inputs for new nodes 11943 m1->add_req(n_region); 11944 m2->add_req(n_region, n_crx); 11945 m2->add_prec(m1); 11946 11947 // operands for new nodes 11948 m1->_opnds[0] = op_dst; 11949 m1->_opnds[1] = new immI16Oper(0); 11950 m2->_opnds[0] = op_dst; 11951 m2->_opnds[1] = op_crx; 11952 11953 // registers for new nodes 11954 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11955 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11956 11957 // Insert new nodes. 11958 nodes->push(m1); 11959 nodes->push(m2); 11960 %} 11961 %} 11962 11963 // Manifest a CmpL3 result in an integer register. Very painful. 11964 // This is the test to avoid. 11965 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11966 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11967 match(Set dst (CmpL3 src1 src2)); 11968 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11969 11970 expand %{ 11971 flagsReg tmp1; 11972 cmpL_reg_reg(tmp1, src1, src2); 11973 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11974 %} 11975 %} 11976 11977 // Implicit range checks. 11978 // A range check in the ideal world has one of the following shapes: 11979 // - (If le (CmpU length index)), (IfTrue throw exception) 11980 // - (If lt (CmpU index length)), (IfFalse throw exception) 11981 // 11982 // Match range check 'If le (CmpU length index)'. 11983 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11984 match(If cmp (CmpU src_length index)); 11985 effect(USE labl); 11986 predicate(TrapBasedRangeChecks && 11987 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11988 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11989 (Matcher::branches_to_uncommon_trap(_leaf))); 11990 11991 ins_is_TrapBasedCheckNode(true); 11992 11993 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11994 size(4); 11995 ins_encode %{ 11996 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11997 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11998 __ trap_range_check_le($src_length$$Register, $index$$constant); 11999 } else { 12000 // Both successors are uncommon traps, probability is 0. 12001 // Node got flipped during fixup flow. 12002 assert($cmp$$cmpcode == 0x9, "must be greater"); 12003 __ trap_range_check_g($src_length$$Register, $index$$constant); 12004 } 12005 %} 12006 ins_pipe(pipe_class_trap); 12007 %} 12008 12009 // Match range check 'If lt (CmpU index length)'. 12010 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 12011 match(If cmp (CmpU src_index src_length)); 12012 effect(USE labl); 12013 predicate(TrapBasedRangeChecks && 12014 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12015 _leaf->as_If()->_prob >= PROB_ALWAYS && 12016 (Matcher::branches_to_uncommon_trap(_leaf))); 12017 12018 ins_is_TrapBasedCheckNode(true); 12019 12020 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 12021 size(4); 12022 ins_encode %{ 12023 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 12024 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12025 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 12026 } else { 12027 // Both successors are uncommon traps, probability is 0. 12028 // Node got flipped during fixup flow. 12029 assert($cmp$$cmpcode == 0x8, "must be less"); 12030 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 12031 } 12032 %} 12033 ins_pipe(pipe_class_trap); 12034 %} 12035 12036 // Match range check 'If lt (CmpU index length)'. 12037 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 12038 match(If cmp (CmpU src_index length)); 12039 effect(USE labl); 12040 predicate(TrapBasedRangeChecks && 12041 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12042 _leaf->as_If()->_prob >= PROB_ALWAYS && 12043 (Matcher::branches_to_uncommon_trap(_leaf))); 12044 12045 ins_is_TrapBasedCheckNode(true); 12046 12047 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 12048 size(4); 12049 ins_encode %{ 12050 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12051 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12052 __ trap_range_check_ge($src_index$$Register, $length$$constant); 12053 } else { 12054 // Both successors are uncommon traps, probability is 0. 12055 // Node got flipped during fixup flow. 12056 assert($cmp$$cmpcode == 0x8, "must be less"); 12057 __ trap_range_check_l($src_index$$Register, $length$$constant); 12058 } 12059 %} 12060 ins_pipe(pipe_class_trap); 12061 %} 12062 12063 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 12064 match(Set crx (CmpU src1 src2)); 12065 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 12066 size(4); 12067 ins_encode %{ 12068 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12069 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12070 %} 12071 ins_pipe(pipe_class_compare); 12072 %} 12073 12074 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 12075 match(Set crx (CmpU src1 src2)); 12076 size(4); 12077 format %{ "CMPLWI $crx, $src1, $src2" %} 12078 ins_encode %{ 12079 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12080 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12081 %} 12082 ins_pipe(pipe_class_compare); 12083 %} 12084 12085 // Implicit zero checks (more implicit null checks). 12086 // No constant pool entries required. 12087 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12088 match(If cmp (CmpN value zero)); 12089 effect(USE labl); 12090 predicate(TrapBasedNullChecks && 12091 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12092 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12093 Matcher::branches_to_uncommon_trap(_leaf)); 12094 ins_cost(1); 12095 12096 ins_is_TrapBasedCheckNode(true); 12097 12098 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12099 size(4); 12100 ins_encode %{ 12101 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12102 if ($cmp$$cmpcode == 0xA) { 12103 __ trap_null_check($value$$Register); 12104 } else { 12105 // Both successors are uncommon traps, probability is 0. 12106 // Node got flipped during fixup flow. 12107 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12108 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12109 } 12110 %} 12111 ins_pipe(pipe_class_trap); 12112 %} 12113 12114 // Compare narrow oops. 12115 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12116 match(Set crx (CmpN src1 src2)); 12117 12118 size(4); 12119 ins_cost(2); 12120 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12121 ins_encode %{ 12122 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12123 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12124 %} 12125 ins_pipe(pipe_class_compare); 12126 %} 12127 12128 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12129 match(Set crx (CmpN src1 src2)); 12130 // Make this more expensive than zeroCheckN_iReg_imm0. 12131 ins_cost(2); 12132 12133 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12134 size(4); 12135 ins_encode %{ 12136 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12137 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12138 %} 12139 ins_pipe(pipe_class_compare); 12140 %} 12141 12142 // Implicit zero checks (more implicit null checks). 12143 // No constant pool entries required. 12144 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12145 match(If cmp (CmpP value zero)); 12146 effect(USE labl); 12147 predicate(TrapBasedNullChecks && 12148 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12149 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12150 Matcher::branches_to_uncommon_trap(_leaf)); 12151 ins_cost(1); // Should not be cheaper than zeroCheckN. 12152 12153 ins_is_TrapBasedCheckNode(true); 12154 12155 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12156 size(4); 12157 ins_encode %{ 12158 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12159 if ($cmp$$cmpcode == 0xA) { 12160 __ trap_null_check($value$$Register); 12161 } else { 12162 // Both successors are uncommon traps, probability is 0. 12163 // Node got flipped during fixup flow. 12164 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12165 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12166 } 12167 %} 12168 ins_pipe(pipe_class_trap); 12169 %} 12170 12171 // Compare Pointers 12172 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12173 match(Set crx (CmpP src1 src2)); 12174 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12175 size(4); 12176 ins_encode %{ 12177 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12178 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12179 %} 12180 ins_pipe(pipe_class_compare); 12181 %} 12182 12183 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12184 match(Set crx (CmpP src1 src2)); 12185 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12186 size(4); 12187 ins_encode %{ 12188 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12189 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12190 %} 12191 ins_pipe(pipe_class_compare); 12192 %} 12193 12194 // Used in postalloc expand. 12195 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12196 // This match rule prevents reordering of node before a safepoint. 12197 // This only makes sense if this instructions is used exclusively 12198 // for the expansion of EncodeP! 12199 match(Set crx (CmpP src1 src2)); 12200 predicate(false); 12201 12202 format %{ "CMPDI $crx, $src1, $src2" %} 12203 size(4); 12204 ins_encode %{ 12205 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12206 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12207 %} 12208 ins_pipe(pipe_class_compare); 12209 %} 12210 12211 //----------Float Compares---------------------------------------------------- 12212 12213 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12214 // Needs matchrule, see cmpDUnordered. 12215 match(Set crx (CmpF src1 src2)); 12216 // no match-rule, false predicate 12217 predicate(false); 12218 12219 format %{ "cmpFUrd $crx, $src1, $src2" %} 12220 size(4); 12221 ins_encode %{ 12222 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12223 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12224 %} 12225 ins_pipe(pipe_class_default); 12226 %} 12227 12228 instruct cmov_bns_less(flagsReg crx) %{ 12229 // no match-rule, false predicate 12230 effect(DEF crx); 12231 predicate(false); 12232 12233 ins_variable_size_depending_on_alignment(true); 12234 12235 format %{ "cmov $crx" %} 12236 // Worst case is branch + move + stop, no stop without scheduler. 12237 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12)); 12238 ins_encode %{ 12239 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12240 Label done; 12241 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12242 __ li(R0, 0); 12243 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12244 // TODO PPC port __ endgroup_if_needed(_size == 16); 12245 __ bind(done); 12246 %} 12247 ins_pipe(pipe_class_default); 12248 %} 12249 12250 // Compare floating, generate condition code. 12251 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12252 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12253 // 12254 // The following code sequence occurs a lot in mpegaudio: 12255 // 12256 // block BXX: 12257 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12258 // cmpFUrd CCR6, F11, F9 12259 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12260 // cmov CCR6 12261 // 8: instruct branchConSched: 12262 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12263 match(Set crx (CmpF src1 src2)); 12264 ins_cost(DEFAULT_COST+BRANCH_COST); 12265 12266 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12267 postalloc_expand %{ 12268 // 12269 // replaces 12270 // 12271 // region src1 src2 12272 // \ | | 12273 // crx=cmpF_reg_reg 12274 // 12275 // with 12276 // 12277 // region src1 src2 12278 // \ | | 12279 // crx=cmpFUnordered_reg_reg 12280 // | 12281 // ^ region 12282 // | \ 12283 // crx=cmov_bns_less 12284 // 12285 12286 // Create new nodes. 12287 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12288 MachNode *m2 = new cmov_bns_lessNode(); 12289 12290 // inputs for new nodes 12291 m1->add_req(n_region, n_src1, n_src2); 12292 m2->add_req(n_region); 12293 m2->add_prec(m1); 12294 12295 // operands for new nodes 12296 m1->_opnds[0] = op_crx; 12297 m1->_opnds[1] = op_src1; 12298 m1->_opnds[2] = op_src2; 12299 m2->_opnds[0] = op_crx; 12300 12301 // registers for new nodes 12302 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12303 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12304 12305 // Insert new nodes. 12306 nodes->push(m1); 12307 nodes->push(m2); 12308 %} 12309 %} 12310 12311 // Compare float, generate -1,0,1 12312 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12313 match(Set dst (CmpF3 src1 src2)); 12314 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12315 12316 expand %{ 12317 flagsReg tmp1; 12318 cmpFUnordered_reg_reg(tmp1, src1, src2); 12319 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12320 %} 12321 %} 12322 12323 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12324 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12325 // node right before the conditional move using it. 12326 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12327 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12328 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12329 // conditional move was supposed to be spilled. 12330 match(Set crx (CmpD src1 src2)); 12331 // False predicate, shall not be matched. 12332 predicate(false); 12333 12334 format %{ "cmpFUrd $crx, $src1, $src2" %} 12335 size(4); 12336 ins_encode %{ 12337 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12338 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12339 %} 12340 ins_pipe(pipe_class_default); 12341 %} 12342 12343 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12344 match(Set crx (CmpD src1 src2)); 12345 ins_cost(DEFAULT_COST+BRANCH_COST); 12346 12347 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12348 postalloc_expand %{ 12349 // 12350 // replaces 12351 // 12352 // region src1 src2 12353 // \ | | 12354 // crx=cmpD_reg_reg 12355 // 12356 // with 12357 // 12358 // region src1 src2 12359 // \ | | 12360 // crx=cmpDUnordered_reg_reg 12361 // | 12362 // ^ region 12363 // | \ 12364 // crx=cmov_bns_less 12365 // 12366 12367 // create new nodes 12368 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12369 MachNode *m2 = new cmov_bns_lessNode(); 12370 12371 // inputs for new nodes 12372 m1->add_req(n_region, n_src1, n_src2); 12373 m2->add_req(n_region); 12374 m2->add_prec(m1); 12375 12376 // operands for new nodes 12377 m1->_opnds[0] = op_crx; 12378 m1->_opnds[1] = op_src1; 12379 m1->_opnds[2] = op_src2; 12380 m2->_opnds[0] = op_crx; 12381 12382 // registers for new nodes 12383 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12384 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12385 12386 // Insert new nodes. 12387 nodes->push(m1); 12388 nodes->push(m2); 12389 %} 12390 %} 12391 12392 // Compare double, generate -1,0,1 12393 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12394 match(Set dst (CmpD3 src1 src2)); 12395 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12396 12397 expand %{ 12398 flagsReg tmp1; 12399 cmpDUnordered_reg_reg(tmp1, src1, src2); 12400 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12401 %} 12402 %} 12403 12404 // Compare char 12405 instruct cmprb_DigitC_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12406 match(Set dst (DigitC src1)); 12407 effect(TEMP src2, TEMP crx); 12408 ins_cost(3 * DEFAULT_COST); 12409 12410 format %{ "LI $src2, 0x3930\n\t" 12411 "CMPRB $crx, 0, $src1, $src2\n\t" 12412 "SETB $dst, $crx" %} 12413 size(12); 12414 ins_encode %{ 12415 // 0x30: 0, 0x39: 9 12416 __ li($src2$$Register, 0x3930); 12417 // compare src1 with ranges 0x30 to 0x39 12418 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12419 __ setb($dst$$Register, $crx$$CondRegister); 12420 %} 12421 ins_pipe(pipe_class_default); 12422 %} 12423 12424 instruct cmprb_LowerCaseC_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12425 match(Set dst (LowerCaseC src1)); 12426 effect(TEMP src2, TEMP crx); 12427 ins_cost(12 * DEFAULT_COST); 12428 12429 format %{ "LI $src2, 0x7A61\n\t" 12430 "CMPRB $crx, 0, $src1, $src2\n\t" 12431 "BGT $crx, done\n\t" 12432 "LIS $src2, (signed short)0xF6DF\n\t" 12433 "ORI $src2, $src2, 0xFFF8\n\t" 12434 "CMPRB $crx, 1, $src1, $src2\n\t" 12435 "BGT $crx, done\n\t" 12436 "LIS $src2, (signed short)0xAAB5\n\t" 12437 "ORI $src2, $src2, 0xBABA\n\t" 12438 "INSRDI $src2, $src2, 32, 0\n\t" 12439 "CMPEQB $crx, 1, $src1, $src2\n\t" 12440 "SETB $dst, $crx" %} 12441 12442 size(48); 12443 ins_encode %{ 12444 Label done; 12445 // 0x61: a, 0x7A: z 12446 __ li($src2$$Register, 0x7A61); 12447 // compare src1 with ranges 0x61 to 0x7A 12448 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12449 __ bgt($crx$$CondRegister, done); 12450 12451 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case 12452 __ lis($src2$$Register, (signed short)0xF6DF); 12453 __ ori($src2$$Register, $src2$$Register, 0xFFF8); 12454 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF 12455 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12456 __ bgt($crx$$CondRegister, done); 12457 12458 // 0xAA: feminine ordinal indicator 12459 // 0xB5: micro sign 12460 // 0xBA: masculine ordinal indicator 12461 __ lis($src2$$Register, (signed short)0xAAB5); 12462 __ ori($src2$$Register, $src2$$Register, 0xBABA); 12463 __ insrdi($src2$$Register, $src2$$Register, 32, 0); 12464 // compare src1 with 0xAA, 0xB5, and 0xBA 12465 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register); 12466 12467 __ bind(done); 12468 __ setb($dst$$Register, $crx$$CondRegister); 12469 %} 12470 ins_pipe(pipe_class_default); 12471 %} 12472 12473 instruct cmprb_UpperCaseC_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12474 match(Set dst (UpperCaseC src1)); 12475 effect(TEMP src2, TEMP crx); 12476 ins_cost(7 * DEFAULT_COST); 12477 12478 format %{ "LI $src2, 0x5A41\n\t" 12479 "CMPRB $crx, 0, $src1, $src2\n\t" 12480 "BGT $crx, done\n\t" 12481 "LIS $src2, (signed short)0xD6C0\n\t" 12482 "ORI $src2, $src2, 0xDED8\n\t" 12483 "CMPRB $crx, 1, $src1, $src2\n\t" 12484 "SETB $dst, $crx" %} 12485 12486 size(28); 12487 ins_encode %{ 12488 Label done; 12489 // 0x41: A, 0x5A: Z 12490 __ li($src2$$Register, 0x5A41); 12491 // compare src1 with a range 0x41 to 0x5A 12492 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12493 __ bgt($crx$$CondRegister, done); 12494 12495 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case 12496 __ lis($src2$$Register, (signed short)0xD6C0); 12497 __ ori($src2$$Register, $src2$$Register, 0xDED8); 12498 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE 12499 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12500 12501 __ bind(done); 12502 __ setb($dst$$Register, $crx$$CondRegister); 12503 %} 12504 ins_pipe(pipe_class_default); 12505 %} 12506 12507 instruct cmprb_WhitespaceC_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12508 match(Set dst (WhitespaceC src1)); 12509 effect(TEMP src2, TEMP crx); 12510 ins_cost(4 * DEFAULT_COST); 12511 12512 format %{ "LI $src2, 0x0D09\n\t" 12513 "ADDIS $src2, 0x201C\n\t" 12514 "CMPRB $crx, 1, $src1, $src2\n\t" 12515 "SETB $dst, $crx" %} 12516 size(16); 12517 ins_encode %{ 12518 // 0x09 to 0x0D, 0x1C to 0x20 12519 __ li($src2$$Register, 0x0D09); 12520 __ addis($src2$$Register, $src2$$Register, 0x0201C); 12521 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20 12522 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12523 __ setb($dst$$Register, $crx$$CondRegister); 12524 %} 12525 ins_pipe(pipe_class_default); 12526 %} 12527 12528 //----------Branches--------------------------------------------------------- 12529 // Jump 12530 12531 // Direct Branch. 12532 instruct branch(label labl) %{ 12533 match(Goto); 12534 effect(USE labl); 12535 ins_cost(BRANCH_COST); 12536 12537 format %{ "B $labl" %} 12538 size(4); 12539 ins_encode %{ 12540 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12541 Label d; // dummy 12542 __ bind(d); 12543 Label* p = $labl$$label; 12544 // `p' is `NULL' when this encoding class is used only to 12545 // determine the size of the encoded instruction. 12546 Label& l = (NULL == p)? d : *(p); 12547 __ b(l); 12548 %} 12549 ins_pipe(pipe_class_default); 12550 %} 12551 12552 // Conditional Near Branch 12553 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12554 // Same match rule as `branchConFar'. 12555 match(If cmp crx); 12556 effect(USE lbl); 12557 ins_cost(BRANCH_COST); 12558 12559 // If set to 1 this indicates that the current instruction is a 12560 // short variant of a long branch. This avoids using this 12561 // instruction in first-pass matching. It will then only be used in 12562 // the `Shorten_branches' pass. 12563 ins_short_branch(1); 12564 12565 format %{ "B$cmp $crx, $lbl" %} 12566 size(4); 12567 ins_encode( enc_bc(crx, cmp, lbl) ); 12568 ins_pipe(pipe_class_default); 12569 %} 12570 12571 // This is for cases when the ppc64 `bc' instruction does not 12572 // reach far enough. So we emit a far branch here, which is more 12573 // expensive. 12574 // 12575 // Conditional Far Branch 12576 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12577 // Same match rule as `branchCon'. 12578 match(If cmp crx); 12579 effect(USE crx, USE lbl); 12580 predicate(!false /* TODO: PPC port HB_Schedule*/); 12581 // Higher cost than `branchCon'. 12582 ins_cost(5*BRANCH_COST); 12583 12584 // This is not a short variant of a branch, but the long variant. 12585 ins_short_branch(0); 12586 12587 format %{ "B_FAR$cmp $crx, $lbl" %} 12588 size(8); 12589 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12590 ins_pipe(pipe_class_default); 12591 %} 12592 12593 // Conditional Branch used with Power6 scheduler (can be far or short). 12594 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12595 // Same match rule as `branchCon'. 12596 match(If cmp crx); 12597 effect(USE crx, USE lbl); 12598 predicate(false /* TODO: PPC port HB_Schedule*/); 12599 // Higher cost than `branchCon'. 12600 ins_cost(5*BRANCH_COST); 12601 12602 // Actually size doesn't depend on alignment but on shortening. 12603 ins_variable_size_depending_on_alignment(true); 12604 // long variant. 12605 ins_short_branch(0); 12606 12607 format %{ "B_FAR$cmp $crx, $lbl" %} 12608 size(8); // worst case 12609 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12610 ins_pipe(pipe_class_default); 12611 %} 12612 12613 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12614 match(CountedLoopEnd cmp crx); 12615 effect(USE labl); 12616 ins_cost(BRANCH_COST); 12617 12618 // short variant. 12619 ins_short_branch(1); 12620 12621 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12622 size(4); 12623 ins_encode( enc_bc(crx, cmp, labl) ); 12624 ins_pipe(pipe_class_default); 12625 %} 12626 12627 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12628 match(CountedLoopEnd cmp crx); 12629 effect(USE labl); 12630 predicate(!false /* TODO: PPC port HB_Schedule */); 12631 ins_cost(BRANCH_COST); 12632 12633 // Long variant. 12634 ins_short_branch(0); 12635 12636 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12637 size(8); 12638 ins_encode( enc_bc_far(crx, cmp, labl) ); 12639 ins_pipe(pipe_class_default); 12640 %} 12641 12642 // Conditional Branch used with Power6 scheduler (can be far or short). 12643 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12644 match(CountedLoopEnd cmp crx); 12645 effect(USE labl); 12646 predicate(false /* TODO: PPC port HB_Schedule */); 12647 // Higher cost than `branchCon'. 12648 ins_cost(5*BRANCH_COST); 12649 12650 // Actually size doesn't depend on alignment but on shortening. 12651 ins_variable_size_depending_on_alignment(true); 12652 // Long variant. 12653 ins_short_branch(0); 12654 12655 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12656 size(8); // worst case 12657 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12658 ins_pipe(pipe_class_default); 12659 %} 12660 12661 // ============================================================================ 12662 // Java runtime operations, intrinsics and other complex operations. 12663 12664 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12665 // array for an instance of the superklass. Set a hidden internal cache on a 12666 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12667 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12668 // 12669 // GL TODO: Improve this. 12670 // - result should not be a TEMP 12671 // - Add match rule as on sparc avoiding additional Cmp. 12672 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12673 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12674 match(Set result (PartialSubtypeCheck subklass superklass)); 12675 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12676 ins_cost(DEFAULT_COST*10); 12677 12678 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12679 ins_encode %{ 12680 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12681 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12682 $tmp_klass$$Register, NULL, $result$$Register); 12683 %} 12684 ins_pipe(pipe_class_default); 12685 %} 12686 12687 // inlined locking and unlocking 12688 12689 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12690 match(Set crx (FastLock oop box)); 12691 effect(TEMP tmp1, TEMP tmp2); 12692 predicate(!Compile::current()->use_rtm()); 12693 12694 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12695 ins_encode %{ 12696 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12697 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12698 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12699 UseBiasedLocking && !UseOptoBiasInlining); 12700 // If locking was successfull, crx should indicate 'EQ'. 12701 // The compiler generates a branch to the runtime call to 12702 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12703 %} 12704 ins_pipe(pipe_class_compare); 12705 %} 12706 12707 // Separate version for TM. Use bound register for box to enable USE_KILL. 12708 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12709 match(Set crx (FastLock oop box)); 12710 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12711 predicate(Compile::current()->use_rtm()); 12712 12713 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12714 ins_encode %{ 12715 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12716 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12717 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12718 /*Biased Locking*/ false, 12719 _rtm_counters, _stack_rtm_counters, 12720 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12721 /*TM*/ true, ra_->C->profile_rtm()); 12722 // If locking was successfull, crx should indicate 'EQ'. 12723 // The compiler generates a branch to the runtime call to 12724 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12725 %} 12726 ins_pipe(pipe_class_compare); 12727 %} 12728 12729 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12730 match(Set crx (FastUnlock oop box)); 12731 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12732 predicate(!Compile::current()->use_rtm()); 12733 12734 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12735 ins_encode %{ 12736 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12737 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12738 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12739 UseBiasedLocking && !UseOptoBiasInlining, 12740 false); 12741 // If unlocking was successfull, crx should indicate 'EQ'. 12742 // The compiler generates a branch to the runtime call to 12743 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12744 %} 12745 ins_pipe(pipe_class_compare); 12746 %} 12747 12748 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12749 match(Set crx (FastUnlock oop box)); 12750 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12751 predicate(Compile::current()->use_rtm()); 12752 12753 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12754 ins_encode %{ 12755 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12756 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12757 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12758 /*Biased Locking*/ false, /*TM*/ true); 12759 // If unlocking was successfull, crx should indicate 'EQ'. 12760 // The compiler generates a branch to the runtime call to 12761 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12762 %} 12763 ins_pipe(pipe_class_compare); 12764 %} 12765 12766 // Align address. 12767 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12768 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12769 12770 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12771 size(4); 12772 ins_encode %{ 12773 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12774 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12775 %} 12776 ins_pipe(pipe_class_default); 12777 %} 12778 12779 // Array size computation. 12780 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12781 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12782 12783 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12784 size(4); 12785 ins_encode %{ 12786 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12787 __ subf($dst$$Register, $start$$Register, $end$$Register); 12788 %} 12789 ins_pipe(pipe_class_default); 12790 %} 12791 12792 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12793 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12794 match(Set dummy (ClearArray cnt base)); 12795 effect(USE_KILL base, KILL ctr); 12796 ins_cost(2 * MEMORY_REF_COST); 12797 12798 format %{ "ClearArray $cnt, $base" %} 12799 ins_encode %{ 12800 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12801 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12802 %} 12803 ins_pipe(pipe_class_default); 12804 %} 12805 12806 // Clear-array with constant large array length. 12807 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12808 match(Set dummy (ClearArray cnt base)); 12809 effect(USE_KILL base, TEMP tmp, KILL ctr); 12810 ins_cost(3 * MEMORY_REF_COST); 12811 12812 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12813 ins_encode %{ 12814 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12815 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12816 %} 12817 ins_pipe(pipe_class_default); 12818 %} 12819 12820 // Clear-array with dynamic array length. 12821 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12822 match(Set dummy (ClearArray cnt base)); 12823 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12824 ins_cost(4 * MEMORY_REF_COST); 12825 12826 format %{ "ClearArray $cnt, $base" %} 12827 ins_encode %{ 12828 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12829 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12830 %} 12831 ins_pipe(pipe_class_default); 12832 %} 12833 12834 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12835 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12836 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12837 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12838 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12839 ins_cost(300); 12840 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12841 ins_encode %{ 12842 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12843 __ string_compare($str1$$Register, $str2$$Register, 12844 $cnt1$$Register, $cnt2$$Register, 12845 $tmp$$Register, 12846 $result$$Register, StrIntrinsicNode::LL); 12847 %} 12848 ins_pipe(pipe_class_default); 12849 %} 12850 12851 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12852 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12853 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12854 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12855 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12856 ins_cost(300); 12857 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12858 ins_encode %{ 12859 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12860 __ string_compare($str1$$Register, $str2$$Register, 12861 $cnt1$$Register, $cnt2$$Register, 12862 $tmp$$Register, 12863 $result$$Register, StrIntrinsicNode::UU); 12864 %} 12865 ins_pipe(pipe_class_default); 12866 %} 12867 12868 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12869 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12870 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12871 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12872 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12873 ins_cost(300); 12874 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12875 ins_encode %{ 12876 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12877 __ string_compare($str1$$Register, $str2$$Register, 12878 $cnt1$$Register, $cnt2$$Register, 12879 $tmp$$Register, 12880 $result$$Register, StrIntrinsicNode::LU); 12881 %} 12882 ins_pipe(pipe_class_default); 12883 %} 12884 12885 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12886 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12887 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12888 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12889 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12890 ins_cost(300); 12891 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12892 ins_encode %{ 12893 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12894 __ string_compare($str2$$Register, $str1$$Register, 12895 $cnt2$$Register, $cnt1$$Register, 12896 $tmp$$Register, 12897 $result$$Register, StrIntrinsicNode::UL); 12898 %} 12899 ins_pipe(pipe_class_default); 12900 %} 12901 12902 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12903 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12904 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12905 match(Set result (StrEquals (Binary str1 str2) cnt)); 12906 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12907 ins_cost(300); 12908 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12909 ins_encode %{ 12910 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12911 __ array_equals(false, $str1$$Register, $str2$$Register, 12912 $cnt$$Register, $tmp$$Register, 12913 $result$$Register, true /* byte */); 12914 %} 12915 ins_pipe(pipe_class_default); 12916 %} 12917 12918 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12919 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12920 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12921 match(Set result (StrEquals (Binary str1 str2) cnt)); 12922 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12923 ins_cost(300); 12924 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12925 ins_encode %{ 12926 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12927 __ array_equals(false, $str1$$Register, $str2$$Register, 12928 $cnt$$Register, $tmp$$Register, 12929 $result$$Register, false /* byte */); 12930 %} 12931 ins_pipe(pipe_class_default); 12932 %} 12933 12934 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12935 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12936 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12937 match(Set result (AryEq ary1 ary2)); 12938 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12939 ins_cost(300); 12940 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12941 ins_encode %{ 12942 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12943 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12944 $tmp1$$Register, $tmp2$$Register, 12945 $result$$Register, true /* byte */); 12946 %} 12947 ins_pipe(pipe_class_default); 12948 %} 12949 12950 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12951 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12952 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12953 match(Set result (AryEq ary1 ary2)); 12954 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12955 ins_cost(300); 12956 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12957 ins_encode %{ 12958 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12959 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12960 $tmp1$$Register, $tmp2$$Register, 12961 $result$$Register, false /* byte */); 12962 %} 12963 ins_pipe(pipe_class_default); 12964 %} 12965 12966 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12967 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12968 iRegIdst tmp1, iRegIdst tmp2, 12969 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12970 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12971 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12972 // Required for EA: check if it is still a type_array. 12973 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12974 ins_cost(150); 12975 12976 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12977 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12978 12979 ins_encode %{ 12980 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12981 immPOper *needleOper = (immPOper *)$needleImm; 12982 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12983 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12984 jchar chr; 12985 #ifdef VM_LITTLE_ENDIAN 12986 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12987 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12988 #else 12989 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12990 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12991 #endif 12992 __ string_indexof_char($result$$Register, 12993 $haystack$$Register, $haycnt$$Register, 12994 R0, chr, 12995 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12996 %} 12997 ins_pipe(pipe_class_compare); 12998 %} 12999 13000 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13001 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13002 iRegIdst tmp1, iRegIdst tmp2, 13003 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13004 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13005 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13006 // Required for EA: check if it is still a type_array. 13007 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13008 ins_cost(150); 13009 13010 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13011 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13012 13013 ins_encode %{ 13014 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13015 immPOper *needleOper = (immPOper *)$needleImm; 13016 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13017 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13018 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13019 __ string_indexof_char($result$$Register, 13020 $haystack$$Register, $haycnt$$Register, 13021 R0, chr, 13022 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13023 %} 13024 ins_pipe(pipe_class_compare); 13025 %} 13026 13027 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13028 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13029 iRegIdst tmp1, iRegIdst tmp2, 13030 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13031 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13032 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13033 // Required for EA: check if it is still a type_array. 13034 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13035 ins_cost(150); 13036 13037 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13038 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13039 13040 ins_encode %{ 13041 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13042 immPOper *needleOper = (immPOper *)$needleImm; 13043 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13044 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13045 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13046 __ string_indexof_char($result$$Register, 13047 $haystack$$Register, $haycnt$$Register, 13048 R0, chr, 13049 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13050 %} 13051 ins_pipe(pipe_class_compare); 13052 %} 13053 13054 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13055 rscratch2RegP needle, immI_1 needlecntImm, 13056 iRegIdst tmp1, iRegIdst tmp2, 13057 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13058 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13059 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13060 // Required for EA: check if it is still a type_array. 13061 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13062 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13063 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13064 ins_cost(180); 13065 13066 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13067 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13068 ins_encode %{ 13069 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13070 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13071 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13072 guarantee(needle_values, "sanity"); 13073 jchar chr; 13074 #ifdef VM_LITTLE_ENDIAN 13075 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 13076 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 13077 #else 13078 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 13079 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 13080 #endif 13081 __ string_indexof_char($result$$Register, 13082 $haystack$$Register, $haycnt$$Register, 13083 R0, chr, 13084 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13085 %} 13086 ins_pipe(pipe_class_compare); 13087 %} 13088 13089 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13090 rscratch2RegP needle, immI_1 needlecntImm, 13091 iRegIdst tmp1, iRegIdst tmp2, 13092 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13093 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13094 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13095 // Required for EA: check if it is still a type_array. 13096 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13097 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13098 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13099 ins_cost(180); 13100 13101 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13102 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13103 ins_encode %{ 13104 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13105 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13106 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13107 guarantee(needle_values, "sanity"); 13108 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13109 __ string_indexof_char($result$$Register, 13110 $haystack$$Register, $haycnt$$Register, 13111 R0, chr, 13112 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13113 %} 13114 ins_pipe(pipe_class_compare); 13115 %} 13116 13117 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13118 rscratch2RegP needle, immI_1 needlecntImm, 13119 iRegIdst tmp1, iRegIdst tmp2, 13120 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13121 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13122 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13123 // Required for EA: check if it is still a type_array. 13124 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13125 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13126 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13127 ins_cost(180); 13128 13129 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13130 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13131 ins_encode %{ 13132 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13133 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13134 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13135 guarantee(needle_values, "sanity"); 13136 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13137 __ string_indexof_char($result$$Register, 13138 $haystack$$Register, $haycnt$$Register, 13139 R0, chr, 13140 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13141 %} 13142 ins_pipe(pipe_class_compare); 13143 %} 13144 13145 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13146 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 13147 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13148 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 13149 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13150 ins_cost(180); 13151 13152 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 13153 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13154 ins_encode %{ 13155 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13156 __ string_indexof_char($result$$Register, 13157 $haystack$$Register, $haycnt$$Register, 13158 $ch$$Register, 0 /* this is not used if the character is already in a register */, 13159 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13160 %} 13161 ins_pipe(pipe_class_compare); 13162 %} 13163 13164 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13165 iRegPsrc needle, uimmI15 needlecntImm, 13166 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13167 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13168 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13169 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13170 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13171 // Required for EA: check if it is still a type_array. 13172 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13173 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13174 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13175 ins_cost(250); 13176 13177 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13178 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13179 ins_encode %{ 13180 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13181 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13182 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13183 13184 __ string_indexof($result$$Register, 13185 $haystack$$Register, $haycnt$$Register, 13186 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13187 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13188 %} 13189 ins_pipe(pipe_class_compare); 13190 %} 13191 13192 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13193 iRegPsrc needle, uimmI15 needlecntImm, 13194 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13195 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13196 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13197 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13198 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13199 // Required for EA: check if it is still a type_array. 13200 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13201 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13202 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13203 ins_cost(250); 13204 13205 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13206 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13207 ins_encode %{ 13208 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13209 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13210 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13211 13212 __ string_indexof($result$$Register, 13213 $haystack$$Register, $haycnt$$Register, 13214 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13215 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13216 %} 13217 ins_pipe(pipe_class_compare); 13218 %} 13219 13220 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13221 iRegPsrc needle, uimmI15 needlecntImm, 13222 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13223 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13224 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13225 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13226 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13227 // Required for EA: check if it is still a type_array. 13228 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13229 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13230 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13231 ins_cost(250); 13232 13233 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13234 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13235 ins_encode %{ 13236 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13237 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13238 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13239 13240 __ string_indexof($result$$Register, 13241 $haystack$$Register, $haycnt$$Register, 13242 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13243 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13244 %} 13245 ins_pipe(pipe_class_compare); 13246 %} 13247 13248 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13249 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13250 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13251 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13252 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13253 TEMP_DEF result, 13254 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13255 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13256 ins_cost(300); 13257 13258 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13259 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13260 ins_encode %{ 13261 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13262 __ string_indexof($result$$Register, 13263 $haystack$$Register, $haycnt$$Register, 13264 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13265 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13266 %} 13267 ins_pipe(pipe_class_compare); 13268 %} 13269 13270 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13271 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13272 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13273 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13274 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13275 TEMP_DEF result, 13276 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13277 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13278 ins_cost(300); 13279 13280 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13281 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13282 ins_encode %{ 13283 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13284 __ string_indexof($result$$Register, 13285 $haystack$$Register, $haycnt$$Register, 13286 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13287 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13288 %} 13289 ins_pipe(pipe_class_compare); 13290 %} 13291 13292 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13293 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13294 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13295 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13296 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13297 TEMP_DEF result, 13298 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13299 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13300 ins_cost(300); 13301 13302 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13303 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13304 ins_encode %{ 13305 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13306 __ string_indexof($result$$Register, 13307 $haystack$$Register, $haycnt$$Register, 13308 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13309 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13310 %} 13311 ins_pipe(pipe_class_compare); 13312 %} 13313 13314 // char[] to byte[] compression 13315 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13316 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13317 match(Set result (StrCompressedCopy src (Binary dst len))); 13318 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13319 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13320 ins_cost(300); 13321 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13322 ins_encode %{ 13323 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13324 Label Lskip, Ldone; 13325 __ li($result$$Register, 0); 13326 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13327 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13328 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13329 __ beq(CCR0, Lskip); 13330 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13331 __ bind(Lskip); 13332 __ mr($result$$Register, $len$$Register); 13333 __ bind(Ldone); 13334 %} 13335 ins_pipe(pipe_class_default); 13336 %} 13337 13338 // byte[] to char[] inflation 13339 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13340 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13341 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13342 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13343 ins_cost(300); 13344 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13345 ins_encode %{ 13346 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13347 Label Ldone; 13348 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13349 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13350 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13351 __ beq(CCR0, Ldone); 13352 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13353 __ bind(Ldone); 13354 %} 13355 ins_pipe(pipe_class_default); 13356 %} 13357 13358 // StringCoding.java intrinsics 13359 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13360 regCTR ctr, flagsRegCR0 cr0) 13361 %{ 13362 match(Set result (HasNegatives ary1 len)); 13363 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13364 ins_cost(300); 13365 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13366 ins_encode %{ 13367 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13368 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13369 $tmp1$$Register, $tmp2$$Register); 13370 %} 13371 ins_pipe(pipe_class_default); 13372 %} 13373 13374 // encode char[] to byte[] in ISO_8859_1 13375 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13376 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13377 match(Set result (EncodeISOArray src (Binary dst len))); 13378 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13379 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13380 ins_cost(300); 13381 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13382 ins_encode %{ 13383 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13384 Label Lslow, Lfailure1, Lfailure2, Ldone; 13385 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13386 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13387 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13388 __ beq(CCR0, Ldone); 13389 __ bind(Lslow); 13390 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13391 __ li($result$$Register, 0); 13392 __ b(Ldone); 13393 13394 __ bind(Lfailure1); 13395 __ mr($result$$Register, $len$$Register); 13396 __ mfctr($tmp1$$Register); 13397 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13398 __ beq(CCR0, Ldone); 13399 __ b(Lslow); 13400 13401 __ bind(Lfailure2); 13402 __ mfctr($result$$Register); // Remaining characters. 13403 13404 __ bind(Ldone); 13405 __ subf($result$$Register, $result$$Register, $len$$Register); 13406 %} 13407 ins_pipe(pipe_class_default); 13408 %} 13409 13410 13411 //---------- Min/Max Instructions --------------------------------------------- 13412 13413 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13414 match(Set dst (MinI src1 src2)); 13415 ins_cost(DEFAULT_COST*6); 13416 13417 expand %{ 13418 iRegLdst src1s; 13419 iRegLdst src2s; 13420 iRegLdst diff; 13421 iRegLdst sm; 13422 iRegLdst doz; // difference or zero 13423 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13424 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13425 subL_reg_reg(diff, src2s, src1s); 13426 // Need to consider >=33 bit result, therefore we need signmaskL. 13427 signmask64L_regL(sm, diff); 13428 andL_reg_reg(doz, diff, sm); // <=0 13429 addI_regL_regL(dst, doz, src1s); 13430 %} 13431 %} 13432 13433 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13434 match(Set dst (MinI src1 src2)); 13435 effect(KILL cr0); 13436 predicate(VM_Version::has_isel()); 13437 ins_cost(DEFAULT_COST*2); 13438 13439 ins_encode %{ 13440 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13441 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13442 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13443 %} 13444 ins_pipe(pipe_class_default); 13445 %} 13446 13447 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13448 match(Set dst (MaxI src1 src2)); 13449 ins_cost(DEFAULT_COST*6); 13450 13451 expand %{ 13452 iRegLdst src1s; 13453 iRegLdst src2s; 13454 iRegLdst diff; 13455 iRegLdst sm; 13456 iRegLdst doz; // difference or zero 13457 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13458 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13459 subL_reg_reg(diff, src2s, src1s); 13460 // Need to consider >=33 bit result, therefore we need signmaskL. 13461 signmask64L_regL(sm, diff); 13462 andcL_reg_reg(doz, diff, sm); // >=0 13463 addI_regL_regL(dst, doz, src1s); 13464 %} 13465 %} 13466 13467 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13468 match(Set dst (MaxI src1 src2)); 13469 effect(KILL cr0); 13470 predicate(VM_Version::has_isel()); 13471 ins_cost(DEFAULT_COST*2); 13472 13473 ins_encode %{ 13474 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13475 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13476 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13477 %} 13478 ins_pipe(pipe_class_default); 13479 %} 13480 13481 //---------- Population Count Instructions ------------------------------------ 13482 13483 // Popcnt for Power7. 13484 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13485 match(Set dst (PopCountI src)); 13486 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13487 ins_cost(DEFAULT_COST); 13488 13489 format %{ "POPCNTW $dst, $src" %} 13490 size(4); 13491 ins_encode %{ 13492 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13493 __ popcntw($dst$$Register, $src$$Register); 13494 %} 13495 ins_pipe(pipe_class_default); 13496 %} 13497 13498 // Popcnt for Power7. 13499 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13500 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13501 match(Set dst (PopCountL src)); 13502 ins_cost(DEFAULT_COST); 13503 13504 format %{ "POPCNTD $dst, $src" %} 13505 size(4); 13506 ins_encode %{ 13507 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13508 __ popcntd($dst$$Register, $src$$Register); 13509 %} 13510 ins_pipe(pipe_class_default); 13511 %} 13512 13513 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13514 match(Set dst (CountLeadingZerosI src)); 13515 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13516 ins_cost(DEFAULT_COST); 13517 13518 format %{ "CNTLZW $dst, $src" %} 13519 size(4); 13520 ins_encode %{ 13521 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13522 __ cntlzw($dst$$Register, $src$$Register); 13523 %} 13524 ins_pipe(pipe_class_default); 13525 %} 13526 13527 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13528 match(Set dst (CountLeadingZerosL src)); 13529 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13530 ins_cost(DEFAULT_COST); 13531 13532 format %{ "CNTLZD $dst, $src" %} 13533 size(4); 13534 ins_encode %{ 13535 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13536 __ cntlzd($dst$$Register, $src$$Register); 13537 %} 13538 ins_pipe(pipe_class_default); 13539 %} 13540 13541 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13542 // no match-rule, false predicate 13543 effect(DEF dst, USE src); 13544 predicate(false); 13545 13546 format %{ "CNTLZD $dst, $src" %} 13547 size(4); 13548 ins_encode %{ 13549 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13550 __ cntlzd($dst$$Register, $src$$Register); 13551 %} 13552 ins_pipe(pipe_class_default); 13553 %} 13554 13555 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13556 match(Set dst (CountTrailingZerosI src)); 13557 predicate(UseCountLeadingZerosInstructionsPPC64); 13558 ins_cost(DEFAULT_COST); 13559 13560 expand %{ 13561 immI16 imm1 %{ (int)-1 %} 13562 immI16 imm2 %{ (int)32 %} 13563 immI_minus1 m1 %{ -1 %} 13564 iRegIdst tmpI1; 13565 iRegIdst tmpI2; 13566 iRegIdst tmpI3; 13567 addI_reg_imm16(tmpI1, src, imm1); 13568 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13569 countLeadingZerosI(tmpI3, tmpI2); 13570 subI_imm16_reg(dst, imm2, tmpI3); 13571 %} 13572 %} 13573 13574 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13575 match(Set dst (CountTrailingZerosL src)); 13576 predicate(UseCountLeadingZerosInstructionsPPC64); 13577 ins_cost(DEFAULT_COST); 13578 13579 expand %{ 13580 immL16 imm1 %{ (long)-1 %} 13581 immI16 imm2 %{ (int)64 %} 13582 iRegLdst tmpL1; 13583 iRegLdst tmpL2; 13584 iRegIdst tmpL3; 13585 addL_reg_imm16(tmpL1, src, imm1); 13586 andcL_reg_reg(tmpL2, tmpL1, src); 13587 countLeadingZerosL(tmpL3, tmpL2); 13588 subI_imm16_reg(dst, imm2, tmpL3); 13589 %} 13590 %} 13591 13592 // Expand nodes for byte_reverse_int. 13593 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13594 effect(DEF dst, USE src, USE pos, USE shift); 13595 predicate(false); 13596 13597 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13598 size(4); 13599 ins_encode %{ 13600 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13601 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13602 %} 13603 ins_pipe(pipe_class_default); 13604 %} 13605 13606 // As insrwi_a, but with USE_DEF. 13607 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13608 effect(USE_DEF dst, USE src, USE pos, USE shift); 13609 predicate(false); 13610 13611 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13612 size(4); 13613 ins_encode %{ 13614 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13615 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13616 %} 13617 ins_pipe(pipe_class_default); 13618 %} 13619 13620 // Just slightly faster than java implementation. 13621 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13622 match(Set dst (ReverseBytesI src)); 13623 ins_cost(7*DEFAULT_COST); 13624 13625 expand %{ 13626 immI16 imm24 %{ (int) 24 %} 13627 immI16 imm16 %{ (int) 16 %} 13628 immI16 imm8 %{ (int) 8 %} 13629 immI16 imm4 %{ (int) 4 %} 13630 immI16 imm0 %{ (int) 0 %} 13631 iRegLdst tmpI1; 13632 iRegLdst tmpI2; 13633 iRegLdst tmpI3; 13634 13635 urShiftI_reg_imm(tmpI1, src, imm24); 13636 insrwi_a(dst, tmpI1, imm24, imm8); 13637 urShiftI_reg_imm(tmpI2, src, imm16); 13638 insrwi(dst, tmpI2, imm8, imm16); 13639 urShiftI_reg_imm(tmpI3, src, imm8); 13640 insrwi(dst, tmpI3, imm8, imm8); 13641 insrwi(dst, src, imm0, imm8); 13642 %} 13643 %} 13644 13645 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13646 match(Set dst (ReverseBytesL src)); 13647 ins_cost(15*DEFAULT_COST); 13648 13649 expand %{ 13650 immI16 imm56 %{ (int) 56 %} 13651 immI16 imm48 %{ (int) 48 %} 13652 immI16 imm40 %{ (int) 40 %} 13653 immI16 imm32 %{ (int) 32 %} 13654 immI16 imm24 %{ (int) 24 %} 13655 immI16 imm16 %{ (int) 16 %} 13656 immI16 imm8 %{ (int) 8 %} 13657 immI16 imm0 %{ (int) 0 %} 13658 iRegLdst tmpL1; 13659 iRegLdst tmpL2; 13660 iRegLdst tmpL3; 13661 iRegLdst tmpL4; 13662 iRegLdst tmpL5; 13663 iRegLdst tmpL6; 13664 13665 // src : |a|b|c|d|e|f|g|h| 13666 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13667 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13668 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13669 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13670 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13671 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13672 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13673 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13674 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13675 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13676 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13677 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13678 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13679 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13680 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13681 %} 13682 %} 13683 13684 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13685 match(Set dst (ReverseBytesUS src)); 13686 ins_cost(2*DEFAULT_COST); 13687 13688 expand %{ 13689 immI16 imm16 %{ (int) 16 %} 13690 immI16 imm8 %{ (int) 8 %} 13691 13692 urShiftI_reg_imm(dst, src, imm8); 13693 insrwi(dst, src, imm16, imm8); 13694 %} 13695 %} 13696 13697 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13698 match(Set dst (ReverseBytesS src)); 13699 ins_cost(3*DEFAULT_COST); 13700 13701 expand %{ 13702 immI16 imm16 %{ (int) 16 %} 13703 immI16 imm8 %{ (int) 8 %} 13704 iRegLdst tmpI1; 13705 13706 urShiftI_reg_imm(tmpI1, src, imm8); 13707 insrwi(tmpI1, src, imm16, imm8); 13708 extsh(dst, tmpI1); 13709 %} 13710 %} 13711 13712 // Load Integer reversed byte order 13713 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13714 match(Set dst (ReverseBytesI (LoadI mem))); 13715 ins_cost(MEMORY_REF_COST); 13716 13717 size(4); 13718 ins_encode %{ 13719 __ lwbrx($dst$$Register, $mem$$Register); 13720 %} 13721 ins_pipe(pipe_class_default); 13722 %} 13723 13724 // Load Long - aligned and reversed 13725 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13726 match(Set dst (ReverseBytesL (LoadL mem))); 13727 predicate(VM_Version::has_ldbrx()); 13728 ins_cost(MEMORY_REF_COST); 13729 13730 size(4); 13731 ins_encode %{ 13732 __ ldbrx($dst$$Register, $mem$$Register); 13733 %} 13734 ins_pipe(pipe_class_default); 13735 %} 13736 13737 // Load unsigned short / char reversed byte order 13738 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13739 match(Set dst (ReverseBytesUS (LoadUS mem))); 13740 ins_cost(MEMORY_REF_COST); 13741 13742 size(4); 13743 ins_encode %{ 13744 __ lhbrx($dst$$Register, $mem$$Register); 13745 %} 13746 ins_pipe(pipe_class_default); 13747 %} 13748 13749 // Load short reversed byte order 13750 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13751 match(Set dst (ReverseBytesS (LoadS mem))); 13752 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13753 13754 size(8); 13755 ins_encode %{ 13756 __ lhbrx($dst$$Register, $mem$$Register); 13757 __ extsh($dst$$Register, $dst$$Register); 13758 %} 13759 ins_pipe(pipe_class_default); 13760 %} 13761 13762 // Store Integer reversed byte order 13763 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13764 match(Set mem (StoreI mem (ReverseBytesI src))); 13765 ins_cost(MEMORY_REF_COST); 13766 13767 size(4); 13768 ins_encode %{ 13769 __ stwbrx($src$$Register, $mem$$Register); 13770 %} 13771 ins_pipe(pipe_class_default); 13772 %} 13773 13774 // Store Long reversed byte order 13775 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13776 match(Set mem (StoreL mem (ReverseBytesL src))); 13777 predicate(VM_Version::has_stdbrx()); 13778 ins_cost(MEMORY_REF_COST); 13779 13780 size(4); 13781 ins_encode %{ 13782 __ stdbrx($src$$Register, $mem$$Register); 13783 %} 13784 ins_pipe(pipe_class_default); 13785 %} 13786 13787 // Store unsigned short / char reversed byte order 13788 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13789 match(Set mem (StoreC mem (ReverseBytesUS src))); 13790 ins_cost(MEMORY_REF_COST); 13791 13792 size(4); 13793 ins_encode %{ 13794 __ sthbrx($src$$Register, $mem$$Register); 13795 %} 13796 ins_pipe(pipe_class_default); 13797 %} 13798 13799 // Store short reversed byte order 13800 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13801 match(Set mem (StoreC mem (ReverseBytesS src))); 13802 ins_cost(MEMORY_REF_COST); 13803 13804 size(4); 13805 ins_encode %{ 13806 __ sthbrx($src$$Register, $mem$$Register); 13807 %} 13808 ins_pipe(pipe_class_default); 13809 %} 13810 13811 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13812 effect(DEF temp1, USE src); 13813 13814 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %} 13815 size(4); 13816 ins_encode %{ 13817 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13818 %} 13819 ins_pipe(pipe_class_default); 13820 %} 13821 13822 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13823 effect(DEF dst, USE src, USE imm1); 13824 13825 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %} 13826 size(4); 13827 ins_encode %{ 13828 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13829 %} 13830 ins_pipe(pipe_class_default); 13831 %} 13832 13833 instruct xscvdpspn_regF(vecX dst, regF src) %{ 13834 effect(DEF dst, USE src); 13835 13836 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %} 13837 size(4); 13838 ins_encode %{ 13839 __ xscvdpspn($dst$$VectorSRegister, $src$$FloatRegister->to_vsr()); 13840 %} 13841 ins_pipe(pipe_class_default); 13842 %} 13843 13844 //---------- Replicate Vector Instructions ------------------------------------ 13845 13846 // Insrdi does replicate if src == dst. 13847 instruct repl32(iRegLdst dst) %{ 13848 predicate(false); 13849 effect(USE_DEF dst); 13850 13851 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13852 size(4); 13853 ins_encode %{ 13854 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13855 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13856 %} 13857 ins_pipe(pipe_class_default); 13858 %} 13859 13860 // Insrdi does replicate if src == dst. 13861 instruct repl48(iRegLdst dst) %{ 13862 predicate(false); 13863 effect(USE_DEF dst); 13864 13865 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13866 size(4); 13867 ins_encode %{ 13868 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13869 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13870 %} 13871 ins_pipe(pipe_class_default); 13872 %} 13873 13874 // Insrdi does replicate if src == dst. 13875 instruct repl56(iRegLdst dst) %{ 13876 predicate(false); 13877 effect(USE_DEF dst); 13878 13879 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13880 size(4); 13881 ins_encode %{ 13882 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13883 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 13884 %} 13885 ins_pipe(pipe_class_default); 13886 %} 13887 13888 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13889 match(Set dst (ReplicateB src)); 13890 predicate(n->as_Vector()->length() == 8); 13891 expand %{ 13892 moveReg(dst, src); 13893 repl56(dst); 13894 repl48(dst); 13895 repl32(dst); 13896 %} 13897 %} 13898 13899 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 13900 match(Set dst (ReplicateB zero)); 13901 predicate(n->as_Vector()->length() == 8); 13902 format %{ "LI $dst, #0 \t// replicate8B" %} 13903 size(4); 13904 ins_encode %{ 13905 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13906 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13907 %} 13908 ins_pipe(pipe_class_default); 13909 %} 13910 13911 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13912 match(Set dst (ReplicateB src)); 13913 predicate(n->as_Vector()->length() == 8); 13914 format %{ "LI $dst, #-1 \t// replicate8B" %} 13915 size(4); 13916 ins_encode %{ 13917 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13918 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13919 %} 13920 ins_pipe(pipe_class_default); 13921 %} 13922 13923 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 13924 match(Set dst (ReplicateB src)); 13925 predicate(n->as_Vector()->length() == 16); 13926 13927 expand %{ 13928 iRegLdst tmpL; 13929 vecX tmpV; 13930 immI8 imm1 %{ (int) 1 %} 13931 moveReg(tmpL, src); 13932 repl56(tmpL); 13933 repl48(tmpL); 13934 mtvsrwz(tmpV, tmpL); 13935 xxspltw(dst, tmpV, imm1); 13936 %} 13937 %} 13938 13939 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 13940 match(Set dst (ReplicateB zero)); 13941 predicate(n->as_Vector()->length() == 16); 13942 13943 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 13944 size(4); 13945 ins_encode %{ 13946 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13947 %} 13948 ins_pipe(pipe_class_default); 13949 %} 13950 13951 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 13952 match(Set dst (ReplicateB src)); 13953 predicate(n->as_Vector()->length() == 16); 13954 13955 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13956 size(4); 13957 ins_encode %{ 13958 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13959 %} 13960 ins_pipe(pipe_class_default); 13961 %} 13962 13963 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13964 match(Set dst (ReplicateS src)); 13965 predicate(n->as_Vector()->length() == 4); 13966 expand %{ 13967 moveReg(dst, src); 13968 repl48(dst); 13969 repl32(dst); 13970 %} 13971 %} 13972 13973 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 13974 match(Set dst (ReplicateS zero)); 13975 predicate(n->as_Vector()->length() == 4); 13976 format %{ "LI $dst, #0 \t// replicate4C" %} 13977 size(4); 13978 ins_encode %{ 13979 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13980 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13981 %} 13982 ins_pipe(pipe_class_default); 13983 %} 13984 13985 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13986 match(Set dst (ReplicateS src)); 13987 predicate(n->as_Vector()->length() == 4); 13988 format %{ "LI $dst, -1 \t// replicate4C" %} 13989 size(4); 13990 ins_encode %{ 13991 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13992 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13993 %} 13994 ins_pipe(pipe_class_default); 13995 %} 13996 13997 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 13998 match(Set dst (ReplicateS src)); 13999 predicate(n->as_Vector()->length() == 8); 14000 14001 expand %{ 14002 iRegLdst tmpL; 14003 vecX tmpV; 14004 immI8 zero %{ (int) 0 %} 14005 moveReg(tmpL, src); 14006 repl48(tmpL); 14007 repl32(tmpL); 14008 mtvsrd(tmpV, tmpL); 14009 xxpermdi(dst, tmpV, tmpV, zero); 14010 %} 14011 %} 14012 14013 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 14014 match(Set dst (ReplicateS zero)); 14015 predicate(n->as_Vector()->length() == 8); 14016 14017 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 14018 size(4); 14019 ins_encode %{ 14020 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14021 %} 14022 ins_pipe(pipe_class_default); 14023 %} 14024 14025 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 14026 match(Set dst (ReplicateS src)); 14027 predicate(n->as_Vector()->length() == 8); 14028 14029 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14030 size(4); 14031 ins_encode %{ 14032 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14033 %} 14034 ins_pipe(pipe_class_default); 14035 %} 14036 14037 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14038 match(Set dst (ReplicateI src)); 14039 predicate(n->as_Vector()->length() == 2); 14040 ins_cost(2 * DEFAULT_COST); 14041 expand %{ 14042 moveReg(dst, src); 14043 repl32(dst); 14044 %} 14045 %} 14046 14047 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 14048 match(Set dst (ReplicateI zero)); 14049 predicate(n->as_Vector()->length() == 2); 14050 format %{ "LI $dst, #0 \t// replicate4C" %} 14051 size(4); 14052 ins_encode %{ 14053 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14054 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14055 %} 14056 ins_pipe(pipe_class_default); 14057 %} 14058 14059 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14060 match(Set dst (ReplicateI src)); 14061 predicate(n->as_Vector()->length() == 2); 14062 format %{ "LI $dst, -1 \t// replicate4C" %} 14063 size(4); 14064 ins_encode %{ 14065 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14066 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14067 %} 14068 ins_pipe(pipe_class_default); 14069 %} 14070 14071 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 14072 match(Set dst (ReplicateI src)); 14073 predicate(n->as_Vector()->length() == 4); 14074 ins_cost(2 * DEFAULT_COST); 14075 14076 expand %{ 14077 iRegLdst tmpL; 14078 vecX tmpV; 14079 immI8 zero %{ (int) 0 %} 14080 moveReg(tmpL, src); 14081 repl32(tmpL); 14082 mtvsrd(tmpV, tmpL); 14083 xxpermdi(dst, tmpV, tmpV, zero); 14084 %} 14085 %} 14086 14087 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 14088 match(Set dst (ReplicateI zero)); 14089 predicate(n->as_Vector()->length() == 4); 14090 14091 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 14092 size(4); 14093 ins_encode %{ 14094 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14095 %} 14096 ins_pipe(pipe_class_default); 14097 %} 14098 14099 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 14100 match(Set dst (ReplicateI src)); 14101 predicate(n->as_Vector()->length() == 4); 14102 14103 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 14104 size(4); 14105 ins_encode %{ 14106 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14107 %} 14108 ins_pipe(pipe_class_default); 14109 %} 14110 14111 // Move float to int register via stack, replicate. 14112 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 14113 match(Set dst (ReplicateF src)); 14114 predicate(n->as_Vector()->length() == 2); 14115 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14116 expand %{ 14117 stackSlotL tmpS; 14118 iRegIdst tmpI; 14119 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14120 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14121 moveReg(dst, tmpI); // Move int to long reg. 14122 repl32(dst); // Replicate bitpattern. 14123 %} 14124 %} 14125 14126 // Replicate scalar constant to packed float values in Double register 14127 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 14128 match(Set dst (ReplicateF src)); 14129 predicate(n->as_Vector()->length() == 2); 14130 ins_cost(5 * DEFAULT_COST); 14131 14132 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 14133 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 14134 %} 14135 14136 // Replicate scalar zero constant to packed float values in Double register 14137 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 14138 match(Set dst (ReplicateF zero)); 14139 predicate(n->as_Vector()->length() == 2); 14140 14141 format %{ "LI $dst, #0 \t// replicate2F" %} 14142 ins_encode %{ 14143 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14144 __ li($dst$$Register, 0x0); 14145 %} 14146 ins_pipe(pipe_class_default); 14147 %} 14148 14149 14150 //----------Vector Arithmetic Instructions-------------------------------------- 14151 14152 // Vector Addition Instructions 14153 14154 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{ 14155 match(Set dst (AddVB src1 src2)); 14156 predicate(n->as_Vector()->length() == 16); 14157 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %} 14158 size(4); 14159 ins_encode %{ 14160 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14161 %} 14162 ins_pipe(pipe_class_default); 14163 %} 14164 14165 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{ 14166 match(Set dst (AddVS src1 src2)); 14167 predicate(n->as_Vector()->length() == 8); 14168 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %} 14169 size(4); 14170 ins_encode %{ 14171 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14172 %} 14173 ins_pipe(pipe_class_default); 14174 %} 14175 14176 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{ 14177 match(Set dst (AddVI src1 src2)); 14178 predicate(n->as_Vector()->length() == 4); 14179 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %} 14180 size(4); 14181 ins_encode %{ 14182 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14183 %} 14184 ins_pipe(pipe_class_default); 14185 %} 14186 14187 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{ 14188 match(Set dst (AddVF src1 src2)); 14189 predicate(n->as_Vector()->length() == 4); 14190 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %} 14191 size(4); 14192 ins_encode %{ 14193 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14194 %} 14195 ins_pipe(pipe_class_default); 14196 %} 14197 14198 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{ 14199 match(Set dst (AddVL src1 src2)); 14200 predicate(n->as_Vector()->length() == 2); 14201 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %} 14202 size(4); 14203 ins_encode %{ 14204 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14205 %} 14206 ins_pipe(pipe_class_default); 14207 %} 14208 14209 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{ 14210 match(Set dst (AddVD src1 src2)); 14211 predicate(n->as_Vector()->length() == 2); 14212 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %} 14213 size(4); 14214 ins_encode %{ 14215 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14216 %} 14217 ins_pipe(pipe_class_default); 14218 %} 14219 14220 // Vector Subtraction Instructions 14221 14222 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{ 14223 match(Set dst (SubVB src1 src2)); 14224 predicate(n->as_Vector()->length() == 16); 14225 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %} 14226 size(4); 14227 ins_encode %{ 14228 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14229 %} 14230 ins_pipe(pipe_class_default); 14231 %} 14232 14233 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{ 14234 match(Set dst (SubVS src1 src2)); 14235 predicate(n->as_Vector()->length() == 8); 14236 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %} 14237 size(4); 14238 ins_encode %{ 14239 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14240 %} 14241 ins_pipe(pipe_class_default); 14242 %} 14243 14244 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{ 14245 match(Set dst (SubVI src1 src2)); 14246 predicate(n->as_Vector()->length() == 4); 14247 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %} 14248 size(4); 14249 ins_encode %{ 14250 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14251 %} 14252 ins_pipe(pipe_class_default); 14253 %} 14254 14255 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{ 14256 match(Set dst (SubVF src1 src2)); 14257 predicate(n->as_Vector()->length() == 4); 14258 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %} 14259 size(4); 14260 ins_encode %{ 14261 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14262 %} 14263 ins_pipe(pipe_class_default); 14264 %} 14265 14266 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{ 14267 match(Set dst (SubVL src1 src2)); 14268 predicate(n->as_Vector()->length() == 2); 14269 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %} 14270 size(4); 14271 ins_encode %{ 14272 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14273 %} 14274 ins_pipe(pipe_class_default); 14275 %} 14276 14277 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{ 14278 match(Set dst (SubVD src1 src2)); 14279 predicate(n->as_Vector()->length() == 2); 14280 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %} 14281 size(4); 14282 ins_encode %{ 14283 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14284 %} 14285 ins_pipe(pipe_class_default); 14286 %} 14287 14288 // Vector Multiplication Instructions 14289 14290 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 14291 match(Set dst (MulVS src1 src2)); 14292 predicate(n->as_Vector()->length() == 8); 14293 effect(TEMP tmp); 14294 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %} 14295 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %} 14296 size(8); 14297 ins_encode %{ 14298 __ vspltish($tmp$$VectorSRegister->to_vr(), 0); 14299 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr()); 14300 %} 14301 ins_pipe(pipe_class_default); 14302 %} 14303 14304 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{ 14305 match(Set dst (MulVI src1 src2)); 14306 predicate(n->as_Vector()->length() == 4); 14307 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %} 14308 size(4); 14309 ins_encode %{ 14310 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14311 %} 14312 ins_pipe(pipe_class_default); 14313 %} 14314 14315 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{ 14316 match(Set dst (MulVF src1 src2)); 14317 predicate(n->as_Vector()->length() == 4); 14318 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %} 14319 size(4); 14320 ins_encode %{ 14321 __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14322 %} 14323 ins_pipe(pipe_class_default); 14324 %} 14325 14326 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{ 14327 match(Set dst (MulVD src1 src2)); 14328 predicate(n->as_Vector()->length() == 2); 14329 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %} 14330 size(4); 14331 ins_encode %{ 14332 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14333 %} 14334 ins_pipe(pipe_class_default); 14335 %} 14336 14337 // Vector Division Instructions 14338 14339 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{ 14340 match(Set dst (DivVF src1 src2)); 14341 predicate(n->as_Vector()->length() == 4); 14342 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %} 14343 size(4); 14344 ins_encode %{ 14345 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14346 %} 14347 ins_pipe(pipe_class_default); 14348 %} 14349 14350 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ 14351 match(Set dst (DivVD src1 src2)); 14352 predicate(n->as_Vector()->length() == 2); 14353 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %} 14354 size(4); 14355 ins_encode %{ 14356 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14357 %} 14358 ins_pipe(pipe_class_default); 14359 %} 14360 14361 // Vector Absolute Instructions 14362 14363 instruct vabs4F_reg(vecX dst, vecX src) %{ 14364 match(Set dst (AbsVF src)); 14365 predicate(n->as_Vector()->length() == 4); 14366 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %} 14367 size(4); 14368 ins_encode %{ 14369 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister); 14370 %} 14371 ins_pipe(pipe_class_default); 14372 %} 14373 14374 instruct vabs2D_reg(vecX dst, vecX src) %{ 14375 match(Set dst (AbsVD src)); 14376 predicate(n->as_Vector()->length() == 2); 14377 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %} 14378 size(4); 14379 ins_encode %{ 14380 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister); 14381 %} 14382 ins_pipe(pipe_class_default); 14383 %} 14384 14385 // Vector Negate Instructions 14386 14387 instruct vneg4F_reg(vecX dst, vecX src) %{ 14388 match(Set dst (NegVF src)); 14389 predicate(n->as_Vector()->length() == 4); 14390 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %} 14391 size(4); 14392 ins_encode %{ 14393 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister); 14394 %} 14395 ins_pipe(pipe_class_default); 14396 %} 14397 14398 instruct vneg2D_reg(vecX dst, vecX src) %{ 14399 match(Set dst (NegVD src)); 14400 predicate(n->as_Vector()->length() == 2); 14401 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %} 14402 size(4); 14403 ins_encode %{ 14404 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister); 14405 %} 14406 ins_pipe(pipe_class_default); 14407 %} 14408 14409 // Vector Square Root Instructions 14410 14411 instruct vsqrt4F_reg(vecX dst, vecX src) %{ 14412 match(Set dst (SqrtVF src)); 14413 predicate(n->as_Vector()->length() == 4); 14414 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %} 14415 size(4); 14416 ins_encode %{ 14417 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister); 14418 %} 14419 ins_pipe(pipe_class_default); 14420 %} 14421 14422 instruct vsqrt2D_reg(vecX dst, vecX src) %{ 14423 match(Set dst (SqrtVD src)); 14424 predicate(n->as_Vector()->length() == 2); 14425 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %} 14426 size(4); 14427 ins_encode %{ 14428 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister); 14429 %} 14430 ins_pipe(pipe_class_default); 14431 %} 14432 14433 // Vector Population Count Instructions 14434 14435 instruct vpopcnt4I_reg(vecX dst, vecX src) %{ 14436 match(Set dst (PopCountVI src)); 14437 predicate(n->as_Vector()->length() == 4); 14438 format %{ "VPOPCNTW $dst,$src\t// pop count packed4I" %} 14439 size(4); 14440 ins_encode %{ 14441 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14442 %} 14443 ins_pipe(pipe_class_default); 14444 %} 14445 14446 14447 //----------Overflow Math Instructions----------------------------------------- 14448 14449 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 14450 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14451 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14452 14453 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14454 match(Set cr0 (OverflowAddL op1 op2)); 14455 14456 format %{ "add_ $op1, $op2\t# overflow check long" %} 14457 ins_encode %{ 14458 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14459 __ li(R0, 0); 14460 __ mtxer(R0); // clear XER.SO 14461 __ addo_(R0, $op1$$Register, $op2$$Register); 14462 %} 14463 ins_pipe(pipe_class_default); 14464 %} 14465 14466 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14467 match(Set cr0 (OverflowSubL op1 op2)); 14468 14469 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14470 ins_encode %{ 14471 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14472 __ li(R0, 0); 14473 __ mtxer(R0); // clear XER.SO 14474 __ subfo_(R0, $op2$$Register, $op1$$Register); 14475 %} 14476 ins_pipe(pipe_class_default); 14477 %} 14478 14479 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14480 match(Set cr0 (OverflowSubL zero op2)); 14481 14482 format %{ "nego_ R0, $op2\t# overflow check long" %} 14483 ins_encode %{ 14484 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14485 __ li(R0, 0); 14486 __ mtxer(R0); // clear XER.SO 14487 __ nego_(R0, $op2$$Register); 14488 %} 14489 ins_pipe(pipe_class_default); 14490 %} 14491 14492 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14493 match(Set cr0 (OverflowMulL op1 op2)); 14494 14495 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14496 ins_encode %{ 14497 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14498 __ li(R0, 0); 14499 __ mtxer(R0); // clear XER.SO 14500 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14501 %} 14502 ins_pipe(pipe_class_default); 14503 %} 14504 14505 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14506 match(Set dst (ReplicateF src)); 14507 predicate(n->as_Vector()->length() == 4); 14508 ins_cost(DEFAULT_COST); 14509 expand %{ 14510 vecX tmpV; 14511 immI8 zero %{ (int) 0 %} 14512 14513 xscvdpspn_regF(tmpV, src); 14514 xxspltw(dst, tmpV, zero); 14515 %} 14516 %} 14517 14518 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14519 match(Set dst (ReplicateF src)); 14520 predicate(n->as_Vector()->length() == 4); 14521 effect(TEMP tmp); 14522 ins_cost(10 * DEFAULT_COST); 14523 14524 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14525 %} 14526 14527 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14528 match(Set dst (ReplicateF zero)); 14529 predicate(n->as_Vector()->length() == 4); 14530 14531 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14532 ins_encode %{ 14533 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14534 %} 14535 ins_pipe(pipe_class_default); 14536 %} 14537 14538 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14539 match(Set dst (ReplicateD src)); 14540 predicate(n->as_Vector()->length() == 2); 14541 14542 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %} 14543 size(4); 14544 ins_encode %{ 14545 __ xxpermdi($dst$$VectorSRegister, $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0); 14546 %} 14547 ins_pipe(pipe_class_default); 14548 %} 14549 14550 instruct repl2D_immI0(vecX dst, immI_0 zero) %{ 14551 match(Set dst (ReplicateD zero)); 14552 predicate(n->as_Vector()->length() == 2); 14553 14554 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14555 size(4); 14556 ins_encode %{ 14557 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14558 %} 14559 ins_pipe(pipe_class_default); 14560 %} 14561 14562 instruct repl2D_immIminus1(vecX dst, immI_minus1 src) %{ 14563 match(Set dst (ReplicateD src)); 14564 predicate(n->as_Vector()->length() == 2); 14565 14566 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14567 size(4); 14568 ins_encode %{ 14569 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14570 %} 14571 ins_pipe(pipe_class_default); 14572 %} 14573 14574 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14575 predicate(false); 14576 effect(DEF dst, USE src); 14577 14578 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %} 14579 size(4); 14580 ins_encode %{ 14581 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14582 %} 14583 ins_pipe(pipe_class_default); 14584 %} 14585 14586 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14587 effect(DEF dst, USE src, USE zero); 14588 14589 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %} 14590 size(4); 14591 ins_encode %{ 14592 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14593 %} 14594 ins_pipe(pipe_class_default); 14595 %} 14596 14597 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14598 effect(DEF dst, USE src1, USE src2, USE zero); 14599 14600 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %} 14601 size(4); 14602 ins_encode %{ 14603 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14604 %} 14605 ins_pipe(pipe_class_default); 14606 %} 14607 14608 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14609 match(Set dst (ReplicateL src)); 14610 predicate(n->as_Vector()->length() == 2); 14611 expand %{ 14612 vecX tmpV; 14613 immI8 zero %{ (int) 0 %} 14614 mtvsrd(tmpV, src); 14615 xxpermdi(dst, tmpV, tmpV, zero); 14616 %} 14617 %} 14618 14619 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14620 match(Set dst (ReplicateL zero)); 14621 predicate(n->as_Vector()->length() == 2); 14622 14623 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14624 size(4); 14625 ins_encode %{ 14626 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14627 %} 14628 ins_pipe(pipe_class_default); 14629 %} 14630 14631 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14632 match(Set dst (ReplicateL src)); 14633 predicate(n->as_Vector()->length() == 2); 14634 14635 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14636 size(4); 14637 ins_encode %{ 14638 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14639 %} 14640 ins_pipe(pipe_class_default); 14641 %} 14642 14643 // ============================================================================ 14644 // Safepoint Instruction 14645 14646 instruct safePoint_poll(iRegPdst poll) %{ 14647 match(SafePoint poll); 14648 14649 // It caused problems to add the effect that r0 is killed, but this 14650 // effect no longer needs to be mentioned, since r0 is not contained 14651 // in a reg_class. 14652 14653 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14654 size(4); 14655 ins_encode( enc_poll(0x0, poll) ); 14656 ins_pipe(pipe_class_default); 14657 %} 14658 14659 // ============================================================================ 14660 // Call Instructions 14661 14662 // Call Java Static Instruction 14663 14664 // Schedulable version of call static node. 14665 instruct CallStaticJavaDirect(method meth) %{ 14666 match(CallStaticJava); 14667 effect(USE meth); 14668 ins_cost(CALL_COST); 14669 14670 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14671 14672 format %{ "CALL,static $meth \t// ==> " %} 14673 size(4); 14674 ins_encode( enc_java_static_call(meth) ); 14675 ins_pipe(pipe_class_call); 14676 %} 14677 14678 // Call Java Dynamic Instruction 14679 14680 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14681 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14682 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14683 // The call destination must still be placed in the constant pool. 14684 instruct CallDynamicJavaDirectSched(method meth) %{ 14685 match(CallDynamicJava); // To get all the data fields we need ... 14686 effect(USE meth); 14687 predicate(false); // ... but never match. 14688 14689 ins_field_load_ic_hi_node(loadConL_hiNode*); 14690 ins_field_load_ic_node(loadConLNode*); 14691 ins_num_consts(1 /* 1 patchable constant: call destination */); 14692 14693 format %{ "BL \t// dynamic $meth ==> " %} 14694 size(4); 14695 ins_encode( enc_java_dynamic_call_sched(meth) ); 14696 ins_pipe(pipe_class_call); 14697 %} 14698 14699 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14700 // We use postalloc expanded calls if we use inline caches 14701 // and do not update method data. 14702 // 14703 // This instruction has two constants: inline cache (IC) and call destination. 14704 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14705 // one constant. 14706 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14707 match(CallDynamicJava); 14708 effect(USE meth); 14709 predicate(UseInlineCaches); 14710 ins_cost(CALL_COST); 14711 14712 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14713 14714 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14715 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14716 %} 14717 14718 // Compound version of call dynamic java 14719 // We use postalloc expanded calls if we use inline caches 14720 // and do not update method data. 14721 instruct CallDynamicJavaDirect(method meth) %{ 14722 match(CallDynamicJava); 14723 effect(USE meth); 14724 predicate(!UseInlineCaches); 14725 ins_cost(CALL_COST); 14726 14727 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14728 ins_num_consts(4); 14729 14730 format %{ "CALL,dynamic $meth \t// ==> " %} 14731 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14732 ins_pipe(pipe_class_call); 14733 %} 14734 14735 // Call Runtime Instruction 14736 14737 instruct CallRuntimeDirect(method meth) %{ 14738 match(CallRuntime); 14739 effect(USE meth); 14740 ins_cost(CALL_COST); 14741 14742 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14743 // env for callee, C-toc. 14744 ins_num_consts(3); 14745 14746 format %{ "CALL,runtime" %} 14747 ins_encode( enc_java_to_runtime_call(meth) ); 14748 ins_pipe(pipe_class_call); 14749 %} 14750 14751 // Call Leaf 14752 14753 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14754 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14755 effect(DEF dst, USE src); 14756 14757 ins_num_consts(1); 14758 14759 format %{ "MTCTR $src" %} 14760 size(4); 14761 ins_encode( enc_leaf_call_mtctr(src) ); 14762 ins_pipe(pipe_class_default); 14763 %} 14764 14765 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 14766 instruct CallLeafDirect(method meth) %{ 14767 match(CallLeaf); // To get the data all the data fields we need ... 14768 effect(USE meth); 14769 predicate(false); // but never match. 14770 14771 format %{ "BCTRL \t// leaf call $meth ==> " %} 14772 size(4); 14773 ins_encode %{ 14774 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 14775 __ bctrl(); 14776 %} 14777 ins_pipe(pipe_class_call); 14778 %} 14779 14780 // postalloc expand of CallLeafDirect. 14781 // Load adress to call from TOC, then bl to it. 14782 instruct CallLeafDirect_Ex(method meth) %{ 14783 match(CallLeaf); 14784 effect(USE meth); 14785 ins_cost(CALL_COST); 14786 14787 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14788 // env for callee, C-toc. 14789 ins_num_consts(3); 14790 14791 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14792 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14793 %} 14794 14795 // Call runtime without safepoint - same as CallLeaf. 14796 // postalloc expand of CallLeafNoFPDirect. 14797 // Load adress to call from TOC, then bl to it. 14798 instruct CallLeafNoFPDirect_Ex(method meth) %{ 14799 match(CallLeafNoFP); 14800 effect(USE meth); 14801 ins_cost(CALL_COST); 14802 14803 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14804 // env for callee, C-toc. 14805 ins_num_consts(3); 14806 14807 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14808 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14809 %} 14810 14811 // Tail Call; Jump from runtime stub to Java code. 14812 // Also known as an 'interprocedural jump'. 14813 // Target of jump will eventually return to caller. 14814 // TailJump below removes the return address. 14815 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 14816 match(TailCall jump_target method_oop); 14817 ins_cost(CALL_COST); 14818 14819 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 14820 "BCTR \t// tail call" %} 14821 size(8); 14822 ins_encode %{ 14823 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14824 __ mtctr($jump_target$$Register); 14825 __ bctr(); 14826 %} 14827 ins_pipe(pipe_class_call); 14828 %} 14829 14830 // Return Instruction 14831 instruct Ret() %{ 14832 match(Return); 14833 format %{ "BLR \t// branch to link register" %} 14834 size(4); 14835 ins_encode %{ 14836 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 14837 // LR is restored in MachEpilogNode. Just do the RET here. 14838 __ blr(); 14839 %} 14840 ins_pipe(pipe_class_default); 14841 %} 14842 14843 // Tail Jump; remove the return address; jump to target. 14844 // TailCall above leaves the return address around. 14845 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14846 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14847 // "restore" before this instruction (in Epilogue), we need to materialize it 14848 // in %i0. 14849 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14850 match(TailJump jump_target ex_oop); 14851 ins_cost(CALL_COST); 14852 14853 format %{ "LD R4_ARG2 = LR\n\t" 14854 "MTCTR $jump_target\n\t" 14855 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14856 size(12); 14857 ins_encode %{ 14858 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14859 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 14860 __ mtctr($jump_target$$Register); 14861 __ bctr(); 14862 %} 14863 ins_pipe(pipe_class_call); 14864 %} 14865 14866 // Create exception oop: created by stack-crawling runtime code. 14867 // Created exception is now available to this handler, and is setup 14868 // just prior to jumping to this handler. No code emitted. 14869 instruct CreateException(rarg1RegP ex_oop) %{ 14870 match(Set ex_oop (CreateEx)); 14871 ins_cost(0); 14872 14873 format %{ " -- \t// exception oop; no code emitted" %} 14874 size(0); 14875 ins_encode( /*empty*/ ); 14876 ins_pipe(pipe_class_default); 14877 %} 14878 14879 // Rethrow exception: The exception oop will come in the first 14880 // argument position. Then JUMP (not call) to the rethrow stub code. 14881 instruct RethrowException() %{ 14882 match(Rethrow); 14883 ins_cost(CALL_COST); 14884 14885 format %{ "Jmp rethrow_stub" %} 14886 ins_encode %{ 14887 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14888 cbuf.set_insts_mark(); 14889 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 14890 %} 14891 ins_pipe(pipe_class_call); 14892 %} 14893 14894 // Die now. 14895 instruct ShouldNotReachHere() %{ 14896 match(Halt); 14897 ins_cost(CALL_COST); 14898 14899 format %{ "ShouldNotReachHere" %} 14900 size(4); 14901 ins_encode %{ 14902 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 14903 __ trap_should_not_reach_here(); 14904 %} 14905 ins_pipe(pipe_class_default); 14906 %} 14907 14908 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 14909 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 14910 // Get a DEF on threadRegP, no costs, no encoding, use 14911 // 'ins_should_rematerialize(true)' to avoid spilling. 14912 instruct tlsLoadP(threadRegP dst) %{ 14913 match(Set dst (ThreadLocal)); 14914 ins_cost(0); 14915 14916 ins_should_rematerialize(true); 14917 14918 format %{ " -- \t// $dst=Thread::current(), empty" %} 14919 size(0); 14920 ins_encode( /*empty*/ ); 14921 ins_pipe(pipe_class_empty); 14922 %} 14923 14924 //---Some PPC specific nodes--------------------------------------------------- 14925 14926 // Stop a group. 14927 instruct endGroup() %{ 14928 ins_cost(0); 14929 14930 ins_is_nop(true); 14931 14932 format %{ "End Bundle (ori r1, r1, 0)" %} 14933 size(4); 14934 ins_encode %{ 14935 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 14936 __ endgroup(); 14937 %} 14938 ins_pipe(pipe_class_default); 14939 %} 14940 14941 // Nop instructions 14942 14943 instruct fxNop() %{ 14944 ins_cost(0); 14945 14946 ins_is_nop(true); 14947 14948 format %{ "fxNop" %} 14949 size(4); 14950 ins_encode %{ 14951 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14952 __ nop(); 14953 %} 14954 ins_pipe(pipe_class_default); 14955 %} 14956 14957 instruct fpNop0() %{ 14958 ins_cost(0); 14959 14960 ins_is_nop(true); 14961 14962 format %{ "fpNop0" %} 14963 size(4); 14964 ins_encode %{ 14965 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14966 __ fpnop0(); 14967 %} 14968 ins_pipe(pipe_class_default); 14969 %} 14970 14971 instruct fpNop1() %{ 14972 ins_cost(0); 14973 14974 ins_is_nop(true); 14975 14976 format %{ "fpNop1" %} 14977 size(4); 14978 ins_encode %{ 14979 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14980 __ fpnop1(); 14981 %} 14982 ins_pipe(pipe_class_default); 14983 %} 14984 14985 instruct brNop0() %{ 14986 ins_cost(0); 14987 size(4); 14988 format %{ "brNop0" %} 14989 ins_encode %{ 14990 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14991 __ brnop0(); 14992 %} 14993 ins_is_nop(true); 14994 ins_pipe(pipe_class_default); 14995 %} 14996 14997 instruct brNop1() %{ 14998 ins_cost(0); 14999 15000 ins_is_nop(true); 15001 15002 format %{ "brNop1" %} 15003 size(4); 15004 ins_encode %{ 15005 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15006 __ brnop1(); 15007 %} 15008 ins_pipe(pipe_class_default); 15009 %} 15010 15011 instruct brNop2() %{ 15012 ins_cost(0); 15013 15014 ins_is_nop(true); 15015 15016 format %{ "brNop2" %} 15017 size(4); 15018 ins_encode %{ 15019 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15020 __ brnop2(); 15021 %} 15022 ins_pipe(pipe_class_default); 15023 %} 15024 15025 //----------PEEPHOLE RULES----------------------------------------------------- 15026 // These must follow all instruction definitions as they use the names 15027 // defined in the instructions definitions. 15028 // 15029 // peepmatch ( root_instr_name [preceeding_instruction]* ); 15030 // 15031 // peepconstraint %{ 15032 // (instruction_number.operand_name relational_op instruction_number.operand_name 15033 // [, ...] ); 15034 // // instruction numbers are zero-based using left to right order in peepmatch 15035 // 15036 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 15037 // // provide an instruction_number.operand_name for each operand that appears 15038 // // in the replacement instruction's match rule 15039 // 15040 // ---------VM FLAGS--------------------------------------------------------- 15041 // 15042 // All peephole optimizations can be turned off using -XX:-OptoPeephole 15043 // 15044 // Each peephole rule is given an identifying number starting with zero and 15045 // increasing by one in the order seen by the parser. An individual peephole 15046 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 15047 // on the command-line. 15048 // 15049 // ---------CURRENT LIMITATIONS---------------------------------------------- 15050 // 15051 // Only match adjacent instructions in same basic block 15052 // Only equality constraints 15053 // Only constraints between operands, not (0.dest_reg == EAX_enc) 15054 // Only one replacement instruction 15055 // 15056 // ---------EXAMPLE---------------------------------------------------------- 15057 // 15058 // // pertinent parts of existing instructions in architecture description 15059 // instruct movI(eRegI dst, eRegI src) %{ 15060 // match(Set dst (CopyI src)); 15061 // %} 15062 // 15063 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 15064 // match(Set dst (AddI dst src)); 15065 // effect(KILL cr); 15066 // %} 15067 // 15068 // // Change (inc mov) to lea 15069 // peephole %{ 15070 // // increment preceeded by register-register move 15071 // peepmatch ( incI_eReg movI ); 15072 // // require that the destination register of the increment 15073 // // match the destination register of the move 15074 // peepconstraint ( 0.dst == 1.dst ); 15075 // // construct a replacement instruction that sets 15076 // // the destination to ( move's source register + one ) 15077 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15078 // %} 15079 // 15080 // Implementation no longer uses movX instructions since 15081 // machine-independent system no longer uses CopyX nodes. 15082 // 15083 // peephole %{ 15084 // peepmatch ( incI_eReg movI ); 15085 // peepconstraint ( 0.dst == 1.dst ); 15086 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15087 // %} 15088 // 15089 // peephole %{ 15090 // peepmatch ( decI_eReg movI ); 15091 // peepconstraint ( 0.dst == 1.dst ); 15092 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15093 // %} 15094 // 15095 // peephole %{ 15096 // peepmatch ( addI_eReg_imm movI ); 15097 // peepconstraint ( 0.dst == 1.dst ); 15098 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15099 // %} 15100 // 15101 // peephole %{ 15102 // peepmatch ( addP_eReg_imm movP ); 15103 // peepconstraint ( 0.dst == 1.dst ); 15104 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 15105 // %} 15106 15107 // // Change load of spilled value to only a spill 15108 // instruct storeI(memory mem, eRegI src) %{ 15109 // match(Set mem (StoreI mem src)); 15110 // %} 15111 // 15112 // instruct loadI(eRegI dst, memory mem) %{ 15113 // match(Set dst (LoadI mem)); 15114 // %} 15115 // 15116 peephole %{ 15117 peepmatch ( loadI storeI ); 15118 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15119 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 15120 %} 15121 15122 peephole %{ 15123 peepmatch ( loadL storeL ); 15124 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15125 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 15126 %} 15127 15128 peephole %{ 15129 peepmatch ( loadP storeP ); 15130 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 15131 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 15132 %} 15133 15134 //----------SMARTSPILL RULES--------------------------------------------------- 15135 // These must follow all instruction definitions as they use the names 15136 // defined in the instructions definitions.