1 // 2 // Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2020 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 #include "opto/convertnode.hpp" 976 977 // Returns true if Node n is followed by a MemBar node that 978 // will do an acquire. If so, this node must not do the acquire 979 // operation. 980 bool followed_by_acquire(const Node *n); 981 %} 982 983 source %{ 984 985 void PhaseOutput::pd_perform_mach_node_analysis() { 986 } 987 988 int MachNode::pd_alignment_required() const { 989 return 1; 990 } 991 992 int MachNode::compute_padding(int current_offset) const { 993 return 0; 994 } 995 996 // Should the matcher clone input 'm' of node 'n'? 997 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { 998 return false; 999 } 1000 1001 // Should the Matcher clone shifts on addressing modes, expecting them 1002 // to be subsumed into complex addressing expressions or compute them 1003 // into registers? 1004 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 1005 return clone_base_plus_offset_address(m, mstack, address_visited); 1006 } 1007 1008 void Compile::reshape_address(AddPNode* addp) { 1009 } 1010 1011 // Optimize load-acquire. 1012 // 1013 // Check if acquire is unnecessary due to following operation that does 1014 // acquire anyways. 1015 // Walk the pattern: 1016 // 1017 // n: Load.acq 1018 // | 1019 // MemBarAcquire 1020 // | | 1021 // Proj(ctrl) Proj(mem) 1022 // | | 1023 // MemBarRelease/Volatile 1024 // 1025 bool followed_by_acquire(const Node *load) { 1026 assert(load->is_Load(), "So far implemented only for loads."); 1027 1028 // Find MemBarAcquire. 1029 const Node *mba = NULL; 1030 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 1031 const Node *out = load->fast_out(i); 1032 if (out->Opcode() == Op_MemBarAcquire) { 1033 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 1034 mba = out; 1035 break; 1036 } 1037 } 1038 if (!mba) return false; 1039 1040 // Find following MemBar node. 1041 // 1042 // The following node must be reachable by control AND memory 1043 // edge to assure no other operations are in between the two nodes. 1044 // 1045 // So first get the Proj node, mem_proj, to use it to iterate forward. 1046 Node *mem_proj = NULL; 1047 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 1048 mem_proj = mba->fast_out(i); // Runs out of bounds and asserts if Proj not found. 1049 assert(mem_proj->is_Proj(), "only projections here"); 1050 ProjNode *proj = mem_proj->as_Proj(); 1051 if (proj->_con == TypeFunc::Memory && 1052 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 1053 break; 1054 } 1055 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 1056 1057 // Search MemBar behind Proj. If there are other memory operations 1058 // behind the Proj we lost. 1059 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 1060 Node *x = mem_proj->fast_out(j); 1061 // Proj might have an edge to a store or load node which precedes the membar. 1062 if (x->is_Mem()) return false; 1063 1064 // On PPC64 release and volatile are implemented by an instruction 1065 // that also has acquire semantics. I.e. there is no need for an 1066 // acquire before these. 1067 int xop = x->Opcode(); 1068 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 1069 // Make sure we're not missing Call/Phi/MergeMem by checking 1070 // control edges. The control edge must directly lead back 1071 // to the MemBarAcquire 1072 Node *ctrl_proj = x->in(0); 1073 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 1074 return true; 1075 } 1076 } 1077 } 1078 1079 return false; 1080 } 1081 1082 #define __ _masm. 1083 1084 // Tertiary op of a LoadP or StoreP encoding. 1085 #define REGP_OP true 1086 1087 // **************************************************************************** 1088 1089 // REQUIRED FUNCTIONALITY 1090 1091 // !!!!! Special hack to get all type of calls to specify the byte offset 1092 // from the start of the call to the point where the return address 1093 // will point. 1094 1095 // PPC port: Removed use of lazy constant construct. 1096 1097 int MachCallStaticJavaNode::ret_addr_offset() { 1098 // It's only a single branch-and-link instruction. 1099 return 4; 1100 } 1101 1102 int MachCallDynamicJavaNode::ret_addr_offset() { 1103 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 1104 // postalloc expanded calls if we use inline caches and do not update method data. 1105 if (UseInlineCaches) 1106 return 4; 1107 1108 int vtable_index = this->_vtable_index; 1109 if (vtable_index < 0) { 1110 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 1111 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 1112 return 12; 1113 } else { 1114 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 1115 return 24; 1116 } 1117 } 1118 1119 int MachCallRuntimeNode::ret_addr_offset() { 1120 #if defined(ABI_ELFv2) 1121 return 28; 1122 #else 1123 return 40; 1124 #endif 1125 } 1126 1127 //============================================================================= 1128 1129 // condition code conversions 1130 1131 static int cc_to_boint(int cc) { 1132 return Assembler::bcondCRbiIs0 | (cc & 8); 1133 } 1134 1135 static int cc_to_inverse_boint(int cc) { 1136 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 1137 } 1138 1139 static int cc_to_biint(int cc, int flags_reg) { 1140 return (flags_reg << 2) | (cc & 3); 1141 } 1142 1143 //============================================================================= 1144 1145 // Compute padding required for nodes which need alignment. The padding 1146 // is the number of bytes (not instructions) which will be inserted before 1147 // the instruction. The padding must match the size of a NOP instruction. 1148 1149 // Currently not used on this platform. 1150 1151 //============================================================================= 1152 1153 // Indicate if the safepoint node needs the polling page as an input. 1154 bool SafePointNode::needs_polling_address_input() { 1155 // The address is loaded from thread by a seperate node. 1156 return true; 1157 } 1158 1159 //============================================================================= 1160 1161 // Emit an interrupt that is caught by the debugger (for debugging compiler). 1162 void emit_break(CodeBuffer &cbuf) { 1163 C2_MacroAssembler _masm(&cbuf); 1164 __ illtrap(); 1165 } 1166 1167 #ifndef PRODUCT 1168 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1169 st->print("BREAKPOINT"); 1170 } 1171 #endif 1172 1173 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1174 emit_break(cbuf); 1175 } 1176 1177 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1178 return MachNode::size(ra_); 1179 } 1180 1181 //============================================================================= 1182 1183 void emit_nop(CodeBuffer &cbuf) { 1184 C2_MacroAssembler _masm(&cbuf); 1185 __ nop(); 1186 } 1187 1188 static inline void emit_long(CodeBuffer &cbuf, int value) { 1189 *((int*)(cbuf.insts_end())) = value; 1190 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1191 } 1192 1193 //============================================================================= 1194 1195 %} // interrupt source 1196 1197 source_hpp %{ // Header information of the source block. 1198 1199 //-------------------------------------------------------------- 1200 //---< Used for optimization in Compile::Shorten_branches >--- 1201 //-------------------------------------------------------------- 1202 1203 class C2_MacroAssembler; 1204 1205 class CallStubImpl { 1206 1207 public: 1208 1209 // Emit call stub, compiled java to interpreter. 1210 static void emit_trampoline_stub(C2_MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1211 1212 // Size of call trampoline stub. 1213 // This doesn't need to be accurate to the byte, but it 1214 // must be larger than or equal to the real size of the stub. 1215 static uint size_call_trampoline() { 1216 return MacroAssembler::trampoline_stub_size; 1217 } 1218 1219 // number of relocations needed by a call trampoline stub 1220 static uint reloc_call_trampoline() { 1221 return 5; 1222 } 1223 1224 }; 1225 1226 %} // end source_hpp 1227 1228 source %{ 1229 1230 // Emit a trampoline stub for a call to a target which is too far away. 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 void CallStubImpl::emit_trampoline_stub(C2_MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1242 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1243 if (stub == NULL) { 1244 ciEnv::current()->record_out_of_memory_failure(); 1245 } 1246 } 1247 1248 //============================================================================= 1249 1250 // Emit an inline branch-and-link call and a related trampoline stub. 1251 // 1252 // code sequences: 1253 // 1254 // call-site: 1255 // branch-and-link to <destination> or <trampoline stub> 1256 // 1257 // Related trampoline stub for this call-site in the stub section: 1258 // load the call target from the constant pool 1259 // branch via CTR (LR/link still points to the call-site above) 1260 // 1261 1262 typedef struct { 1263 int insts_call_instruction_offset; 1264 int ret_addr_offset; 1265 } EmitCallOffsets; 1266 1267 // Emit a branch-and-link instruction that branches to a trampoline. 1268 // - Remember the offset of the branch-and-link instruction. 1269 // - Add a relocation at the branch-and-link instruction. 1270 // - Emit a branch-and-link. 1271 // - Remember the return pc offset. 1272 EmitCallOffsets emit_call_with_trampoline_stub(C2_MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1273 EmitCallOffsets offsets = { -1, -1 }; 1274 const int start_offset = __ offset(); 1275 offsets.insts_call_instruction_offset = __ offset(); 1276 1277 // No entry point given, use the current pc. 1278 if (entry_point == NULL) entry_point = __ pc(); 1279 1280 // Put the entry point as a constant into the constant pool. 1281 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1282 if (entry_point_toc_addr == NULL) { 1283 ciEnv::current()->record_out_of_memory_failure(); 1284 return offsets; 1285 } 1286 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1287 1288 // Emit the trampoline stub which will be related to the branch-and-link below. 1289 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1290 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1291 __ relocate(rtype); 1292 1293 // Note: At this point we do not have the address of the trampoline 1294 // stub, and the entry point might be too far away for bl, so __ pc() 1295 // serves as dummy and the bl will be patched later. 1296 __ bl((address) __ pc()); 1297 1298 offsets.ret_addr_offset = __ offset() - start_offset; 1299 1300 return offsets; 1301 } 1302 1303 //============================================================================= 1304 1305 // Factory for creating loadConL* nodes for large/small constant pool. 1306 1307 static inline jlong replicate_immF(float con) { 1308 // Replicate float con 2 times and pack into vector. 1309 int val = *((int*)&con); 1310 jlong lval = val; 1311 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1312 return lval; 1313 } 1314 1315 //============================================================================= 1316 1317 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1318 int ConstantTable::calculate_table_base_offset() const { 1319 return 0; // absolute addressing, no offset 1320 } 1321 1322 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1323 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1324 iRegPdstOper *op_dst = new iRegPdstOper(); 1325 MachNode *m1 = new loadToc_hiNode(); 1326 MachNode *m2 = new loadToc_loNode(); 1327 1328 m1->add_req(NULL); 1329 m2->add_req(NULL, m1); 1330 m1->_opnds[0] = op_dst; 1331 m2->_opnds[0] = op_dst; 1332 m2->_opnds[1] = op_dst; 1333 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1334 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1335 nodes->push(m1); 1336 nodes->push(m2); 1337 } 1338 1339 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1340 // Is postalloc expanded. 1341 ShouldNotReachHere(); 1342 } 1343 1344 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1345 return 0; 1346 } 1347 1348 #ifndef PRODUCT 1349 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1350 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1351 } 1352 #endif 1353 1354 //============================================================================= 1355 1356 #ifndef PRODUCT 1357 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1358 Compile* C = ra_->C; 1359 const long framesize = C->output()->frame_slots() << LogBytesPerInt; 1360 1361 st->print("PROLOG\n\t"); 1362 if (C->output()->need_stack_bang(framesize)) { 1363 st->print("stack_overflow_check\n\t"); 1364 } 1365 1366 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1367 st->print("save return pc\n\t"); 1368 st->print("push frame %ld\n\t", -framesize); 1369 } 1370 } 1371 #endif 1372 1373 // Macro used instead of the common __ to emulate the pipes of PPC. 1374 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1375 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1376 // still no scheduling of this code is possible, the micro scheduler is aware of the 1377 // code and can update its internal data. The following mechanism is used to achieve this: 1378 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1379 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1380 #if 0 // TODO: PPC port 1381 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1382 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1383 _masm. 1384 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1385 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1386 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1387 C->hb_scheduling()->_pdScheduling->advance_offset 1388 #else 1389 #define ___(op) if (UsePower6SchedulerPPC64) \ 1390 Unimplemented(); \ 1391 _masm. 1392 #define ___stop if (UsePower6SchedulerPPC64) \ 1393 Unimplemented() 1394 #define ___advance if (UsePower6SchedulerPPC64) \ 1395 Unimplemented() 1396 #endif 1397 1398 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1399 Compile* C = ra_->C; 1400 C2_MacroAssembler _masm(&cbuf); 1401 1402 const long framesize = C->output()->frame_size_in_bytes(); 1403 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1404 1405 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1406 1407 const Register return_pc = R20; // Must match return_addr() in frame section. 1408 const Register callers_sp = R21; 1409 const Register push_frame_temp = R22; 1410 const Register toc_temp = R23; 1411 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1412 1413 if (method_is_frameless) { 1414 // Add nop at beginning of all frameless methods to prevent any 1415 // oop instructions from getting overwritten by make_not_entrant 1416 // (patching attempt would fail). 1417 ___(nop) nop(); 1418 } else { 1419 // Get return pc. 1420 ___(mflr) mflr(return_pc); 1421 } 1422 1423 if (C->clinit_barrier_on_entry()) { 1424 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1425 1426 Label L_skip_barrier; 1427 Register klass = toc_temp; 1428 1429 // Notify OOP recorder (don't need the relocation) 1430 AddressLiteral md = __ constant_metadata_address(C->method()->holder()->constant_encoding()); 1431 __ load_const_optimized(klass, md.value(), R0); 1432 __ clinit_barrier(klass, R16_thread, &L_skip_barrier /*L_fast_path*/); 1433 1434 __ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub(), R0); 1435 __ mtctr(klass); 1436 __ bctr(); 1437 1438 __ bind(L_skip_barrier); 1439 } 1440 1441 // Calls to C2R adapters often do not accept exceptional returns. 1442 // We require that their callers must bang for them. But be 1443 // careful, because some VM calls (such as call site linkage) can 1444 // use several kilobytes of stack. But the stack safety zone should 1445 // account for that. See bugs 4446381, 4468289, 4497237. 1446 1447 int bangsize = C->output()->bang_size_in_bytes(); 1448 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1449 if (C->output()->need_stack_bang(bangsize) && UseStackBanging) { 1450 // Unfortunately we cannot use the function provided in 1451 // assembler.cpp as we have to emulate the pipes. So I had to 1452 // insert the code of generate_stack_overflow_check(), see 1453 // assembler.cpp for some illuminative comments. 1454 const int page_size = os::vm_page_size(); 1455 int bang_end = JavaThread::stack_shadow_zone_size(); 1456 1457 // This is how far the previous frame's stack banging extended. 1458 const int bang_end_safe = bang_end; 1459 1460 if (bangsize > page_size) { 1461 bang_end += bangsize; 1462 } 1463 1464 int bang_offset = bang_end_safe; 1465 1466 while (bang_offset <= bang_end) { 1467 // Need at least one stack bang at end of shadow zone. 1468 1469 // Again I had to copy code, this time from assembler_ppc.cpp, 1470 // bang_stack_with_offset - see there for comments. 1471 1472 // Stack grows down, caller passes positive offset. 1473 assert(bang_offset > 0, "must bang with positive offset"); 1474 1475 long stdoffset = -bang_offset; 1476 1477 if (Assembler::is_simm(stdoffset, 16)) { 1478 // Signed 16 bit offset, a simple std is ok. 1479 if (UseLoadInstructionsForStackBangingPPC64) { 1480 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1481 } else { 1482 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1483 } 1484 } else if (Assembler::is_simm(stdoffset, 31)) { 1485 // Use largeoffset calculations for addis & ld/std. 1486 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1487 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1488 1489 Register tmp = R11; 1490 ___(addis) addis(tmp, R1_SP, hi); 1491 if (UseLoadInstructionsForStackBangingPPC64) { 1492 ___(ld) ld(R0, lo, tmp); 1493 } else { 1494 ___(std) std(R0, lo, tmp); 1495 } 1496 } else { 1497 ShouldNotReachHere(); 1498 } 1499 1500 bang_offset += page_size; 1501 } 1502 // R11 trashed 1503 } // C->output()->need_stack_bang(framesize) && UseStackBanging 1504 1505 unsigned int bytes = (unsigned int)framesize; 1506 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1507 ciMethod *currMethod = C->method(); 1508 1509 // Optimized version for most common case. 1510 if (UsePower6SchedulerPPC64 && 1511 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1512 !(false /* ConstantsALot TODO: PPC port*/)) { 1513 ___(or) mr(callers_sp, R1_SP); 1514 ___(std) std(return_pc, _abi(lr), R1_SP); 1515 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1516 return; 1517 } 1518 1519 if (!method_is_frameless) { 1520 // Get callers sp. 1521 ___(or) mr(callers_sp, R1_SP); 1522 1523 // Push method's frame, modifies SP. 1524 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1525 // The ABI is already accounted for in 'framesize' via the 1526 // 'out_preserve' area. 1527 Register tmp = push_frame_temp; 1528 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1529 if (Assembler::is_simm(-offset, 16)) { 1530 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1531 } else { 1532 long x = -offset; 1533 // Had to insert load_const(tmp, -offset). 1534 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1535 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1536 ___(rldicr) sldi(tmp, tmp, 32); 1537 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1538 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1539 1540 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1541 } 1542 } 1543 #if 0 // TODO: PPC port 1544 // For testing large constant pools, emit a lot of constants to constant pool. 1545 // "Randomize" const_size. 1546 if (ConstantsALot) { 1547 const int num_consts = const_size(); 1548 for (int i = 0; i < num_consts; i++) { 1549 __ long_constant(0xB0B5B00BBABE); 1550 } 1551 } 1552 #endif 1553 if (!method_is_frameless) { 1554 // Save return pc. 1555 ___(std) std(return_pc, _abi(lr), callers_sp); 1556 } 1557 1558 C->output()->set_frame_complete(cbuf.insts_size()); 1559 } 1560 #undef ___ 1561 #undef ___stop 1562 #undef ___advance 1563 1564 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1565 // Variable size. determine dynamically. 1566 return MachNode::size(ra_); 1567 } 1568 1569 int MachPrologNode::reloc() const { 1570 // Return number of relocatable values contained in this instruction. 1571 return 1; // 1 reloc entry for load_const(toc). 1572 } 1573 1574 //============================================================================= 1575 1576 #ifndef PRODUCT 1577 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1578 Compile* C = ra_->C; 1579 1580 st->print("EPILOG\n\t"); 1581 st->print("restore return pc\n\t"); 1582 st->print("pop frame\n\t"); 1583 1584 if (do_polling() && C->is_method_compilation()) { 1585 st->print("touch polling page\n\t"); 1586 } 1587 } 1588 #endif 1589 1590 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1591 Compile* C = ra_->C; 1592 C2_MacroAssembler _masm(&cbuf); 1593 1594 const long framesize = ((long)C->output()->frame_slots()) << LogBytesPerInt; 1595 assert(framesize >= 0, "negative frame-size?"); 1596 1597 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1598 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1599 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1600 const Register polling_page = R12; 1601 1602 if (!method_is_frameless) { 1603 // Restore return pc relative to callers' sp. 1604 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1605 } 1606 1607 if (method_needs_polling) { 1608 __ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread); 1609 } 1610 1611 if (!method_is_frameless) { 1612 // Move return pc to LR. 1613 __ mtlr(return_pc); 1614 // Pop frame (fixed frame-size). 1615 __ addi(R1_SP, R1_SP, (int)framesize); 1616 } 1617 1618 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1619 __ reserved_stack_check(return_pc); 1620 } 1621 1622 if (method_needs_polling) { 1623 // We need to mark the code position where the load from the safepoint 1624 // polling page was emitted as relocInfo::poll_return_type here. 1625 __ relocate(relocInfo::poll_return_type); 1626 __ load_from_polling_page(polling_page); 1627 } 1628 } 1629 1630 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1631 // Variable size. Determine dynamically. 1632 return MachNode::size(ra_); 1633 } 1634 1635 int MachEpilogNode::reloc() const { 1636 // Return number of relocatable values contained in this instruction. 1637 return 1; // 1 for load_from_polling_page. 1638 } 1639 1640 const Pipeline * MachEpilogNode::pipeline() const { 1641 return MachNode::pipeline_class(); 1642 } 1643 1644 #if 0 // TODO: PPC port 1645 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1646 C2_MacroAssembler _masm(&cbuf); 1647 if (LoadPollAddressFromThread) { 1648 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1649 } else { 1650 _masm.nop(); 1651 } 1652 } 1653 1654 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1655 if (LoadPollAddressFromThread) { 1656 return 4; 1657 } else { 1658 return 4; 1659 } 1660 } 1661 1662 #ifndef PRODUCT 1663 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1664 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1665 } 1666 #endif 1667 1668 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1669 return RSCRATCH1_BITS64_REG_mask(); 1670 } 1671 #endif // PPC port 1672 1673 // ============================================================================= 1674 1675 // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or 1676 // rc_stack. 1677 enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack }; 1678 1679 static enum RC rc_class(OptoReg::Name reg) { 1680 // Return the register class for the given register. The given register 1681 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1682 // enumeration in adGlobals_ppc.hpp. 1683 1684 if (reg == OptoReg::Bad) return rc_bad; 1685 1686 // We have 64 integer register halves, starting at index 0. 1687 if (reg < 64) return rc_int; 1688 1689 // We have 64 floating-point register halves, starting at index 64. 1690 if (reg < 64+64) return rc_float; 1691 1692 // We have 64 vector-scalar registers, starting at index 128. 1693 if (reg < 64+64+64) return rc_vs; 1694 1695 // Between float regs & stack are the flags regs. 1696 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1697 1698 return rc_stack; 1699 } 1700 1701 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1702 bool do_print, Compile* C, outputStream *st) { 1703 1704 assert(opcode == Assembler::LD_OPCODE || 1705 opcode == Assembler::STD_OPCODE || 1706 opcode == Assembler::LWZ_OPCODE || 1707 opcode == Assembler::STW_OPCODE || 1708 opcode == Assembler::LFD_OPCODE || 1709 opcode == Assembler::STFD_OPCODE || 1710 opcode == Assembler::LFS_OPCODE || 1711 opcode == Assembler::STFS_OPCODE, 1712 "opcode not supported"); 1713 1714 if (cbuf) { 1715 int d = 1716 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1717 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1718 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1719 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1720 } 1721 #ifndef PRODUCT 1722 else if (do_print) { 1723 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1724 op_str, 1725 Matcher::regName[reg], 1726 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1727 } 1728 #endif 1729 return 4; // size 1730 } 1731 1732 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1733 Compile* C = ra_->C; 1734 1735 // Get registers to move. 1736 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1737 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1738 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1739 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1740 1741 enum RC src_hi_rc = rc_class(src_hi); 1742 enum RC src_lo_rc = rc_class(src_lo); 1743 enum RC dst_hi_rc = rc_class(dst_hi); 1744 enum RC dst_lo_rc = rc_class(dst_lo); 1745 1746 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1747 if (src_hi != OptoReg::Bad) 1748 assert((src_lo&1)==0 && src_lo+1==src_hi && 1749 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1750 "expected aligned-adjacent pairs"); 1751 // Generate spill code! 1752 int size = 0; 1753 1754 if (src_lo == dst_lo && src_hi == dst_hi) 1755 return size; // Self copy, no move. 1756 1757 if (bottom_type()->isa_vect() != NULL && ideal_reg() == Op_VecX) { 1758 // Memory->Memory Spill. 1759 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1760 int src_offset = ra_->reg2offset(src_lo); 1761 int dst_offset = ra_->reg2offset(dst_lo); 1762 if (cbuf) { 1763 C2_MacroAssembler _masm(cbuf); 1764 __ ld(R0, src_offset, R1_SP); 1765 __ std(R0, dst_offset, R1_SP); 1766 __ ld(R0, src_offset+8, R1_SP); 1767 __ std(R0, dst_offset+8, R1_SP); 1768 } 1769 size += 16; 1770 } 1771 // VectorSRegister->Memory Spill. 1772 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) { 1773 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1774 int dst_offset = ra_->reg2offset(dst_lo); 1775 if (cbuf) { 1776 C2_MacroAssembler _masm(cbuf); 1777 __ addi(R0, R1_SP, dst_offset); 1778 __ stxvd2x(Rsrc, R0); 1779 } 1780 size += 8; 1781 } 1782 // Memory->VectorSRegister Spill. 1783 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) { 1784 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1785 int src_offset = ra_->reg2offset(src_lo); 1786 if (cbuf) { 1787 C2_MacroAssembler _masm(cbuf); 1788 __ addi(R0, R1_SP, src_offset); 1789 __ lxvd2x(Rdst, R0); 1790 } 1791 size += 8; 1792 } 1793 // VectorSRegister->VectorSRegister. 1794 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) { 1795 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1796 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1797 if (cbuf) { 1798 C2_MacroAssembler _masm(cbuf); 1799 __ xxlor(Rdst, Rsrc, Rsrc); 1800 } 1801 size += 4; 1802 } 1803 else { 1804 ShouldNotReachHere(); // No VSR spill. 1805 } 1806 return size; 1807 } 1808 1809 // -------------------------------------- 1810 // Memory->Memory Spill. Use R0 to hold the value. 1811 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1812 int src_offset = ra_->reg2offset(src_lo); 1813 int dst_offset = ra_->reg2offset(dst_lo); 1814 if (src_hi != OptoReg::Bad) { 1815 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1816 "expected same type of move for high parts"); 1817 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1818 if (!cbuf && !do_size) st->print("\n\t"); 1819 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1820 } else { 1821 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1822 if (!cbuf && !do_size) st->print("\n\t"); 1823 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1824 } 1825 return size; 1826 } 1827 1828 // -------------------------------------- 1829 // Check for float->int copy; requires a trip through memory. 1830 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1831 Unimplemented(); 1832 } 1833 1834 // -------------------------------------- 1835 // Check for integer reg-reg copy. 1836 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1837 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1838 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1839 size = (Rsrc != Rdst) ? 4 : 0; 1840 1841 if (cbuf) { 1842 C2_MacroAssembler _masm(cbuf); 1843 if (size) { 1844 __ mr(Rdst, Rsrc); 1845 } 1846 } 1847 #ifndef PRODUCT 1848 else if (!do_size) { 1849 if (size) { 1850 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1851 } else { 1852 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1853 } 1854 } 1855 #endif 1856 return size; 1857 } 1858 1859 // Check for integer store. 1860 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1861 int dst_offset = ra_->reg2offset(dst_lo); 1862 if (src_hi != OptoReg::Bad) { 1863 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1864 "expected same type of move for high parts"); 1865 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1866 } else { 1867 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1868 } 1869 return size; 1870 } 1871 1872 // Check for integer load. 1873 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1874 int src_offset = ra_->reg2offset(src_lo); 1875 if (src_hi != OptoReg::Bad) { 1876 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1877 "expected same type of move for high parts"); 1878 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1879 } else { 1880 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1881 } 1882 return size; 1883 } 1884 1885 // Check for float reg-reg copy. 1886 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1887 if (cbuf) { 1888 C2_MacroAssembler _masm(cbuf); 1889 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1890 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1891 __ fmr(Rdst, Rsrc); 1892 } 1893 #ifndef PRODUCT 1894 else if (!do_size) { 1895 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1896 } 1897 #endif 1898 return 4; 1899 } 1900 1901 // Check for float store. 1902 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1903 int dst_offset = ra_->reg2offset(dst_lo); 1904 if (src_hi != OptoReg::Bad) { 1905 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1906 "expected same type of move for high parts"); 1907 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1908 } else { 1909 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1910 } 1911 return size; 1912 } 1913 1914 // Check for float load. 1915 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1916 int src_offset = ra_->reg2offset(src_lo); 1917 if (src_hi != OptoReg::Bad) { 1918 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1919 "expected same type of move for high parts"); 1920 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1921 } else { 1922 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1923 } 1924 return size; 1925 } 1926 1927 // -------------------------------------------------------------------- 1928 // Check for hi bits still needing moving. Only happens for misaligned 1929 // arguments to native calls. 1930 if (src_hi == dst_hi) 1931 return size; // Self copy; no move. 1932 1933 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1934 ShouldNotReachHere(); // Unimplemented 1935 return 0; 1936 } 1937 1938 #ifndef PRODUCT 1939 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1940 if (!ra_) 1941 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1942 else 1943 implementation(NULL, ra_, false, st); 1944 } 1945 #endif 1946 1947 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1948 implementation(&cbuf, ra_, false, NULL); 1949 } 1950 1951 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1952 return implementation(NULL, ra_, true, NULL); 1953 } 1954 1955 #if 0 // TODO: PPC port 1956 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1957 #ifndef PRODUCT 1958 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1959 #endif 1960 assert(ra_->node_regs_max_index() != 0, ""); 1961 1962 // Get registers to move. 1963 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1964 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1965 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1966 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1967 1968 enum RC src_lo_rc = rc_class(src_lo); 1969 enum RC dst_lo_rc = rc_class(dst_lo); 1970 1971 if (src_lo == dst_lo && src_hi == dst_hi) 1972 return ppc64Opcode_none; // Self copy, no move. 1973 1974 // -------------------------------------- 1975 // Memory->Memory Spill. Use R0 to hold the value. 1976 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1977 return ppc64Opcode_compound; 1978 } 1979 1980 // -------------------------------------- 1981 // Check for float->int copy; requires a trip through memory. 1982 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1983 Unimplemented(); 1984 } 1985 1986 // -------------------------------------- 1987 // Check for integer reg-reg copy. 1988 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1989 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1990 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1991 if (Rsrc == Rdst) { 1992 return ppc64Opcode_none; 1993 } else { 1994 return ppc64Opcode_or; 1995 } 1996 } 1997 1998 // Check for integer store. 1999 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 2000 if (src_hi != OptoReg::Bad) { 2001 return ppc64Opcode_std; 2002 } else { 2003 return ppc64Opcode_stw; 2004 } 2005 } 2006 2007 // Check for integer load. 2008 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 2009 if (src_hi != OptoReg::Bad) { 2010 return ppc64Opcode_ld; 2011 } else { 2012 return ppc64Opcode_lwz; 2013 } 2014 } 2015 2016 // Check for float reg-reg copy. 2017 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 2018 return ppc64Opcode_fmr; 2019 } 2020 2021 // Check for float store. 2022 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 2023 if (src_hi != OptoReg::Bad) { 2024 return ppc64Opcode_stfd; 2025 } else { 2026 return ppc64Opcode_stfs; 2027 } 2028 } 2029 2030 // Check for float load. 2031 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 2032 if (src_hi != OptoReg::Bad) { 2033 return ppc64Opcode_lfd; 2034 } else { 2035 return ppc64Opcode_lfs; 2036 } 2037 } 2038 2039 // -------------------------------------------------------------------- 2040 // Check for hi bits still needing moving. Only happens for misaligned 2041 // arguments to native calls. 2042 if (src_hi == dst_hi) { 2043 return ppc64Opcode_none; // Self copy; no move. 2044 } 2045 2046 ShouldNotReachHere(); 2047 return ppc64Opcode_undefined; 2048 } 2049 #endif // PPC port 2050 2051 #ifndef PRODUCT 2052 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2053 st->print("NOP \t// %d nops to pad for loops.", _count); 2054 } 2055 #endif 2056 2057 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 2058 C2_MacroAssembler _masm(&cbuf); 2059 // _count contains the number of nops needed for padding. 2060 for (int i = 0; i < _count; i++) { 2061 __ nop(); 2062 } 2063 } 2064 2065 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 2066 return _count * 4; 2067 } 2068 2069 #ifndef PRODUCT 2070 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2071 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2072 char reg_str[128]; 2073 ra_->dump_register(this, reg_str); 2074 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 2075 } 2076 #endif 2077 2078 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2079 C2_MacroAssembler _masm(&cbuf); 2080 2081 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2082 int reg = ra_->get_encode(this); 2083 2084 if (Assembler::is_simm(offset, 16)) { 2085 __ addi(as_Register(reg), R1, offset); 2086 } else { 2087 ShouldNotReachHere(); 2088 } 2089 } 2090 2091 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2092 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2093 return 4; 2094 } 2095 2096 #ifndef PRODUCT 2097 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2098 st->print_cr("---- MachUEPNode ----"); 2099 st->print_cr("..."); 2100 } 2101 #endif 2102 2103 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2104 // This is the unverified entry point. 2105 C2_MacroAssembler _masm(&cbuf); 2106 2107 // Inline_cache contains a klass. 2108 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 2109 Register receiver_klass = R12_scratch2; // tmp 2110 2111 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 2112 assert(R11_scratch1 == R11, "need prologue scratch register"); 2113 2114 // Check for NULL argument if we don't have implicit null checks. 2115 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 2116 if (TrapBasedNullChecks) { 2117 __ trap_null_check(R3_ARG1); 2118 } else { 2119 Label valid; 2120 __ cmpdi(CCR0, R3_ARG1, 0); 2121 __ bne_predict_taken(CCR0, valid); 2122 // We have a null argument, branch to ic_miss_stub. 2123 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2124 relocInfo::runtime_call_type); 2125 __ bind(valid); 2126 } 2127 } 2128 // Assume argument is not NULL, load klass from receiver. 2129 __ load_klass(receiver_klass, R3_ARG1); 2130 2131 if (TrapBasedICMissChecks) { 2132 __ trap_ic_miss_check(receiver_klass, ic_klass); 2133 } else { 2134 Label valid; 2135 __ cmpd(CCR0, receiver_klass, ic_klass); 2136 __ beq_predict_taken(CCR0, valid); 2137 // We have an unexpected klass, branch to ic_miss_stub. 2138 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2139 relocInfo::runtime_call_type); 2140 __ bind(valid); 2141 } 2142 2143 // Argument is valid and klass is as expected, continue. 2144 } 2145 2146 #if 0 // TODO: PPC port 2147 // Optimize UEP code on z (save a load_const() call in main path). 2148 int MachUEPNode::ep_offset() { 2149 return 0; 2150 } 2151 #endif 2152 2153 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2154 // Variable size. Determine dynamically. 2155 return MachNode::size(ra_); 2156 } 2157 2158 //============================================================================= 2159 2160 %} // interrupt source 2161 2162 source_hpp %{ // Header information of the source block. 2163 2164 class HandlerImpl { 2165 2166 public: 2167 2168 static int emit_exception_handler(CodeBuffer &cbuf); 2169 static int emit_deopt_handler(CodeBuffer& cbuf); 2170 2171 static uint size_exception_handler() { 2172 // The exception_handler is a b64_patchable. 2173 return MacroAssembler::b64_patchable_size; 2174 } 2175 2176 static uint size_deopt_handler() { 2177 // The deopt_handler is a bl64_patchable. 2178 return MacroAssembler::bl64_patchable_size; 2179 } 2180 2181 }; 2182 2183 class Node::PD { 2184 public: 2185 enum NodeFlags { 2186 _last_flag = Node::_last_flag 2187 }; 2188 }; 2189 2190 %} // end source_hpp 2191 2192 source %{ 2193 2194 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2195 C2_MacroAssembler _masm(&cbuf); 2196 2197 address base = __ start_a_stub(size_exception_handler()); 2198 if (base == NULL) return 0; // CodeBuffer::expand failed 2199 2200 int offset = __ offset(); 2201 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2202 relocInfo::runtime_call_type); 2203 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2204 __ end_a_stub(); 2205 2206 return offset; 2207 } 2208 2209 // The deopt_handler is like the exception handler, but it calls to 2210 // the deoptimization blob instead of jumping to the exception blob. 2211 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2212 C2_MacroAssembler _masm(&cbuf); 2213 2214 address base = __ start_a_stub(size_deopt_handler()); 2215 if (base == NULL) return 0; // CodeBuffer::expand failed 2216 2217 int offset = __ offset(); 2218 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2219 relocInfo::runtime_call_type); 2220 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2221 __ end_a_stub(); 2222 2223 return offset; 2224 } 2225 2226 //============================================================================= 2227 2228 // Use a frame slots bias for frameless methods if accessing the stack. 2229 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2230 if (as_Register(reg_enc) == R1_SP) { 2231 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2232 } 2233 return 0; 2234 } 2235 2236 const bool Matcher::match_rule_supported(int opcode) { 2237 if (!has_match_rule(opcode)) 2238 return false; 2239 2240 bool ret_value = true; 2241 switch (opcode) { 2242 case Op_SqrtD: 2243 return VM_Version::has_fsqrt(); 2244 case Op_CountLeadingZerosI: 2245 case Op_CountLeadingZerosL: 2246 if (!UseCountLeadingZerosInstructionsPPC64) 2247 return false; 2248 break; 2249 case Op_CountTrailingZerosI: 2250 case Op_CountTrailingZerosL: 2251 if (!UseCountLeadingZerosInstructionsPPC64 && 2252 !UseCountTrailingZerosInstructionsPPC64) 2253 return false; 2254 break; 2255 2256 case Op_PopCountI: 2257 case Op_PopCountL: 2258 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2259 2260 case Op_StrComp: 2261 return SpecialStringCompareTo; 2262 case Op_StrEquals: 2263 return SpecialStringEquals; 2264 case Op_StrIndexOf: 2265 case Op_StrIndexOfChar: 2266 return SpecialStringIndexOf; 2267 case Op_AddVB: 2268 case Op_AddVS: 2269 case Op_AddVI: 2270 case Op_AddVF: 2271 case Op_AddVD: 2272 case Op_SubVB: 2273 case Op_SubVS: 2274 case Op_SubVI: 2275 case Op_SubVF: 2276 case Op_SubVD: 2277 case Op_MulVS: 2278 case Op_MulVF: 2279 case Op_MulVD: 2280 case Op_DivVF: 2281 case Op_DivVD: 2282 case Op_AbsVF: 2283 case Op_AbsVD: 2284 case Op_NegVF: 2285 case Op_NegVD: 2286 case Op_SqrtVF: 2287 case Op_SqrtVD: 2288 case Op_AddVL: 2289 case Op_SubVL: 2290 case Op_MulVI: 2291 case Op_RoundDoubleModeV: 2292 return SuperwordUseVSX; 2293 case Op_PopCountVI: 2294 return (SuperwordUseVSX && UsePopCountInstruction); 2295 case Op_FmaVF: 2296 case Op_FmaVD: 2297 return (SuperwordUseVSX && UseFMA); 2298 case Op_Digit: 2299 case Op_LowerCase: 2300 case Op_UpperCase: 2301 case Op_Whitespace: 2302 return UseCharacterCompareIntrinsics; 2303 2304 case Op_CacheWB: 2305 case Op_CacheWBPreSync: 2306 case Op_CacheWBPostSync: 2307 if (!VM_Version::supports_data_cache_line_flush()) { 2308 ret_value = false; 2309 } 2310 break; 2311 } 2312 2313 return ret_value; // Per default match rules are supported. 2314 } 2315 2316 const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { 2317 2318 // TODO 2319 // identify extra cases that we might want to provide match rules for 2320 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2321 bool ret_value = match_rule_supported(opcode); 2322 // Add rules here. 2323 2324 return ret_value; // Per default match rules are supported. 2325 } 2326 2327 const bool Matcher::has_predicated_vectors(void) { 2328 return false; 2329 } 2330 2331 const int Matcher::float_pressure(int default_pressure_threshold) { 2332 return default_pressure_threshold; 2333 } 2334 2335 int Matcher::regnum_to_fpu_offset(int regnum) { 2336 // No user for this method? 2337 Unimplemented(); 2338 return 999; 2339 } 2340 2341 const bool Matcher::convL2FSupported(void) { 2342 // fcfids can do the conversion (>= Power7). 2343 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2344 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2345 } 2346 2347 // Vector width in bytes. 2348 const int Matcher::vector_width_in_bytes(BasicType bt) { 2349 if (SuperwordUseVSX) { 2350 assert(MaxVectorSize == 16, ""); 2351 return 16; 2352 } else { 2353 assert(MaxVectorSize == 8, ""); 2354 return 8; 2355 } 2356 } 2357 2358 // Vector ideal reg. 2359 const uint Matcher::vector_ideal_reg(int size) { 2360 if (SuperwordUseVSX) { 2361 assert(MaxVectorSize == 16 && size == 16, ""); 2362 return Op_VecX; 2363 } else { 2364 assert(MaxVectorSize == 8 && size == 8, ""); 2365 return Op_RegL; 2366 } 2367 } 2368 2369 // Limits on vector size (number of elements) loaded into vector. 2370 const int Matcher::max_vector_size(const BasicType bt) { 2371 assert(is_java_primitive(bt), "only primitive type vectors"); 2372 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2373 } 2374 2375 const int Matcher::min_vector_size(const BasicType bt) { 2376 return max_vector_size(bt); // Same as max. 2377 } 2378 2379 // PPC implementation uses VSX load/store instructions (if 2380 // SuperwordUseVSX) which support 4 byte but not arbitrary alignment 2381 const bool Matcher::misaligned_vectors_ok() { 2382 return false; 2383 } 2384 2385 // PPC AES support not yet implemented 2386 const bool Matcher::pass_original_key_for_aes() { 2387 return false; 2388 } 2389 2390 // RETURNS: whether this branch offset is short enough that a short 2391 // branch can be used. 2392 // 2393 // If the platform does not provide any short branch variants, then 2394 // this method should return `false' for offset 0. 2395 // 2396 // `Compile::Fill_buffer' will decide on basis of this information 2397 // whether to do the pass `Compile::Shorten_branches' at all. 2398 // 2399 // And `Compile::Shorten_branches' will decide on basis of this 2400 // information whether to replace particular branch sites by short 2401 // ones. 2402 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2403 // Is the offset within the range of a ppc64 pc relative branch? 2404 bool b; 2405 2406 const int safety_zone = 3 * BytesPerInstWord; 2407 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2408 29 - 16 + 1 + 2); 2409 return b; 2410 } 2411 2412 const bool Matcher::isSimpleConstant64(jlong value) { 2413 // Probably always true, even if a temp register is required. 2414 return true; 2415 } 2416 /* TODO: PPC port 2417 // Make a new machine dependent decode node (with its operands). 2418 MachTypeNode *Matcher::make_decode_node() { 2419 assert(CompressedOops::base() == NULL && CompressedOops::shift() == 0, 2420 "This method is only implemented for unscaled cOops mode so far"); 2421 MachTypeNode *decode = new decodeN_unscaledNode(); 2422 decode->set_opnd_array(0, new iRegPdstOper()); 2423 decode->set_opnd_array(1, new iRegNsrcOper()); 2424 return decode; 2425 } 2426 */ 2427 2428 // false => size gets scaled to BytesPerLong, ok. 2429 const bool Matcher::init_array_count_is_in_bytes = false; 2430 2431 // Use conditional move (CMOVL) on Power7. 2432 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2433 2434 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2435 // fsel doesn't accept a condition register as input, so this would be slightly different. 2436 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2437 2438 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2439 const bool Matcher::require_postalloc_expand = true; 2440 2441 // Do we need to mask the count passed to shift instructions or does 2442 // the cpu only look at the lower 5/6 bits anyway? 2443 // PowerPC requires masked shift counts. 2444 const bool Matcher::need_masked_shift_count = true; 2445 2446 // No support for generic vector operands. 2447 const bool Matcher::supports_generic_vector_operands = false; 2448 2449 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { 2450 ShouldNotReachHere(); // generic vector operands not supported 2451 return NULL; 2452 } 2453 2454 bool Matcher::is_generic_reg2reg_move(MachNode* m) { 2455 ShouldNotReachHere(); // generic vector operands not supported 2456 return false; 2457 } 2458 2459 bool Matcher::is_generic_vector(MachOper* opnd) { 2460 ShouldNotReachHere(); // generic vector operands not supported 2461 return false; 2462 } 2463 2464 // This affects two different things: 2465 // - how Decode nodes are matched 2466 // - how ImplicitNullCheck opportunities are recognized 2467 // If true, the matcher will try to remove all Decodes and match them 2468 // (as operands) into nodes. NullChecks are not prepared to deal with 2469 // Decodes by final_graph_reshaping(). 2470 // If false, final_graph_reshaping() forces the decode behind the Cmp 2471 // for a NullCheck. The matcher matches the Decode node into a register. 2472 // Implicit_null_check optimization moves the Decode along with the 2473 // memory operation back up before the NullCheck. 2474 bool Matcher::narrow_oop_use_complex_address() { 2475 // TODO: PPC port if (MatchDecodeNodes) return true; 2476 return false; 2477 } 2478 2479 bool Matcher::narrow_klass_use_complex_address() { 2480 NOT_LP64(ShouldNotCallThis()); 2481 assert(UseCompressedClassPointers, "only for compressed klass code"); 2482 // TODO: PPC port if (MatchDecodeNodes) return true; 2483 return false; 2484 } 2485 2486 bool Matcher::const_oop_prefer_decode() { 2487 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2488 return CompressedOops::base() == NULL; 2489 } 2490 2491 bool Matcher::const_klass_prefer_decode() { 2492 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2493 return CompressedKlassPointers::base() == NULL; 2494 } 2495 2496 // Is it better to copy float constants, or load them directly from memory? 2497 // Intel can load a float constant from a direct address, requiring no 2498 // extra registers. Most RISCs will have to materialize an address into a 2499 // register first, so they would do better to copy the constant from stack. 2500 const bool Matcher::rematerialize_float_constants = false; 2501 2502 // If CPU can load and store mis-aligned doubles directly then no fixup is 2503 // needed. Else we split the double into 2 integer pieces and move it 2504 // piece-by-piece. Only happens when passing doubles into C code as the 2505 // Java calling convention forces doubles to be aligned. 2506 const bool Matcher::misaligned_doubles_ok = true; 2507 2508 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2509 Unimplemented(); 2510 } 2511 2512 // Advertise here if the CPU requires explicit rounding operations to implement strictfp mode. 2513 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2514 2515 // Do floats take an entire double register or just half? 2516 // 2517 // A float occupies a ppc64 double register. For the allocator, a 2518 // ppc64 double register appears as a pair of float registers. 2519 bool Matcher::float_in_double() { return true; } 2520 2521 // Do ints take an entire long register or just half? 2522 // The relevant question is how the int is callee-saved: 2523 // the whole long is written but de-opt'ing will have to extract 2524 // the relevant 32 bits. 2525 const bool Matcher::int_in_long = true; 2526 2527 // Constants for c2c and c calling conventions. 2528 2529 const MachRegisterNumbers iarg_reg[8] = { 2530 R3_num, R4_num, R5_num, R6_num, 2531 R7_num, R8_num, R9_num, R10_num 2532 }; 2533 2534 const MachRegisterNumbers farg_reg[13] = { 2535 F1_num, F2_num, F3_num, F4_num, 2536 F5_num, F6_num, F7_num, F8_num, 2537 F9_num, F10_num, F11_num, F12_num, 2538 F13_num 2539 }; 2540 2541 const MachRegisterNumbers vsarg_reg[64] = { 2542 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2543 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2544 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2545 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2546 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2547 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2548 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2549 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2550 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2551 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2552 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2553 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2554 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2555 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2556 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2557 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2558 }; 2559 2560 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2561 2562 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2563 2564 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2565 2566 // Return whether or not this register is ever used as an argument. This 2567 // function is used on startup to build the trampoline stubs in generateOptoStub. 2568 // Registers not mentioned will be killed by the VM call in the trampoline, and 2569 // arguments in those registers not be available to the callee. 2570 bool Matcher::can_be_java_arg(int reg) { 2571 // We return true for all registers contained in iarg_reg[] and 2572 // farg_reg[] and their virtual halves. 2573 // We must include the virtual halves in order to get STDs and LDs 2574 // instead of STWs and LWs in the trampoline stubs. 2575 2576 if ( reg == R3_num || reg == R3_H_num 2577 || reg == R4_num || reg == R4_H_num 2578 || reg == R5_num || reg == R5_H_num 2579 || reg == R6_num || reg == R6_H_num 2580 || reg == R7_num || reg == R7_H_num 2581 || reg == R8_num || reg == R8_H_num 2582 || reg == R9_num || reg == R9_H_num 2583 || reg == R10_num || reg == R10_H_num) 2584 return true; 2585 2586 if ( reg == F1_num || reg == F1_H_num 2587 || reg == F2_num || reg == F2_H_num 2588 || reg == F3_num || reg == F3_H_num 2589 || reg == F4_num || reg == F4_H_num 2590 || reg == F5_num || reg == F5_H_num 2591 || reg == F6_num || reg == F6_H_num 2592 || reg == F7_num || reg == F7_H_num 2593 || reg == F8_num || reg == F8_H_num 2594 || reg == F9_num || reg == F9_H_num 2595 || reg == F10_num || reg == F10_H_num 2596 || reg == F11_num || reg == F11_H_num 2597 || reg == F12_num || reg == F12_H_num 2598 || reg == F13_num || reg == F13_H_num) 2599 return true; 2600 2601 return false; 2602 } 2603 2604 bool Matcher::is_spillable_arg(int reg) { 2605 return can_be_java_arg(reg); 2606 } 2607 2608 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2609 return false; 2610 } 2611 2612 // Register for DIVI projection of divmodI. 2613 RegMask Matcher::divI_proj_mask() { 2614 ShouldNotReachHere(); 2615 return RegMask(); 2616 } 2617 2618 // Register for MODI projection of divmodI. 2619 RegMask Matcher::modI_proj_mask() { 2620 ShouldNotReachHere(); 2621 return RegMask(); 2622 } 2623 2624 // Register for DIVL projection of divmodL. 2625 RegMask Matcher::divL_proj_mask() { 2626 ShouldNotReachHere(); 2627 return RegMask(); 2628 } 2629 2630 // Register for MODL projection of divmodL. 2631 RegMask Matcher::modL_proj_mask() { 2632 ShouldNotReachHere(); 2633 return RegMask(); 2634 } 2635 2636 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2637 return RegMask(); 2638 } 2639 2640 const bool Matcher::convi2l_type_required = true; 2641 2642 %} 2643 2644 //----------ENCODING BLOCK----------------------------------------------------- 2645 // This block specifies the encoding classes used by the compiler to output 2646 // byte streams. Encoding classes are parameterized macros used by 2647 // Machine Instruction Nodes in order to generate the bit encoding of the 2648 // instruction. Operands specify their base encoding interface with the 2649 // interface keyword. There are currently supported four interfaces, 2650 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2651 // operand to generate a function which returns its register number when 2652 // queried. CONST_INTER causes an operand to generate a function which 2653 // returns the value of the constant when queried. MEMORY_INTER causes an 2654 // operand to generate four functions which return the Base Register, the 2655 // Index Register, the Scale Value, and the Offset Value of the operand when 2656 // queried. COND_INTER causes an operand to generate six functions which 2657 // return the encoding code (ie - encoding bits for the instruction) 2658 // associated with each basic boolean condition for a conditional instruction. 2659 // 2660 // Instructions specify two basic values for encoding. Again, a function 2661 // is available to check if the constant displacement is an oop. They use the 2662 // ins_encode keyword to specify their encoding classes (which must be 2663 // a sequence of enc_class names, and their parameters, specified in 2664 // the encoding block), and they use the 2665 // opcode keyword to specify, in order, their primary, secondary, and 2666 // tertiary opcode. Only the opcode sections which a particular instruction 2667 // needs for encoding need to be specified. 2668 encode %{ 2669 enc_class enc_unimplemented %{ 2670 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2671 C2_MacroAssembler _masm(&cbuf); 2672 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2673 %} 2674 2675 enc_class enc_untested %{ 2676 #ifdef ASSERT 2677 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2678 C2_MacroAssembler _masm(&cbuf); 2679 __ untested("Untested mach node encoding in AD file."); 2680 #else 2681 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2682 #endif 2683 %} 2684 2685 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2686 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2687 C2_MacroAssembler _masm(&cbuf); 2688 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2689 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2690 %} 2691 2692 // Load acquire. 2693 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2694 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2695 C2_MacroAssembler _masm(&cbuf); 2696 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2697 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2698 __ twi_0($dst$$Register); 2699 __ isync(); 2700 %} 2701 2702 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2703 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2704 2705 C2_MacroAssembler _masm(&cbuf); 2706 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2707 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2708 %} 2709 2710 // Load acquire. 2711 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2712 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2713 2714 C2_MacroAssembler _masm(&cbuf); 2715 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2716 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2717 __ twi_0($dst$$Register); 2718 __ isync(); 2719 %} 2720 2721 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2722 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2723 2724 C2_MacroAssembler _masm(&cbuf); 2725 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2726 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2727 %} 2728 2729 // Load acquire. 2730 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2731 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2732 2733 C2_MacroAssembler _masm(&cbuf); 2734 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2735 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2736 __ twi_0($dst$$Register); 2737 __ isync(); 2738 %} 2739 2740 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2741 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2742 C2_MacroAssembler _masm(&cbuf); 2743 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2744 // Operand 'ds' requires 4-alignment. 2745 assert((Idisp & 0x3) == 0, "unaligned offset"); 2746 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2747 %} 2748 2749 // Load acquire. 2750 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2751 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2752 C2_MacroAssembler _masm(&cbuf); 2753 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2754 // Operand 'ds' requires 4-alignment. 2755 assert((Idisp & 0x3) == 0, "unaligned offset"); 2756 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2757 __ twi_0($dst$$Register); 2758 __ isync(); 2759 %} 2760 2761 enc_class enc_lfd(RegF dst, memory mem) %{ 2762 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2763 C2_MacroAssembler _masm(&cbuf); 2764 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2765 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2766 %} 2767 2768 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2769 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2770 2771 C2_MacroAssembler _masm(&cbuf); 2772 int toc_offset = 0; 2773 2774 address const_toc_addr; 2775 // Create a non-oop constant, no relocation needed. 2776 // If it is an IC, it has a virtual_call_Relocation. 2777 const_toc_addr = __ long_constant((jlong)$src$$constant); 2778 if (const_toc_addr == NULL) { 2779 ciEnv::current()->record_out_of_memory_failure(); 2780 return; 2781 } 2782 2783 // Get the constant's TOC offset. 2784 toc_offset = __ offset_to_method_toc(const_toc_addr); 2785 2786 // Keep the current instruction offset in mind. 2787 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2788 2789 __ ld($dst$$Register, toc_offset, $toc$$Register); 2790 %} 2791 2792 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2793 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2794 2795 C2_MacroAssembler _masm(&cbuf); 2796 2797 if (!ra_->C->output()->in_scratch_emit_size()) { 2798 address const_toc_addr; 2799 // Create a non-oop constant, no relocation needed. 2800 // If it is an IC, it has a virtual_call_Relocation. 2801 const_toc_addr = __ long_constant((jlong)$src$$constant); 2802 if (const_toc_addr == NULL) { 2803 ciEnv::current()->record_out_of_memory_failure(); 2804 return; 2805 } 2806 2807 // Get the constant's TOC offset. 2808 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2809 // Store the toc offset of the constant. 2810 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2811 2812 // Also keep the current instruction offset in mind. 2813 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2814 } 2815 2816 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2817 %} 2818 2819 %} // encode 2820 2821 source %{ 2822 2823 typedef struct { 2824 loadConL_hiNode *_large_hi; 2825 loadConL_loNode *_large_lo; 2826 loadConLNode *_small; 2827 MachNode *_last; 2828 } loadConLNodesTuple; 2829 2830 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2831 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2832 loadConLNodesTuple nodes; 2833 2834 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2835 if (large_constant_pool) { 2836 // Create new nodes. 2837 loadConL_hiNode *m1 = new loadConL_hiNode(); 2838 loadConL_loNode *m2 = new loadConL_loNode(); 2839 2840 // inputs for new nodes 2841 m1->add_req(NULL, toc); 2842 m2->add_req(NULL, m1); 2843 2844 // operands for new nodes 2845 m1->_opnds[0] = new iRegLdstOper(); // dst 2846 m1->_opnds[1] = immSrc; // src 2847 m1->_opnds[2] = new iRegPdstOper(); // toc 2848 m2->_opnds[0] = new iRegLdstOper(); // dst 2849 m2->_opnds[1] = immSrc; // src 2850 m2->_opnds[2] = new iRegLdstOper(); // base 2851 2852 // Initialize ins_attrib TOC fields. 2853 m1->_const_toc_offset = -1; 2854 m2->_const_toc_offset_hi_node = m1; 2855 2856 // Initialize ins_attrib instruction offset. 2857 m1->_cbuf_insts_offset = -1; 2858 2859 // register allocation for new nodes 2860 ra_->set_pair(m1->_idx, reg_second, reg_first); 2861 ra_->set_pair(m2->_idx, reg_second, reg_first); 2862 2863 // Create result. 2864 nodes._large_hi = m1; 2865 nodes._large_lo = m2; 2866 nodes._small = NULL; 2867 nodes._last = nodes._large_lo; 2868 assert(m2->bottom_type()->isa_long(), "must be long"); 2869 } else { 2870 loadConLNode *m2 = new loadConLNode(); 2871 2872 // inputs for new nodes 2873 m2->add_req(NULL, toc); 2874 2875 // operands for new nodes 2876 m2->_opnds[0] = new iRegLdstOper(); // dst 2877 m2->_opnds[1] = immSrc; // src 2878 m2->_opnds[2] = new iRegPdstOper(); // toc 2879 2880 // Initialize ins_attrib instruction offset. 2881 m2->_cbuf_insts_offset = -1; 2882 2883 // register allocation for new nodes 2884 ra_->set_pair(m2->_idx, reg_second, reg_first); 2885 2886 // Create result. 2887 nodes._large_hi = NULL; 2888 nodes._large_lo = NULL; 2889 nodes._small = m2; 2890 nodes._last = nodes._small; 2891 assert(m2->bottom_type()->isa_long(), "must be long"); 2892 } 2893 2894 return nodes; 2895 } 2896 2897 typedef struct { 2898 loadConL_hiNode *_large_hi; 2899 loadConL_loNode *_large_lo; 2900 mtvsrdNode *_moved; 2901 xxspltdNode *_replicated; 2902 loadConLNode *_small; 2903 MachNode *_last; 2904 } loadConLReplicatedNodesTuple; 2905 2906 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2907 vecXOper *dst, immI_0Oper *zero, 2908 OptoReg::Name reg_second, OptoReg::Name reg_first, 2909 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2910 loadConLReplicatedNodesTuple nodes; 2911 2912 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2913 if (large_constant_pool) { 2914 // Create new nodes. 2915 loadConL_hiNode *m1 = new loadConL_hiNode(); 2916 loadConL_loNode *m2 = new loadConL_loNode(); 2917 mtvsrdNode *m3 = new mtvsrdNode(); 2918 xxspltdNode *m4 = new xxspltdNode(); 2919 2920 // inputs for new nodes 2921 m1->add_req(NULL, toc); 2922 m2->add_req(NULL, m1); 2923 m3->add_req(NULL, m2); 2924 m4->add_req(NULL, m3); 2925 2926 // operands for new nodes 2927 m1->_opnds[0] = new iRegLdstOper(); // dst 2928 m1->_opnds[1] = immSrc; // src 2929 m1->_opnds[2] = new iRegPdstOper(); // toc 2930 2931 m2->_opnds[0] = new iRegLdstOper(); // dst 2932 m2->_opnds[1] = immSrc; // src 2933 m2->_opnds[2] = new iRegLdstOper(); // base 2934 2935 m3->_opnds[0] = new vecXOper(); // dst 2936 m3->_opnds[1] = new iRegLdstOper(); // src 2937 2938 m4->_opnds[0] = new vecXOper(); // dst 2939 m4->_opnds[1] = new vecXOper(); // src 2940 m4->_opnds[2] = zero; 2941 2942 // Initialize ins_attrib TOC fields. 2943 m1->_const_toc_offset = -1; 2944 m2->_const_toc_offset_hi_node = m1; 2945 2946 // Initialize ins_attrib instruction offset. 2947 m1->_cbuf_insts_offset = -1; 2948 2949 // register allocation for new nodes 2950 ra_->set_pair(m1->_idx, reg_second, reg_first); 2951 ra_->set_pair(m2->_idx, reg_second, reg_first); 2952 ra_->set1(m3->_idx, reg_second); 2953 ra_->set2(m3->_idx, reg_vec_first); 2954 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2955 2956 // Create result. 2957 nodes._large_hi = m1; 2958 nodes._large_lo = m2; 2959 nodes._moved = m3; 2960 nodes._replicated = m4; 2961 nodes._small = NULL; 2962 nodes._last = nodes._replicated; 2963 assert(m2->bottom_type()->isa_long(), "must be long"); 2964 } else { 2965 loadConLNode *m2 = new loadConLNode(); 2966 mtvsrdNode *m3 = new mtvsrdNode(); 2967 xxspltdNode *m4 = new xxspltdNode(); 2968 2969 // inputs for new nodes 2970 m2->add_req(NULL, toc); 2971 2972 // operands for new nodes 2973 m2->_opnds[0] = new iRegLdstOper(); // dst 2974 m2->_opnds[1] = immSrc; // src 2975 m2->_opnds[2] = new iRegPdstOper(); // toc 2976 2977 m3->_opnds[0] = new vecXOper(); // dst 2978 m3->_opnds[1] = new iRegLdstOper(); // src 2979 2980 m4->_opnds[0] = new vecXOper(); // dst 2981 m4->_opnds[1] = new vecXOper(); // src 2982 m4->_opnds[2] = zero; 2983 2984 // Initialize ins_attrib instruction offset. 2985 m2->_cbuf_insts_offset = -1; 2986 ra_->set1(m3->_idx, reg_second); 2987 ra_->set2(m3->_idx, reg_vec_first); 2988 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2989 2990 // register allocation for new nodes 2991 ra_->set_pair(m2->_idx, reg_second, reg_first); 2992 2993 // Create result. 2994 nodes._large_hi = NULL; 2995 nodes._large_lo = NULL; 2996 nodes._small = m2; 2997 nodes._moved = m3; 2998 nodes._replicated = m4; 2999 nodes._last = nodes._replicated; 3000 assert(m2->bottom_type()->isa_long(), "must be long"); 3001 } 3002 3003 return nodes; 3004 } 3005 3006 %} // source 3007 3008 encode %{ 3009 // Postalloc expand emitter for loading a long constant from the method's TOC. 3010 // Enc_class needed as consttanttablebase is not supported by postalloc 3011 // expand. 3012 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 3013 // Create new nodes. 3014 loadConLNodesTuple loadConLNodes = 3015 loadConLNodesTuple_create(ra_, n_toc, op_src, 3016 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3017 3018 // Push new nodes. 3019 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3020 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3021 3022 // some asserts 3023 assert(nodes->length() >= 1, "must have created at least 1 node"); 3024 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3025 %} 3026 3027 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 3028 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3029 3030 C2_MacroAssembler _masm(&cbuf); 3031 int toc_offset = 0; 3032 3033 intptr_t val = $src$$constant; 3034 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 3035 address const_toc_addr; 3036 if (constant_reloc == relocInfo::oop_type) { 3037 // Create an oop constant and a corresponding relocation. 3038 AddressLiteral a = __ allocate_oop_address((jobject)val); 3039 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3040 __ relocate(a.rspec()); 3041 } else if (constant_reloc == relocInfo::metadata_type) { 3042 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 3043 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3044 __ relocate(a.rspec()); 3045 } else { 3046 // Create a non-oop constant, no relocation needed. 3047 const_toc_addr = __ long_constant((jlong)$src$$constant); 3048 } 3049 3050 if (const_toc_addr == NULL) { 3051 ciEnv::current()->record_out_of_memory_failure(); 3052 return; 3053 } 3054 // Get the constant's TOC offset. 3055 toc_offset = __ offset_to_method_toc(const_toc_addr); 3056 3057 __ ld($dst$$Register, toc_offset, $toc$$Register); 3058 %} 3059 3060 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 3061 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 3062 3063 C2_MacroAssembler _masm(&cbuf); 3064 if (!ra_->C->output()->in_scratch_emit_size()) { 3065 intptr_t val = $src$$constant; 3066 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 3067 address const_toc_addr; 3068 if (constant_reloc == relocInfo::oop_type) { 3069 // Create an oop constant and a corresponding relocation. 3070 AddressLiteral a = __ allocate_oop_address((jobject)val); 3071 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3072 __ relocate(a.rspec()); 3073 } else if (constant_reloc == relocInfo::metadata_type) { 3074 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 3075 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3076 __ relocate(a.rspec()); 3077 } else { // non-oop pointers, e.g. card mark base, heap top 3078 // Create a non-oop constant, no relocation needed. 3079 const_toc_addr = __ long_constant((jlong)$src$$constant); 3080 } 3081 3082 if (const_toc_addr == NULL) { 3083 ciEnv::current()->record_out_of_memory_failure(); 3084 return; 3085 } 3086 // Get the constant's TOC offset. 3087 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 3088 // Store the toc offset of the constant. 3089 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 3090 } 3091 3092 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 3093 %} 3094 3095 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 3096 // Enc_class needed as consttanttablebase is not supported by postalloc 3097 // expand. 3098 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 3099 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3100 if (large_constant_pool) { 3101 // Create new nodes. 3102 loadConP_hiNode *m1 = new loadConP_hiNode(); 3103 loadConP_loNode *m2 = new loadConP_loNode(); 3104 3105 // inputs for new nodes 3106 m1->add_req(NULL, n_toc); 3107 m2->add_req(NULL, m1); 3108 3109 // operands for new nodes 3110 m1->_opnds[0] = new iRegPdstOper(); // dst 3111 m1->_opnds[1] = op_src; // src 3112 m1->_opnds[2] = new iRegPdstOper(); // toc 3113 m2->_opnds[0] = new iRegPdstOper(); // dst 3114 m2->_opnds[1] = op_src; // src 3115 m2->_opnds[2] = new iRegLdstOper(); // base 3116 3117 // Initialize ins_attrib TOC fields. 3118 m1->_const_toc_offset = -1; 3119 m2->_const_toc_offset_hi_node = m1; 3120 3121 // Register allocation for new nodes. 3122 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3123 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3124 3125 nodes->push(m1); 3126 nodes->push(m2); 3127 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3128 } else { 3129 loadConPNode *m2 = new loadConPNode(); 3130 3131 // inputs for new nodes 3132 m2->add_req(NULL, n_toc); 3133 3134 // operands for new nodes 3135 m2->_opnds[0] = new iRegPdstOper(); // dst 3136 m2->_opnds[1] = op_src; // src 3137 m2->_opnds[2] = new iRegPdstOper(); // toc 3138 3139 // Register allocation for new nodes. 3140 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3141 3142 nodes->push(m2); 3143 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3144 } 3145 %} 3146 3147 // Enc_class needed as consttanttablebase is not supported by postalloc 3148 // expand. 3149 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3150 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3151 3152 MachNode *m2; 3153 if (large_constant_pool) { 3154 m2 = new loadConFCompNode(); 3155 } else { 3156 m2 = new loadConFNode(); 3157 } 3158 // inputs for new nodes 3159 m2->add_req(NULL, n_toc); 3160 3161 // operands for new nodes 3162 m2->_opnds[0] = op_dst; 3163 m2->_opnds[1] = op_src; 3164 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3165 3166 // register allocation for new nodes 3167 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3168 nodes->push(m2); 3169 %} 3170 3171 // Enc_class needed as consttanttablebase is not supported by postalloc 3172 // expand. 3173 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3174 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3175 3176 MachNode *m2; 3177 if (large_constant_pool) { 3178 m2 = new loadConDCompNode(); 3179 } else { 3180 m2 = new loadConDNode(); 3181 } 3182 // inputs for new nodes 3183 m2->add_req(NULL, n_toc); 3184 3185 // operands for new nodes 3186 m2->_opnds[0] = op_dst; 3187 m2->_opnds[1] = op_src; 3188 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3189 3190 // register allocation for new nodes 3191 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3192 nodes->push(m2); 3193 %} 3194 3195 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3196 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3197 C2_MacroAssembler _masm(&cbuf); 3198 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3199 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3200 %} 3201 3202 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3203 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3204 C2_MacroAssembler _masm(&cbuf); 3205 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3206 // Operand 'ds' requires 4-alignment. 3207 assert((Idisp & 0x3) == 0, "unaligned offset"); 3208 __ std($src$$Register, Idisp, $mem$$base$$Register); 3209 %} 3210 3211 enc_class enc_stfs(RegF src, memory mem) %{ 3212 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3213 C2_MacroAssembler _masm(&cbuf); 3214 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3215 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3216 %} 3217 3218 enc_class enc_stfd(RegF src, memory mem) %{ 3219 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3220 C2_MacroAssembler _masm(&cbuf); 3221 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3222 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3223 %} 3224 3225 // Use release_store for card-marking to ensure that previous 3226 // oop-stores are visible before the card-mark change. 3227 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3228 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3229 // FIXME: Implement this as a cmove and use a fixed condition code 3230 // register which is written on every transition to compiled code, 3231 // e.g. in call-stub and when returning from runtime stubs. 3232 // 3233 // Proposed code sequence for the cmove implementation: 3234 // 3235 // Label skip_release; 3236 // __ beq(CCRfixed, skip_release); 3237 // __ release(); 3238 // __ bind(skip_release); 3239 // __ stb(card mark); 3240 3241 C2_MacroAssembler _masm(&cbuf); 3242 Label skip_storestore; 3243 3244 #if 0 // TODO: PPC port 3245 // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the 3246 // StoreStore barrier conditionally. 3247 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3248 __ cmpwi($crx$$CondRegister, R0, 0); 3249 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3250 #endif 3251 __ li(R0, 0); 3252 __ membar(Assembler::StoreStore); 3253 #if 0 // TODO: PPC port 3254 __ bind(skip_storestore); 3255 #endif 3256 3257 // Do the store. 3258 if ($mem$$index == 0) { 3259 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3260 } else { 3261 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3262 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3263 } 3264 %} 3265 3266 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3267 3268 if (VM_Version::has_isel()) { 3269 // use isel instruction with Power 7 3270 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3271 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3272 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3273 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3274 3275 n_compare->add_req(n_region, n_src); 3276 n_compare->_opnds[0] = op_crx; 3277 n_compare->_opnds[1] = op_src; 3278 n_compare->_opnds[2] = new immL16Oper(0); 3279 3280 n_sub_base->add_req(n_region, n_src); 3281 n_sub_base->_opnds[0] = op_dst; 3282 n_sub_base->_opnds[1] = op_src; 3283 n_sub_base->_bottom_type = _bottom_type; 3284 3285 n_shift->add_req(n_region, n_sub_base); 3286 n_shift->_opnds[0] = op_dst; 3287 n_shift->_opnds[1] = op_dst; 3288 n_shift->_bottom_type = _bottom_type; 3289 3290 n_cond_set->add_req(n_region, n_compare, n_shift); 3291 n_cond_set->_opnds[0] = op_dst; 3292 n_cond_set->_opnds[1] = op_crx; 3293 n_cond_set->_opnds[2] = op_dst; 3294 n_cond_set->_bottom_type = _bottom_type; 3295 3296 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3297 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3298 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3299 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3300 3301 nodes->push(n_compare); 3302 nodes->push(n_sub_base); 3303 nodes->push(n_shift); 3304 nodes->push(n_cond_set); 3305 3306 } else { 3307 // before Power 7 3308 moveRegNode *n_move = new moveRegNode(); 3309 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3310 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3311 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3312 3313 n_move->add_req(n_region, n_src); 3314 n_move->_opnds[0] = op_dst; 3315 n_move->_opnds[1] = op_src; 3316 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3317 3318 n_compare->add_req(n_region, n_src); 3319 n_compare->add_prec(n_move); 3320 3321 n_compare->_opnds[0] = op_crx; 3322 n_compare->_opnds[1] = op_src; 3323 n_compare->_opnds[2] = new immL16Oper(0); 3324 3325 n_sub_base->add_req(n_region, n_compare, n_src); 3326 n_sub_base->_opnds[0] = op_dst; 3327 n_sub_base->_opnds[1] = op_crx; 3328 n_sub_base->_opnds[2] = op_src; 3329 n_sub_base->_bottom_type = _bottom_type; 3330 3331 n_shift->add_req(n_region, n_sub_base); 3332 n_shift->_opnds[0] = op_dst; 3333 n_shift->_opnds[1] = op_dst; 3334 n_shift->_bottom_type = _bottom_type; 3335 3336 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3337 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3338 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3339 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3340 3341 nodes->push(n_move); 3342 nodes->push(n_compare); 3343 nodes->push(n_sub_base); 3344 nodes->push(n_shift); 3345 } 3346 3347 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3348 %} 3349 3350 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3351 3352 encodeP_subNode *n1 = new encodeP_subNode(); 3353 n1->add_req(n_region, n_src); 3354 n1->_opnds[0] = op_dst; 3355 n1->_opnds[1] = op_src; 3356 n1->_bottom_type = _bottom_type; 3357 3358 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3359 n2->add_req(n_region, n1); 3360 n2->_opnds[0] = op_dst; 3361 n2->_opnds[1] = op_dst; 3362 n2->_bottom_type = _bottom_type; 3363 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3364 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3365 3366 nodes->push(n1); 3367 nodes->push(n2); 3368 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3369 %} 3370 3371 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3372 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3373 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3374 3375 n_compare->add_req(n_region, n_src); 3376 n_compare->_opnds[0] = op_crx; 3377 n_compare->_opnds[1] = op_src; 3378 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3379 3380 n_shift->add_req(n_region, n_src); 3381 n_shift->_opnds[0] = op_dst; 3382 n_shift->_opnds[1] = op_src; 3383 n_shift->_bottom_type = _bottom_type; 3384 3385 if (VM_Version::has_isel()) { 3386 // use isel instruction with Power 7 3387 3388 decodeN_addNode *n_add_base = new decodeN_addNode(); 3389 n_add_base->add_req(n_region, n_shift); 3390 n_add_base->_opnds[0] = op_dst; 3391 n_add_base->_opnds[1] = op_dst; 3392 n_add_base->_bottom_type = _bottom_type; 3393 3394 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3395 n_cond_set->add_req(n_region, n_compare, n_add_base); 3396 n_cond_set->_opnds[0] = op_dst; 3397 n_cond_set->_opnds[1] = op_crx; 3398 n_cond_set->_opnds[2] = op_dst; 3399 n_cond_set->_bottom_type = _bottom_type; 3400 3401 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3402 ra_->set_oop(n_cond_set, true); 3403 3404 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3405 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3406 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3407 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3408 3409 nodes->push(n_compare); 3410 nodes->push(n_shift); 3411 nodes->push(n_add_base); 3412 nodes->push(n_cond_set); 3413 3414 } else { 3415 // before Power 7 3416 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3417 3418 n_add_base->add_req(n_region, n_compare, n_shift); 3419 n_add_base->_opnds[0] = op_dst; 3420 n_add_base->_opnds[1] = op_crx; 3421 n_add_base->_opnds[2] = op_dst; 3422 n_add_base->_bottom_type = _bottom_type; 3423 3424 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3425 ra_->set_oop(n_add_base, true); 3426 3427 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3428 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3429 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3430 3431 nodes->push(n_compare); 3432 nodes->push(n_shift); 3433 nodes->push(n_add_base); 3434 } 3435 %} 3436 3437 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3438 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3439 n1->add_req(n_region, n_src); 3440 n1->_opnds[0] = op_dst; 3441 n1->_opnds[1] = op_src; 3442 n1->_bottom_type = _bottom_type; 3443 3444 decodeN_addNode *n2 = new decodeN_addNode(); 3445 n2->add_req(n_region, n1); 3446 n2->_opnds[0] = op_dst; 3447 n2->_opnds[1] = op_dst; 3448 n2->_bottom_type = _bottom_type; 3449 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3450 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3451 3452 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3453 ra_->set_oop(n2, true); 3454 3455 nodes->push(n1); 3456 nodes->push(n2); 3457 %} 3458 3459 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3460 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3461 3462 C2_MacroAssembler _masm(&cbuf); 3463 int cc = $cmp$$cmpcode; 3464 int flags_reg = $crx$$reg; 3465 Label done; 3466 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3467 // Branch if not (cmp crx). 3468 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3469 __ mr($dst$$Register, $src$$Register); 3470 // TODO PPC port __ endgroup_if_needed(_size == 12); 3471 __ bind(done); 3472 %} 3473 3474 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3475 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3476 3477 C2_MacroAssembler _masm(&cbuf); 3478 Label done; 3479 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3480 // Branch if not (cmp crx). 3481 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3482 __ li($dst$$Register, $src$$constant); 3483 // TODO PPC port __ endgroup_if_needed(_size == 12); 3484 __ bind(done); 3485 %} 3486 3487 // This enc_class is needed so that scheduler gets proper 3488 // input mapping for latency computation. 3489 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3490 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3491 C2_MacroAssembler _masm(&cbuf); 3492 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3493 %} 3494 3495 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3496 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3497 3498 C2_MacroAssembler _masm(&cbuf); 3499 3500 Label done; 3501 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3502 __ li($dst$$Register, $zero$$constant); 3503 __ beq($crx$$CondRegister, done); 3504 __ li($dst$$Register, $notzero$$constant); 3505 __ bind(done); 3506 %} 3507 3508 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3509 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3510 3511 C2_MacroAssembler _masm(&cbuf); 3512 3513 Label done; 3514 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3515 __ li($dst$$Register, $zero$$constant); 3516 __ beq($crx$$CondRegister, done); 3517 __ li($dst$$Register, $notzero$$constant); 3518 __ bind(done); 3519 %} 3520 3521 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3522 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3523 3524 C2_MacroAssembler _masm(&cbuf); 3525 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3526 Label done; 3527 __ bso($crx$$CondRegister, done); 3528 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3529 // TODO PPC port __ endgroup_if_needed(_size == 12); 3530 __ bind(done); 3531 %} 3532 3533 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3534 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3535 3536 C2_MacroAssembler _masm(&cbuf); 3537 Label done; 3538 __ bso($crx$$CondRegister, done); 3539 __ mffprd($dst$$Register, $src$$FloatRegister); 3540 // TODO PPC port __ endgroup_if_needed(_size == 12); 3541 __ bind(done); 3542 %} 3543 3544 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3545 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3546 3547 C2_MacroAssembler _masm(&cbuf); 3548 Label d; // dummy 3549 __ bind(d); 3550 Label* p = ($lbl$$label); 3551 // `p' is `NULL' when this encoding class is used only to 3552 // determine the size of the encoded instruction. 3553 Label& l = (NULL == p)? d : *(p); 3554 int cc = $cmp$$cmpcode; 3555 int flags_reg = $crx$$reg; 3556 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3557 int bhint = Assembler::bhintNoHint; 3558 3559 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3560 if (_prob <= PROB_NEVER) { 3561 bhint = Assembler::bhintIsNotTaken; 3562 } else if (_prob >= PROB_ALWAYS) { 3563 bhint = Assembler::bhintIsTaken; 3564 } 3565 } 3566 3567 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3568 cc_to_biint(cc, flags_reg), 3569 l); 3570 %} 3571 3572 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3573 // The scheduler doesn't know about branch shortening, so we set the opcode 3574 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3575 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3576 3577 C2_MacroAssembler _masm(&cbuf); 3578 Label d; // dummy 3579 __ bind(d); 3580 Label* p = ($lbl$$label); 3581 // `p' is `NULL' when this encoding class is used only to 3582 // determine the size of the encoded instruction. 3583 Label& l = (NULL == p)? d : *(p); 3584 int cc = $cmp$$cmpcode; 3585 int flags_reg = $crx$$reg; 3586 int bhint = Assembler::bhintNoHint; 3587 3588 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3589 if (_prob <= PROB_NEVER) { 3590 bhint = Assembler::bhintIsNotTaken; 3591 } else if (_prob >= PROB_ALWAYS) { 3592 bhint = Assembler::bhintIsTaken; 3593 } 3594 } 3595 3596 // Tell the conditional far branch to optimize itself when being relocated. 3597 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3598 cc_to_biint(cc, flags_reg), 3599 l, 3600 MacroAssembler::bc_far_optimize_on_relocate); 3601 %} 3602 3603 // Branch used with Power6 scheduling (can be shortened without changing the node). 3604 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3605 // The scheduler doesn't know about branch shortening, so we set the opcode 3606 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3607 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3608 3609 C2_MacroAssembler _masm(&cbuf); 3610 Label d; // dummy 3611 __ bind(d); 3612 Label* p = ($lbl$$label); 3613 // `p' is `NULL' when this encoding class is used only to 3614 // determine the size of the encoded instruction. 3615 Label& l = (NULL == p)? d : *(p); 3616 int cc = $cmp$$cmpcode; 3617 int flags_reg = $crx$$reg; 3618 int bhint = Assembler::bhintNoHint; 3619 3620 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3621 if (_prob <= PROB_NEVER) { 3622 bhint = Assembler::bhintIsNotTaken; 3623 } else if (_prob >= PROB_ALWAYS) { 3624 bhint = Assembler::bhintIsTaken; 3625 } 3626 } 3627 3628 #if 0 // TODO: PPC port 3629 if (_size == 8) { 3630 // Tell the conditional far branch to optimize itself when being relocated. 3631 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3632 cc_to_biint(cc, flags_reg), 3633 l, 3634 MacroAssembler::bc_far_optimize_on_relocate); 3635 } else { 3636 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3637 cc_to_biint(cc, flags_reg), 3638 l); 3639 } 3640 #endif 3641 Unimplemented(); 3642 %} 3643 3644 // Postalloc expand emitter for loading a replicatef float constant from 3645 // the method's TOC. 3646 // Enc_class needed as consttanttablebase is not supported by postalloc 3647 // expand. 3648 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3649 // Create new nodes. 3650 3651 // Make an operand with the bit pattern to load as float. 3652 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3653 3654 loadConLNodesTuple loadConLNodes = 3655 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3656 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3657 3658 // Push new nodes. 3659 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3660 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3661 3662 assert(nodes->length() >= 1, "must have created at least 1 node"); 3663 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3664 %} 3665 3666 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3667 // Create new nodes. 3668 3669 // Make an operand with the bit pattern to load as float. 3670 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3671 immI_0Oper *op_zero = new immI_0Oper(0); 3672 3673 loadConLReplicatedNodesTuple loadConLNodes = 3674 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3675 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3676 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3677 3678 // Push new nodes. 3679 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3680 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3681 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3682 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3683 3684 assert(nodes->length() >= 1, "must have created at least 1 node"); 3685 %} 3686 3687 // This enc_class is needed so that scheduler gets proper 3688 // input mapping for latency computation. 3689 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3690 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3691 // Fake operand dst needed for PPC scheduler. 3692 assert($dst$$constant == 0x0, "dst must be 0x0"); 3693 3694 C2_MacroAssembler _masm(&cbuf); 3695 // Mark the code position where the load from the safepoint 3696 // polling page was emitted as relocInfo::poll_type. 3697 __ relocate(relocInfo::poll_type); 3698 __ load_from_polling_page($poll$$Register); 3699 %} 3700 3701 // A Java static call or a runtime call. 3702 // 3703 // Branch-and-link relative to a trampoline. 3704 // The trampoline loads the target address and does a long branch to there. 3705 // In case we call java, the trampoline branches to a interpreter_stub 3706 // which loads the inline cache and the real call target from the constant pool. 3707 // 3708 // This basically looks like this: 3709 // 3710 // >>>> consts -+ -+ 3711 // | |- offset1 3712 // [call target1] | <-+ 3713 // [IC cache] |- offset2 3714 // [call target2] <--+ 3715 // 3716 // <<<< consts 3717 // >>>> insts 3718 // 3719 // bl offset16 -+ -+ ??? // How many bits available? 3720 // | | 3721 // <<<< insts | | 3722 // >>>> stubs | | 3723 // | |- trampoline_stub_Reloc 3724 // trampoline stub: | <-+ 3725 // r2 = toc | 3726 // r2 = [r2 + offset1] | // Load call target1 from const section 3727 // mtctr r2 | 3728 // bctr |- static_stub_Reloc 3729 // comp_to_interp_stub: <---+ 3730 // r1 = toc 3731 // ICreg = [r1 + IC_offset] // Load IC from const section 3732 // r1 = [r1 + offset2] // Load call target2 from const section 3733 // mtctr r1 3734 // bctr 3735 // 3736 // <<<< stubs 3737 // 3738 // The call instruction in the code either 3739 // - Branches directly to a compiled method if the offset is encodable in instruction. 3740 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3741 // - Branches to the compiled_to_interp stub if the target is interpreted. 3742 // 3743 // Further there are three relocations from the loads to the constants in 3744 // the constant section. 3745 // 3746 // Usage of r1 and r2 in the stubs allows to distinguish them. 3747 enc_class enc_java_static_call(method meth) %{ 3748 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3749 3750 C2_MacroAssembler _masm(&cbuf); 3751 address entry_point = (address)$meth$$method; 3752 3753 if (!_method) { 3754 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3755 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3756 } else { 3757 // Remember the offset not the address. 3758 const int start_offset = __ offset(); 3759 3760 // The trampoline stub. 3761 // No entry point given, use the current pc. 3762 // Make sure branch fits into 3763 if (entry_point == 0) entry_point = __ pc(); 3764 3765 // Put the entry point as a constant into the constant pool. 3766 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3767 if (entry_point_toc_addr == NULL) { 3768 ciEnv::current()->record_out_of_memory_failure(); 3769 return; 3770 } 3771 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3772 3773 // Emit the trampoline stub which will be related to the branch-and-link below. 3774 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3775 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3776 int method_index = resolved_method_index(cbuf); 3777 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3778 : static_call_Relocation::spec(method_index)); 3779 3780 // The real call. 3781 // Note: At this point we do not have the address of the trampoline 3782 // stub, and the entry point might be too far away for bl, so __ pc() 3783 // serves as dummy and the bl will be patched later. 3784 cbuf.set_insts_mark(); 3785 __ bl(__ pc()); // Emits a relocation. 3786 3787 // The stub for call to interpreter. 3788 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3789 if (stub == NULL) { 3790 ciEnv::current()->record_failure("CodeCache is full"); 3791 return; 3792 } 3793 } 3794 %} 3795 3796 // Second node of expanded dynamic call - the call. 3797 enc_class enc_java_dynamic_call_sched(method meth) %{ 3798 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3799 3800 C2_MacroAssembler _masm(&cbuf); 3801 3802 if (!ra_->C->output()->in_scratch_emit_size()) { 3803 // Create a call trampoline stub for the given method. 3804 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3805 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3806 if (entry_point_const == NULL) { 3807 ciEnv::current()->record_out_of_memory_failure(); 3808 return; 3809 } 3810 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3811 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3812 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3813 3814 // Build relocation at call site with ic position as data. 3815 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3816 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3817 "must have one, but can't have both"); 3818 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3819 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3820 "must contain instruction offset"); 3821 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3822 ? _load_ic_hi_node->_cbuf_insts_offset 3823 : _load_ic_node->_cbuf_insts_offset; 3824 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3825 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3826 "should be load from TOC"); 3827 int method_index = resolved_method_index(cbuf); 3828 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3829 } 3830 3831 // At this point I do not have the address of the trampoline stub, 3832 // and the entry point might be too far away for bl. Pc() serves 3833 // as dummy and bl will be patched later. 3834 __ bl((address) __ pc()); 3835 %} 3836 3837 // postalloc expand emitter for virtual calls. 3838 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3839 3840 // Create the nodes for loading the IC from the TOC. 3841 loadConLNodesTuple loadConLNodes_IC = 3842 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3843 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3844 3845 // Create the call node. 3846 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3847 call->_method_handle_invoke = _method_handle_invoke; 3848 call->_vtable_index = _vtable_index; 3849 call->_method = _method; 3850 call->_bci = _bci; 3851 call->_optimized_virtual = _optimized_virtual; 3852 call->_tf = _tf; 3853 call->_entry_point = _entry_point; 3854 call->_cnt = _cnt; 3855 call->_argsize = _argsize; 3856 call->_oop_map = _oop_map; 3857 call->_jvms = _jvms; 3858 call->_jvmadj = _jvmadj; 3859 call->_in_rms = _in_rms; 3860 call->_nesting = _nesting; 3861 call->_override_symbolic_info = _override_symbolic_info; 3862 3863 // New call needs all inputs of old call. 3864 // Req... 3865 for (uint i = 0; i < req(); ++i) { 3866 // The expanded node does not need toc any more. 3867 // Add the inline cache constant here instead. This expresses the 3868 // register of the inline cache must be live at the call. 3869 // Else we would have to adapt JVMState by -1. 3870 if (i == mach_constant_base_node_input()) { 3871 call->add_req(loadConLNodes_IC._last); 3872 } else { 3873 call->add_req(in(i)); 3874 } 3875 } 3876 // ...as well as prec 3877 for (uint i = req(); i < len(); ++i) { 3878 call->add_prec(in(i)); 3879 } 3880 3881 // Remember nodes loading the inline cache into r19. 3882 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3883 call->_load_ic_node = loadConLNodes_IC._small; 3884 3885 // Operands for new nodes. 3886 call->_opnds[0] = _opnds[0]; 3887 call->_opnds[1] = _opnds[1]; 3888 3889 // Only the inline cache is associated with a register. 3890 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3891 3892 // Push new nodes. 3893 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3894 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3895 nodes->push(call); 3896 %} 3897 3898 // Compound version of call dynamic 3899 // Toc is only passed so that it can be used in ins_encode statement. 3900 // In the code we have to use $constanttablebase. 3901 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3902 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3903 C2_MacroAssembler _masm(&cbuf); 3904 int start_offset = __ offset(); 3905 3906 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3907 #if 0 3908 int vtable_index = this->_vtable_index; 3909 if (_vtable_index < 0) { 3910 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3911 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3912 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3913 3914 // Virtual call relocation will point to ic load. 3915 address virtual_call_meta_addr = __ pc(); 3916 // Load a clear inline cache. 3917 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3918 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3919 if (!success) { 3920 ciEnv::current()->record_out_of_memory_failure(); 3921 return; 3922 } 3923 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3924 // to determine who we intended to call. 3925 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3926 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3927 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3928 "Fix constant in ret_addr_offset()"); 3929 } else { 3930 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3931 // Go thru the vtable. Get receiver klass. Receiver already 3932 // checked for non-null. If we'll go thru a C2I adapter, the 3933 // interpreter expects method in R19_method. 3934 3935 __ load_klass(R11_scratch1, R3); 3936 3937 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3938 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3939 __ li(R19_method, v_off); 3940 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3941 // NOTE: for vtable dispatches, the vtable entry will never be 3942 // null. However it may very well end up in handle_wrong_method 3943 // if the method is abstract for the particular class. 3944 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3945 // Call target. Either compiled code or C2I adapter. 3946 __ mtctr(R11_scratch1); 3947 __ bctrl(); 3948 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3949 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3950 } 3951 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3952 "Fix constant in ret_addr_offset()"); 3953 } 3954 #endif 3955 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3956 %} 3957 3958 // a runtime call 3959 enc_class enc_java_to_runtime_call (method meth) %{ 3960 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3961 3962 C2_MacroAssembler _masm(&cbuf); 3963 const address start_pc = __ pc(); 3964 3965 #if defined(ABI_ELFv2) 3966 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3967 __ call_c(entry, relocInfo::runtime_call_type); 3968 #else 3969 // The function we're going to call. 3970 FunctionDescriptor fdtemp; 3971 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3972 3973 Register Rtoc = R12_scratch2; 3974 // Calculate the method's TOC. 3975 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3976 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3977 // pool entries; call_c_using_toc will optimize the call. 3978 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3979 if (!success) { 3980 ciEnv::current()->record_out_of_memory_failure(); 3981 return; 3982 } 3983 #endif 3984 3985 // Check the ret_addr_offset. 3986 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3987 "Fix constant in ret_addr_offset()"); 3988 %} 3989 3990 // Move to ctr for leaf call. 3991 // This enc_class is needed so that scheduler gets proper 3992 // input mapping for latency computation. 3993 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3994 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3995 C2_MacroAssembler _masm(&cbuf); 3996 __ mtctr($src$$Register); 3997 %} 3998 3999 // Postalloc expand emitter for runtime leaf calls. 4000 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 4001 loadConLNodesTuple loadConLNodes_Entry; 4002 #if defined(ABI_ELFv2) 4003 jlong entry_address = (jlong) this->entry_point(); 4004 assert(entry_address, "need address here"); 4005 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 4006 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 4007 #else 4008 // Get the struct that describes the function we are about to call. 4009 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 4010 assert(fd, "need fd here"); 4011 jlong entry_address = (jlong) fd->entry(); 4012 // new nodes 4013 loadConLNodesTuple loadConLNodes_Env; 4014 loadConLNodesTuple loadConLNodes_Toc; 4015 4016 // Create nodes and operands for loading the entry point. 4017 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 4018 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 4019 4020 4021 // Create nodes and operands for loading the env pointer. 4022 if (fd->env() != NULL) { 4023 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 4024 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 4025 } else { 4026 loadConLNodes_Env._large_hi = NULL; 4027 loadConLNodes_Env._large_lo = NULL; 4028 loadConLNodes_Env._small = NULL; 4029 loadConLNodes_Env._last = new loadConL16Node(); 4030 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 4031 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 4032 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 4033 } 4034 4035 // Create nodes and operands for loading the Toc point. 4036 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 4037 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 4038 #endif // ABI_ELFv2 4039 // mtctr node 4040 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 4041 4042 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 4043 mtctr->add_req(0, loadConLNodes_Entry._last); 4044 4045 mtctr->_opnds[0] = new iRegLdstOper(); 4046 mtctr->_opnds[1] = new iRegLdstOper(); 4047 4048 // call node 4049 MachCallLeafNode *call = new CallLeafDirectNode(); 4050 4051 call->_opnds[0] = _opnds[0]; 4052 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 4053 4054 // Make the new call node look like the old one. 4055 call->_name = _name; 4056 call->_tf = _tf; 4057 call->_entry_point = _entry_point; 4058 call->_cnt = _cnt; 4059 call->_argsize = _argsize; 4060 call->_oop_map = _oop_map; 4061 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 4062 call->_jvms = NULL; 4063 call->_jvmadj = _jvmadj; 4064 call->_in_rms = _in_rms; 4065 call->_nesting = _nesting; 4066 4067 4068 // New call needs all inputs of old call. 4069 // Req... 4070 for (uint i = 0; i < req(); ++i) { 4071 if (i != mach_constant_base_node_input()) { 4072 call->add_req(in(i)); 4073 } 4074 } 4075 4076 // These must be reqired edges, as the registers are live up to 4077 // the call. Else the constants are handled as kills. 4078 call->add_req(mtctr); 4079 #if !defined(ABI_ELFv2) 4080 call->add_req(loadConLNodes_Env._last); 4081 call->add_req(loadConLNodes_Toc._last); 4082 #endif 4083 4084 // ...as well as prec 4085 for (uint i = req(); i < len(); ++i) { 4086 call->add_prec(in(i)); 4087 } 4088 4089 // registers 4090 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 4091 4092 // Insert the new nodes. 4093 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 4094 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 4095 #if !defined(ABI_ELFv2) 4096 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 4097 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 4098 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 4099 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 4100 #endif 4101 nodes->push(mtctr); 4102 nodes->push(call); 4103 %} 4104 %} 4105 4106 //----------FRAME-------------------------------------------------------------- 4107 // Definition of frame structure and management information. 4108 4109 frame %{ 4110 // What direction does stack grow in (assumed to be same for native & Java). 4111 stack_direction(TOWARDS_LOW); 4112 4113 // These two registers define part of the calling convention between 4114 // compiled code and the interpreter. 4115 4116 // Inline Cache Register or method for I2C. 4117 inline_cache_reg(R19); // R19_method 4118 4119 // Method Oop Register when calling interpreter. 4120 interpreter_method_oop_reg(R19); // R19_method 4121 4122 // Optional: name the operand used by cisc-spilling to access 4123 // [stack_pointer + offset]. 4124 cisc_spilling_operand_name(indOffset); 4125 4126 // Number of stack slots consumed by a Monitor enter. 4127 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 4128 4129 // Compiled code's Frame Pointer. 4130 frame_pointer(R1); // R1_SP 4131 4132 // Interpreter stores its frame pointer in a register which is 4133 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 4134 // interpreted java to compiled java. 4135 // 4136 // R14_state holds pointer to caller's cInterpreter. 4137 interpreter_frame_pointer(R14); // R14_state 4138 4139 stack_alignment(frame::alignment_in_bytes); 4140 4141 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4142 4143 // Number of outgoing stack slots killed above the 4144 // out_preserve_stack_slots for calls to C. Supports the var-args 4145 // backing area for register parms. 4146 // 4147 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4148 4149 // The after-PROLOG location of the return address. Location of 4150 // return address specifies a type (REG or STACK) and a number 4151 // representing the register number (i.e. - use a register name) or 4152 // stack slot. 4153 // 4154 // A: Link register is stored in stack slot ... 4155 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4156 // J: Therefore, we make sure that the link register is also in R11_scratch1 4157 // at the end of the prolog. 4158 // B: We use R20, now. 4159 //return_addr(REG R20); 4160 4161 // G: After reading the comments made by all the luminaries on their 4162 // failure to tell the compiler where the return address really is, 4163 // I hardly dare to try myself. However, I'm convinced it's in slot 4164 // 4 what apparently works and saves us some spills. 4165 return_addr(STACK 4); 4166 4167 // This is the body of the function 4168 // 4169 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4170 // uint length, // length of array 4171 // bool is_outgoing) 4172 // 4173 // The `sig' array is to be updated. sig[j] represents the location 4174 // of the j-th argument, either a register or a stack slot. 4175 4176 // Comment taken from i486.ad: 4177 // Body of function which returns an integer array locating 4178 // arguments either in registers or in stack slots. Passed an array 4179 // of ideal registers called "sig" and a "length" count. Stack-slot 4180 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4181 // arguments for a CALLEE. Incoming stack arguments are 4182 // automatically biased by the preserve_stack_slots field above. 4183 calling_convention %{ 4184 // No difference between ingoing/outgoing. Just pass false. 4185 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4186 %} 4187 4188 // Comment taken from i486.ad: 4189 // Body of function which returns an integer array locating 4190 // arguments either in registers or in stack slots. Passed an array 4191 // of ideal registers called "sig" and a "length" count. Stack-slot 4192 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4193 // arguments for a CALLEE. Incoming stack arguments are 4194 // automatically biased by the preserve_stack_slots field above. 4195 c_calling_convention %{ 4196 // This is obviously always outgoing. 4197 // C argument in register AND stack slot. 4198 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4199 %} 4200 4201 // Location of native (C/C++) and interpreter return values. This 4202 // is specified to be the same as Java. In the 32-bit VM, long 4203 // values are actually returned from native calls in O0:O1 and 4204 // returned to the interpreter in I0:I1. The copying to and from 4205 // the register pairs is done by the appropriate call and epilog 4206 // opcodes. This simplifies the register allocator. 4207 c_return_value %{ 4208 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4209 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0), 4210 "only return normal values"); 4211 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4212 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4213 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4214 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4215 %} 4216 4217 // Location of compiled Java return values. Same as C 4218 return_value %{ 4219 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4220 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0), 4221 "only return normal values"); 4222 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4223 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4224 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4225 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4226 %} 4227 %} 4228 4229 4230 //----------ATTRIBUTES--------------------------------------------------------- 4231 4232 //----------Operand Attributes------------------------------------------------- 4233 op_attrib op_cost(1); // Required cost attribute. 4234 4235 //----------Instruction Attributes--------------------------------------------- 4236 4237 // Cost attribute. required. 4238 ins_attrib ins_cost(DEFAULT_COST); 4239 4240 // Is this instruction a non-matching short branch variant of some 4241 // long branch? Not required. 4242 ins_attrib ins_short_branch(0); 4243 4244 ins_attrib ins_is_TrapBasedCheckNode(true); 4245 4246 // Number of constants. 4247 // This instruction uses the given number of constants 4248 // (optional attribute). 4249 // This is needed to determine in time whether the constant pool will 4250 // exceed 4000 entries. Before postalloc_expand the overall number of constants 4251 // is determined. It's also used to compute the constant pool size 4252 // in Output(). 4253 ins_attrib ins_num_consts(0); 4254 4255 // Required alignment attribute (must be a power of 2) specifies the 4256 // alignment that some part of the instruction (not necessarily the 4257 // start) requires. If > 1, a compute_padding() function must be 4258 // provided for the instruction. 4259 ins_attrib ins_alignment(1); 4260 4261 // Enforce/prohibit rematerializations. 4262 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4263 // then rematerialization of that instruction is prohibited and the 4264 // instruction's value will be spilled if necessary. 4265 // Causes that MachNode::rematerialize() returns false. 4266 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 4267 // then rematerialization should be enforced and a copy of the instruction 4268 // should be inserted if possible; rematerialization is not guaranteed. 4269 // Note: this may result in rematerializations in front of every use. 4270 // Causes that MachNode::rematerialize() can return true. 4271 // (optional attribute) 4272 ins_attrib ins_cannot_rematerialize(false); 4273 ins_attrib ins_should_rematerialize(false); 4274 4275 // Instruction has variable size depending on alignment. 4276 ins_attrib ins_variable_size_depending_on_alignment(false); 4277 4278 // Instruction is a nop. 4279 ins_attrib ins_is_nop(false); 4280 4281 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4282 ins_attrib ins_use_mach_if_fast_lock_node(false); 4283 4284 // Field for the toc offset of a constant. 4285 // 4286 // This is needed if the toc offset is not encodable as an immediate in 4287 // the PPC load instruction. If so, the upper (hi) bits of the offset are 4288 // added to the toc, and from this a load with immediate is performed. 4289 // With postalloc expand, we get two nodes that require the same offset 4290 // but which don't know about each other. The offset is only known 4291 // when the constant is added to the constant pool during emitting. 4292 // It is generated in the 'hi'-node adding the upper bits, and saved 4293 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 4294 // the offset from there when it gets encoded. 4295 ins_attrib ins_field_const_toc_offset(0); 4296 ins_attrib ins_field_const_toc_offset_hi_node(0); 4297 4298 // A field that can hold the instructions offset in the code buffer. 4299 // Set in the nodes emitter. 4300 ins_attrib ins_field_cbuf_insts_offset(-1); 4301 4302 // Fields for referencing a call's load-IC-node. 4303 // If the toc offset can not be encoded as an immediate in a load, we 4304 // use two nodes. 4305 ins_attrib ins_field_load_ic_hi_node(0); 4306 ins_attrib ins_field_load_ic_node(0); 4307 4308 //----------OPERANDS----------------------------------------------------------- 4309 // Operand definitions must precede instruction definitions for correct 4310 // parsing in the ADLC because operands constitute user defined types 4311 // which are used in instruction definitions. 4312 // 4313 // Formats are generated automatically for constants and base registers. 4314 4315 operand vecX() %{ 4316 constraint(ALLOC_IN_RC(vs_reg)); 4317 match(VecX); 4318 4319 format %{ %} 4320 interface(REG_INTER); 4321 %} 4322 4323 //----------Simple Operands---------------------------------------------------- 4324 // Immediate Operands 4325 4326 // Integer Immediate: 32-bit 4327 operand immI() %{ 4328 match(ConI); 4329 op_cost(40); 4330 format %{ %} 4331 interface(CONST_INTER); 4332 %} 4333 4334 operand immI8() %{ 4335 predicate(Assembler::is_simm(n->get_int(), 8)); 4336 op_cost(0); 4337 match(ConI); 4338 format %{ %} 4339 interface(CONST_INTER); 4340 %} 4341 4342 // Integer Immediate: 16-bit 4343 operand immI16() %{ 4344 predicate(Assembler::is_simm(n->get_int(), 16)); 4345 op_cost(0); 4346 match(ConI); 4347 format %{ %} 4348 interface(CONST_INTER); 4349 %} 4350 4351 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4352 operand immIhi16() %{ 4353 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4354 match(ConI); 4355 op_cost(0); 4356 format %{ %} 4357 interface(CONST_INTER); 4358 %} 4359 4360 operand immInegpow2() %{ 4361 predicate(is_power_of_2((jlong) (julong) (juint) (-(n->get_int())))); 4362 match(ConI); 4363 op_cost(0); 4364 format %{ %} 4365 interface(CONST_INTER); 4366 %} 4367 4368 operand immIpow2minus1() %{ 4369 predicate(is_power_of_2((((jlong) (n->get_int()))+1))); 4370 match(ConI); 4371 op_cost(0); 4372 format %{ %} 4373 interface(CONST_INTER); 4374 %} 4375 4376 operand immIpowerOf2() %{ 4377 predicate(is_power_of_2((((jlong) (julong) (juint) (n->get_int()))))); 4378 match(ConI); 4379 op_cost(0); 4380 format %{ %} 4381 interface(CONST_INTER); 4382 %} 4383 4384 // Unsigned Integer Immediate: the values 0-31 4385 operand uimmI5() %{ 4386 predicate(Assembler::is_uimm(n->get_int(), 5)); 4387 match(ConI); 4388 op_cost(0); 4389 format %{ %} 4390 interface(CONST_INTER); 4391 %} 4392 4393 // Unsigned Integer Immediate: 6-bit 4394 operand uimmI6() %{ 4395 predicate(Assembler::is_uimm(n->get_int(), 6)); 4396 match(ConI); 4397 op_cost(0); 4398 format %{ %} 4399 interface(CONST_INTER); 4400 %} 4401 4402 // Unsigned Integer Immediate: 6-bit int, greater than 32 4403 operand uimmI6_ge32() %{ 4404 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4405 match(ConI); 4406 op_cost(0); 4407 format %{ %} 4408 interface(CONST_INTER); 4409 %} 4410 4411 // Unsigned Integer Immediate: 15-bit 4412 operand uimmI15() %{ 4413 predicate(Assembler::is_uimm(n->get_int(), 15)); 4414 match(ConI); 4415 op_cost(0); 4416 format %{ %} 4417 interface(CONST_INTER); 4418 %} 4419 4420 // Unsigned Integer Immediate: 16-bit 4421 operand uimmI16() %{ 4422 predicate(Assembler::is_uimm(n->get_int(), 16)); 4423 match(ConI); 4424 op_cost(0); 4425 format %{ %} 4426 interface(CONST_INTER); 4427 %} 4428 4429 // constant 'int 0'. 4430 operand immI_0() %{ 4431 predicate(n->get_int() == 0); 4432 match(ConI); 4433 op_cost(0); 4434 format %{ %} 4435 interface(CONST_INTER); 4436 %} 4437 4438 // constant 'int 1'. 4439 operand immI_1() %{ 4440 predicate(n->get_int() == 1); 4441 match(ConI); 4442 op_cost(0); 4443 format %{ %} 4444 interface(CONST_INTER); 4445 %} 4446 4447 // constant 'int -1'. 4448 operand immI_minus1() %{ 4449 predicate(n->get_int() == -1); 4450 match(ConI); 4451 op_cost(0); 4452 format %{ %} 4453 interface(CONST_INTER); 4454 %} 4455 4456 // int value 16. 4457 operand immI_16() %{ 4458 predicate(n->get_int() == 16); 4459 match(ConI); 4460 op_cost(0); 4461 format %{ %} 4462 interface(CONST_INTER); 4463 %} 4464 4465 // int value 24. 4466 operand immI_24() %{ 4467 predicate(n->get_int() == 24); 4468 match(ConI); 4469 op_cost(0); 4470 format %{ %} 4471 interface(CONST_INTER); 4472 %} 4473 4474 // Compressed oops constants 4475 // Pointer Immediate 4476 operand immN() %{ 4477 match(ConN); 4478 4479 op_cost(10); 4480 format %{ %} 4481 interface(CONST_INTER); 4482 %} 4483 4484 // NULL Pointer Immediate 4485 operand immN_0() %{ 4486 predicate(n->get_narrowcon() == 0); 4487 match(ConN); 4488 4489 op_cost(0); 4490 format %{ %} 4491 interface(CONST_INTER); 4492 %} 4493 4494 // Compressed klass constants 4495 operand immNKlass() %{ 4496 match(ConNKlass); 4497 4498 op_cost(0); 4499 format %{ %} 4500 interface(CONST_INTER); 4501 %} 4502 4503 // This operand can be used to avoid matching of an instruct 4504 // with chain rule. 4505 operand immNKlass_NM() %{ 4506 match(ConNKlass); 4507 predicate(false); 4508 op_cost(0); 4509 format %{ %} 4510 interface(CONST_INTER); 4511 %} 4512 4513 // Pointer Immediate: 64-bit 4514 operand immP() %{ 4515 match(ConP); 4516 op_cost(0); 4517 format %{ %} 4518 interface(CONST_INTER); 4519 %} 4520 4521 // Operand to avoid match of loadConP. 4522 // This operand can be used to avoid matching of an instruct 4523 // with chain rule. 4524 operand immP_NM() %{ 4525 match(ConP); 4526 predicate(false); 4527 op_cost(0); 4528 format %{ %} 4529 interface(CONST_INTER); 4530 %} 4531 4532 // costant 'pointer 0'. 4533 operand immP_0() %{ 4534 predicate(n->get_ptr() == 0); 4535 match(ConP); 4536 op_cost(0); 4537 format %{ %} 4538 interface(CONST_INTER); 4539 %} 4540 4541 // pointer 0x0 or 0x1 4542 operand immP_0or1() %{ 4543 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4544 match(ConP); 4545 op_cost(0); 4546 format %{ %} 4547 interface(CONST_INTER); 4548 %} 4549 4550 operand immL() %{ 4551 match(ConL); 4552 op_cost(40); 4553 format %{ %} 4554 interface(CONST_INTER); 4555 %} 4556 4557 operand immLmax30() %{ 4558 predicate((n->get_long() <= 30)); 4559 match(ConL); 4560 op_cost(0); 4561 format %{ %} 4562 interface(CONST_INTER); 4563 %} 4564 4565 // Long Immediate: 16-bit 4566 operand immL16() %{ 4567 predicate(Assembler::is_simm(n->get_long(), 16)); 4568 match(ConL); 4569 op_cost(0); 4570 format %{ %} 4571 interface(CONST_INTER); 4572 %} 4573 4574 // Long Immediate: 16-bit, 4-aligned 4575 operand immL16Alg4() %{ 4576 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4577 match(ConL); 4578 op_cost(0); 4579 format %{ %} 4580 interface(CONST_INTER); 4581 %} 4582 4583 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4584 operand immL32hi16() %{ 4585 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4586 match(ConL); 4587 op_cost(0); 4588 format %{ %} 4589 interface(CONST_INTER); 4590 %} 4591 4592 // Long Immediate: 32-bit 4593 operand immL32() %{ 4594 predicate(Assembler::is_simm(n->get_long(), 32)); 4595 match(ConL); 4596 op_cost(0); 4597 format %{ %} 4598 interface(CONST_INTER); 4599 %} 4600 4601 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4602 operand immLhighest16() %{ 4603 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4604 match(ConL); 4605 op_cost(0); 4606 format %{ %} 4607 interface(CONST_INTER); 4608 %} 4609 4610 operand immLnegpow2() %{ 4611 predicate(is_power_of_2((jlong)-(n->get_long()))); 4612 match(ConL); 4613 op_cost(0); 4614 format %{ %} 4615 interface(CONST_INTER); 4616 %} 4617 4618 operand immLpow2minus1() %{ 4619 predicate(is_power_of_2((((jlong) (n->get_long()))+1)) && 4620 (n->get_long() != (jlong)0xffffffffffffffffL)); 4621 match(ConL); 4622 op_cost(0); 4623 format %{ %} 4624 interface(CONST_INTER); 4625 %} 4626 4627 // constant 'long 0'. 4628 operand immL_0() %{ 4629 predicate(n->get_long() == 0L); 4630 match(ConL); 4631 op_cost(0); 4632 format %{ %} 4633 interface(CONST_INTER); 4634 %} 4635 4636 // constat ' long -1'. 4637 operand immL_minus1() %{ 4638 predicate(n->get_long() == -1L); 4639 match(ConL); 4640 op_cost(0); 4641 format %{ %} 4642 interface(CONST_INTER); 4643 %} 4644 4645 // Long Immediate: low 32-bit mask 4646 operand immL_32bits() %{ 4647 predicate(n->get_long() == 0xFFFFFFFFL); 4648 match(ConL); 4649 op_cost(0); 4650 format %{ %} 4651 interface(CONST_INTER); 4652 %} 4653 4654 // Unsigned Long Immediate: 16-bit 4655 operand uimmL16() %{ 4656 predicate(Assembler::is_uimm(n->get_long(), 16)); 4657 match(ConL); 4658 op_cost(0); 4659 format %{ %} 4660 interface(CONST_INTER); 4661 %} 4662 4663 // Float Immediate 4664 operand immF() %{ 4665 match(ConF); 4666 op_cost(40); 4667 format %{ %} 4668 interface(CONST_INTER); 4669 %} 4670 4671 // Float Immediate: +0.0f. 4672 operand immF_0() %{ 4673 predicate(jint_cast(n->getf()) == 0); 4674 match(ConF); 4675 4676 op_cost(0); 4677 format %{ %} 4678 interface(CONST_INTER); 4679 %} 4680 4681 // Double Immediate 4682 operand immD() %{ 4683 match(ConD); 4684 op_cost(40); 4685 format %{ %} 4686 interface(CONST_INTER); 4687 %} 4688 4689 // Double Immediate: +0.0d. 4690 operand immD_0() %{ 4691 predicate(jlong_cast(n->getd()) == 0); 4692 match(ConD); 4693 4694 op_cost(0); 4695 format %{ %} 4696 interface(CONST_INTER); 4697 %} 4698 4699 // Integer Register Operands 4700 // Integer Destination Register 4701 // See definition of reg_class bits32_reg_rw. 4702 operand iRegIdst() %{ 4703 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4704 match(RegI); 4705 match(rscratch1RegI); 4706 match(rscratch2RegI); 4707 match(rarg1RegI); 4708 match(rarg2RegI); 4709 match(rarg3RegI); 4710 match(rarg4RegI); 4711 format %{ %} 4712 interface(REG_INTER); 4713 %} 4714 4715 // Integer Source Register 4716 // See definition of reg_class bits32_reg_ro. 4717 operand iRegIsrc() %{ 4718 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4719 match(RegI); 4720 match(rscratch1RegI); 4721 match(rscratch2RegI); 4722 match(rarg1RegI); 4723 match(rarg2RegI); 4724 match(rarg3RegI); 4725 match(rarg4RegI); 4726 format %{ %} 4727 interface(REG_INTER); 4728 %} 4729 4730 operand rscratch1RegI() %{ 4731 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4732 match(iRegIdst); 4733 format %{ %} 4734 interface(REG_INTER); 4735 %} 4736 4737 operand rscratch2RegI() %{ 4738 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4739 match(iRegIdst); 4740 format %{ %} 4741 interface(REG_INTER); 4742 %} 4743 4744 operand rarg1RegI() %{ 4745 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4746 match(iRegIdst); 4747 format %{ %} 4748 interface(REG_INTER); 4749 %} 4750 4751 operand rarg2RegI() %{ 4752 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4753 match(iRegIdst); 4754 format %{ %} 4755 interface(REG_INTER); 4756 %} 4757 4758 operand rarg3RegI() %{ 4759 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4760 match(iRegIdst); 4761 format %{ %} 4762 interface(REG_INTER); 4763 %} 4764 4765 operand rarg4RegI() %{ 4766 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4767 match(iRegIdst); 4768 format %{ %} 4769 interface(REG_INTER); 4770 %} 4771 4772 operand rarg1RegL() %{ 4773 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4774 match(iRegLdst); 4775 format %{ %} 4776 interface(REG_INTER); 4777 %} 4778 4779 operand rarg2RegL() %{ 4780 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4781 match(iRegLdst); 4782 format %{ %} 4783 interface(REG_INTER); 4784 %} 4785 4786 operand rarg3RegL() %{ 4787 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4788 match(iRegLdst); 4789 format %{ %} 4790 interface(REG_INTER); 4791 %} 4792 4793 operand rarg4RegL() %{ 4794 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4795 match(iRegLdst); 4796 format %{ %} 4797 interface(REG_INTER); 4798 %} 4799 4800 // Pointer Destination Register 4801 // See definition of reg_class bits64_reg_rw. 4802 operand iRegPdst() %{ 4803 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4804 match(RegP); 4805 match(rscratch1RegP); 4806 match(rscratch2RegP); 4807 match(rarg1RegP); 4808 match(rarg2RegP); 4809 match(rarg3RegP); 4810 match(rarg4RegP); 4811 format %{ %} 4812 interface(REG_INTER); 4813 %} 4814 4815 // Pointer Destination Register 4816 // Operand not using r11 and r12 (killed in epilog). 4817 operand iRegPdstNoScratch() %{ 4818 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4819 match(RegP); 4820 match(rarg1RegP); 4821 match(rarg2RegP); 4822 match(rarg3RegP); 4823 match(rarg4RegP); 4824 format %{ %} 4825 interface(REG_INTER); 4826 %} 4827 4828 // Pointer Source Register 4829 // See definition of reg_class bits64_reg_ro. 4830 operand iRegPsrc() %{ 4831 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4832 match(RegP); 4833 match(iRegPdst); 4834 match(rscratch1RegP); 4835 match(rscratch2RegP); 4836 match(rarg1RegP); 4837 match(rarg2RegP); 4838 match(rarg3RegP); 4839 match(rarg4RegP); 4840 match(threadRegP); 4841 format %{ %} 4842 interface(REG_INTER); 4843 %} 4844 4845 // Thread operand. 4846 operand threadRegP() %{ 4847 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4848 match(iRegPdst); 4849 format %{ "R16" %} 4850 interface(REG_INTER); 4851 %} 4852 4853 operand rscratch1RegP() %{ 4854 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4855 match(iRegPdst); 4856 format %{ "R11" %} 4857 interface(REG_INTER); 4858 %} 4859 4860 operand rscratch2RegP() %{ 4861 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4862 match(iRegPdst); 4863 format %{ %} 4864 interface(REG_INTER); 4865 %} 4866 4867 operand rarg1RegP() %{ 4868 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4869 match(iRegPdst); 4870 format %{ %} 4871 interface(REG_INTER); 4872 %} 4873 4874 operand rarg2RegP() %{ 4875 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4876 match(iRegPdst); 4877 format %{ %} 4878 interface(REG_INTER); 4879 %} 4880 4881 operand rarg3RegP() %{ 4882 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4883 match(iRegPdst); 4884 format %{ %} 4885 interface(REG_INTER); 4886 %} 4887 4888 operand rarg4RegP() %{ 4889 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4890 match(iRegPdst); 4891 format %{ %} 4892 interface(REG_INTER); 4893 %} 4894 4895 operand iRegNsrc() %{ 4896 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4897 match(RegN); 4898 match(iRegNdst); 4899 4900 format %{ %} 4901 interface(REG_INTER); 4902 %} 4903 4904 operand iRegNdst() %{ 4905 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4906 match(RegN); 4907 4908 format %{ %} 4909 interface(REG_INTER); 4910 %} 4911 4912 // Long Destination Register 4913 // See definition of reg_class bits64_reg_rw. 4914 operand iRegLdst() %{ 4915 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4916 match(RegL); 4917 match(rscratch1RegL); 4918 match(rscratch2RegL); 4919 format %{ %} 4920 interface(REG_INTER); 4921 %} 4922 4923 // Long Source Register 4924 // See definition of reg_class bits64_reg_ro. 4925 operand iRegLsrc() %{ 4926 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4927 match(RegL); 4928 match(iRegLdst); 4929 match(rscratch1RegL); 4930 match(rscratch2RegL); 4931 format %{ %} 4932 interface(REG_INTER); 4933 %} 4934 4935 // Special operand for ConvL2I. 4936 operand iRegL2Isrc(iRegLsrc reg) %{ 4937 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4938 match(ConvL2I reg); 4939 format %{ "ConvL2I($reg)" %} 4940 interface(REG_INTER) 4941 %} 4942 4943 operand rscratch1RegL() %{ 4944 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4945 match(RegL); 4946 format %{ %} 4947 interface(REG_INTER); 4948 %} 4949 4950 operand rscratch2RegL() %{ 4951 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4952 match(RegL); 4953 format %{ %} 4954 interface(REG_INTER); 4955 %} 4956 4957 // Condition Code Flag Registers 4958 operand flagsReg() %{ 4959 constraint(ALLOC_IN_RC(int_flags)); 4960 match(RegFlags); 4961 format %{ %} 4962 interface(REG_INTER); 4963 %} 4964 4965 operand flagsRegSrc() %{ 4966 constraint(ALLOC_IN_RC(int_flags_ro)); 4967 match(RegFlags); 4968 match(flagsReg); 4969 match(flagsRegCR0); 4970 format %{ %} 4971 interface(REG_INTER); 4972 %} 4973 4974 // Condition Code Flag Register CR0 4975 operand flagsRegCR0() %{ 4976 constraint(ALLOC_IN_RC(int_flags_CR0)); 4977 match(RegFlags); 4978 format %{ "CR0" %} 4979 interface(REG_INTER); 4980 %} 4981 4982 operand flagsRegCR1() %{ 4983 constraint(ALLOC_IN_RC(int_flags_CR1)); 4984 match(RegFlags); 4985 format %{ "CR1" %} 4986 interface(REG_INTER); 4987 %} 4988 4989 operand flagsRegCR6() %{ 4990 constraint(ALLOC_IN_RC(int_flags_CR6)); 4991 match(RegFlags); 4992 format %{ "CR6" %} 4993 interface(REG_INTER); 4994 %} 4995 4996 operand regCTR() %{ 4997 constraint(ALLOC_IN_RC(ctr_reg)); 4998 // RegFlags should work. Introducing a RegSpecial type would cause a 4999 // lot of changes. 5000 match(RegFlags); 5001 format %{"SR_CTR" %} 5002 interface(REG_INTER); 5003 %} 5004 5005 operand regD() %{ 5006 constraint(ALLOC_IN_RC(dbl_reg)); 5007 match(RegD); 5008 format %{ %} 5009 interface(REG_INTER); 5010 %} 5011 5012 operand regF() %{ 5013 constraint(ALLOC_IN_RC(flt_reg)); 5014 match(RegF); 5015 format %{ %} 5016 interface(REG_INTER); 5017 %} 5018 5019 // Special Registers 5020 5021 // Method Register 5022 operand inline_cache_regP(iRegPdst reg) %{ 5023 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 5024 match(reg); 5025 format %{ %} 5026 interface(REG_INTER); 5027 %} 5028 5029 operand compiler_method_oop_regP(iRegPdst reg) %{ 5030 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 5031 match(reg); 5032 format %{ %} 5033 interface(REG_INTER); 5034 %} 5035 5036 operand interpreter_method_oop_regP(iRegPdst reg) %{ 5037 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 5038 match(reg); 5039 format %{ %} 5040 interface(REG_INTER); 5041 %} 5042 5043 // Operands to remove register moves in unscaled mode. 5044 // Match read/write registers with an EncodeP node if neither shift nor add are required. 5045 operand iRegP2N(iRegPsrc reg) %{ 5046 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0); 5047 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5048 match(EncodeP reg); 5049 format %{ "$reg" %} 5050 interface(REG_INTER) 5051 %} 5052 5053 operand iRegN2P(iRegNsrc reg) %{ 5054 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5055 constraint(ALLOC_IN_RC(bits32_reg_ro)); 5056 match(DecodeN reg); 5057 format %{ "$reg" %} 5058 interface(REG_INTER) 5059 %} 5060 5061 operand iRegN2P_klass(iRegNsrc reg) %{ 5062 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5063 constraint(ALLOC_IN_RC(bits32_reg_ro)); 5064 match(DecodeNKlass reg); 5065 format %{ "$reg" %} 5066 interface(REG_INTER) 5067 %} 5068 5069 //----------Complex Operands--------------------------------------------------- 5070 // Indirect Memory Reference 5071 operand indirect(iRegPsrc reg) %{ 5072 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5073 match(reg); 5074 op_cost(100); 5075 format %{ "[$reg]" %} 5076 interface(MEMORY_INTER) %{ 5077 base($reg); 5078 index(0x0); 5079 scale(0x0); 5080 disp(0x0); 5081 %} 5082 %} 5083 5084 // Indirect with Offset 5085 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 5086 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5087 match(AddP reg offset); 5088 op_cost(100); 5089 format %{ "[$reg + $offset]" %} 5090 interface(MEMORY_INTER) %{ 5091 base($reg); 5092 index(0x0); 5093 scale(0x0); 5094 disp($offset); 5095 %} 5096 %} 5097 5098 // Indirect with 4-aligned Offset 5099 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 5100 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5101 match(AddP reg offset); 5102 op_cost(100); 5103 format %{ "[$reg + $offset]" %} 5104 interface(MEMORY_INTER) %{ 5105 base($reg); 5106 index(0x0); 5107 scale(0x0); 5108 disp($offset); 5109 %} 5110 %} 5111 5112 //----------Complex Operands for Compressed OOPs------------------------------- 5113 // Compressed OOPs with narrow_oop_shift == 0. 5114 5115 // Indirect Memory Reference, compressed OOP 5116 operand indirectNarrow(iRegNsrc reg) %{ 5117 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5118 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5119 match(DecodeN reg); 5120 op_cost(100); 5121 format %{ "[$reg]" %} 5122 interface(MEMORY_INTER) %{ 5123 base($reg); 5124 index(0x0); 5125 scale(0x0); 5126 disp(0x0); 5127 %} 5128 %} 5129 5130 operand indirectNarrow_klass(iRegNsrc reg) %{ 5131 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5132 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5133 match(DecodeNKlass reg); 5134 op_cost(100); 5135 format %{ "[$reg]" %} 5136 interface(MEMORY_INTER) %{ 5137 base($reg); 5138 index(0x0); 5139 scale(0x0); 5140 disp(0x0); 5141 %} 5142 %} 5143 5144 // Indirect with Offset, compressed OOP 5145 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 5146 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5147 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5148 match(AddP (DecodeN reg) offset); 5149 op_cost(100); 5150 format %{ "[$reg + $offset]" %} 5151 interface(MEMORY_INTER) %{ 5152 base($reg); 5153 index(0x0); 5154 scale(0x0); 5155 disp($offset); 5156 %} 5157 %} 5158 5159 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5160 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5161 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5162 match(AddP (DecodeNKlass reg) offset); 5163 op_cost(100); 5164 format %{ "[$reg + $offset]" %} 5165 interface(MEMORY_INTER) %{ 5166 base($reg); 5167 index(0x0); 5168 scale(0x0); 5169 disp($offset); 5170 %} 5171 %} 5172 5173 // Indirect with 4-aligned Offset, compressed OOP 5174 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 5175 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5176 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5177 match(AddP (DecodeN reg) offset); 5178 op_cost(100); 5179 format %{ "[$reg + $offset]" %} 5180 interface(MEMORY_INTER) %{ 5181 base($reg); 5182 index(0x0); 5183 scale(0x0); 5184 disp($offset); 5185 %} 5186 %} 5187 5188 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5189 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5190 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5191 match(AddP (DecodeNKlass reg) offset); 5192 op_cost(100); 5193 format %{ "[$reg + $offset]" %} 5194 interface(MEMORY_INTER) %{ 5195 base($reg); 5196 index(0x0); 5197 scale(0x0); 5198 disp($offset); 5199 %} 5200 %} 5201 5202 //----------Special Memory Operands-------------------------------------------- 5203 // Stack Slot Operand 5204 // 5205 // This operand is used for loading and storing temporary values on 5206 // the stack where a match requires a value to flow through memory. 5207 operand stackSlotI(sRegI reg) %{ 5208 constraint(ALLOC_IN_RC(stack_slots)); 5209 op_cost(100); 5210 //match(RegI); 5211 format %{ "[sp+$reg]" %} 5212 interface(MEMORY_INTER) %{ 5213 base(0x1); // R1_SP 5214 index(0x0); 5215 scale(0x0); 5216 disp($reg); // Stack Offset 5217 %} 5218 %} 5219 5220 operand stackSlotL(sRegL reg) %{ 5221 constraint(ALLOC_IN_RC(stack_slots)); 5222 op_cost(100); 5223 //match(RegL); 5224 format %{ "[sp+$reg]" %} 5225 interface(MEMORY_INTER) %{ 5226 base(0x1); // R1_SP 5227 index(0x0); 5228 scale(0x0); 5229 disp($reg); // Stack Offset 5230 %} 5231 %} 5232 5233 operand stackSlotP(sRegP reg) %{ 5234 constraint(ALLOC_IN_RC(stack_slots)); 5235 op_cost(100); 5236 //match(RegP); 5237 format %{ "[sp+$reg]" %} 5238 interface(MEMORY_INTER) %{ 5239 base(0x1); // R1_SP 5240 index(0x0); 5241 scale(0x0); 5242 disp($reg); // Stack Offset 5243 %} 5244 %} 5245 5246 operand stackSlotF(sRegF reg) %{ 5247 constraint(ALLOC_IN_RC(stack_slots)); 5248 op_cost(100); 5249 //match(RegF); 5250 format %{ "[sp+$reg]" %} 5251 interface(MEMORY_INTER) %{ 5252 base(0x1); // R1_SP 5253 index(0x0); 5254 scale(0x0); 5255 disp($reg); // Stack Offset 5256 %} 5257 %} 5258 5259 operand stackSlotD(sRegD reg) %{ 5260 constraint(ALLOC_IN_RC(stack_slots)); 5261 op_cost(100); 5262 //match(RegD); 5263 format %{ "[sp+$reg]" %} 5264 interface(MEMORY_INTER) %{ 5265 base(0x1); // R1_SP 5266 index(0x0); 5267 scale(0x0); 5268 disp($reg); // Stack Offset 5269 %} 5270 %} 5271 5272 // Operands for expressing Control Flow 5273 // NOTE: Label is a predefined operand which should not be redefined in 5274 // the AD file. It is generically handled within the ADLC. 5275 5276 //----------Conditional Branch Operands---------------------------------------- 5277 // Comparison Op 5278 // 5279 // This is the operation of the comparison, and is limited to the 5280 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5281 // (!=). 5282 // 5283 // Other attributes of the comparison, such as unsignedness, are specified 5284 // by the comparison instruction that sets a condition code flags register. 5285 // That result is represented by a flags operand whose subtype is appropriate 5286 // to the unsignedness (etc.) of the comparison. 5287 // 5288 // Later, the instruction which matches both the Comparison Op (a Bool) and 5289 // the flags (produced by the Cmp) specifies the coding of the comparison op 5290 // by matching a specific subtype of Bool operand below. 5291 5292 // When used for floating point comparisons: unordered same as less. 5293 operand cmpOp() %{ 5294 match(Bool); 5295 format %{ "" %} 5296 interface(COND_INTER) %{ 5297 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5298 // BO & BI 5299 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5300 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5301 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5302 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5303 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5304 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5305 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5306 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5307 %} 5308 %} 5309 5310 //----------OPERAND CLASSES---------------------------------------------------- 5311 // Operand Classes are groups of operands that are used to simplify 5312 // instruction definitions by not requiring the AD writer to specify 5313 // seperate instructions for every form of operand when the 5314 // instruction accepts multiple operand types with the same basic 5315 // encoding and format. The classic case of this is memory operands. 5316 // Indirect is not included since its use is limited to Compare & Swap. 5317 5318 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5319 // Memory operand where offsets are 4-aligned. Required for ld, std. 5320 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5321 opclass indirectMemory(indirect, indirectNarrow); 5322 5323 // Special opclass for I and ConvL2I. 5324 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5325 5326 // Operand classes to match encode and decode. iRegN_P2N is only used 5327 // for storeN. I have never seen an encode node elsewhere. 5328 opclass iRegN_P2N(iRegNsrc, iRegP2N); 5329 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5330 5331 //----------PIPELINE----------------------------------------------------------- 5332 5333 pipeline %{ 5334 5335 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5336 // J. Res. & Dev., No. 1, Jan. 2002. 5337 5338 //----------ATTRIBUTES--------------------------------------------------------- 5339 attributes %{ 5340 5341 // Power4 instructions are of fixed length. 5342 fixed_size_instructions; 5343 5344 // TODO: if `bundle' means number of instructions fetched 5345 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5346 // max instructions issued per cycle, this is 5. 5347 max_instructions_per_bundle = 8; 5348 5349 // A Power4 instruction is 4 bytes long. 5350 instruction_unit_size = 4; 5351 5352 // The Power4 processor fetches 64 bytes... 5353 instruction_fetch_unit_size = 64; 5354 5355 // ...in one line 5356 instruction_fetch_units = 1 5357 5358 // Unused, list one so that array generated by adlc is not empty. 5359 // Aix compiler chokes if _nop_count = 0. 5360 nops(fxNop); 5361 %} 5362 5363 //----------RESOURCES---------------------------------------------------------- 5364 // Resources are the functional units available to the machine 5365 resources( 5366 PPC_BR, // branch unit 5367 PPC_CR, // condition unit 5368 PPC_FX1, // integer arithmetic unit 1 5369 PPC_FX2, // integer arithmetic unit 2 5370 PPC_LDST1, // load/store unit 1 5371 PPC_LDST2, // load/store unit 2 5372 PPC_FP1, // float arithmetic unit 1 5373 PPC_FP2, // float arithmetic unit 2 5374 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5375 PPC_FX = PPC_FX1 | PPC_FX2, 5376 PPC_FP = PPC_FP1 | PPC_FP2 5377 ); 5378 5379 //----------PIPELINE DESCRIPTION----------------------------------------------- 5380 // Pipeline Description specifies the stages in the machine's pipeline 5381 pipe_desc( 5382 // Power4 longest pipeline path 5383 PPC_IF, // instruction fetch 5384 PPC_IC, 5385 //PPC_BP, // branch prediction 5386 PPC_D0, // decode 5387 PPC_D1, // decode 5388 PPC_D2, // decode 5389 PPC_D3, // decode 5390 PPC_Xfer1, 5391 PPC_GD, // group definition 5392 PPC_MP, // map 5393 PPC_ISS, // issue 5394 PPC_RF, // resource fetch 5395 PPC_EX1, // execute (all units) 5396 PPC_EX2, // execute (FP, LDST) 5397 PPC_EX3, // execute (FP, LDST) 5398 PPC_EX4, // execute (FP) 5399 PPC_EX5, // execute (FP) 5400 PPC_EX6, // execute (FP) 5401 PPC_WB, // write back 5402 PPC_Xfer2, 5403 PPC_CP 5404 ); 5405 5406 //----------PIPELINE CLASSES--------------------------------------------------- 5407 // Pipeline Classes describe the stages in which input and output are 5408 // referenced by the hardware pipeline. 5409 5410 // Simple pipeline classes. 5411 5412 // Default pipeline class. 5413 pipe_class pipe_class_default() %{ 5414 single_instruction; 5415 fixed_latency(2); 5416 %} 5417 5418 // Pipeline class for empty instructions. 5419 pipe_class pipe_class_empty() %{ 5420 single_instruction; 5421 fixed_latency(0); 5422 %} 5423 5424 // Pipeline class for compares. 5425 pipe_class pipe_class_compare() %{ 5426 single_instruction; 5427 fixed_latency(16); 5428 %} 5429 5430 // Pipeline class for traps. 5431 pipe_class pipe_class_trap() %{ 5432 single_instruction; 5433 fixed_latency(100); 5434 %} 5435 5436 // Pipeline class for memory operations. 5437 pipe_class pipe_class_memory() %{ 5438 single_instruction; 5439 fixed_latency(16); 5440 %} 5441 5442 // Pipeline class for call. 5443 pipe_class pipe_class_call() %{ 5444 single_instruction; 5445 fixed_latency(100); 5446 %} 5447 5448 // Define the class for the Nop node. 5449 define %{ 5450 MachNop = pipe_class_default; 5451 %} 5452 5453 %} 5454 5455 //----------INSTRUCTIONS------------------------------------------------------- 5456 5457 // Naming of instructions: 5458 // opA_operB / opA_operB_operC: 5459 // Operation 'op' with one or two source operands 'oper'. Result 5460 // type is A, source operand types are B and C. 5461 // Iff A == B == C, B and C are left out. 5462 // 5463 // The instructions are ordered according to the following scheme: 5464 // - loads 5465 // - load constants 5466 // - prefetch 5467 // - store 5468 // - encode/decode 5469 // - membar 5470 // - conditional moves 5471 // - compare & swap 5472 // - arithmetic and logic operations 5473 // * int: Add, Sub, Mul, Div, Mod 5474 // * int: lShift, arShift, urShift, rot 5475 // * float: Add, Sub, Mul, Div 5476 // * and, or, xor ... 5477 // - register moves: float <-> int, reg <-> stack, repl 5478 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5479 // - conv (low level type cast requiring bit changes (sign extend etc) 5480 // - compares, range & zero checks. 5481 // - branches 5482 // - complex operations, intrinsics, min, max, replicate 5483 // - lock 5484 // - Calls 5485 // 5486 // If there are similar instructions with different types they are sorted: 5487 // int before float 5488 // small before big 5489 // signed before unsigned 5490 // e.g., loadS before loadUS before loadI before loadF. 5491 5492 5493 //----------Load/Store Instructions-------------------------------------------- 5494 5495 //----------Load Instructions-------------------------------------------------- 5496 5497 // Converts byte to int. 5498 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5499 // reuses the 'amount' operand, but adlc expects that operand specification 5500 // and operands in match rule are equivalent. 5501 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5502 effect(DEF dst, USE src); 5503 format %{ "EXTSB $dst, $src \t// byte->int" %} 5504 size(4); 5505 ins_encode %{ 5506 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5507 __ extsb($dst$$Register, $src$$Register); 5508 %} 5509 ins_pipe(pipe_class_default); 5510 %} 5511 5512 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5513 // match-rule, false predicate 5514 match(Set dst (LoadB mem)); 5515 predicate(false); 5516 5517 format %{ "LBZ $dst, $mem" %} 5518 size(4); 5519 ins_encode( enc_lbz(dst, mem) ); 5520 ins_pipe(pipe_class_memory); 5521 %} 5522 5523 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5524 // match-rule, false predicate 5525 match(Set dst (LoadB mem)); 5526 predicate(false); 5527 5528 format %{ "LBZ $dst, $mem\n\t" 5529 "TWI $dst\n\t" 5530 "ISYNC" %} 5531 size(12); 5532 ins_encode( enc_lbz_ac(dst, mem) ); 5533 ins_pipe(pipe_class_memory); 5534 %} 5535 5536 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5537 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5538 match(Set dst (LoadB mem)); 5539 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5540 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5541 expand %{ 5542 iRegIdst tmp; 5543 loadUB_indirect(tmp, mem); 5544 convB2I_reg_2(dst, tmp); 5545 %} 5546 %} 5547 5548 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5549 match(Set dst (LoadB mem)); 5550 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5551 expand %{ 5552 iRegIdst tmp; 5553 loadUB_indirect_ac(tmp, mem); 5554 convB2I_reg_2(dst, tmp); 5555 %} 5556 %} 5557 5558 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5559 // match-rule, false predicate 5560 match(Set dst (LoadB mem)); 5561 predicate(false); 5562 5563 format %{ "LBZ $dst, $mem" %} 5564 size(4); 5565 ins_encode( enc_lbz(dst, mem) ); 5566 ins_pipe(pipe_class_memory); 5567 %} 5568 5569 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5570 // match-rule, false predicate 5571 match(Set dst (LoadB mem)); 5572 predicate(false); 5573 5574 format %{ "LBZ $dst, $mem\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 Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5583 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5584 match(Set dst (LoadB mem)); 5585 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5586 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5587 5588 expand %{ 5589 iRegIdst tmp; 5590 loadUB_indOffset16(tmp, mem); 5591 convB2I_reg_2(dst, tmp); 5592 %} 5593 %} 5594 5595 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5596 match(Set dst (LoadB mem)); 5597 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5598 5599 expand %{ 5600 iRegIdst tmp; 5601 loadUB_indOffset16_ac(tmp, mem); 5602 convB2I_reg_2(dst, tmp); 5603 %} 5604 %} 5605 5606 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5607 instruct loadUB(iRegIdst dst, memory mem) %{ 5608 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5609 match(Set dst (LoadUB mem)); 5610 ins_cost(MEMORY_REF_COST); 5611 5612 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5613 size(4); 5614 ins_encode( enc_lbz(dst, mem) ); 5615 ins_pipe(pipe_class_memory); 5616 %} 5617 5618 // Load Unsigned Byte (8bit UNsigned) acquire. 5619 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5620 match(Set dst (LoadUB mem)); 5621 ins_cost(3*MEMORY_REF_COST); 5622 5623 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5624 "TWI $dst\n\t" 5625 "ISYNC" %} 5626 size(12); 5627 ins_encode( enc_lbz_ac(dst, mem) ); 5628 ins_pipe(pipe_class_memory); 5629 %} 5630 5631 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5632 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5633 match(Set dst (ConvI2L (LoadUB mem))); 5634 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5635 ins_cost(MEMORY_REF_COST); 5636 5637 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5638 size(4); 5639 ins_encode( enc_lbz(dst, mem) ); 5640 ins_pipe(pipe_class_memory); 5641 %} 5642 5643 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5644 match(Set dst (ConvI2L (LoadUB mem))); 5645 ins_cost(3*MEMORY_REF_COST); 5646 5647 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5648 "TWI $dst\n\t" 5649 "ISYNC" %} 5650 size(12); 5651 ins_encode( enc_lbz_ac(dst, mem) ); 5652 ins_pipe(pipe_class_memory); 5653 %} 5654 5655 // Load Short (16bit signed) 5656 instruct loadS(iRegIdst dst, memory mem) %{ 5657 match(Set dst (LoadS mem)); 5658 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5659 ins_cost(MEMORY_REF_COST); 5660 5661 format %{ "LHA $dst, $mem" %} 5662 size(4); 5663 ins_encode %{ 5664 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5665 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5666 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5667 %} 5668 ins_pipe(pipe_class_memory); 5669 %} 5670 5671 // Load Short (16bit signed) acquire. 5672 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5673 match(Set dst (LoadS mem)); 5674 ins_cost(3*MEMORY_REF_COST); 5675 5676 format %{ "LHA $dst, $mem\t acquire\n\t" 5677 "TWI $dst\n\t" 5678 "ISYNC" %} 5679 size(12); 5680 ins_encode %{ 5681 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5682 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5683 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5684 __ twi_0($dst$$Register); 5685 __ isync(); 5686 %} 5687 ins_pipe(pipe_class_memory); 5688 %} 5689 5690 // Load Char (16bit unsigned) 5691 instruct loadUS(iRegIdst dst, memory mem) %{ 5692 match(Set dst (LoadUS mem)); 5693 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5694 ins_cost(MEMORY_REF_COST); 5695 5696 format %{ "LHZ $dst, $mem" %} 5697 size(4); 5698 ins_encode( enc_lhz(dst, mem) ); 5699 ins_pipe(pipe_class_memory); 5700 %} 5701 5702 // Load Char (16bit unsigned) acquire. 5703 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5704 match(Set dst (LoadUS mem)); 5705 ins_cost(3*MEMORY_REF_COST); 5706 5707 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5708 "TWI $dst\n\t" 5709 "ISYNC" %} 5710 size(12); 5711 ins_encode( enc_lhz_ac(dst, mem) ); 5712 ins_pipe(pipe_class_memory); 5713 %} 5714 5715 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5716 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5717 match(Set dst (ConvI2L (LoadUS mem))); 5718 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5719 ins_cost(MEMORY_REF_COST); 5720 5721 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5722 size(4); 5723 ins_encode( enc_lhz(dst, mem) ); 5724 ins_pipe(pipe_class_memory); 5725 %} 5726 5727 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5728 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5729 match(Set dst (ConvI2L (LoadUS mem))); 5730 ins_cost(3*MEMORY_REF_COST); 5731 5732 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5733 "TWI $dst\n\t" 5734 "ISYNC" %} 5735 size(12); 5736 ins_encode( enc_lhz_ac(dst, mem) ); 5737 ins_pipe(pipe_class_memory); 5738 %} 5739 5740 // Load Integer. 5741 instruct loadI(iRegIdst dst, memory mem) %{ 5742 match(Set dst (LoadI mem)); 5743 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5744 ins_cost(MEMORY_REF_COST); 5745 5746 format %{ "LWZ $dst, $mem" %} 5747 size(4); 5748 ins_encode( enc_lwz(dst, mem) ); 5749 ins_pipe(pipe_class_memory); 5750 %} 5751 5752 // Load Integer acquire. 5753 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5754 match(Set dst (LoadI mem)); 5755 ins_cost(3*MEMORY_REF_COST); 5756 5757 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5758 "TWI $dst\n\t" 5759 "ISYNC" %} 5760 size(12); 5761 ins_encode( enc_lwz_ac(dst, mem) ); 5762 ins_pipe(pipe_class_memory); 5763 %} 5764 5765 // Match loading integer and casting it to unsigned int in 5766 // long register. 5767 // LoadI + ConvI2L + AndL 0xffffffff. 5768 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5769 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5770 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5771 ins_cost(MEMORY_REF_COST); 5772 5773 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5774 size(4); 5775 ins_encode( enc_lwz(dst, mem) ); 5776 ins_pipe(pipe_class_memory); 5777 %} 5778 5779 // Match loading integer and casting it to long. 5780 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5781 match(Set dst (ConvI2L (LoadI mem))); 5782 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5783 ins_cost(MEMORY_REF_COST); 5784 5785 format %{ "LWA $dst, $mem \t// loadI2L" %} 5786 size(4); 5787 ins_encode %{ 5788 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5789 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5790 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5791 %} 5792 ins_pipe(pipe_class_memory); 5793 %} 5794 5795 // Match loading integer and casting it to long - acquire. 5796 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5797 match(Set dst (ConvI2L (LoadI mem))); 5798 ins_cost(3*MEMORY_REF_COST); 5799 5800 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5801 "TWI $dst\n\t" 5802 "ISYNC" %} 5803 size(12); 5804 ins_encode %{ 5805 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5806 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5807 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5808 __ twi_0($dst$$Register); 5809 __ isync(); 5810 %} 5811 ins_pipe(pipe_class_memory); 5812 %} 5813 5814 // Load Long - aligned 5815 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5816 match(Set dst (LoadL mem)); 5817 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5818 ins_cost(MEMORY_REF_COST); 5819 5820 format %{ "LD $dst, $mem \t// long" %} 5821 size(4); 5822 ins_encode( enc_ld(dst, mem) ); 5823 ins_pipe(pipe_class_memory); 5824 %} 5825 5826 // Load Long - aligned acquire. 5827 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5828 match(Set dst (LoadL mem)); 5829 ins_cost(3*MEMORY_REF_COST); 5830 5831 format %{ "LD $dst, $mem \t// long acquire\n\t" 5832 "TWI $dst\n\t" 5833 "ISYNC" %} 5834 size(12); 5835 ins_encode( enc_ld_ac(dst, mem) ); 5836 ins_pipe(pipe_class_memory); 5837 %} 5838 5839 // Load Long - UNaligned 5840 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5841 match(Set dst (LoadL_unaligned mem)); 5842 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5843 ins_cost(MEMORY_REF_COST); 5844 5845 format %{ "LD $dst, $mem \t// unaligned long" %} 5846 size(4); 5847 ins_encode( enc_ld(dst, mem) ); 5848 ins_pipe(pipe_class_memory); 5849 %} 5850 5851 // Load nodes for superwords 5852 5853 // Load Aligned Packed Byte 5854 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5855 predicate(n->as_LoadVector()->memory_size() == 8); 5856 match(Set dst (LoadVector mem)); 5857 ins_cost(MEMORY_REF_COST); 5858 5859 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5860 size(4); 5861 ins_encode( enc_ld(dst, mem) ); 5862 ins_pipe(pipe_class_memory); 5863 %} 5864 5865 // Load Aligned Packed Byte 5866 instruct loadV16(vecX dst, indirect mem) %{ 5867 predicate(n->as_LoadVector()->memory_size() == 16); 5868 match(Set dst (LoadVector mem)); 5869 ins_cost(MEMORY_REF_COST); 5870 5871 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5872 size(4); 5873 ins_encode %{ 5874 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5875 %} 5876 ins_pipe(pipe_class_default); 5877 %} 5878 5879 // Load Range, range = array length (=jint) 5880 instruct loadRange(iRegIdst dst, memory mem) %{ 5881 match(Set dst (LoadRange mem)); 5882 ins_cost(MEMORY_REF_COST); 5883 5884 format %{ "LWZ $dst, $mem \t// range" %} 5885 size(4); 5886 ins_encode( enc_lwz(dst, mem) ); 5887 ins_pipe(pipe_class_memory); 5888 %} 5889 5890 // Load Compressed Pointer 5891 instruct loadN(iRegNdst dst, memory mem) %{ 5892 match(Set dst (LoadN mem)); 5893 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5894 ins_cost(MEMORY_REF_COST); 5895 5896 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5897 size(4); 5898 ins_encode( enc_lwz(dst, mem) ); 5899 ins_pipe(pipe_class_memory); 5900 %} 5901 5902 // Load Compressed Pointer acquire. 5903 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5904 match(Set dst (LoadN mem)); 5905 ins_cost(3*MEMORY_REF_COST); 5906 5907 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5908 "TWI $dst\n\t" 5909 "ISYNC" %} 5910 size(12); 5911 ins_encode( enc_lwz_ac(dst, mem) ); 5912 ins_pipe(pipe_class_memory); 5913 %} 5914 5915 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5916 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5917 match(Set dst (DecodeN (LoadN mem))); 5918 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0); 5919 ins_cost(MEMORY_REF_COST); 5920 5921 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5922 size(4); 5923 ins_encode( enc_lwz(dst, mem) ); 5924 ins_pipe(pipe_class_memory); 5925 %} 5926 5927 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5928 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5929 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0 && 5930 _kids[0]->_leaf->as_Load()->is_unordered()); 5931 ins_cost(MEMORY_REF_COST); 5932 5933 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5934 size(4); 5935 ins_encode( enc_lwz(dst, mem) ); 5936 ins_pipe(pipe_class_memory); 5937 %} 5938 5939 // Load Pointer 5940 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5941 match(Set dst (LoadP mem)); 5942 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5943 ins_cost(MEMORY_REF_COST); 5944 5945 format %{ "LD $dst, $mem \t// ptr" %} 5946 size(4); 5947 ins_encode( enc_ld(dst, mem) ); 5948 ins_pipe(pipe_class_memory); 5949 %} 5950 5951 // Load Pointer acquire. 5952 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5953 match(Set dst (LoadP mem)); 5954 ins_cost(3*MEMORY_REF_COST); 5955 5956 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5957 "TWI $dst\n\t" 5958 "ISYNC" %} 5959 size(12); 5960 ins_encode( enc_ld_ac(dst, mem) ); 5961 ins_pipe(pipe_class_memory); 5962 %} 5963 5964 // LoadP + CastP2L 5965 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5966 match(Set dst (CastP2X (LoadP mem))); 5967 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5968 ins_cost(MEMORY_REF_COST); 5969 5970 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5971 size(4); 5972 ins_encode( enc_ld(dst, mem) ); 5973 ins_pipe(pipe_class_memory); 5974 %} 5975 5976 // Load compressed klass pointer. 5977 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5978 match(Set dst (LoadNKlass mem)); 5979 ins_cost(MEMORY_REF_COST); 5980 5981 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5982 size(4); 5983 ins_encode( enc_lwz(dst, mem) ); 5984 ins_pipe(pipe_class_memory); 5985 %} 5986 5987 // Load Klass Pointer 5988 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5989 match(Set dst (LoadKlass mem)); 5990 ins_cost(MEMORY_REF_COST); 5991 5992 format %{ "LD $dst, $mem \t// klass ptr" %} 5993 size(4); 5994 ins_encode( enc_ld(dst, mem) ); 5995 ins_pipe(pipe_class_memory); 5996 %} 5997 5998 // Load Float 5999 instruct loadF(regF dst, memory mem) %{ 6000 match(Set dst (LoadF mem)); 6001 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 6002 ins_cost(MEMORY_REF_COST); 6003 6004 format %{ "LFS $dst, $mem" %} 6005 size(4); 6006 ins_encode %{ 6007 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6008 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6009 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 6010 %} 6011 ins_pipe(pipe_class_memory); 6012 %} 6013 6014 // Load Float acquire. 6015 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 6016 match(Set dst (LoadF mem)); 6017 effect(TEMP cr0); 6018 ins_cost(3*MEMORY_REF_COST); 6019 6020 format %{ "LFS $dst, $mem \t// acquire\n\t" 6021 "FCMPU cr0, $dst, $dst\n\t" 6022 "BNE cr0, next\n" 6023 "next:\n\t" 6024 "ISYNC" %} 6025 size(16); 6026 ins_encode %{ 6027 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6028 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6029 Label next; 6030 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 6031 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 6032 __ bne(CCR0, next); 6033 __ bind(next); 6034 __ isync(); 6035 %} 6036 ins_pipe(pipe_class_memory); 6037 %} 6038 6039 // Load Double - aligned 6040 instruct loadD(regD dst, memory mem) %{ 6041 match(Set dst (LoadD mem)); 6042 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 6043 ins_cost(MEMORY_REF_COST); 6044 6045 format %{ "LFD $dst, $mem" %} 6046 size(4); 6047 ins_encode( enc_lfd(dst, mem) ); 6048 ins_pipe(pipe_class_memory); 6049 %} 6050 6051 // Load Double - aligned acquire. 6052 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 6053 match(Set dst (LoadD mem)); 6054 effect(TEMP cr0); 6055 ins_cost(3*MEMORY_REF_COST); 6056 6057 format %{ "LFD $dst, $mem \t// acquire\n\t" 6058 "FCMPU cr0, $dst, $dst\n\t" 6059 "BNE cr0, next\n" 6060 "next:\n\t" 6061 "ISYNC" %} 6062 size(16); 6063 ins_encode %{ 6064 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6065 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6066 Label next; 6067 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 6068 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 6069 __ bne(CCR0, next); 6070 __ bind(next); 6071 __ isync(); 6072 %} 6073 ins_pipe(pipe_class_memory); 6074 %} 6075 6076 // Load Double - UNaligned 6077 instruct loadD_unaligned(regD dst, memory mem) %{ 6078 match(Set dst (LoadD_unaligned mem)); 6079 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 6080 ins_cost(MEMORY_REF_COST); 6081 6082 format %{ "LFD $dst, $mem" %} 6083 size(4); 6084 ins_encode( enc_lfd(dst, mem) ); 6085 ins_pipe(pipe_class_memory); 6086 %} 6087 6088 //----------Constants-------------------------------------------------------- 6089 6090 // Load MachConstantTableBase: add hi offset to global toc. 6091 // TODO: Handle hidden register r29 in bundler! 6092 instruct loadToc_hi(iRegLdst dst) %{ 6093 effect(DEF dst); 6094 ins_cost(DEFAULT_COST); 6095 6096 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 6097 size(4); 6098 ins_encode %{ 6099 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6100 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 6101 %} 6102 ins_pipe(pipe_class_default); 6103 %} 6104 6105 // Load MachConstantTableBase: add lo offset to global toc. 6106 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 6107 effect(DEF dst, USE src); 6108 ins_cost(DEFAULT_COST); 6109 6110 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 6111 size(4); 6112 ins_encode %{ 6113 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6114 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 6115 %} 6116 ins_pipe(pipe_class_default); 6117 %} 6118 6119 // Load 16-bit integer constant 0xssss???? 6120 instruct loadConI16(iRegIdst dst, immI16 src) %{ 6121 match(Set dst src); 6122 6123 format %{ "LI $dst, $src" %} 6124 size(4); 6125 ins_encode %{ 6126 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6127 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6128 %} 6129 ins_pipe(pipe_class_default); 6130 %} 6131 6132 // Load integer constant 0x????0000 6133 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 6134 match(Set dst src); 6135 ins_cost(DEFAULT_COST); 6136 6137 format %{ "LIS $dst, $src.hi" %} 6138 size(4); 6139 ins_encode %{ 6140 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6141 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 6142 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6143 %} 6144 ins_pipe(pipe_class_default); 6145 %} 6146 6147 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 6148 // and sign extended), this adds the low 16 bits. 6149 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6150 // no match-rule, false predicate 6151 effect(DEF dst, USE src1, USE src2); 6152 predicate(false); 6153 6154 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6155 size(4); 6156 ins_encode %{ 6157 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6158 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6159 %} 6160 ins_pipe(pipe_class_default); 6161 %} 6162 6163 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6164 match(Set dst src); 6165 ins_cost(DEFAULT_COST*2); 6166 6167 expand %{ 6168 // Would like to use $src$$constant. 6169 immI16 srcLo %{ _opnds[1]->constant() %} 6170 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6171 immIhi16 srcHi %{ _opnds[1]->constant() %} 6172 iRegIdst tmpI; 6173 loadConIhi16(tmpI, srcHi); 6174 loadConI32_lo16(dst, tmpI, srcLo); 6175 %} 6176 %} 6177 6178 // No constant pool entries required. 6179 instruct loadConL16(iRegLdst dst, immL16 src) %{ 6180 match(Set dst src); 6181 6182 format %{ "LI $dst, $src \t// long" %} 6183 size(4); 6184 ins_encode %{ 6185 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6186 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6187 %} 6188 ins_pipe(pipe_class_default); 6189 %} 6190 6191 // Load long constant 0xssssssss????0000 6192 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6193 match(Set dst src); 6194 ins_cost(DEFAULT_COST); 6195 6196 format %{ "LIS $dst, $src.hi \t// long" %} 6197 size(4); 6198 ins_encode %{ 6199 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6200 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6201 %} 6202 ins_pipe(pipe_class_default); 6203 %} 6204 6205 // To load a 32 bit constant: merge lower 16 bits into already loaded 6206 // high 16 bits. 6207 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6208 // no match-rule, false predicate 6209 effect(DEF dst, USE src1, USE src2); 6210 predicate(false); 6211 6212 format %{ "ORI $dst, $src1, $src2.lo" %} 6213 size(4); 6214 ins_encode %{ 6215 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6216 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6217 %} 6218 ins_pipe(pipe_class_default); 6219 %} 6220 6221 // Load 32-bit long constant 6222 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6223 match(Set dst src); 6224 ins_cost(DEFAULT_COST*2); 6225 6226 expand %{ 6227 // Would like to use $src$$constant. 6228 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6229 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6230 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6231 iRegLdst tmpL; 6232 loadConL32hi16(tmpL, srcHi); 6233 loadConL32_lo16(dst, tmpL, srcLo); 6234 %} 6235 %} 6236 6237 // Load long constant 0x????000000000000. 6238 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6239 match(Set dst src); 6240 ins_cost(DEFAULT_COST); 6241 6242 expand %{ 6243 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6244 immI shift32 %{ 32 %} 6245 iRegLdst tmpL; 6246 loadConL32hi16(tmpL, srcHi); 6247 lshiftL_regL_immI(dst, tmpL, shift32); 6248 %} 6249 %} 6250 6251 // Expand node for constant pool load: small offset. 6252 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6253 effect(DEF dst, USE src, USE toc); 6254 ins_cost(MEMORY_REF_COST); 6255 6256 ins_num_consts(1); 6257 // Needed so that CallDynamicJavaDirect can compute the address of this 6258 // instruction for relocation. 6259 ins_field_cbuf_insts_offset(int); 6260 6261 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6262 size(4); 6263 ins_encode( enc_load_long_constL(dst, src, toc) ); 6264 ins_pipe(pipe_class_memory); 6265 %} 6266 6267 // Expand node for constant pool load: large offset. 6268 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6269 effect(DEF dst, USE src, USE toc); 6270 predicate(false); 6271 6272 ins_num_consts(1); 6273 ins_field_const_toc_offset(int); 6274 // Needed so that CallDynamicJavaDirect can compute the address of this 6275 // instruction for relocation. 6276 ins_field_cbuf_insts_offset(int); 6277 6278 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6279 size(4); 6280 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6281 ins_pipe(pipe_class_default); 6282 %} 6283 6284 // Expand node for constant pool load: large offset. 6285 // No constant pool entries required. 6286 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6287 effect(DEF dst, USE src, USE base); 6288 predicate(false); 6289 6290 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6291 6292 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6293 size(4); 6294 ins_encode %{ 6295 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6296 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6297 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6298 %} 6299 ins_pipe(pipe_class_memory); 6300 %} 6301 6302 // Load long constant from constant table. Expand in case of 6303 // offset > 16 bit is needed. 6304 // Adlc adds toc node MachConstantTableBase. 6305 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6306 match(Set dst src); 6307 ins_cost(MEMORY_REF_COST); 6308 6309 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6310 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6311 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6312 %} 6313 6314 // Load NULL as compressed oop. 6315 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6316 match(Set dst src); 6317 ins_cost(DEFAULT_COST); 6318 6319 format %{ "LI $dst, $src \t// compressed ptr" %} 6320 size(4); 6321 ins_encode %{ 6322 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6323 __ li($dst$$Register, 0); 6324 %} 6325 ins_pipe(pipe_class_default); 6326 %} 6327 6328 // Load hi part of compressed oop constant. 6329 instruct loadConN_hi(iRegNdst dst, immN src) %{ 6330 effect(DEF dst, USE src); 6331 ins_cost(DEFAULT_COST); 6332 6333 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6334 size(4); 6335 ins_encode %{ 6336 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6337 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6338 %} 6339 ins_pipe(pipe_class_default); 6340 %} 6341 6342 // Add lo part of compressed oop constant to already loaded hi part. 6343 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6344 effect(DEF dst, USE src1, USE src2); 6345 ins_cost(DEFAULT_COST); 6346 6347 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6348 size(4); 6349 ins_encode %{ 6350 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6351 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6352 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6353 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6354 __ relocate(rspec, 1); 6355 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6356 %} 6357 ins_pipe(pipe_class_default); 6358 %} 6359 6360 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6361 effect(DEF dst, USE src, USE shift, USE mask_begin); 6362 6363 size(4); 6364 ins_encode %{ 6365 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6366 %} 6367 ins_pipe(pipe_class_default); 6368 %} 6369 6370 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6371 // leaving the upper 32 bits with sign-extension bits. 6372 // This clears these bits: dst = src & 0xFFFFFFFF. 6373 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6374 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6375 effect(DEF dst, USE src); 6376 predicate(false); 6377 6378 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6379 size(4); 6380 ins_encode %{ 6381 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6382 __ clrldi($dst$$Register, $src$$Register, 0x20); 6383 %} 6384 ins_pipe(pipe_class_default); 6385 %} 6386 6387 // Optimize DecodeN for disjoint base. 6388 // Load base of compressed oops into a register 6389 instruct loadBase(iRegLdst dst) %{ 6390 effect(DEF dst); 6391 6392 format %{ "LoadConst $dst, heapbase" %} 6393 ins_encode %{ 6394 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6395 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0); 6396 %} 6397 ins_pipe(pipe_class_default); 6398 %} 6399 6400 // Loading ConN must be postalloc expanded so that edges between 6401 // the nodes are safe. They may not interfere with a safepoint. 6402 // GL TODO: This needs three instructions: better put this into the constant pool. 6403 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6404 match(Set dst src); 6405 ins_cost(DEFAULT_COST*2); 6406 6407 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6408 postalloc_expand %{ 6409 MachNode *m1 = new loadConN_hiNode(); 6410 MachNode *m2 = new loadConN_loNode(); 6411 MachNode *m3 = new clearMs32bNode(); 6412 m1->add_req(NULL); 6413 m2->add_req(NULL, m1); 6414 m3->add_req(NULL, m2); 6415 m1->_opnds[0] = op_dst; 6416 m1->_opnds[1] = op_src; 6417 m2->_opnds[0] = op_dst; 6418 m2->_opnds[1] = op_dst; 6419 m2->_opnds[2] = op_src; 6420 m3->_opnds[0] = op_dst; 6421 m3->_opnds[1] = op_dst; 6422 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6423 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6424 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6425 nodes->push(m1); 6426 nodes->push(m2); 6427 nodes->push(m3); 6428 %} 6429 %} 6430 6431 // We have seen a safepoint between the hi and lo parts, and this node was handled 6432 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6433 // not a narrow oop. 6434 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6435 match(Set dst src); 6436 effect(DEF dst, USE src); 6437 ins_cost(DEFAULT_COST); 6438 6439 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6440 size(4); 6441 ins_encode %{ 6442 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6443 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant); 6444 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6445 %} 6446 ins_pipe(pipe_class_default); 6447 %} 6448 6449 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6450 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6451 match(Set dst src1); 6452 effect(TEMP src2); 6453 ins_cost(DEFAULT_COST); 6454 6455 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6456 size(4); 6457 ins_encode %{ 6458 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6459 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6460 %} 6461 ins_pipe(pipe_class_default); 6462 %} 6463 6464 // This needs a match rule so that build_oop_map knows this is 6465 // not a narrow oop. 6466 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6467 match(Set dst src1); 6468 effect(TEMP src2); 6469 ins_cost(DEFAULT_COST); 6470 6471 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6472 size(4); 6473 ins_encode %{ 6474 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6475 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src1$$constant); 6476 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6477 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6478 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6479 6480 __ relocate(rspec, 1); 6481 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6482 %} 6483 ins_pipe(pipe_class_default); 6484 %} 6485 6486 // Loading ConNKlass must be postalloc expanded so that edges between 6487 // the nodes are safe. They may not interfere with a safepoint. 6488 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6489 match(Set dst src); 6490 ins_cost(DEFAULT_COST*2); 6491 6492 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6493 postalloc_expand %{ 6494 // Load high bits into register. Sign extended. 6495 MachNode *m1 = new loadConNKlass_hiNode(); 6496 m1->add_req(NULL); 6497 m1->_opnds[0] = op_dst; 6498 m1->_opnds[1] = op_src; 6499 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6500 nodes->push(m1); 6501 6502 MachNode *m2 = m1; 6503 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) { 6504 // Value might be 1-extended. Mask out these bits. 6505 m2 = new loadConNKlass_maskNode(); 6506 m2->add_req(NULL, m1); 6507 m2->_opnds[0] = op_dst; 6508 m2->_opnds[1] = op_src; 6509 m2->_opnds[2] = op_dst; 6510 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6511 nodes->push(m2); 6512 } 6513 6514 MachNode *m3 = new loadConNKlass_loNode(); 6515 m3->add_req(NULL, m2); 6516 m3->_opnds[0] = op_dst; 6517 m3->_opnds[1] = op_src; 6518 m3->_opnds[2] = op_dst; 6519 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6520 nodes->push(m3); 6521 %} 6522 %} 6523 6524 // 0x1 is used in object initialization (initial object header). 6525 // No constant pool entries required. 6526 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6527 match(Set dst src); 6528 6529 format %{ "LI $dst, $src \t// ptr" %} 6530 size(4); 6531 ins_encode %{ 6532 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6533 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6534 %} 6535 ins_pipe(pipe_class_default); 6536 %} 6537 6538 // Expand node for constant pool load: small offset. 6539 // The match rule is needed to generate the correct bottom_type(), 6540 // however this node should never match. The use of predicate is not 6541 // possible since ADLC forbids predicates for chain rules. The higher 6542 // costs do not prevent matching in this case. For that reason the 6543 // operand immP_NM with predicate(false) is used. 6544 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6545 match(Set dst src); 6546 effect(TEMP toc); 6547 6548 ins_num_consts(1); 6549 6550 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6551 size(4); 6552 ins_encode( enc_load_long_constP(dst, src, toc) ); 6553 ins_pipe(pipe_class_memory); 6554 %} 6555 6556 // Expand node for constant pool load: large offset. 6557 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6558 effect(DEF dst, USE src, USE toc); 6559 predicate(false); 6560 6561 ins_num_consts(1); 6562 ins_field_const_toc_offset(int); 6563 6564 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6565 size(4); 6566 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6567 ins_pipe(pipe_class_default); 6568 %} 6569 6570 // Expand node for constant pool load: large offset. 6571 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6572 match(Set dst src); 6573 effect(TEMP base); 6574 6575 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6576 6577 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6578 size(4); 6579 ins_encode %{ 6580 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6581 int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6582 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6583 %} 6584 ins_pipe(pipe_class_memory); 6585 %} 6586 6587 // Load pointer constant from constant table. Expand in case an 6588 // offset > 16 bit is needed. 6589 // Adlc adds toc node MachConstantTableBase. 6590 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6591 match(Set dst src); 6592 ins_cost(MEMORY_REF_COST); 6593 6594 // This rule does not use "expand" because then 6595 // the result type is not known to be an Oop. An ADLC 6596 // enhancement will be needed to make that work - not worth it! 6597 6598 // If this instruction rematerializes, it prolongs the live range 6599 // of the toc node, causing illegal graphs. 6600 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6601 ins_cannot_rematerialize(true); 6602 6603 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6604 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6605 %} 6606 6607 // Expand node for constant pool load: small offset. 6608 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6609 effect(DEF dst, USE src, USE toc); 6610 ins_cost(MEMORY_REF_COST); 6611 6612 ins_num_consts(1); 6613 6614 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6615 size(4); 6616 ins_encode %{ 6617 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6618 address float_address = __ float_constant($src$$constant); 6619 if (float_address == NULL) { 6620 ciEnv::current()->record_out_of_memory_failure(); 6621 return; 6622 } 6623 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6624 %} 6625 ins_pipe(pipe_class_memory); 6626 %} 6627 6628 // Expand node for constant pool load: large offset. 6629 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6630 effect(DEF dst, USE src, USE toc); 6631 ins_cost(MEMORY_REF_COST); 6632 6633 ins_num_consts(1); 6634 6635 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6636 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6637 "ADDIS $toc, $toc, -offset_hi"%} 6638 size(12); 6639 ins_encode %{ 6640 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6641 FloatRegister Rdst = $dst$$FloatRegister; 6642 Register Rtoc = $toc$$Register; 6643 address float_address = __ float_constant($src$$constant); 6644 if (float_address == NULL) { 6645 ciEnv::current()->record_out_of_memory_failure(); 6646 return; 6647 } 6648 int offset = __ offset_to_method_toc(float_address); 6649 int hi = (offset + (1<<15))>>16; 6650 int lo = offset - hi * (1<<16); 6651 6652 __ addis(Rtoc, Rtoc, hi); 6653 __ lfs(Rdst, lo, Rtoc); 6654 __ addis(Rtoc, Rtoc, -hi); 6655 %} 6656 ins_pipe(pipe_class_memory); 6657 %} 6658 6659 // Adlc adds toc node MachConstantTableBase. 6660 instruct loadConF_Ex(regF dst, immF src) %{ 6661 match(Set dst src); 6662 ins_cost(MEMORY_REF_COST); 6663 6664 // See loadConP. 6665 ins_cannot_rematerialize(true); 6666 6667 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6668 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6669 %} 6670 6671 // Expand node for constant pool load: small offset. 6672 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6673 effect(DEF dst, USE src, USE toc); 6674 ins_cost(MEMORY_REF_COST); 6675 6676 ins_num_consts(1); 6677 6678 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6679 size(4); 6680 ins_encode %{ 6681 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6682 address float_address = __ double_constant($src$$constant); 6683 if (float_address == NULL) { 6684 ciEnv::current()->record_out_of_memory_failure(); 6685 return; 6686 } 6687 int offset = __ offset_to_method_toc(float_address); 6688 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6689 %} 6690 ins_pipe(pipe_class_memory); 6691 %} 6692 6693 // Expand node for constant pool load: large offset. 6694 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6695 effect(DEF dst, USE src, USE toc); 6696 ins_cost(MEMORY_REF_COST); 6697 6698 ins_num_consts(1); 6699 6700 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6701 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6702 "ADDIS $toc, $toc, -offset_hi" %} 6703 size(12); 6704 ins_encode %{ 6705 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6706 FloatRegister Rdst = $dst$$FloatRegister; 6707 Register Rtoc = $toc$$Register; 6708 address float_address = __ double_constant($src$$constant); 6709 if (float_address == NULL) { 6710 ciEnv::current()->record_out_of_memory_failure(); 6711 return; 6712 } 6713 int offset = __ offset_to_method_toc(float_address); 6714 int hi = (offset + (1<<15))>>16; 6715 int lo = offset - hi * (1<<16); 6716 6717 __ addis(Rtoc, Rtoc, hi); 6718 __ lfd(Rdst, lo, Rtoc); 6719 __ addis(Rtoc, Rtoc, -hi); 6720 %} 6721 ins_pipe(pipe_class_memory); 6722 %} 6723 6724 // Adlc adds toc node MachConstantTableBase. 6725 instruct loadConD_Ex(regD dst, immD src) %{ 6726 match(Set dst src); 6727 ins_cost(MEMORY_REF_COST); 6728 6729 // See loadConP. 6730 ins_cannot_rematerialize(true); 6731 6732 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6733 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6734 %} 6735 6736 // Prefetch instructions. 6737 // Must be safe to execute with invalid address (cannot fault). 6738 6739 // Special prefetch versions which use the dcbz instruction. 6740 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6741 match(PrefetchAllocation (AddP mem src)); 6742 predicate(AllocatePrefetchStyle == 3); 6743 ins_cost(MEMORY_REF_COST); 6744 6745 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6746 size(4); 6747 ins_encode %{ 6748 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6749 __ dcbz($src$$Register, $mem$$base$$Register); 6750 %} 6751 ins_pipe(pipe_class_memory); 6752 %} 6753 6754 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6755 match(PrefetchAllocation mem); 6756 predicate(AllocatePrefetchStyle == 3); 6757 ins_cost(MEMORY_REF_COST); 6758 6759 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6760 size(4); 6761 ins_encode %{ 6762 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6763 __ dcbz($mem$$base$$Register); 6764 %} 6765 ins_pipe(pipe_class_memory); 6766 %} 6767 6768 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6769 match(PrefetchAllocation (AddP mem src)); 6770 predicate(AllocatePrefetchStyle != 3); 6771 ins_cost(MEMORY_REF_COST); 6772 6773 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6774 size(4); 6775 ins_encode %{ 6776 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6777 __ dcbtst($src$$Register, $mem$$base$$Register); 6778 %} 6779 ins_pipe(pipe_class_memory); 6780 %} 6781 6782 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6783 match(PrefetchAllocation mem); 6784 predicate(AllocatePrefetchStyle != 3); 6785 ins_cost(MEMORY_REF_COST); 6786 6787 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6788 size(4); 6789 ins_encode %{ 6790 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6791 __ dcbtst($mem$$base$$Register); 6792 %} 6793 ins_pipe(pipe_class_memory); 6794 %} 6795 6796 //----------Store Instructions------------------------------------------------- 6797 6798 // Store Byte 6799 instruct storeB(memory mem, iRegIsrc src) %{ 6800 match(Set mem (StoreB mem src)); 6801 ins_cost(MEMORY_REF_COST); 6802 6803 format %{ "STB $src, $mem \t// byte" %} 6804 size(4); 6805 ins_encode %{ 6806 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6807 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6808 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6809 %} 6810 ins_pipe(pipe_class_memory); 6811 %} 6812 6813 // Store Char/Short 6814 instruct storeC(memory mem, iRegIsrc src) %{ 6815 match(Set mem (StoreC mem src)); 6816 ins_cost(MEMORY_REF_COST); 6817 6818 format %{ "STH $src, $mem \t// short" %} 6819 size(4); 6820 ins_encode %{ 6821 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6822 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6823 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6824 %} 6825 ins_pipe(pipe_class_memory); 6826 %} 6827 6828 // Store Integer 6829 instruct storeI(memory mem, iRegIsrc src) %{ 6830 match(Set mem (StoreI mem src)); 6831 ins_cost(MEMORY_REF_COST); 6832 6833 format %{ "STW $src, $mem" %} 6834 size(4); 6835 ins_encode( enc_stw(src, mem) ); 6836 ins_pipe(pipe_class_memory); 6837 %} 6838 6839 // ConvL2I + StoreI. 6840 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6841 match(Set mem (StoreI mem (ConvL2I src))); 6842 ins_cost(MEMORY_REF_COST); 6843 6844 format %{ "STW l2i($src), $mem" %} 6845 size(4); 6846 ins_encode( enc_stw(src, mem) ); 6847 ins_pipe(pipe_class_memory); 6848 %} 6849 6850 // Store Long 6851 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6852 match(Set mem (StoreL mem src)); 6853 ins_cost(MEMORY_REF_COST); 6854 6855 format %{ "STD $src, $mem \t// long" %} 6856 size(4); 6857 ins_encode( enc_std(src, mem) ); 6858 ins_pipe(pipe_class_memory); 6859 %} 6860 6861 // Store super word nodes. 6862 6863 // Store Aligned Packed Byte long register to memory 6864 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6865 predicate(n->as_StoreVector()->memory_size() == 8); 6866 match(Set mem (StoreVector mem src)); 6867 ins_cost(MEMORY_REF_COST); 6868 6869 format %{ "STD $mem, $src \t// packed8B" %} 6870 size(4); 6871 ins_encode( enc_std(src, mem) ); 6872 ins_pipe(pipe_class_memory); 6873 %} 6874 6875 // Store Packed Byte long register to memory 6876 instruct storeV16(indirect mem, vecX src) %{ 6877 predicate(n->as_StoreVector()->memory_size() == 16); 6878 match(Set mem (StoreVector mem src)); 6879 ins_cost(MEMORY_REF_COST); 6880 6881 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6882 size(4); 6883 ins_encode %{ 6884 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6885 %} 6886 ins_pipe(pipe_class_default); 6887 %} 6888 6889 // Store Compressed Oop 6890 instruct storeN(memory dst, iRegN_P2N src) %{ 6891 match(Set dst (StoreN dst src)); 6892 ins_cost(MEMORY_REF_COST); 6893 6894 format %{ "STW $src, $dst \t// compressed oop" %} 6895 size(4); 6896 ins_encode( enc_stw(src, dst) ); 6897 ins_pipe(pipe_class_memory); 6898 %} 6899 6900 // Store Compressed KLass 6901 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6902 match(Set dst (StoreNKlass dst src)); 6903 ins_cost(MEMORY_REF_COST); 6904 6905 format %{ "STW $src, $dst \t// compressed klass" %} 6906 size(4); 6907 ins_encode( enc_stw(src, dst) ); 6908 ins_pipe(pipe_class_memory); 6909 %} 6910 6911 // Store Pointer 6912 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6913 match(Set dst (StoreP dst src)); 6914 ins_cost(MEMORY_REF_COST); 6915 6916 format %{ "STD $src, $dst \t// ptr" %} 6917 size(4); 6918 ins_encode( enc_std(src, dst) ); 6919 ins_pipe(pipe_class_memory); 6920 %} 6921 6922 // Store Float 6923 instruct storeF(memory mem, regF src) %{ 6924 match(Set mem (StoreF mem src)); 6925 ins_cost(MEMORY_REF_COST); 6926 6927 format %{ "STFS $src, $mem" %} 6928 size(4); 6929 ins_encode( enc_stfs(src, mem) ); 6930 ins_pipe(pipe_class_memory); 6931 %} 6932 6933 // Store Double 6934 instruct storeD(memory mem, regD src) %{ 6935 match(Set mem (StoreD mem src)); 6936 ins_cost(MEMORY_REF_COST); 6937 6938 format %{ "STFD $src, $mem" %} 6939 size(4); 6940 ins_encode( enc_stfd(src, mem) ); 6941 ins_pipe(pipe_class_memory); 6942 %} 6943 6944 //----------Store Instructions With Zeros-------------------------------------- 6945 6946 // Card-mark for CMS garbage collection. 6947 // This cardmark does an optimization so that it must not always 6948 // do a releasing store. For this, it gets the address of 6949 // CMSCollectorCardTableBarrierSetBSExt::_requires_release as input. 6950 // (Using releaseFieldAddr in the match rule is a hack.) 6951 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6952 match(Set mem (StoreCM mem releaseFieldAddr)); 6953 effect(TEMP crx); 6954 predicate(false); 6955 ins_cost(MEMORY_REF_COST); 6956 6957 // See loadConP. 6958 ins_cannot_rematerialize(true); 6959 6960 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6961 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6962 ins_pipe(pipe_class_memory); 6963 %} 6964 6965 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6966 match(Set mem (StoreCM mem zero)); 6967 predicate(UseG1GC); 6968 ins_cost(MEMORY_REF_COST); 6969 6970 ins_cannot_rematerialize(true); 6971 6972 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6973 size(8); 6974 ins_encode %{ 6975 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6976 __ li(R0, 0); 6977 //__ release(); // G1: oops are allowed to get visible after dirty marking 6978 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6979 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6980 %} 6981 ins_pipe(pipe_class_memory); 6982 %} 6983 6984 // Convert oop pointer into compressed form. 6985 6986 // Nodes for postalloc expand. 6987 6988 // Shift node for expand. 6989 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6990 // The match rule is needed to make it a 'MachTypeNode'! 6991 match(Set dst (EncodeP src)); 6992 predicate(false); 6993 6994 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6995 size(4); 6996 ins_encode %{ 6997 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6998 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 6999 %} 7000 ins_pipe(pipe_class_default); 7001 %} 7002 7003 // Add node for expand. 7004 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 7005 // The match rule is needed to make it a 'MachTypeNode'! 7006 match(Set dst (EncodeP src)); 7007 predicate(false); 7008 7009 format %{ "SUB $dst, $src, oop_base \t// encode" %} 7010 ins_encode %{ 7011 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7012 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 7013 %} 7014 ins_pipe(pipe_class_default); 7015 %} 7016 7017 // Conditional sub base. 7018 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7019 // The match rule is needed to make it a 'MachTypeNode'! 7020 match(Set dst (EncodeP (Binary crx src1))); 7021 predicate(false); 7022 7023 format %{ "BEQ $crx, done\n\t" 7024 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 7025 "done:" %} 7026 ins_encode %{ 7027 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7028 Label done; 7029 __ beq($crx$$CondRegister, done); 7030 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0); 7031 __ bind(done); 7032 %} 7033 ins_pipe(pipe_class_default); 7034 %} 7035 7036 // Power 7 can use isel instruction 7037 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7038 // The match rule is needed to make it a 'MachTypeNode'! 7039 match(Set dst (EncodeP (Binary crx src1))); 7040 predicate(false); 7041 7042 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 7043 size(4); 7044 ins_encode %{ 7045 // This is a Power7 instruction for which no machine description exists. 7046 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7047 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7048 %} 7049 ins_pipe(pipe_class_default); 7050 %} 7051 7052 // Disjoint narrow oop base. 7053 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7054 match(Set dst (EncodeP src)); 7055 predicate(CompressedOops::base_disjoint()); 7056 7057 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7058 size(4); 7059 ins_encode %{ 7060 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7061 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32); 7062 %} 7063 ins_pipe(pipe_class_default); 7064 %} 7065 7066 // shift != 0, base != 0 7067 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 7068 match(Set dst (EncodeP src)); 7069 effect(TEMP crx); 7070 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 7071 CompressedOops::shift() != 0 && 7072 CompressedOops::base_overlaps()); 7073 7074 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 7075 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 7076 %} 7077 7078 // shift != 0, base != 0 7079 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 7080 match(Set dst (EncodeP src)); 7081 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 7082 CompressedOops::shift() != 0 && 7083 CompressedOops::base_overlaps()); 7084 7085 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 7086 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 7087 %} 7088 7089 // shift != 0, base == 0 7090 // TODO: This is the same as encodeP_shift. Merge! 7091 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 7092 match(Set dst (EncodeP src)); 7093 predicate(CompressedOops::shift() != 0 && 7094 CompressedOops::base() ==0); 7095 7096 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 7097 size(4); 7098 ins_encode %{ 7099 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7100 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 7101 %} 7102 ins_pipe(pipe_class_default); 7103 %} 7104 7105 // Compressed OOPs with narrow_oop_shift == 0. 7106 // shift == 0, base == 0 7107 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 7108 match(Set dst (EncodeP src)); 7109 predicate(CompressedOops::shift() == 0); 7110 7111 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 7112 // variable size, 0 or 4. 7113 ins_encode %{ 7114 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7115 __ mr_if_needed($dst$$Register, $src$$Register); 7116 %} 7117 ins_pipe(pipe_class_default); 7118 %} 7119 7120 // Decode nodes. 7121 7122 // Shift node for expand. 7123 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 7124 // The match rule is needed to make it a 'MachTypeNode'! 7125 match(Set dst (DecodeN src)); 7126 predicate(false); 7127 7128 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 7129 size(4); 7130 ins_encode %{ 7131 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7132 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 7133 %} 7134 ins_pipe(pipe_class_default); 7135 %} 7136 7137 // Add node for expand. 7138 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7139 // The match rule is needed to make it a 'MachTypeNode'! 7140 match(Set dst (DecodeN src)); 7141 predicate(false); 7142 7143 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7144 ins_encode %{ 7145 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7146 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 7147 %} 7148 ins_pipe(pipe_class_default); 7149 %} 7150 7151 // conditianal add base for expand 7152 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7153 // The match rule is needed to make it a 'MachTypeNode'! 7154 // NOTICE that the rule is nonsense - we just have to make sure that: 7155 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7156 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7157 match(Set dst (DecodeN (Binary crx src))); 7158 predicate(false); 7159 7160 format %{ "BEQ $crx, done\n\t" 7161 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7162 "done:" %} 7163 ins_encode %{ 7164 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7165 Label done; 7166 __ beq($crx$$CondRegister, done); 7167 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 7168 __ bind(done); 7169 %} 7170 ins_pipe(pipe_class_default); 7171 %} 7172 7173 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7174 // The match rule is needed to make it a 'MachTypeNode'! 7175 // NOTICE that the rule is nonsense - we just have to make sure that: 7176 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7177 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7178 match(Set dst (DecodeN (Binary crx src1))); 7179 predicate(false); 7180 7181 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7182 size(4); 7183 ins_encode %{ 7184 // This is a Power7 instruction for which no machine description exists. 7185 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7186 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7187 %} 7188 ins_pipe(pipe_class_default); 7189 %} 7190 7191 // shift != 0, base != 0 7192 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7193 match(Set dst (DecodeN src)); 7194 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7195 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7196 CompressedOops::shift() != 0 && 7197 CompressedOops::base() != 0); 7198 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7199 effect(TEMP crx); 7200 7201 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7202 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7203 %} 7204 7205 // shift != 0, base == 0 7206 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7207 match(Set dst (DecodeN src)); 7208 predicate(CompressedOops::shift() != 0 && 7209 CompressedOops::base() == 0); 7210 7211 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7212 size(4); 7213 ins_encode %{ 7214 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7215 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 7216 %} 7217 ins_pipe(pipe_class_default); 7218 %} 7219 7220 // Optimize DecodeN for disjoint base. 7221 // Shift narrow oop and or it into register that already contains the heap base. 7222 // Base == dst must hold, and is assured by construction in postaloc_expand. 7223 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7224 match(Set dst (DecodeN src)); 7225 effect(TEMP base); 7226 predicate(false); 7227 7228 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7229 size(4); 7230 ins_encode %{ 7231 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7232 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift()); 7233 %} 7234 ins_pipe(pipe_class_default); 7235 %} 7236 7237 // Optimize DecodeN for disjoint base. 7238 // This node requires only one cycle on the critical path. 7239 // We must postalloc_expand as we can not express use_def effects where 7240 // the used register is L and the def'ed register P. 7241 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7242 match(Set dst (DecodeN src)); 7243 effect(TEMP_DEF dst); 7244 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7245 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7246 CompressedOops::base_disjoint()); 7247 ins_cost(DEFAULT_COST); 7248 7249 format %{ "MOV $dst, heapbase \t\n" 7250 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7251 postalloc_expand %{ 7252 loadBaseNode *n1 = new loadBaseNode(); 7253 n1->add_req(NULL); 7254 n1->_opnds[0] = op_dst; 7255 7256 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7257 n2->add_req(n_region, n_src, n1); 7258 n2->_opnds[0] = op_dst; 7259 n2->_opnds[1] = op_src; 7260 n2->_opnds[2] = op_dst; 7261 n2->_bottom_type = _bottom_type; 7262 7263 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7264 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7265 7266 nodes->push(n1); 7267 nodes->push(n2); 7268 %} 7269 %} 7270 7271 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7272 match(Set dst (DecodeN src)); 7273 effect(TEMP_DEF dst, TEMP crx); 7274 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7275 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7276 CompressedOops::base_disjoint() && VM_Version::has_isel()); 7277 ins_cost(3 * DEFAULT_COST); 7278 7279 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7280 postalloc_expand %{ 7281 loadBaseNode *n1 = new loadBaseNode(); 7282 n1->add_req(NULL); 7283 n1->_opnds[0] = op_dst; 7284 7285 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7286 n_compare->add_req(n_region, n_src); 7287 n_compare->_opnds[0] = op_crx; 7288 n_compare->_opnds[1] = op_src; 7289 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7290 7291 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7292 n2->add_req(n_region, n_src, n1); 7293 n2->_opnds[0] = op_dst; 7294 n2->_opnds[1] = op_src; 7295 n2->_opnds[2] = op_dst; 7296 n2->_bottom_type = _bottom_type; 7297 7298 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7299 n_cond_set->add_req(n_region, n_compare, n2); 7300 n_cond_set->_opnds[0] = op_dst; 7301 n_cond_set->_opnds[1] = op_crx; 7302 n_cond_set->_opnds[2] = op_dst; 7303 n_cond_set->_bottom_type = _bottom_type; 7304 7305 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7306 ra_->set_oop(n_cond_set, true); 7307 7308 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7309 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7310 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7311 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7312 7313 nodes->push(n1); 7314 nodes->push(n_compare); 7315 nodes->push(n2); 7316 nodes->push(n_cond_set); 7317 %} 7318 %} 7319 7320 // src != 0, shift != 0, base != 0 7321 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7322 match(Set dst (DecodeN src)); 7323 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7324 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7325 CompressedOops::shift() != 0 && 7326 CompressedOops::base() != 0); 7327 ins_cost(2 * DEFAULT_COST); 7328 7329 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7330 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7331 %} 7332 7333 // Compressed OOPs with narrow_oop_shift == 0. 7334 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7335 match(Set dst (DecodeN src)); 7336 predicate(CompressedOops::shift() == 0); 7337 ins_cost(DEFAULT_COST); 7338 7339 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7340 // variable size, 0 or 4. 7341 ins_encode %{ 7342 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7343 __ mr_if_needed($dst$$Register, $src$$Register); 7344 %} 7345 ins_pipe(pipe_class_default); 7346 %} 7347 7348 // Convert compressed oop into int for vectors alignment masking. 7349 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7350 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7351 predicate(CompressedOops::shift() == 0); 7352 ins_cost(DEFAULT_COST); 7353 7354 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7355 // variable size, 0 or 4. 7356 ins_encode %{ 7357 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7358 __ mr_if_needed($dst$$Register, $src$$Register); 7359 %} 7360 ins_pipe(pipe_class_default); 7361 %} 7362 7363 // Convert klass pointer into compressed form. 7364 7365 // Nodes for postalloc expand. 7366 7367 // Shift node for expand. 7368 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7369 // The match rule is needed to make it a 'MachTypeNode'! 7370 match(Set dst (EncodePKlass src)); 7371 predicate(false); 7372 7373 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7374 size(4); 7375 ins_encode %{ 7376 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7377 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 7378 %} 7379 ins_pipe(pipe_class_default); 7380 %} 7381 7382 // Add node for expand. 7383 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7384 // The match rule is needed to make it a 'MachTypeNode'! 7385 match(Set dst (EncodePKlass (Binary base src))); 7386 predicate(false); 7387 7388 format %{ "SUB $dst, $base, $src \t// encode" %} 7389 size(4); 7390 ins_encode %{ 7391 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7392 __ subf($dst$$Register, $base$$Register, $src$$Register); 7393 %} 7394 ins_pipe(pipe_class_default); 7395 %} 7396 7397 // Disjoint narrow oop base. 7398 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7399 match(Set dst (EncodePKlass src)); 7400 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/); 7401 7402 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7403 size(4); 7404 ins_encode %{ 7405 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7406 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32); 7407 %} 7408 ins_pipe(pipe_class_default); 7409 %} 7410 7411 // shift != 0, base != 0 7412 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7413 match(Set dst (EncodePKlass (Binary base src))); 7414 predicate(false); 7415 7416 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7417 postalloc_expand %{ 7418 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7419 n1->add_req(n_region, n_base, n_src); 7420 n1->_opnds[0] = op_dst; 7421 n1->_opnds[1] = op_base; 7422 n1->_opnds[2] = op_src; 7423 n1->_bottom_type = _bottom_type; 7424 7425 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7426 n2->add_req(n_region, n1); 7427 n2->_opnds[0] = op_dst; 7428 n2->_opnds[1] = op_dst; 7429 n2->_bottom_type = _bottom_type; 7430 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7431 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7432 7433 nodes->push(n1); 7434 nodes->push(n2); 7435 %} 7436 %} 7437 7438 // shift != 0, base != 0 7439 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7440 match(Set dst (EncodePKlass src)); 7441 //predicate(CompressedKlassPointers::shift() != 0 && 7442 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/); 7443 7444 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7445 ins_cost(DEFAULT_COST*2); // Don't count constant. 7446 expand %{ 7447 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %} 7448 iRegLdst base; 7449 loadConL_Ex(base, baseImm); 7450 encodePKlass_not_null_Ex(dst, base, src); 7451 %} 7452 %} 7453 7454 // Decode nodes. 7455 7456 // Shift node for expand. 7457 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7458 // The match rule is needed to make it a 'MachTypeNode'! 7459 match(Set dst (DecodeNKlass src)); 7460 predicate(false); 7461 7462 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7463 size(4); 7464 ins_encode %{ 7465 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7466 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 7467 %} 7468 ins_pipe(pipe_class_default); 7469 %} 7470 7471 // Add node for expand. 7472 7473 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7474 // The match rule is needed to make it a 'MachTypeNode'! 7475 match(Set dst (DecodeNKlass (Binary base src))); 7476 predicate(false); 7477 7478 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7479 size(4); 7480 ins_encode %{ 7481 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7482 __ add($dst$$Register, $base$$Register, $src$$Register); 7483 %} 7484 ins_pipe(pipe_class_default); 7485 %} 7486 7487 // src != 0, shift != 0, base != 0 7488 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7489 match(Set dst (DecodeNKlass (Binary base src))); 7490 //effect(kill src); // We need a register for the immediate result after shifting. 7491 predicate(false); 7492 7493 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7494 postalloc_expand %{ 7495 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7496 n1->add_req(n_region, n_base, n_src); 7497 n1->_opnds[0] = op_dst; 7498 n1->_opnds[1] = op_base; 7499 n1->_opnds[2] = op_src; 7500 n1->_bottom_type = _bottom_type; 7501 7502 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7503 n2->add_req(n_region, n1); 7504 n2->_opnds[0] = op_dst; 7505 n2->_opnds[1] = op_dst; 7506 n2->_bottom_type = _bottom_type; 7507 7508 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7509 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7510 7511 nodes->push(n1); 7512 nodes->push(n2); 7513 %} 7514 %} 7515 7516 // src != 0, shift != 0, base != 0 7517 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7518 match(Set dst (DecodeNKlass src)); 7519 // predicate(CompressedKlassPointers::shift() != 0 && 7520 // CompressedKlassPointers::base() != 0); 7521 7522 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7523 7524 ins_cost(DEFAULT_COST*2); // Don't count constant. 7525 expand %{ 7526 // We add first, then we shift. Like this, we can get along with one register less. 7527 // But we have to load the base pre-shifted. 7528 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %} 7529 iRegLdst base; 7530 loadConL_Ex(base, baseImm); 7531 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7532 %} 7533 %} 7534 7535 //----------MemBar Instructions----------------------------------------------- 7536 // Memory barrier flavors 7537 7538 instruct membar_acquire() %{ 7539 match(LoadFence); 7540 ins_cost(4*MEMORY_REF_COST); 7541 7542 format %{ "MEMBAR-acquire" %} 7543 size(4); 7544 ins_encode %{ 7545 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7546 __ acquire(); 7547 %} 7548 ins_pipe(pipe_class_default); 7549 %} 7550 7551 instruct unnecessary_membar_acquire() %{ 7552 match(MemBarAcquire); 7553 ins_cost(0); 7554 7555 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7556 size(0); 7557 ins_encode( /*empty*/ ); 7558 ins_pipe(pipe_class_default); 7559 %} 7560 7561 instruct membar_acquire_lock() %{ 7562 match(MemBarAcquireLock); 7563 ins_cost(0); 7564 7565 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7566 size(0); 7567 ins_encode( /*empty*/ ); 7568 ins_pipe(pipe_class_default); 7569 %} 7570 7571 instruct membar_release() %{ 7572 match(MemBarRelease); 7573 match(StoreFence); 7574 ins_cost(4*MEMORY_REF_COST); 7575 7576 format %{ "MEMBAR-release" %} 7577 size(4); 7578 ins_encode %{ 7579 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7580 __ release(); 7581 %} 7582 ins_pipe(pipe_class_default); 7583 %} 7584 7585 instruct membar_storestore() %{ 7586 match(MemBarStoreStore); 7587 ins_cost(4*MEMORY_REF_COST); 7588 7589 format %{ "MEMBAR-store-store" %} 7590 size(4); 7591 ins_encode %{ 7592 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7593 __ membar(Assembler::StoreStore); 7594 %} 7595 ins_pipe(pipe_class_default); 7596 %} 7597 7598 instruct membar_release_lock() %{ 7599 match(MemBarReleaseLock); 7600 ins_cost(0); 7601 7602 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7603 size(0); 7604 ins_encode( /*empty*/ ); 7605 ins_pipe(pipe_class_default); 7606 %} 7607 7608 instruct membar_volatile() %{ 7609 match(MemBarVolatile); 7610 ins_cost(4*MEMORY_REF_COST); 7611 7612 format %{ "MEMBAR-volatile" %} 7613 size(4); 7614 ins_encode %{ 7615 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7616 __ fence(); 7617 %} 7618 ins_pipe(pipe_class_default); 7619 %} 7620 7621 // This optimization is wrong on PPC. The following pattern is not supported: 7622 // MemBarVolatile 7623 // ^ ^ 7624 // | | 7625 // CtrlProj MemProj 7626 // ^ ^ 7627 // | | 7628 // | Load 7629 // | 7630 // MemBarVolatile 7631 // 7632 // The first MemBarVolatile could get optimized out! According to 7633 // Vladimir, this pattern can not occur on Oracle platforms. 7634 // However, it does occur on PPC64 (because of membars in 7635 // inline_unsafe_load_store). 7636 // 7637 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7638 // Don't forget to look at the implementation of post_store_load_barrier again, 7639 // we did other fixes in that method. 7640 //instruct unnecessary_membar_volatile() %{ 7641 // match(MemBarVolatile); 7642 // predicate(Matcher::post_store_load_barrier(n)); 7643 // ins_cost(0); 7644 // 7645 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7646 // size(0); 7647 // ins_encode( /*empty*/ ); 7648 // ins_pipe(pipe_class_default); 7649 //%} 7650 7651 instruct membar_CPUOrder() %{ 7652 match(MemBarCPUOrder); 7653 ins_cost(0); 7654 7655 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7656 size(0); 7657 ins_encode( /*empty*/ ); 7658 ins_pipe(pipe_class_default); 7659 %} 7660 7661 //----------Conditional Move--------------------------------------------------- 7662 7663 // Cmove using isel. 7664 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7665 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7666 predicate(VM_Version::has_isel()); 7667 ins_cost(DEFAULT_COST); 7668 7669 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7670 size(4); 7671 ins_encode %{ 7672 // This is a Power7 instruction for which no machine description 7673 // exists. Anyways, the scheduler should be off on Power7. 7674 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7675 int cc = $cmp$$cmpcode; 7676 __ isel($dst$$Register, $crx$$CondRegister, 7677 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7678 %} 7679 ins_pipe(pipe_class_default); 7680 %} 7681 7682 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7683 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7684 predicate(!VM_Version::has_isel()); 7685 ins_cost(DEFAULT_COST+BRANCH_COST); 7686 7687 ins_variable_size_depending_on_alignment(true); 7688 7689 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7690 // Worst case is branch + move + stop, no stop without scheduler 7691 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7692 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7693 ins_pipe(pipe_class_default); 7694 %} 7695 7696 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7697 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7698 ins_cost(DEFAULT_COST+BRANCH_COST); 7699 7700 ins_variable_size_depending_on_alignment(true); 7701 7702 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7703 // Worst case is branch + move + stop, no stop without scheduler 7704 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7705 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7706 ins_pipe(pipe_class_default); 7707 %} 7708 7709 // Cmove using isel. 7710 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7711 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7712 predicate(VM_Version::has_isel()); 7713 ins_cost(DEFAULT_COST); 7714 7715 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7716 size(4); 7717 ins_encode %{ 7718 // This is a Power7 instruction for which no machine description 7719 // exists. Anyways, the scheduler should be off on Power7. 7720 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7721 int cc = $cmp$$cmpcode; 7722 __ isel($dst$$Register, $crx$$CondRegister, 7723 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7724 %} 7725 ins_pipe(pipe_class_default); 7726 %} 7727 7728 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7729 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7730 predicate(!VM_Version::has_isel()); 7731 ins_cost(DEFAULT_COST+BRANCH_COST); 7732 7733 ins_variable_size_depending_on_alignment(true); 7734 7735 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7736 // Worst case is branch + move + stop, no stop without scheduler. 7737 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7738 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7739 ins_pipe(pipe_class_default); 7740 %} 7741 7742 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7743 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7744 ins_cost(DEFAULT_COST+BRANCH_COST); 7745 7746 ins_variable_size_depending_on_alignment(true); 7747 7748 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7749 // Worst case is branch + move + stop, no stop without scheduler. 7750 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7751 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7752 ins_pipe(pipe_class_default); 7753 %} 7754 7755 // Cmove using isel. 7756 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7757 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7758 predicate(VM_Version::has_isel()); 7759 ins_cost(DEFAULT_COST); 7760 7761 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7762 size(4); 7763 ins_encode %{ 7764 // This is a Power7 instruction for which no machine description 7765 // exists. Anyways, the scheduler should be off on Power7. 7766 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7767 int cc = $cmp$$cmpcode; 7768 __ isel($dst$$Register, $crx$$CondRegister, 7769 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7770 %} 7771 ins_pipe(pipe_class_default); 7772 %} 7773 7774 // Conditional move for RegN. Only cmov(reg, reg). 7775 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7776 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7777 predicate(!VM_Version::has_isel()); 7778 ins_cost(DEFAULT_COST+BRANCH_COST); 7779 7780 ins_variable_size_depending_on_alignment(true); 7781 7782 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7783 // Worst case is branch + move + stop, no stop without scheduler. 7784 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7785 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7786 ins_pipe(pipe_class_default); 7787 %} 7788 7789 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7790 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7791 ins_cost(DEFAULT_COST+BRANCH_COST); 7792 7793 ins_variable_size_depending_on_alignment(true); 7794 7795 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7796 // Worst case is branch + move + stop, no stop without scheduler. 7797 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7798 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7799 ins_pipe(pipe_class_default); 7800 %} 7801 7802 // Cmove using isel. 7803 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7804 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7805 predicate(VM_Version::has_isel()); 7806 ins_cost(DEFAULT_COST); 7807 7808 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7809 size(4); 7810 ins_encode %{ 7811 // This is a Power7 instruction for which no machine description 7812 // exists. Anyways, the scheduler should be off on Power7. 7813 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7814 int cc = $cmp$$cmpcode; 7815 __ isel($dst$$Register, $crx$$CondRegister, 7816 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7817 %} 7818 ins_pipe(pipe_class_default); 7819 %} 7820 7821 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7822 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7823 predicate(!VM_Version::has_isel()); 7824 ins_cost(DEFAULT_COST+BRANCH_COST); 7825 7826 ins_variable_size_depending_on_alignment(true); 7827 7828 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7829 // Worst case is branch + move + stop, no stop without scheduler. 7830 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7831 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7832 ins_pipe(pipe_class_default); 7833 %} 7834 7835 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7836 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7837 ins_cost(DEFAULT_COST+BRANCH_COST); 7838 7839 ins_variable_size_depending_on_alignment(true); 7840 7841 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7842 // Worst case is branch + move + stop, no stop without scheduler. 7843 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7844 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7845 ins_pipe(pipe_class_default); 7846 %} 7847 7848 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7849 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7850 ins_cost(DEFAULT_COST+BRANCH_COST); 7851 7852 ins_variable_size_depending_on_alignment(true); 7853 7854 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7855 // Worst case is branch + move + stop, no stop without scheduler. 7856 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7857 ins_encode %{ 7858 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7859 Label done; 7860 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7861 // Branch if not (cmp crx). 7862 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7863 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7864 // TODO PPC port __ endgroup_if_needed(_size == 12); 7865 __ bind(done); 7866 %} 7867 ins_pipe(pipe_class_default); 7868 %} 7869 7870 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7871 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7872 ins_cost(DEFAULT_COST+BRANCH_COST); 7873 7874 ins_variable_size_depending_on_alignment(true); 7875 7876 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7877 // Worst case is branch + move + stop, no stop without scheduler. 7878 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7879 ins_encode %{ 7880 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7881 Label done; 7882 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7883 // Branch if not (cmp crx). 7884 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7885 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7886 // TODO PPC port __ endgroup_if_needed(_size == 12); 7887 __ bind(done); 7888 %} 7889 ins_pipe(pipe_class_default); 7890 %} 7891 7892 //----------Conditional_store-------------------------------------------------- 7893 // Conditional-store of the updated heap-top. 7894 // Used during allocation of the shared heap. 7895 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7896 7897 // As compareAndSwapL, but return flag register instead of boolean value in 7898 // int register. 7899 // Used by sun/misc/AtomicLongCSImpl.java. 7900 // Mem_ptr must be a memory operand, else this node does not get 7901 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7902 // can be rematerialized which leads to errors. 7903 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7904 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7905 effect(TEMP cr0); 7906 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7907 ins_encode %{ 7908 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7909 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7910 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7911 noreg, NULL, true); 7912 %} 7913 ins_pipe(pipe_class_default); 7914 %} 7915 7916 // As compareAndSwapP, but return flag register instead of boolean value in 7917 // int register. 7918 // This instruction is matched if UseTLAB is off. 7919 // Mem_ptr must be a memory operand, else this node does not get 7920 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7921 // can be rematerialized which leads to errors. 7922 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7923 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7924 ins_cost(2*MEMORY_REF_COST); 7925 7926 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7927 ins_encode %{ 7928 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7929 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7930 %} 7931 ins_pipe(pipe_class_memory); 7932 %} 7933 7934 // Implement LoadPLocked. Must be ordered against changes of the memory location 7935 // by storePConditional. 7936 // Don't know whether this is ever used. 7937 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7938 match(Set dst (LoadPLocked mem)); 7939 ins_cost(2*MEMORY_REF_COST); 7940 7941 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7942 size(4); 7943 ins_encode %{ 7944 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7945 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7946 %} 7947 ins_pipe(pipe_class_memory); 7948 %} 7949 7950 //----------Compare-And-Swap--------------------------------------------------- 7951 7952 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7953 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7954 // matched. 7955 7956 // Strong versions: 7957 7958 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7959 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7960 predicate(VM_Version::has_lqarx()); 7961 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7962 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7963 ins_encode %{ 7964 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7965 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7966 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7967 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7968 $res$$Register, true); 7969 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7970 __ isync(); 7971 } else { 7972 __ sync(); 7973 } 7974 %} 7975 ins_pipe(pipe_class_default); 7976 %} 7977 7978 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7979 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7980 predicate(!VM_Version::has_lqarx()); 7981 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7982 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7983 ins_encode %{ 7984 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7985 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7986 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7987 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7988 $res$$Register, true); 7989 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7990 __ isync(); 7991 } else { 7992 __ sync(); 7993 } 7994 %} 7995 ins_pipe(pipe_class_default); 7996 %} 7997 7998 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7999 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 8000 predicate(VM_Version::has_lqarx()); 8001 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8002 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8003 ins_encode %{ 8004 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8005 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8006 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8007 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8008 $res$$Register, true); 8009 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8010 __ isync(); 8011 } else { 8012 __ sync(); 8013 } 8014 %} 8015 ins_pipe(pipe_class_default); 8016 %} 8017 8018 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8019 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 8020 predicate(!VM_Version::has_lqarx()); 8021 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8022 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8023 ins_encode %{ 8024 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8025 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8026 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8027 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8028 $res$$Register, true); 8029 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8030 __ isync(); 8031 } else { 8032 __ sync(); 8033 } 8034 %} 8035 ins_pipe(pipe_class_default); 8036 %} 8037 8038 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8039 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 8040 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8041 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8042 ins_encode %{ 8043 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8044 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8045 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8046 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8047 $res$$Register, true); 8048 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8049 __ isync(); 8050 } else { 8051 __ sync(); 8052 } 8053 %} 8054 ins_pipe(pipe_class_default); 8055 %} 8056 8057 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8058 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 8059 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8060 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8061 ins_encode %{ 8062 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8063 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8064 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8065 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8066 $res$$Register, true); 8067 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8068 __ isync(); 8069 } else { 8070 __ sync(); 8071 } 8072 %} 8073 ins_pipe(pipe_class_default); 8074 %} 8075 8076 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8077 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 8078 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8079 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8080 ins_encode %{ 8081 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8082 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8083 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8084 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8085 $res$$Register, NULL, true); 8086 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8087 __ isync(); 8088 } else { 8089 __ sync(); 8090 } 8091 %} 8092 ins_pipe(pipe_class_default); 8093 %} 8094 8095 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8096 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 8097 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8098 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8099 ins_encode %{ 8100 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8101 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8102 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8103 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8104 $res$$Register, NULL, true); 8105 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8106 __ isync(); 8107 } else { 8108 __ sync(); 8109 } 8110 %} 8111 ins_pipe(pipe_class_default); 8112 %} 8113 8114 // Weak versions: 8115 8116 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8117 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8118 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8119 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8120 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8121 ins_encode %{ 8122 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8123 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8124 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8125 MacroAssembler::MemBarNone, 8126 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8127 %} 8128 ins_pipe(pipe_class_default); 8129 %} 8130 8131 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8132 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8133 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8134 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8135 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8136 ins_encode %{ 8137 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8138 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8139 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8140 MacroAssembler::MemBarNone, 8141 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8142 %} 8143 ins_pipe(pipe_class_default); 8144 %} 8145 8146 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8147 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8148 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8149 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8150 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8151 ins_encode %{ 8152 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8153 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8154 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8155 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8156 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8157 %} 8158 ins_pipe(pipe_class_default); 8159 %} 8160 8161 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8162 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8163 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8164 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8165 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8166 ins_encode %{ 8167 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8168 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8169 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8170 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8171 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8172 %} 8173 ins_pipe(pipe_class_default); 8174 %} 8175 8176 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8177 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8178 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8179 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8180 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8181 ins_encode %{ 8182 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8183 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8184 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8185 MacroAssembler::MemBarNone, 8186 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8187 %} 8188 ins_pipe(pipe_class_default); 8189 %} 8190 8191 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8192 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8193 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8194 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8195 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8196 ins_encode %{ 8197 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8198 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8199 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8200 MacroAssembler::MemBarNone, 8201 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8202 %} 8203 ins_pipe(pipe_class_default); 8204 %} 8205 8206 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8207 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8208 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8209 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8210 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8211 ins_encode %{ 8212 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8213 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8214 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8215 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8216 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8217 %} 8218 ins_pipe(pipe_class_default); 8219 %} 8220 8221 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8222 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8223 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8224 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8225 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8226 ins_encode %{ 8227 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8228 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8229 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8230 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8231 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8232 %} 8233 ins_pipe(pipe_class_default); 8234 %} 8235 8236 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8237 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8238 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8239 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8240 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8241 ins_encode %{ 8242 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8243 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8244 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8245 MacroAssembler::MemBarNone, 8246 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8247 %} 8248 ins_pipe(pipe_class_default); 8249 %} 8250 8251 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8252 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8253 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8254 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8255 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8256 ins_encode %{ 8257 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8258 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8259 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8260 // value is never passed to caller. 8261 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8262 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8263 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8264 %} 8265 ins_pipe(pipe_class_default); 8266 %} 8267 8268 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8269 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8270 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8271 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8272 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8273 ins_encode %{ 8274 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8275 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8276 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8277 MacroAssembler::MemBarNone, 8278 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8279 %} 8280 ins_pipe(pipe_class_default); 8281 %} 8282 8283 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8284 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8285 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8286 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8287 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8288 ins_encode %{ 8289 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8290 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8291 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8292 // value is never passed to caller. 8293 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8294 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8295 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8296 %} 8297 ins_pipe(pipe_class_default); 8298 %} 8299 8300 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8301 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8302 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8303 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8304 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8305 ins_encode %{ 8306 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8307 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8308 // value is never passed to caller. 8309 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8310 MacroAssembler::MemBarNone, 8311 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8312 %} 8313 ins_pipe(pipe_class_default); 8314 %} 8315 8316 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8317 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8318 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8319 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8320 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 8321 ins_encode %{ 8322 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8323 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8324 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8325 // value is never passed to caller. 8326 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8327 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8328 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8329 %} 8330 ins_pipe(pipe_class_default); 8331 %} 8332 8333 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8334 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8335 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8336 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8337 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8338 ins_encode %{ 8339 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8340 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8341 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8342 MacroAssembler::MemBarNone, 8343 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8344 %} 8345 ins_pipe(pipe_class_default); 8346 %} 8347 8348 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8349 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8350 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8351 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8352 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8353 ins_encode %{ 8354 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8355 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8356 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8357 // value is never passed to caller. 8358 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8359 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8360 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8361 %} 8362 ins_pipe(pipe_class_default); 8363 %} 8364 8365 // CompareAndExchange 8366 8367 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8368 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8369 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8370 effect(TEMP_DEF res, TEMP cr0); 8371 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8372 ins_encode %{ 8373 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8374 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8375 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8376 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8377 noreg, true); 8378 %} 8379 ins_pipe(pipe_class_default); 8380 %} 8381 8382 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8383 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8384 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8385 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8386 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8387 ins_encode %{ 8388 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8389 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8390 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8391 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8392 noreg, true); 8393 %} 8394 ins_pipe(pipe_class_default); 8395 %} 8396 8397 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8398 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8399 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8400 effect(TEMP_DEF res, TEMP cr0); 8401 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8402 ins_encode %{ 8403 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8404 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8405 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8406 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8407 noreg, true); 8408 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8409 __ isync(); 8410 } else { 8411 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8412 __ sync(); 8413 } 8414 %} 8415 ins_pipe(pipe_class_default); 8416 %} 8417 8418 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8419 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8420 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8421 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8422 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8423 ins_encode %{ 8424 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8425 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8426 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8427 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8428 noreg, true); 8429 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8430 __ isync(); 8431 } else { 8432 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8433 __ sync(); 8434 } 8435 %} 8436 ins_pipe(pipe_class_default); 8437 %} 8438 8439 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8440 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8441 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8442 effect(TEMP_DEF res, TEMP cr0); 8443 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8444 ins_encode %{ 8445 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8446 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8447 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8448 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8449 noreg, true); 8450 %} 8451 ins_pipe(pipe_class_default); 8452 %} 8453 8454 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8455 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8456 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8457 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8458 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8459 ins_encode %{ 8460 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8461 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8462 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8463 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8464 noreg, true); 8465 %} 8466 ins_pipe(pipe_class_default); 8467 %} 8468 8469 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8470 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8471 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8472 effect(TEMP_DEF res, TEMP cr0); 8473 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8474 ins_encode %{ 8475 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8476 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8477 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8478 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8479 noreg, true); 8480 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8481 __ isync(); 8482 } else { 8483 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8484 __ sync(); 8485 } 8486 %} 8487 ins_pipe(pipe_class_default); 8488 %} 8489 8490 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8491 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8492 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8493 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8494 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8495 ins_encode %{ 8496 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8497 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8498 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8499 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8500 noreg, true); 8501 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8502 __ isync(); 8503 } else { 8504 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8505 __ sync(); 8506 } 8507 %} 8508 ins_pipe(pipe_class_default); 8509 %} 8510 8511 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8512 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8513 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8514 effect(TEMP_DEF res, TEMP cr0); 8515 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8516 ins_encode %{ 8517 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8518 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8519 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8520 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8521 noreg, true); 8522 %} 8523 ins_pipe(pipe_class_default); 8524 %} 8525 8526 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8527 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8528 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8529 effect(TEMP_DEF res, TEMP cr0); 8530 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8531 ins_encode %{ 8532 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8533 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8534 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8535 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8536 noreg, true); 8537 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8538 __ isync(); 8539 } else { 8540 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8541 __ sync(); 8542 } 8543 %} 8544 ins_pipe(pipe_class_default); 8545 %} 8546 8547 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8548 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8549 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8550 effect(TEMP_DEF res, TEMP cr0); 8551 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8552 ins_encode %{ 8553 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8554 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8555 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8556 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8557 noreg, true); 8558 %} 8559 ins_pipe(pipe_class_default); 8560 %} 8561 8562 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8563 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8564 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8565 effect(TEMP_DEF res, TEMP cr0); 8566 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8567 ins_encode %{ 8568 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8569 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8570 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8571 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8572 noreg, true); 8573 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8574 __ isync(); 8575 } else { 8576 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8577 __ sync(); 8578 } 8579 %} 8580 ins_pipe(pipe_class_default); 8581 %} 8582 8583 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8584 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8585 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8586 effect(TEMP_DEF res, TEMP cr0); 8587 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8588 ins_encode %{ 8589 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8590 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8591 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8592 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8593 noreg, NULL, true); 8594 %} 8595 ins_pipe(pipe_class_default); 8596 %} 8597 8598 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8599 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8600 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8601 effect(TEMP_DEF res, TEMP cr0); 8602 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8603 ins_encode %{ 8604 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8605 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8606 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8607 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8608 noreg, NULL, true); 8609 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8610 __ isync(); 8611 } else { 8612 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8613 __ sync(); 8614 } 8615 %} 8616 ins_pipe(pipe_class_default); 8617 %} 8618 8619 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8620 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8621 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8622 effect(TEMP_DEF res, TEMP cr0); 8623 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8624 ins_encode %{ 8625 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8626 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8627 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8628 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8629 noreg, NULL, true); 8630 %} 8631 ins_pipe(pipe_class_default); 8632 %} 8633 8634 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8635 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8636 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8637 effect(TEMP_DEF res, TEMP cr0); 8638 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8639 ins_encode %{ 8640 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8641 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8642 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8643 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8644 noreg, NULL, true); 8645 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8646 __ isync(); 8647 } else { 8648 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8649 __ sync(); 8650 } 8651 %} 8652 ins_pipe(pipe_class_default); 8653 %} 8654 8655 // Special RMW 8656 8657 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8658 match(Set res (GetAndAddB mem_ptr src)); 8659 predicate(VM_Version::has_lqarx()); 8660 effect(TEMP_DEF res, TEMP cr0); 8661 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8662 ins_encode %{ 8663 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8664 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8665 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8666 __ isync(); 8667 } else { 8668 __ sync(); 8669 } 8670 %} 8671 ins_pipe(pipe_class_default); 8672 %} 8673 8674 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8675 match(Set res (GetAndAddB mem_ptr src)); 8676 predicate(!VM_Version::has_lqarx()); 8677 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8678 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8679 ins_encode %{ 8680 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8681 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8682 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8683 __ isync(); 8684 } else { 8685 __ sync(); 8686 } 8687 %} 8688 ins_pipe(pipe_class_default); 8689 %} 8690 8691 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8692 match(Set res (GetAndAddS mem_ptr src)); 8693 predicate(VM_Version::has_lqarx()); 8694 effect(TEMP_DEF res, TEMP cr0); 8695 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8696 ins_encode %{ 8697 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8698 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8699 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8700 __ isync(); 8701 } else { 8702 __ sync(); 8703 } 8704 %} 8705 ins_pipe(pipe_class_default); 8706 %} 8707 8708 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8709 match(Set res (GetAndAddS mem_ptr src)); 8710 predicate(!VM_Version::has_lqarx()); 8711 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8712 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8713 ins_encode %{ 8714 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8715 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8716 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8717 __ isync(); 8718 } else { 8719 __ sync(); 8720 } 8721 %} 8722 ins_pipe(pipe_class_default); 8723 %} 8724 8725 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8726 match(Set res (GetAndAddI mem_ptr src)); 8727 effect(TEMP_DEF res, TEMP cr0); 8728 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8729 ins_encode %{ 8730 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8731 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8732 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8733 __ isync(); 8734 } else { 8735 __ sync(); 8736 } 8737 %} 8738 ins_pipe(pipe_class_default); 8739 %} 8740 8741 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8742 match(Set res (GetAndAddL mem_ptr src)); 8743 effect(TEMP_DEF res, TEMP cr0); 8744 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8745 ins_encode %{ 8746 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8747 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8748 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8749 __ isync(); 8750 } else { 8751 __ sync(); 8752 } 8753 %} 8754 ins_pipe(pipe_class_default); 8755 %} 8756 8757 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8758 match(Set res (GetAndSetB mem_ptr src)); 8759 predicate(VM_Version::has_lqarx()); 8760 effect(TEMP_DEF res, TEMP cr0); 8761 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8762 ins_encode %{ 8763 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8764 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8765 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8766 __ isync(); 8767 } else { 8768 __ sync(); 8769 } 8770 %} 8771 ins_pipe(pipe_class_default); 8772 %} 8773 8774 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8775 match(Set res (GetAndSetB mem_ptr src)); 8776 predicate(!VM_Version::has_lqarx()); 8777 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8778 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8779 ins_encode %{ 8780 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8781 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8782 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8783 __ isync(); 8784 } else { 8785 __ sync(); 8786 } 8787 %} 8788 ins_pipe(pipe_class_default); 8789 %} 8790 8791 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8792 match(Set res (GetAndSetS mem_ptr src)); 8793 predicate(VM_Version::has_lqarx()); 8794 effect(TEMP_DEF res, TEMP cr0); 8795 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8796 ins_encode %{ 8797 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8798 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8799 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8800 __ isync(); 8801 } else { 8802 __ sync(); 8803 } 8804 %} 8805 ins_pipe(pipe_class_default); 8806 %} 8807 8808 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8809 match(Set res (GetAndSetS mem_ptr src)); 8810 predicate(!VM_Version::has_lqarx()); 8811 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8812 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8813 ins_encode %{ 8814 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8815 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8816 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8817 __ isync(); 8818 } else { 8819 __ sync(); 8820 } 8821 %} 8822 ins_pipe(pipe_class_default); 8823 %} 8824 8825 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8826 match(Set res (GetAndSetI mem_ptr src)); 8827 effect(TEMP_DEF res, TEMP cr0); 8828 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8829 ins_encode %{ 8830 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8831 MacroAssembler::cmpxchgx_hint_atomic_update()); 8832 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8833 __ isync(); 8834 } else { 8835 __ sync(); 8836 } 8837 %} 8838 ins_pipe(pipe_class_default); 8839 %} 8840 8841 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8842 match(Set res (GetAndSetL mem_ptr src)); 8843 effect(TEMP_DEF res, TEMP cr0); 8844 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8845 ins_encode %{ 8846 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8847 MacroAssembler::cmpxchgx_hint_atomic_update()); 8848 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8849 __ isync(); 8850 } else { 8851 __ sync(); 8852 } 8853 %} 8854 ins_pipe(pipe_class_default); 8855 %} 8856 8857 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8858 match(Set res (GetAndSetP mem_ptr src)); 8859 effect(TEMP_DEF res, TEMP cr0); 8860 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8861 ins_encode %{ 8862 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8863 MacroAssembler::cmpxchgx_hint_atomic_update()); 8864 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8865 __ isync(); 8866 } else { 8867 __ sync(); 8868 } 8869 %} 8870 ins_pipe(pipe_class_default); 8871 %} 8872 8873 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8874 match(Set res (GetAndSetN mem_ptr src)); 8875 effect(TEMP_DEF res, TEMP cr0); 8876 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8877 ins_encode %{ 8878 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8879 MacroAssembler::cmpxchgx_hint_atomic_update()); 8880 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8881 __ isync(); 8882 } else { 8883 __ sync(); 8884 } 8885 %} 8886 ins_pipe(pipe_class_default); 8887 %} 8888 8889 //----------Arithmetic Instructions-------------------------------------------- 8890 // Addition Instructions 8891 8892 // Register Addition 8893 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8894 match(Set dst (AddI src1 src2)); 8895 format %{ "ADD $dst, $src1, $src2" %} 8896 size(4); 8897 ins_encode %{ 8898 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8899 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8900 %} 8901 ins_pipe(pipe_class_default); 8902 %} 8903 8904 // Expand does not work with above instruct. (??) 8905 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8906 // no match-rule 8907 effect(DEF dst, USE src1, USE src2); 8908 format %{ "ADD $dst, $src1, $src2" %} 8909 size(4); 8910 ins_encode %{ 8911 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8912 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8913 %} 8914 ins_pipe(pipe_class_default); 8915 %} 8916 8917 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8918 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8919 ins_cost(DEFAULT_COST*3); 8920 8921 expand %{ 8922 // FIXME: we should do this in the ideal world. 8923 iRegIdst tmp1; 8924 iRegIdst tmp2; 8925 addI_reg_reg(tmp1, src1, src2); 8926 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8927 addI_reg_reg(dst, tmp1, tmp2); 8928 %} 8929 %} 8930 8931 // Immediate Addition 8932 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8933 match(Set dst (AddI src1 src2)); 8934 format %{ "ADDI $dst, $src1, $src2" %} 8935 size(4); 8936 ins_encode %{ 8937 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8938 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8939 %} 8940 ins_pipe(pipe_class_default); 8941 %} 8942 8943 // Immediate Addition with 16-bit shifted operand 8944 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8945 match(Set dst (AddI src1 src2)); 8946 format %{ "ADDIS $dst, $src1, $src2" %} 8947 size(4); 8948 ins_encode %{ 8949 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8950 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8951 %} 8952 ins_pipe(pipe_class_default); 8953 %} 8954 8955 // Long Addition 8956 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8957 match(Set dst (AddL src1 src2)); 8958 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8959 size(4); 8960 ins_encode %{ 8961 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8962 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8963 %} 8964 ins_pipe(pipe_class_default); 8965 %} 8966 8967 // Expand does not work with above instruct. (??) 8968 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8969 // no match-rule 8970 effect(DEF dst, USE src1, USE src2); 8971 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8972 size(4); 8973 ins_encode %{ 8974 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8975 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8976 %} 8977 ins_pipe(pipe_class_default); 8978 %} 8979 8980 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8981 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8982 ins_cost(DEFAULT_COST*3); 8983 8984 expand %{ 8985 // FIXME: we should do this in the ideal world. 8986 iRegLdst tmp1; 8987 iRegLdst tmp2; 8988 addL_reg_reg(tmp1, src1, src2); 8989 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8990 addL_reg_reg(dst, tmp1, tmp2); 8991 %} 8992 %} 8993 8994 // AddL + ConvL2I. 8995 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8996 match(Set dst (ConvL2I (AddL src1 src2))); 8997 8998 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8999 size(4); 9000 ins_encode %{ 9001 // TODO: PPC port $archOpcode(ppc64Opcode_add); 9002 __ add($dst$$Register, $src1$$Register, $src2$$Register); 9003 %} 9004 ins_pipe(pipe_class_default); 9005 %} 9006 9007 // No constant pool entries required. 9008 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9009 match(Set dst (AddL src1 src2)); 9010 9011 format %{ "ADDI $dst, $src1, $src2" %} 9012 size(4); 9013 ins_encode %{ 9014 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 9015 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 9016 %} 9017 ins_pipe(pipe_class_default); 9018 %} 9019 9020 // Long Immediate Addition with 16-bit shifted operand. 9021 // No constant pool entries required. 9022 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 9023 match(Set dst (AddL src1 src2)); 9024 9025 format %{ "ADDIS $dst, $src1, $src2" %} 9026 size(4); 9027 ins_encode %{ 9028 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 9029 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 9030 %} 9031 ins_pipe(pipe_class_default); 9032 %} 9033 9034 // Pointer Register Addition 9035 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 9036 match(Set dst (AddP src1 src2)); 9037 format %{ "ADD $dst, $src1, $src2" %} 9038 size(4); 9039 ins_encode %{ 9040 // TODO: PPC port $archOpcode(ppc64Opcode_add); 9041 __ add($dst$$Register, $src1$$Register, $src2$$Register); 9042 %} 9043 ins_pipe(pipe_class_default); 9044 %} 9045 9046 // Pointer Immediate Addition 9047 // No constant pool entries required. 9048 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 9049 match(Set dst (AddP src1 src2)); 9050 9051 format %{ "ADDI $dst, $src1, $src2" %} 9052 size(4); 9053 ins_encode %{ 9054 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 9055 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 9056 %} 9057 ins_pipe(pipe_class_default); 9058 %} 9059 9060 // Pointer Immediate Addition with 16-bit shifted operand. 9061 // No constant pool entries required. 9062 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 9063 match(Set dst (AddP src1 src2)); 9064 9065 format %{ "ADDIS $dst, $src1, $src2" %} 9066 size(4); 9067 ins_encode %{ 9068 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 9069 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 9070 %} 9071 ins_pipe(pipe_class_default); 9072 %} 9073 9074 //--------------------- 9075 // Subtraction Instructions 9076 9077 // Register Subtraction 9078 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9079 match(Set dst (SubI src1 src2)); 9080 format %{ "SUBF $dst, $src2, $src1" %} 9081 size(4); 9082 ins_encode %{ 9083 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9084 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9085 %} 9086 ins_pipe(pipe_class_default); 9087 %} 9088 9089 // Immediate Subtraction 9090 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 9091 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 9092 9093 // SubI from constant (using subfic). 9094 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 9095 match(Set dst (SubI src1 src2)); 9096 format %{ "SUBI $dst, $src1, $src2" %} 9097 9098 size(4); 9099 ins_encode %{ 9100 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 9101 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 9102 %} 9103 ins_pipe(pipe_class_default); 9104 %} 9105 9106 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 9107 // positive integers and 0xF...F for negative ones. 9108 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 9109 // no match-rule, false predicate 9110 effect(DEF dst, USE src); 9111 predicate(false); 9112 9113 format %{ "SRAWI $dst, $src, #31" %} 9114 size(4); 9115 ins_encode %{ 9116 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9117 __ srawi($dst$$Register, $src$$Register, 0x1f); 9118 %} 9119 ins_pipe(pipe_class_default); 9120 %} 9121 9122 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 9123 match(Set dst (AbsI src)); 9124 ins_cost(DEFAULT_COST*3); 9125 9126 expand %{ 9127 iRegIdst tmp1; 9128 iRegIdst tmp2; 9129 signmask32I_regI(tmp1, src); 9130 xorI_reg_reg(tmp2, tmp1, src); 9131 subI_reg_reg(dst, tmp2, tmp1); 9132 %} 9133 %} 9134 9135 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9136 match(Set dst (SubI zero src2)); 9137 format %{ "NEG $dst, $src2" %} 9138 size(4); 9139 ins_encode %{ 9140 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9141 __ neg($dst$$Register, $src2$$Register); 9142 %} 9143 ins_pipe(pipe_class_default); 9144 %} 9145 9146 // Long subtraction 9147 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9148 match(Set dst (SubL src1 src2)); 9149 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9150 size(4); 9151 ins_encode %{ 9152 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9153 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9154 %} 9155 ins_pipe(pipe_class_default); 9156 %} 9157 9158 // SubL + convL2I. 9159 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9160 match(Set dst (ConvL2I (SubL src1 src2))); 9161 9162 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9163 size(4); 9164 ins_encode %{ 9165 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9166 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9167 %} 9168 ins_pipe(pipe_class_default); 9169 %} 9170 9171 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9172 // positive longs and 0xF...F for negative ones. 9173 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9174 // no match-rule, false predicate 9175 effect(DEF dst, USE src); 9176 predicate(false); 9177 9178 format %{ "SRADI $dst, $src, #63" %} 9179 size(4); 9180 ins_encode %{ 9181 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9182 __ sradi($dst$$Register, $src$$Register, 0x3f); 9183 %} 9184 ins_pipe(pipe_class_default); 9185 %} 9186 9187 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9188 // positive longs and 0xF...F for negative ones. 9189 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9190 // no match-rule, false predicate 9191 effect(DEF dst, USE src); 9192 predicate(false); 9193 9194 format %{ "SRADI $dst, $src, #63" %} 9195 size(4); 9196 ins_encode %{ 9197 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9198 __ sradi($dst$$Register, $src$$Register, 0x3f); 9199 %} 9200 ins_pipe(pipe_class_default); 9201 %} 9202 9203 // Long negation 9204 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9205 match(Set dst (SubL zero src2)); 9206 format %{ "NEG $dst, $src2 \t// long" %} 9207 size(4); 9208 ins_encode %{ 9209 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9210 __ neg($dst$$Register, $src2$$Register); 9211 %} 9212 ins_pipe(pipe_class_default); 9213 %} 9214 9215 // NegL + ConvL2I. 9216 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9217 match(Set dst (ConvL2I (SubL zero src2))); 9218 9219 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9220 size(4); 9221 ins_encode %{ 9222 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9223 __ neg($dst$$Register, $src2$$Register); 9224 %} 9225 ins_pipe(pipe_class_default); 9226 %} 9227 9228 // Multiplication Instructions 9229 // Integer Multiplication 9230 9231 // Register Multiplication 9232 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9233 match(Set dst (MulI src1 src2)); 9234 ins_cost(DEFAULT_COST); 9235 9236 format %{ "MULLW $dst, $src1, $src2" %} 9237 size(4); 9238 ins_encode %{ 9239 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9240 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9241 %} 9242 ins_pipe(pipe_class_default); 9243 %} 9244 9245 // Immediate Multiplication 9246 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9247 match(Set dst (MulI src1 src2)); 9248 ins_cost(DEFAULT_COST); 9249 9250 format %{ "MULLI $dst, $src1, $src2" %} 9251 size(4); 9252 ins_encode %{ 9253 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9254 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9255 %} 9256 ins_pipe(pipe_class_default); 9257 %} 9258 9259 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9260 match(Set dst (MulL src1 src2)); 9261 ins_cost(DEFAULT_COST); 9262 9263 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9264 size(4); 9265 ins_encode %{ 9266 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9267 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9268 %} 9269 ins_pipe(pipe_class_default); 9270 %} 9271 9272 // Multiply high for optimized long division by constant. 9273 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9274 match(Set dst (MulHiL src1 src2)); 9275 ins_cost(DEFAULT_COST); 9276 9277 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9278 size(4); 9279 ins_encode %{ 9280 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9281 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9282 %} 9283 ins_pipe(pipe_class_default); 9284 %} 9285 9286 // Immediate Multiplication 9287 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9288 match(Set dst (MulL src1 src2)); 9289 ins_cost(DEFAULT_COST); 9290 9291 format %{ "MULLI $dst, $src1, $src2" %} 9292 size(4); 9293 ins_encode %{ 9294 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9295 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9296 %} 9297 ins_pipe(pipe_class_default); 9298 %} 9299 9300 // Integer Division with Immediate -1: Negate. 9301 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9302 match(Set dst (DivI src1 src2)); 9303 ins_cost(DEFAULT_COST); 9304 9305 format %{ "NEG $dst, $src1 \t// /-1" %} 9306 size(4); 9307 ins_encode %{ 9308 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9309 __ neg($dst$$Register, $src1$$Register); 9310 %} 9311 ins_pipe(pipe_class_default); 9312 %} 9313 9314 // Integer Division with constant, but not -1. 9315 // We should be able to improve this by checking the type of src2. 9316 // It might well be that src2 is known to be positive. 9317 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9318 match(Set dst (DivI src1 src2)); 9319 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9320 ins_cost(2*DEFAULT_COST); 9321 9322 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9323 size(4); 9324 ins_encode %{ 9325 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9326 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9327 %} 9328 ins_pipe(pipe_class_default); 9329 %} 9330 9331 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9332 effect(USE_DEF dst, USE src1, USE crx); 9333 predicate(false); 9334 9335 ins_variable_size_depending_on_alignment(true); 9336 9337 format %{ "CMOVE $dst, neg($src1), $crx" %} 9338 // Worst case is branch + move + stop, no stop without scheduler. 9339 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9340 ins_encode %{ 9341 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9342 Label done; 9343 __ bne($crx$$CondRegister, done); 9344 __ neg($dst$$Register, $src1$$Register); 9345 // TODO PPC port __ endgroup_if_needed(_size == 12); 9346 __ bind(done); 9347 %} 9348 ins_pipe(pipe_class_default); 9349 %} 9350 9351 // Integer Division with Registers not containing constants. 9352 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9353 match(Set dst (DivI src1 src2)); 9354 ins_cost(10*DEFAULT_COST); 9355 9356 expand %{ 9357 immI16 imm %{ (int)-1 %} 9358 flagsReg tmp1; 9359 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9360 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9361 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9362 %} 9363 %} 9364 9365 // Long Division with Immediate -1: Negate. 9366 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9367 match(Set dst (DivL src1 src2)); 9368 ins_cost(DEFAULT_COST); 9369 9370 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9371 size(4); 9372 ins_encode %{ 9373 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9374 __ neg($dst$$Register, $src1$$Register); 9375 %} 9376 ins_pipe(pipe_class_default); 9377 %} 9378 9379 // Long Division with constant, but not -1. 9380 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9381 match(Set dst (DivL src1 src2)); 9382 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9383 ins_cost(2*DEFAULT_COST); 9384 9385 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9386 size(4); 9387 ins_encode %{ 9388 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9389 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9390 %} 9391 ins_pipe(pipe_class_default); 9392 %} 9393 9394 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9395 effect(USE_DEF dst, USE src1, USE crx); 9396 predicate(false); 9397 9398 ins_variable_size_depending_on_alignment(true); 9399 9400 format %{ "CMOVE $dst, neg($src1), $crx" %} 9401 // Worst case is branch + move + stop, no stop without scheduler. 9402 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9403 ins_encode %{ 9404 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9405 Label done; 9406 __ bne($crx$$CondRegister, done); 9407 __ neg($dst$$Register, $src1$$Register); 9408 // TODO PPC port __ endgroup_if_needed(_size == 12); 9409 __ bind(done); 9410 %} 9411 ins_pipe(pipe_class_default); 9412 %} 9413 9414 // Long Division with Registers not containing constants. 9415 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9416 match(Set dst (DivL src1 src2)); 9417 ins_cost(10*DEFAULT_COST); 9418 9419 expand %{ 9420 immL16 imm %{ (int)-1 %} 9421 flagsReg tmp1; 9422 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9423 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9424 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9425 %} 9426 %} 9427 9428 // Integer Remainder with registers. 9429 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9430 match(Set dst (ModI src1 src2)); 9431 ins_cost(10*DEFAULT_COST); 9432 9433 expand %{ 9434 immI16 imm %{ (int)-1 %} 9435 flagsReg tmp1; 9436 iRegIdst tmp2; 9437 iRegIdst tmp3; 9438 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9439 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9440 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9441 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9442 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9443 %} 9444 %} 9445 9446 // Long Remainder with registers 9447 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9448 match(Set dst (ModL src1 src2)); 9449 ins_cost(10*DEFAULT_COST); 9450 9451 expand %{ 9452 immL16 imm %{ (int)-1 %} 9453 flagsReg tmp1; 9454 iRegLdst tmp2; 9455 iRegLdst tmp3; 9456 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9457 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9458 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9459 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9460 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9461 %} 9462 %} 9463 9464 // Integer Shift Instructions 9465 9466 // Register Shift Left 9467 9468 // Clear all but the lowest #mask bits. 9469 // Used to normalize shift amounts in registers. 9470 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9471 // no match-rule, false predicate 9472 effect(DEF dst, USE src, USE mask); 9473 predicate(false); 9474 9475 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9476 size(4); 9477 ins_encode %{ 9478 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9479 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9480 %} 9481 ins_pipe(pipe_class_default); 9482 %} 9483 9484 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9485 // no match-rule, false predicate 9486 effect(DEF dst, USE src1, USE src2); 9487 predicate(false); 9488 9489 format %{ "SLW $dst, $src1, $src2" %} 9490 size(4); 9491 ins_encode %{ 9492 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9493 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9494 %} 9495 ins_pipe(pipe_class_default); 9496 %} 9497 9498 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9499 match(Set dst (LShiftI src1 src2)); 9500 ins_cost(DEFAULT_COST*2); 9501 expand %{ 9502 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9503 iRegIdst tmpI; 9504 maskI_reg_imm(tmpI, src2, mask); 9505 lShiftI_reg_reg(dst, src1, tmpI); 9506 %} 9507 %} 9508 9509 // Register Shift Left Immediate 9510 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9511 match(Set dst (LShiftI src1 src2)); 9512 9513 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9514 size(4); 9515 ins_encode %{ 9516 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9517 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9518 %} 9519 ins_pipe(pipe_class_default); 9520 %} 9521 9522 // AndI with negpow2-constant + LShiftI 9523 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9524 match(Set dst (LShiftI (AndI src1 src2) src3)); 9525 predicate(UseRotateAndMaskInstructionsPPC64); 9526 9527 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9528 size(4); 9529 ins_encode %{ 9530 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9531 long src2 = $src2$$constant; 9532 long src3 = $src3$$constant; 9533 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9534 if (maskbits >= 32) { 9535 __ li($dst$$Register, 0); // addi 9536 } else { 9537 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9538 } 9539 %} 9540 ins_pipe(pipe_class_default); 9541 %} 9542 9543 // RShiftI + AndI with negpow2-constant + LShiftI 9544 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9545 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9546 predicate(UseRotateAndMaskInstructionsPPC64); 9547 9548 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9549 size(4); 9550 ins_encode %{ 9551 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9552 long src2 = $src2$$constant; 9553 long src3 = $src3$$constant; 9554 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9555 if (maskbits >= 32) { 9556 __ li($dst$$Register, 0); // addi 9557 } else { 9558 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9559 } 9560 %} 9561 ins_pipe(pipe_class_default); 9562 %} 9563 9564 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9565 // no match-rule, false predicate 9566 effect(DEF dst, USE src1, USE src2); 9567 predicate(false); 9568 9569 format %{ "SLD $dst, $src1, $src2" %} 9570 size(4); 9571 ins_encode %{ 9572 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9573 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9574 %} 9575 ins_pipe(pipe_class_default); 9576 %} 9577 9578 // Register Shift Left 9579 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9580 match(Set dst (LShiftL src1 src2)); 9581 ins_cost(DEFAULT_COST*2); 9582 expand %{ 9583 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9584 iRegIdst tmpI; 9585 maskI_reg_imm(tmpI, src2, mask); 9586 lShiftL_regL_regI(dst, src1, tmpI); 9587 %} 9588 %} 9589 9590 // Register Shift Left Immediate 9591 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9592 match(Set dst (LShiftL src1 src2)); 9593 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9594 size(4); 9595 ins_encode %{ 9596 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9597 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9598 %} 9599 ins_pipe(pipe_class_default); 9600 %} 9601 9602 // If we shift more than 32 bits, we need not convert I2L. 9603 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9604 match(Set dst (LShiftL (ConvI2L src1) src2)); 9605 ins_cost(DEFAULT_COST); 9606 9607 size(4); 9608 format %{ "SLDI $dst, i2l($src1), $src2" %} 9609 ins_encode %{ 9610 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9611 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9612 %} 9613 ins_pipe(pipe_class_default); 9614 %} 9615 9616 // Shift a postivie int to the left. 9617 // Clrlsldi clears the upper 32 bits and shifts. 9618 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9619 match(Set dst (LShiftL (ConvI2L src1) src2)); 9620 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9621 9622 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9623 size(4); 9624 ins_encode %{ 9625 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9626 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9627 %} 9628 ins_pipe(pipe_class_default); 9629 %} 9630 9631 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9632 // no match-rule, false predicate 9633 effect(DEF dst, USE src1, USE src2); 9634 predicate(false); 9635 9636 format %{ "SRAW $dst, $src1, $src2" %} 9637 size(4); 9638 ins_encode %{ 9639 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9640 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9641 %} 9642 ins_pipe(pipe_class_default); 9643 %} 9644 9645 // Register Arithmetic Shift Right 9646 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9647 match(Set dst (RShiftI src1 src2)); 9648 ins_cost(DEFAULT_COST*2); 9649 expand %{ 9650 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9651 iRegIdst tmpI; 9652 maskI_reg_imm(tmpI, src2, mask); 9653 arShiftI_reg_reg(dst, src1, tmpI); 9654 %} 9655 %} 9656 9657 // Register Arithmetic Shift Right Immediate 9658 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9659 match(Set dst (RShiftI src1 src2)); 9660 9661 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9662 size(4); 9663 ins_encode %{ 9664 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9665 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9666 %} 9667 ins_pipe(pipe_class_default); 9668 %} 9669 9670 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9671 // no match-rule, false predicate 9672 effect(DEF dst, USE src1, USE src2); 9673 predicate(false); 9674 9675 format %{ "SRAD $dst, $src1, $src2" %} 9676 size(4); 9677 ins_encode %{ 9678 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9679 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9680 %} 9681 ins_pipe(pipe_class_default); 9682 %} 9683 9684 // Register Shift Right Arithmetic Long 9685 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9686 match(Set dst (RShiftL src1 src2)); 9687 ins_cost(DEFAULT_COST*2); 9688 9689 expand %{ 9690 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9691 iRegIdst tmpI; 9692 maskI_reg_imm(tmpI, src2, mask); 9693 arShiftL_regL_regI(dst, src1, tmpI); 9694 %} 9695 %} 9696 9697 // Register Shift Right Immediate 9698 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9699 match(Set dst (RShiftL src1 src2)); 9700 9701 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9702 size(4); 9703 ins_encode %{ 9704 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9705 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9706 %} 9707 ins_pipe(pipe_class_default); 9708 %} 9709 9710 // RShiftL + ConvL2I 9711 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9712 match(Set dst (ConvL2I (RShiftL src1 src2))); 9713 9714 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9715 size(4); 9716 ins_encode %{ 9717 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9718 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9719 %} 9720 ins_pipe(pipe_class_default); 9721 %} 9722 9723 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9724 // no match-rule, false predicate 9725 effect(DEF dst, USE src1, USE src2); 9726 predicate(false); 9727 9728 format %{ "SRW $dst, $src1, $src2" %} 9729 size(4); 9730 ins_encode %{ 9731 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9732 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9733 %} 9734 ins_pipe(pipe_class_default); 9735 %} 9736 9737 // Register Shift Right 9738 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9739 match(Set dst (URShiftI src1 src2)); 9740 ins_cost(DEFAULT_COST*2); 9741 9742 expand %{ 9743 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9744 iRegIdst tmpI; 9745 maskI_reg_imm(tmpI, src2, mask); 9746 urShiftI_reg_reg(dst, src1, tmpI); 9747 %} 9748 %} 9749 9750 // Register Shift Right Immediate 9751 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9752 match(Set dst (URShiftI src1 src2)); 9753 9754 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9755 size(4); 9756 ins_encode %{ 9757 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9758 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9759 %} 9760 ins_pipe(pipe_class_default); 9761 %} 9762 9763 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9764 // no match-rule, false predicate 9765 effect(DEF dst, USE src1, USE src2); 9766 predicate(false); 9767 9768 format %{ "SRD $dst, $src1, $src2" %} 9769 size(4); 9770 ins_encode %{ 9771 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9772 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9773 %} 9774 ins_pipe(pipe_class_default); 9775 %} 9776 9777 // Register Shift Right 9778 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9779 match(Set dst (URShiftL src1 src2)); 9780 ins_cost(DEFAULT_COST*2); 9781 9782 expand %{ 9783 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9784 iRegIdst tmpI; 9785 maskI_reg_imm(tmpI, src2, mask); 9786 urShiftL_regL_regI(dst, src1, tmpI); 9787 %} 9788 %} 9789 9790 // Register Shift Right Immediate 9791 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9792 match(Set dst (URShiftL src1 src2)); 9793 9794 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9795 size(4); 9796 ins_encode %{ 9797 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9798 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9799 %} 9800 ins_pipe(pipe_class_default); 9801 %} 9802 9803 // URShiftL + ConvL2I. 9804 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9805 match(Set dst (ConvL2I (URShiftL src1 src2))); 9806 9807 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9808 size(4); 9809 ins_encode %{ 9810 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9811 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9812 %} 9813 ins_pipe(pipe_class_default); 9814 %} 9815 9816 // Register Shift Right Immediate with a CastP2X 9817 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9818 match(Set dst (URShiftL (CastP2X src1) src2)); 9819 9820 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9821 size(4); 9822 ins_encode %{ 9823 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9824 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9825 %} 9826 ins_pipe(pipe_class_default); 9827 %} 9828 9829 // Bitfield Extract: URShiftI + AndI 9830 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9831 match(Set dst (AndI (URShiftI src1 src2) src3)); 9832 9833 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9834 size(4); 9835 ins_encode %{ 9836 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9837 int rshift = ($src2$$constant) & 0x1f; 9838 int length = log2_long(((jlong) $src3$$constant) + 1); 9839 if (rshift + length > 32) { 9840 // if necessary, adjust mask to omit rotated bits. 9841 length = 32 - rshift; 9842 } 9843 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9844 %} 9845 ins_pipe(pipe_class_default); 9846 %} 9847 9848 // Bitfield Extract: URShiftL + AndL 9849 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9850 match(Set dst (AndL (URShiftL src1 src2) src3)); 9851 9852 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9853 size(4); 9854 ins_encode %{ 9855 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9856 int rshift = ($src2$$constant) & 0x3f; 9857 int length = log2_long(((jlong) $src3$$constant) + 1); 9858 if (rshift + length > 64) { 9859 // if necessary, adjust mask to omit rotated bits. 9860 length = 64 - rshift; 9861 } 9862 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9863 %} 9864 ins_pipe(pipe_class_default); 9865 %} 9866 9867 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9868 match(Set dst (ConvL2I (ConvI2L src))); 9869 9870 format %{ "EXTSW $dst, $src \t// int->int" %} 9871 size(4); 9872 ins_encode %{ 9873 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9874 __ extsw($dst$$Register, $src$$Register); 9875 %} 9876 ins_pipe(pipe_class_default); 9877 %} 9878 9879 //----------Rotate Instructions------------------------------------------------ 9880 9881 // Rotate Left by 8-bit immediate 9882 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9883 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9884 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9885 9886 format %{ "ROTLWI $dst, $src, $lshift" %} 9887 size(4); 9888 ins_encode %{ 9889 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9890 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9891 %} 9892 ins_pipe(pipe_class_default); 9893 %} 9894 9895 // Rotate Right by 8-bit immediate 9896 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9897 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9898 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9899 9900 format %{ "ROTRWI $dst, $rshift" %} 9901 size(4); 9902 ins_encode %{ 9903 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9904 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9905 %} 9906 ins_pipe(pipe_class_default); 9907 %} 9908 9909 //----------Floating Point Arithmetic Instructions----------------------------- 9910 9911 // Add float single precision 9912 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9913 match(Set dst (AddF src1 src2)); 9914 9915 format %{ "FADDS $dst, $src1, $src2" %} 9916 size(4); 9917 ins_encode %{ 9918 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9919 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9920 %} 9921 ins_pipe(pipe_class_default); 9922 %} 9923 9924 // Add float double precision 9925 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9926 match(Set dst (AddD src1 src2)); 9927 9928 format %{ "FADD $dst, $src1, $src2" %} 9929 size(4); 9930 ins_encode %{ 9931 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9932 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9933 %} 9934 ins_pipe(pipe_class_default); 9935 %} 9936 9937 // Sub float single precision 9938 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9939 match(Set dst (SubF src1 src2)); 9940 9941 format %{ "FSUBS $dst, $src1, $src2" %} 9942 size(4); 9943 ins_encode %{ 9944 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9945 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9946 %} 9947 ins_pipe(pipe_class_default); 9948 %} 9949 9950 // Sub float double precision 9951 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9952 match(Set dst (SubD src1 src2)); 9953 format %{ "FSUB $dst, $src1, $src2" %} 9954 size(4); 9955 ins_encode %{ 9956 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9957 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9958 %} 9959 ins_pipe(pipe_class_default); 9960 %} 9961 9962 // Mul float single precision 9963 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9964 match(Set dst (MulF src1 src2)); 9965 format %{ "FMULS $dst, $src1, $src2" %} 9966 size(4); 9967 ins_encode %{ 9968 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9969 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9970 %} 9971 ins_pipe(pipe_class_default); 9972 %} 9973 9974 // Mul float double precision 9975 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9976 match(Set dst (MulD src1 src2)); 9977 format %{ "FMUL $dst, $src1, $src2" %} 9978 size(4); 9979 ins_encode %{ 9980 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9981 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9982 %} 9983 ins_pipe(pipe_class_default); 9984 %} 9985 9986 // Div float single precision 9987 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9988 match(Set dst (DivF src1 src2)); 9989 format %{ "FDIVS $dst, $src1, $src2" %} 9990 size(4); 9991 ins_encode %{ 9992 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9993 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9994 %} 9995 ins_pipe(pipe_class_default); 9996 %} 9997 9998 // Div float double precision 9999 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 10000 match(Set dst (DivD src1 src2)); 10001 format %{ "FDIV $dst, $src1, $src2" %} 10002 size(4); 10003 ins_encode %{ 10004 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 10005 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 10006 %} 10007 ins_pipe(pipe_class_default); 10008 %} 10009 10010 // Absolute float single precision 10011 instruct absF_reg(regF dst, regF src) %{ 10012 match(Set dst (AbsF src)); 10013 format %{ "FABS $dst, $src \t// float" %} 10014 size(4); 10015 ins_encode %{ 10016 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 10017 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 10018 %} 10019 ins_pipe(pipe_class_default); 10020 %} 10021 10022 // Absolute float double precision 10023 instruct absD_reg(regD dst, regD src) %{ 10024 match(Set dst (AbsD src)); 10025 format %{ "FABS $dst, $src \t// double" %} 10026 size(4); 10027 ins_encode %{ 10028 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 10029 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 10030 %} 10031 ins_pipe(pipe_class_default); 10032 %} 10033 10034 instruct negF_reg(regF dst, regF src) %{ 10035 match(Set dst (NegF src)); 10036 format %{ "FNEG $dst, $src \t// float" %} 10037 size(4); 10038 ins_encode %{ 10039 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 10040 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 10041 %} 10042 ins_pipe(pipe_class_default); 10043 %} 10044 10045 instruct negD_reg(regD dst, regD src) %{ 10046 match(Set dst (NegD src)); 10047 format %{ "FNEG $dst, $src \t// double" %} 10048 size(4); 10049 ins_encode %{ 10050 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 10051 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 10052 %} 10053 ins_pipe(pipe_class_default); 10054 %} 10055 10056 // AbsF + NegF. 10057 instruct negF_absF_reg(regF dst, regF src) %{ 10058 match(Set dst (NegF (AbsF src))); 10059 format %{ "FNABS $dst, $src \t// float" %} 10060 size(4); 10061 ins_encode %{ 10062 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10063 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10064 %} 10065 ins_pipe(pipe_class_default); 10066 %} 10067 10068 // AbsD + NegD. 10069 instruct negD_absD_reg(regD dst, regD src) %{ 10070 match(Set dst (NegD (AbsD src))); 10071 format %{ "FNABS $dst, $src \t// double" %} 10072 size(4); 10073 ins_encode %{ 10074 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10075 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10076 %} 10077 ins_pipe(pipe_class_default); 10078 %} 10079 10080 // VM_Version::has_fsqrt() decides if this node will be used. 10081 // Sqrt float double precision 10082 instruct sqrtD_reg(regD dst, regD src) %{ 10083 match(Set dst (SqrtD src)); 10084 format %{ "FSQRT $dst, $src" %} 10085 size(4); 10086 ins_encode %{ 10087 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 10088 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 10089 %} 10090 ins_pipe(pipe_class_default); 10091 %} 10092 10093 // Single-precision sqrt. 10094 instruct sqrtF_reg(regF dst, regF src) %{ 10095 match(Set dst (SqrtF src)); 10096 predicate(VM_Version::has_fsqrts()); 10097 ins_cost(DEFAULT_COST); 10098 10099 format %{ "FSQRTS $dst, $src" %} 10100 size(4); 10101 ins_encode %{ 10102 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 10103 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 10104 %} 10105 ins_pipe(pipe_class_default); 10106 %} 10107 10108 instruct roundDouble_nop(regD dst) %{ 10109 match(Set dst (RoundDouble dst)); 10110 ins_cost(0); 10111 10112 format %{ " -- \t// RoundDouble not needed - empty" %} 10113 size(0); 10114 // PPC results are already "rounded" (i.e., normal-format IEEE). 10115 ins_encode( /*empty*/ ); 10116 ins_pipe(pipe_class_default); 10117 %} 10118 10119 instruct roundFloat_nop(regF dst) %{ 10120 match(Set dst (RoundFloat dst)); 10121 ins_cost(0); 10122 10123 format %{ " -- \t// RoundFloat not needed - empty" %} 10124 size(0); 10125 // PPC results are already "rounded" (i.e., normal-format IEEE). 10126 ins_encode( /*empty*/ ); 10127 ins_pipe(pipe_class_default); 10128 %} 10129 10130 10131 // Multiply-Accumulate 10132 // src1 * src2 + src3 10133 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10134 match(Set dst (FmaF src3 (Binary src1 src2))); 10135 10136 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10137 size(4); 10138 ins_encode %{ 10139 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10140 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10141 %} 10142 ins_pipe(pipe_class_default); 10143 %} 10144 10145 // src1 * src2 + src3 10146 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10147 match(Set dst (FmaD src3 (Binary src1 src2))); 10148 10149 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10150 size(4); 10151 ins_encode %{ 10152 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10153 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10154 %} 10155 ins_pipe(pipe_class_default); 10156 %} 10157 10158 // -src1 * src2 + src3 = -(src1*src2-src3) 10159 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10160 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10161 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10162 10163 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10164 size(4); 10165 ins_encode %{ 10166 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10167 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10168 %} 10169 ins_pipe(pipe_class_default); 10170 %} 10171 10172 // -src1 * src2 + src3 = -(src1*src2-src3) 10173 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10174 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10175 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10176 10177 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10178 size(4); 10179 ins_encode %{ 10180 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10181 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10182 %} 10183 ins_pipe(pipe_class_default); 10184 %} 10185 10186 // -src1 * src2 - src3 = -(src1*src2+src3) 10187 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10188 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10189 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10190 10191 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10192 size(4); 10193 ins_encode %{ 10194 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10195 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10196 %} 10197 ins_pipe(pipe_class_default); 10198 %} 10199 10200 // -src1 * src2 - src3 = -(src1*src2+src3) 10201 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10202 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10203 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10204 10205 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10206 size(4); 10207 ins_encode %{ 10208 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10209 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10210 %} 10211 ins_pipe(pipe_class_default); 10212 %} 10213 10214 // src1 * src2 - src3 10215 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10216 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10217 10218 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10219 size(4); 10220 ins_encode %{ 10221 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10222 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10223 %} 10224 ins_pipe(pipe_class_default); 10225 %} 10226 10227 // src1 * src2 - src3 10228 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10229 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10230 10231 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10232 size(4); 10233 ins_encode %{ 10234 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10235 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10236 %} 10237 ins_pipe(pipe_class_default); 10238 %} 10239 10240 10241 //----------Logical Instructions----------------------------------------------- 10242 10243 // And Instructions 10244 10245 // Register And 10246 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10247 match(Set dst (AndI src1 src2)); 10248 format %{ "AND $dst, $src1, $src2" %} 10249 size(4); 10250 ins_encode %{ 10251 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10252 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10253 %} 10254 ins_pipe(pipe_class_default); 10255 %} 10256 10257 // Left shifted Immediate And 10258 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10259 match(Set dst (AndI src1 src2)); 10260 effect(KILL cr0); 10261 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10262 size(4); 10263 ins_encode %{ 10264 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10265 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10266 %} 10267 ins_pipe(pipe_class_default); 10268 %} 10269 10270 // Immediate And 10271 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10272 match(Set dst (AndI src1 src2)); 10273 effect(KILL cr0); 10274 10275 format %{ "ANDI $dst, $src1, $src2" %} 10276 size(4); 10277 ins_encode %{ 10278 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10279 // FIXME: avoid andi_ ? 10280 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10281 %} 10282 ins_pipe(pipe_class_default); 10283 %} 10284 10285 // Immediate And where the immediate is a negative power of 2. 10286 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10287 match(Set dst (AndI src1 src2)); 10288 format %{ "ANDWI $dst, $src1, $src2" %} 10289 size(4); 10290 ins_encode %{ 10291 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10292 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10293 %} 10294 ins_pipe(pipe_class_default); 10295 %} 10296 10297 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10298 match(Set dst (AndI src1 src2)); 10299 format %{ "ANDWI $dst, $src1, $src2" %} 10300 size(4); 10301 ins_encode %{ 10302 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10303 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10304 %} 10305 ins_pipe(pipe_class_default); 10306 %} 10307 10308 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10309 match(Set dst (AndI src1 src2)); 10310 predicate(UseRotateAndMaskInstructionsPPC64); 10311 format %{ "ANDWI $dst, $src1, $src2" %} 10312 size(4); 10313 ins_encode %{ 10314 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10315 __ rlwinm($dst$$Register, $src1$$Register, 0, 10316 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10317 %} 10318 ins_pipe(pipe_class_default); 10319 %} 10320 10321 // Register And Long 10322 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10323 match(Set dst (AndL src1 src2)); 10324 ins_cost(DEFAULT_COST); 10325 10326 format %{ "AND $dst, $src1, $src2 \t// long" %} 10327 size(4); 10328 ins_encode %{ 10329 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10330 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10331 %} 10332 ins_pipe(pipe_class_default); 10333 %} 10334 10335 // Immediate And long 10336 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10337 match(Set dst (AndL src1 src2)); 10338 effect(KILL cr0); 10339 10340 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10341 size(4); 10342 ins_encode %{ 10343 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10344 // FIXME: avoid andi_ ? 10345 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10346 %} 10347 ins_pipe(pipe_class_default); 10348 %} 10349 10350 // Immediate And Long where the immediate is a negative power of 2. 10351 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10352 match(Set dst (AndL src1 src2)); 10353 format %{ "ANDDI $dst, $src1, $src2" %} 10354 size(4); 10355 ins_encode %{ 10356 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10357 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10358 %} 10359 ins_pipe(pipe_class_default); 10360 %} 10361 10362 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10363 match(Set dst (AndL src1 src2)); 10364 format %{ "ANDDI $dst, $src1, $src2" %} 10365 size(4); 10366 ins_encode %{ 10367 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10368 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10369 %} 10370 ins_pipe(pipe_class_default); 10371 %} 10372 10373 // AndL + ConvL2I. 10374 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10375 match(Set dst (ConvL2I (AndL src1 src2))); 10376 ins_cost(DEFAULT_COST); 10377 10378 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10379 size(4); 10380 ins_encode %{ 10381 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10382 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10383 %} 10384 ins_pipe(pipe_class_default); 10385 %} 10386 10387 // Or Instructions 10388 10389 // Register Or 10390 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10391 match(Set dst (OrI src1 src2)); 10392 format %{ "OR $dst, $src1, $src2" %} 10393 size(4); 10394 ins_encode %{ 10395 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10396 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10397 %} 10398 ins_pipe(pipe_class_default); 10399 %} 10400 10401 // Expand does not work with above instruct. (??) 10402 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10403 // no match-rule 10404 effect(DEF dst, USE src1, USE src2); 10405 format %{ "OR $dst, $src1, $src2" %} 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 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10415 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10416 ins_cost(DEFAULT_COST*3); 10417 10418 expand %{ 10419 // FIXME: we should do this in the ideal world. 10420 iRegIdst tmp1; 10421 iRegIdst tmp2; 10422 orI_reg_reg(tmp1, src1, src2); 10423 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10424 orI_reg_reg(dst, tmp1, tmp2); 10425 %} 10426 %} 10427 10428 // Immediate Or 10429 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10430 match(Set dst (OrI src1 src2)); 10431 format %{ "ORI $dst, $src1, $src2" %} 10432 size(4); 10433 ins_encode %{ 10434 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10435 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10436 %} 10437 ins_pipe(pipe_class_default); 10438 %} 10439 10440 // Register Or Long 10441 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10442 match(Set dst (OrL src1 src2)); 10443 ins_cost(DEFAULT_COST); 10444 10445 size(4); 10446 format %{ "OR $dst, $src1, $src2 \t// long" %} 10447 ins_encode %{ 10448 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10449 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10450 %} 10451 ins_pipe(pipe_class_default); 10452 %} 10453 10454 // OrL + ConvL2I. 10455 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10456 match(Set dst (ConvL2I (OrL src1 src2))); 10457 ins_cost(DEFAULT_COST); 10458 10459 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10460 size(4); 10461 ins_encode %{ 10462 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10463 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10464 %} 10465 ins_pipe(pipe_class_default); 10466 %} 10467 10468 // Immediate Or long 10469 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10470 match(Set dst (OrL src1 con)); 10471 ins_cost(DEFAULT_COST); 10472 10473 format %{ "ORI $dst, $src1, $con \t// long" %} 10474 size(4); 10475 ins_encode %{ 10476 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10477 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10478 %} 10479 ins_pipe(pipe_class_default); 10480 %} 10481 10482 // Xor Instructions 10483 10484 // Register Xor 10485 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10486 match(Set dst (XorI src1 src2)); 10487 format %{ "XOR $dst, $src1, $src2" %} 10488 size(4); 10489 ins_encode %{ 10490 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10491 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10492 %} 10493 ins_pipe(pipe_class_default); 10494 %} 10495 10496 // Expand does not work with above instruct. (??) 10497 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10498 // no match-rule 10499 effect(DEF dst, USE src1, USE src2); 10500 format %{ "XOR $dst, $src1, $src2" %} 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 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10510 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10511 ins_cost(DEFAULT_COST*3); 10512 10513 expand %{ 10514 // FIXME: we should do this in the ideal world. 10515 iRegIdst tmp1; 10516 iRegIdst tmp2; 10517 xorI_reg_reg(tmp1, src1, src2); 10518 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10519 xorI_reg_reg(dst, tmp1, tmp2); 10520 %} 10521 %} 10522 10523 // Immediate Xor 10524 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10525 match(Set dst (XorI src1 src2)); 10526 format %{ "XORI $dst, $src1, $src2" %} 10527 size(4); 10528 ins_encode %{ 10529 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10530 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10531 %} 10532 ins_pipe(pipe_class_default); 10533 %} 10534 10535 // Register Xor Long 10536 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10537 match(Set dst (XorL src1 src2)); 10538 ins_cost(DEFAULT_COST); 10539 10540 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10541 size(4); 10542 ins_encode %{ 10543 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10544 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10545 %} 10546 ins_pipe(pipe_class_default); 10547 %} 10548 10549 // XorL + ConvL2I. 10550 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10551 match(Set dst (ConvL2I (XorL src1 src2))); 10552 ins_cost(DEFAULT_COST); 10553 10554 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10555 size(4); 10556 ins_encode %{ 10557 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10558 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10559 %} 10560 ins_pipe(pipe_class_default); 10561 %} 10562 10563 // Immediate Xor Long 10564 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10565 match(Set dst (XorL src1 src2)); 10566 ins_cost(DEFAULT_COST); 10567 10568 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10569 size(4); 10570 ins_encode %{ 10571 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10572 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10573 %} 10574 ins_pipe(pipe_class_default); 10575 %} 10576 10577 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10578 match(Set dst (XorI src1 src2)); 10579 ins_cost(DEFAULT_COST); 10580 10581 format %{ "NOT $dst, $src1 ($src2)" %} 10582 size(4); 10583 ins_encode %{ 10584 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10585 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10586 %} 10587 ins_pipe(pipe_class_default); 10588 %} 10589 10590 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10591 match(Set dst (XorL src1 src2)); 10592 ins_cost(DEFAULT_COST); 10593 10594 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10595 size(4); 10596 ins_encode %{ 10597 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10598 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10599 %} 10600 ins_pipe(pipe_class_default); 10601 %} 10602 10603 // And-complement 10604 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10605 match(Set dst (AndI (XorI src1 src2) src3)); 10606 ins_cost(DEFAULT_COST); 10607 10608 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10609 size(4); 10610 ins_encode( enc_andc(dst, src3, src1) ); 10611 ins_pipe(pipe_class_default); 10612 %} 10613 10614 // And-complement 10615 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10616 // no match-rule, false predicate 10617 effect(DEF dst, USE src1, USE src2); 10618 predicate(false); 10619 10620 format %{ "ANDC $dst, $src1, $src2" %} 10621 size(4); 10622 ins_encode %{ 10623 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10624 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10625 %} 10626 ins_pipe(pipe_class_default); 10627 %} 10628 10629 //----------Moves between int/long and float/double---------------------------- 10630 // 10631 // The following rules move values from int/long registers/stack-locations 10632 // to float/double registers/stack-locations and vice versa, without doing any 10633 // conversions. These rules are used to implement the bit-conversion methods 10634 // of java.lang.Float etc., e.g. 10635 // int floatToIntBits(float value) 10636 // float intBitsToFloat(int bits) 10637 // 10638 // Notes on the implementation on ppc64: 10639 // For Power7 and earlier, the rules are limited to those which move between a 10640 // register and a stack-location, because we always have to go through memory 10641 // when moving between a float register and an integer register. 10642 // This restriction is removed in Power8 with the introduction of the mtfprd 10643 // and mffprd instructions. 10644 10645 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10646 match(Set dst (MoveL2D src)); 10647 predicate(VM_Version::has_mtfprd()); 10648 10649 format %{ "MTFPRD $dst, $src" %} 10650 size(4); 10651 ins_encode %{ 10652 __ mtfprd($dst$$FloatRegister, $src$$Register); 10653 %} 10654 ins_pipe(pipe_class_default); 10655 %} 10656 10657 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10658 // no match-rule, false predicate 10659 effect(DEF dst, USE src); 10660 predicate(false); 10661 10662 format %{ "MTFPRWA $dst, $src" %} 10663 size(4); 10664 ins_encode %{ 10665 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10666 %} 10667 ins_pipe(pipe_class_default); 10668 %} 10669 10670 //---------- Chain stack slots between similar types -------- 10671 10672 // These are needed so that the rules below can match. 10673 10674 // Load integer from stack slot 10675 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10676 match(Set dst src); 10677 ins_cost(MEMORY_REF_COST); 10678 10679 format %{ "LWZ $dst, $src" %} 10680 size(4); 10681 ins_encode( enc_lwz(dst, src) ); 10682 ins_pipe(pipe_class_memory); 10683 %} 10684 10685 // Store integer to stack slot 10686 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10687 match(Set dst src); 10688 ins_cost(MEMORY_REF_COST); 10689 10690 format %{ "STW $src, $dst \t// stk" %} 10691 size(4); 10692 ins_encode( enc_stw(src, dst) ); // rs=rt 10693 ins_pipe(pipe_class_memory); 10694 %} 10695 10696 // Load long from stack slot 10697 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10698 match(Set dst src); 10699 ins_cost(MEMORY_REF_COST); 10700 10701 format %{ "LD $dst, $src \t// long" %} 10702 size(4); 10703 ins_encode( enc_ld(dst, src) ); 10704 ins_pipe(pipe_class_memory); 10705 %} 10706 10707 // Store long to stack slot 10708 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10709 match(Set dst src); 10710 ins_cost(MEMORY_REF_COST); 10711 10712 format %{ "STD $src, $dst \t// long" %} 10713 size(4); 10714 ins_encode( enc_std(src, dst) ); // rs=rt 10715 ins_pipe(pipe_class_memory); 10716 %} 10717 10718 //----------Moves between int and float 10719 10720 // Move float value from float stack-location to integer register. 10721 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10722 match(Set dst (MoveF2I src)); 10723 ins_cost(MEMORY_REF_COST); 10724 10725 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10726 size(4); 10727 ins_encode( enc_lwz(dst, src) ); 10728 ins_pipe(pipe_class_memory); 10729 %} 10730 10731 // Move float value from float register to integer stack-location. 10732 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10733 match(Set dst (MoveF2I src)); 10734 ins_cost(MEMORY_REF_COST); 10735 10736 format %{ "STFS $src, $dst \t// MoveF2I" %} 10737 size(4); 10738 ins_encode( enc_stfs(src, dst) ); 10739 ins_pipe(pipe_class_memory); 10740 %} 10741 10742 // Move integer value from integer stack-location to float register. 10743 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10744 match(Set dst (MoveI2F src)); 10745 ins_cost(MEMORY_REF_COST); 10746 10747 format %{ "LFS $dst, $src \t// MoveI2F" %} 10748 size(4); 10749 ins_encode %{ 10750 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10751 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10752 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10753 %} 10754 ins_pipe(pipe_class_memory); 10755 %} 10756 10757 // Move integer value from integer register to float stack-location. 10758 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10759 match(Set dst (MoveI2F src)); 10760 ins_cost(MEMORY_REF_COST); 10761 10762 format %{ "STW $src, $dst \t// MoveI2F" %} 10763 size(4); 10764 ins_encode( enc_stw(src, dst) ); 10765 ins_pipe(pipe_class_memory); 10766 %} 10767 10768 //----------Moves between long and float 10769 10770 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10771 // no match-rule, false predicate 10772 effect(DEF dst, USE src); 10773 predicate(false); 10774 10775 format %{ "storeD $src, $dst \t// STACK" %} 10776 size(4); 10777 ins_encode( enc_stfd(src, dst) ); 10778 ins_pipe(pipe_class_default); 10779 %} 10780 10781 //----------Moves between long and double 10782 10783 // Move double value from double stack-location to long register. 10784 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10785 match(Set dst (MoveD2L src)); 10786 ins_cost(MEMORY_REF_COST); 10787 size(4); 10788 format %{ "LD $dst, $src \t// MoveD2L" %} 10789 ins_encode( enc_ld(dst, src) ); 10790 ins_pipe(pipe_class_memory); 10791 %} 10792 10793 // Move double value from double register to long stack-location. 10794 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10795 match(Set dst (MoveD2L src)); 10796 effect(DEF dst, USE src); 10797 ins_cost(MEMORY_REF_COST); 10798 10799 format %{ "STFD $src, $dst \t// MoveD2L" %} 10800 size(4); 10801 ins_encode( enc_stfd(src, dst) ); 10802 ins_pipe(pipe_class_memory); 10803 %} 10804 10805 // Move long value from long stack-location to double register. 10806 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10807 match(Set dst (MoveL2D src)); 10808 ins_cost(MEMORY_REF_COST); 10809 10810 format %{ "LFD $dst, $src \t// MoveL2D" %} 10811 size(4); 10812 ins_encode( enc_lfd(dst, src) ); 10813 ins_pipe(pipe_class_memory); 10814 %} 10815 10816 // Move long value from long register to double stack-location. 10817 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10818 match(Set dst (MoveL2D src)); 10819 ins_cost(MEMORY_REF_COST); 10820 10821 format %{ "STD $src, $dst \t// MoveL2D" %} 10822 size(4); 10823 ins_encode( enc_std(src, dst) ); 10824 ins_pipe(pipe_class_memory); 10825 %} 10826 10827 //----------Register Move Instructions----------------------------------------- 10828 10829 // Replicate for Superword 10830 10831 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10832 predicate(false); 10833 effect(DEF dst, USE src); 10834 10835 format %{ "MR $dst, $src \t// replicate " %} 10836 // variable size, 0 or 4. 10837 ins_encode %{ 10838 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10839 __ mr_if_needed($dst$$Register, $src$$Register); 10840 %} 10841 ins_pipe(pipe_class_default); 10842 %} 10843 10844 //----------Cast instructions (Java-level type cast)--------------------------- 10845 10846 // Cast Long to Pointer for unsafe natives. 10847 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10848 match(Set dst (CastX2P src)); 10849 10850 format %{ "MR $dst, $src \t// Long->Ptr" %} 10851 // variable size, 0 or 4. 10852 ins_encode %{ 10853 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10854 __ mr_if_needed($dst$$Register, $src$$Register); 10855 %} 10856 ins_pipe(pipe_class_default); 10857 %} 10858 10859 // Cast Pointer to Long for unsafe natives. 10860 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10861 match(Set dst (CastP2X src)); 10862 10863 format %{ "MR $dst, $src \t// Ptr->Long" %} 10864 // variable size, 0 or 4. 10865 ins_encode %{ 10866 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10867 __ mr_if_needed($dst$$Register, $src$$Register); 10868 %} 10869 ins_pipe(pipe_class_default); 10870 %} 10871 10872 instruct castPP(iRegPdst dst) %{ 10873 match(Set dst (CastPP dst)); 10874 format %{ " -- \t// castPP of $dst" %} 10875 size(0); 10876 ins_encode( /*empty*/ ); 10877 ins_pipe(pipe_class_default); 10878 %} 10879 10880 instruct castII(iRegIdst dst) %{ 10881 match(Set dst (CastII dst)); 10882 format %{ " -- \t// castII of $dst" %} 10883 size(0); 10884 ins_encode( /*empty*/ ); 10885 ins_pipe(pipe_class_default); 10886 %} 10887 10888 instruct checkCastPP(iRegPdst dst) %{ 10889 match(Set dst (CheckCastPP dst)); 10890 format %{ " -- \t// checkcastPP of $dst" %} 10891 size(0); 10892 ins_encode( /*empty*/ ); 10893 ins_pipe(pipe_class_default); 10894 %} 10895 10896 //----------Convert instructions----------------------------------------------- 10897 10898 // Convert to boolean. 10899 10900 // int_to_bool(src) : { 1 if src != 0 10901 // { 0 else 10902 // 10903 // strategy: 10904 // 1) Count leading zeros of 32 bit-value src, 10905 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10906 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10907 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10908 10909 // convI2Bool 10910 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10911 match(Set dst (Conv2B src)); 10912 predicate(UseCountLeadingZerosInstructionsPPC64); 10913 ins_cost(DEFAULT_COST); 10914 10915 expand %{ 10916 immI shiftAmount %{ 0x5 %} 10917 uimmI16 mask %{ 0x1 %} 10918 iRegIdst tmp1; 10919 iRegIdst tmp2; 10920 countLeadingZerosI(tmp1, src); 10921 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10922 xorI_reg_uimm16(dst, tmp2, mask); 10923 %} 10924 %} 10925 10926 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10927 match(Set dst (Conv2B src)); 10928 effect(TEMP crx); 10929 predicate(!UseCountLeadingZerosInstructionsPPC64); 10930 ins_cost(DEFAULT_COST); 10931 10932 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10933 "LI $dst, #0\n\t" 10934 "BEQ $crx, done\n\t" 10935 "LI $dst, #1\n" 10936 "done:" %} 10937 size(16); 10938 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10939 ins_pipe(pipe_class_compare); 10940 %} 10941 10942 // ConvI2B + XorI 10943 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10944 match(Set dst (XorI (Conv2B src) mask)); 10945 predicate(UseCountLeadingZerosInstructionsPPC64); 10946 ins_cost(DEFAULT_COST); 10947 10948 expand %{ 10949 immI shiftAmount %{ 0x5 %} 10950 iRegIdst tmp1; 10951 countLeadingZerosI(tmp1, src); 10952 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10953 %} 10954 %} 10955 10956 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10957 match(Set dst (XorI (Conv2B src) mask)); 10958 effect(TEMP crx); 10959 predicate(!UseCountLeadingZerosInstructionsPPC64); 10960 ins_cost(DEFAULT_COST); 10961 10962 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10963 "LI $dst, #1\n\t" 10964 "BEQ $crx, done\n\t" 10965 "LI $dst, #0\n" 10966 "done:" %} 10967 size(16); 10968 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10969 ins_pipe(pipe_class_compare); 10970 %} 10971 10972 // AndI 0b0..010..0 + ConvI2B 10973 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10974 match(Set dst (Conv2B (AndI src mask))); 10975 predicate(UseRotateAndMaskInstructionsPPC64); 10976 ins_cost(DEFAULT_COST); 10977 10978 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10979 size(4); 10980 ins_encode %{ 10981 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10982 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10983 %} 10984 ins_pipe(pipe_class_default); 10985 %} 10986 10987 // Convert pointer to boolean. 10988 // 10989 // ptr_to_bool(src) : { 1 if src != 0 10990 // { 0 else 10991 // 10992 // strategy: 10993 // 1) Count leading zeros of 64 bit-value src, 10994 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10995 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10996 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10997 10998 // ConvP2B 10999 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 11000 match(Set dst (Conv2B src)); 11001 predicate(UseCountLeadingZerosInstructionsPPC64); 11002 ins_cost(DEFAULT_COST); 11003 11004 expand %{ 11005 immI shiftAmount %{ 0x6 %} 11006 uimmI16 mask %{ 0x1 %} 11007 iRegIdst tmp1; 11008 iRegIdst tmp2; 11009 countLeadingZerosP(tmp1, src); 11010 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 11011 xorI_reg_uimm16(dst, tmp2, mask); 11012 %} 11013 %} 11014 11015 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 11016 match(Set dst (Conv2B src)); 11017 effect(TEMP crx); 11018 predicate(!UseCountLeadingZerosInstructionsPPC64); 11019 ins_cost(DEFAULT_COST); 11020 11021 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 11022 "LI $dst, #0\n\t" 11023 "BEQ $crx, done\n\t" 11024 "LI $dst, #1\n" 11025 "done:" %} 11026 size(16); 11027 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 11028 ins_pipe(pipe_class_compare); 11029 %} 11030 11031 // ConvP2B + XorI 11032 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 11033 match(Set dst (XorI (Conv2B src) mask)); 11034 predicate(UseCountLeadingZerosInstructionsPPC64); 11035 ins_cost(DEFAULT_COST); 11036 11037 expand %{ 11038 immI shiftAmount %{ 0x6 %} 11039 iRegIdst tmp1; 11040 countLeadingZerosP(tmp1, src); 11041 urShiftI_reg_imm(dst, tmp1, shiftAmount); 11042 %} 11043 %} 11044 11045 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 11046 match(Set dst (XorI (Conv2B src) mask)); 11047 effect(TEMP crx); 11048 predicate(!UseCountLeadingZerosInstructionsPPC64); 11049 ins_cost(DEFAULT_COST); 11050 11051 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 11052 "LI $dst, #1\n\t" 11053 "BEQ $crx, done\n\t" 11054 "LI $dst, #0\n" 11055 "done:" %} 11056 size(16); 11057 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 11058 ins_pipe(pipe_class_compare); 11059 %} 11060 11061 // if src1 < src2, return -1 else return 0 11062 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 11063 match(Set dst (CmpLTMask src1 src2)); 11064 ins_cost(DEFAULT_COST*4); 11065 11066 expand %{ 11067 iRegLdst src1s; 11068 iRegLdst src2s; 11069 iRegLdst diff; 11070 convI2L_reg(src1s, src1); // Ensure proper sign extension. 11071 convI2L_reg(src2s, src2); // Ensure proper sign extension. 11072 subL_reg_reg(diff, src1s, src2s); 11073 // Need to consider >=33 bit result, therefore we need signmaskL. 11074 signmask64I_regL(dst, diff); 11075 %} 11076 %} 11077 11078 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 11079 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 11080 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 11081 size(4); 11082 ins_encode %{ 11083 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 11084 __ srawi($dst$$Register, $src1$$Register, 0x1f); 11085 %} 11086 ins_pipe(pipe_class_default); 11087 %} 11088 11089 //----------Arithmetic Conversion Instructions--------------------------------- 11090 11091 // Convert to Byte -- nop 11092 // Convert to Short -- nop 11093 11094 // Convert to Int 11095 11096 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 11097 match(Set dst (RShiftI (LShiftI src amount) amount)); 11098 format %{ "EXTSB $dst, $src \t// byte->int" %} 11099 size(4); 11100 ins_encode %{ 11101 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 11102 __ extsb($dst$$Register, $src$$Register); 11103 %} 11104 ins_pipe(pipe_class_default); 11105 %} 11106 11107 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 11108 effect(DEF dst, USE src); 11109 11110 size(4); 11111 ins_encode %{ 11112 __ extsh($dst$$Register, $src$$Register); 11113 %} 11114 ins_pipe(pipe_class_default); 11115 %} 11116 11117 // LShiftI 16 + RShiftI 16 converts short to int. 11118 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 11119 match(Set dst (RShiftI (LShiftI src amount) amount)); 11120 format %{ "EXTSH $dst, $src \t// short->int" %} 11121 size(4); 11122 ins_encode %{ 11123 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 11124 __ extsh($dst$$Register, $src$$Register); 11125 %} 11126 ins_pipe(pipe_class_default); 11127 %} 11128 11129 // ConvL2I + ConvI2L: Sign extend int in long register. 11130 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11131 match(Set dst (ConvI2L (ConvL2I src))); 11132 11133 format %{ "EXTSW $dst, $src \t// long->long" %} 11134 size(4); 11135 ins_encode %{ 11136 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11137 __ extsw($dst$$Register, $src$$Register); 11138 %} 11139 ins_pipe(pipe_class_default); 11140 %} 11141 11142 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11143 match(Set dst (ConvL2I src)); 11144 format %{ "MR $dst, $src \t// long->int" %} 11145 // variable size, 0 or 4 11146 ins_encode %{ 11147 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11148 __ mr_if_needed($dst$$Register, $src$$Register); 11149 %} 11150 ins_pipe(pipe_class_default); 11151 %} 11152 11153 instruct convD2IRaw_regD(regD dst, regD src) %{ 11154 // no match-rule, false predicate 11155 effect(DEF dst, USE src); 11156 predicate(false); 11157 11158 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11159 size(4); 11160 ins_encode %{ 11161 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11162 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11163 %} 11164 ins_pipe(pipe_class_default); 11165 %} 11166 11167 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 11168 // no match-rule, false predicate 11169 effect(DEF dst, USE crx, USE src); 11170 predicate(false); 11171 11172 ins_variable_size_depending_on_alignment(true); 11173 11174 format %{ "cmovI $crx, $dst, $src" %} 11175 // Worst case is branch + move + stop, no stop without scheduler. 11176 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11177 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11178 ins_pipe(pipe_class_default); 11179 %} 11180 11181 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11182 // no match-rule, false predicate 11183 effect(DEF dst, USE crx, USE src); 11184 predicate(false); 11185 11186 ins_variable_size_depending_on_alignment(true); 11187 11188 format %{ "cmovI $crx, $dst, $src" %} 11189 // Worst case is branch + move + stop, no stop without scheduler. 11190 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11191 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11192 ins_pipe(pipe_class_default); 11193 %} 11194 11195 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11196 // no match-rule, false predicate 11197 effect(DEF dst, USE crx, USE mem); 11198 predicate(false); 11199 11200 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11201 postalloc_expand %{ 11202 // 11203 // replaces 11204 // 11205 // region dst crx mem 11206 // \ | | / 11207 // dst=cmovI_bso_stackSlotL_conLvalue0 11208 // 11209 // with 11210 // 11211 // region dst 11212 // \ / 11213 // dst=loadConI16(0) 11214 // | 11215 // ^ region dst crx mem 11216 // | \ | | / 11217 // dst=cmovI_bso_stackSlotL 11218 // 11219 11220 // Create new nodes. 11221 MachNode *m1 = new loadConI16Node(); 11222 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11223 11224 // inputs for new nodes 11225 m1->add_req(n_region); 11226 m2->add_req(n_region, n_crx, n_mem); 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_mem; 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 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11250 // no match-rule, false predicate 11251 effect(DEF dst, USE crx, USE src); 11252 predicate(false); 11253 11254 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11255 postalloc_expand %{ 11256 // 11257 // replaces 11258 // 11259 // region dst crx src 11260 // \ | | / 11261 // dst=cmovI_bso_reg_conLvalue0 11262 // 11263 // with 11264 // 11265 // region dst 11266 // \ / 11267 // dst=loadConI16(0) 11268 // | 11269 // ^ region dst crx src 11270 // | \ | | / 11271 // dst=cmovI_bso_reg 11272 // 11273 11274 // Create new nodes. 11275 MachNode *m1 = new loadConI16Node(); 11276 MachNode *m2 = new cmovI_bso_regNode(); 11277 11278 // inputs for new nodes 11279 m1->add_req(n_region); 11280 m2->add_req(n_region, n_crx, n_src); 11281 11282 // precedences for new nodes 11283 m2->add_prec(m1); 11284 11285 // operands for new nodes 11286 m1->_opnds[0] = op_dst; 11287 m1->_opnds[1] = new immI16Oper(0); 11288 11289 m2->_opnds[0] = op_dst; 11290 m2->_opnds[1] = op_crx; 11291 m2->_opnds[2] = op_src; 11292 11293 // registers for new nodes 11294 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11295 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11296 11297 // Insert new nodes. 11298 nodes->push(m1); 11299 nodes->push(m2); 11300 %} 11301 %} 11302 11303 // Double to Int conversion, NaN is mapped to 0. 11304 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11305 match(Set dst (ConvD2I src)); 11306 predicate(!VM_Version::has_mtfprd()); 11307 ins_cost(DEFAULT_COST); 11308 11309 expand %{ 11310 regD tmpD; 11311 stackSlotL tmpS; 11312 flagsReg crx; 11313 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11314 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11315 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11316 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11317 %} 11318 %} 11319 11320 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11321 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11322 match(Set dst (ConvD2I src)); 11323 predicate(VM_Version::has_mtfprd()); 11324 ins_cost(DEFAULT_COST); 11325 11326 expand %{ 11327 regD tmpD; 11328 flagsReg crx; 11329 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11330 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11331 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11332 %} 11333 %} 11334 11335 instruct convF2IRaw_regF(regF dst, regF src) %{ 11336 // no match-rule, false predicate 11337 effect(DEF dst, USE src); 11338 predicate(false); 11339 11340 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11341 size(4); 11342 ins_encode %{ 11343 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11344 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11345 %} 11346 ins_pipe(pipe_class_default); 11347 %} 11348 11349 // Float to Int conversion, NaN is mapped to 0. 11350 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11351 match(Set dst (ConvF2I src)); 11352 predicate(!VM_Version::has_mtfprd()); 11353 ins_cost(DEFAULT_COST); 11354 11355 expand %{ 11356 regF tmpF; 11357 stackSlotL tmpS; 11358 flagsReg crx; 11359 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11360 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11361 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11362 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11363 %} 11364 %} 11365 11366 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11367 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11368 match(Set dst (ConvF2I src)); 11369 predicate(VM_Version::has_mtfprd()); 11370 ins_cost(DEFAULT_COST); 11371 11372 expand %{ 11373 regF tmpF; 11374 flagsReg crx; 11375 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11376 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11377 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11378 %} 11379 %} 11380 11381 // Convert to Long 11382 11383 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11384 match(Set dst (ConvI2L src)); 11385 format %{ "EXTSW $dst, $src \t// int->long" %} 11386 size(4); 11387 ins_encode %{ 11388 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11389 __ extsw($dst$$Register, $src$$Register); 11390 %} 11391 ins_pipe(pipe_class_default); 11392 %} 11393 11394 // Zero-extend: convert unsigned int to long (convUI2L). 11395 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11396 match(Set dst (AndL (ConvI2L src) mask)); 11397 ins_cost(DEFAULT_COST); 11398 11399 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11400 size(4); 11401 ins_encode %{ 11402 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11403 __ clrldi($dst$$Register, $src$$Register, 32); 11404 %} 11405 ins_pipe(pipe_class_default); 11406 %} 11407 11408 // Zero-extend: convert unsigned int to long in long register. 11409 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11410 match(Set dst (AndL src mask)); 11411 ins_cost(DEFAULT_COST); 11412 11413 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11414 size(4); 11415 ins_encode %{ 11416 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11417 __ clrldi($dst$$Register, $src$$Register, 32); 11418 %} 11419 ins_pipe(pipe_class_default); 11420 %} 11421 11422 instruct convF2LRaw_regF(regF dst, regF src) %{ 11423 // no match-rule, false predicate 11424 effect(DEF dst, USE src); 11425 predicate(false); 11426 11427 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11428 size(4); 11429 ins_encode %{ 11430 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11431 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11432 %} 11433 ins_pipe(pipe_class_default); 11434 %} 11435 11436 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 11437 // no match-rule, false predicate 11438 effect(DEF dst, USE crx, USE src); 11439 predicate(false); 11440 11441 ins_variable_size_depending_on_alignment(true); 11442 11443 format %{ "cmovL $crx, $dst, $src" %} 11444 // Worst case is branch + move + stop, no stop without scheduler. 11445 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11446 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11447 ins_pipe(pipe_class_default); 11448 %} 11449 11450 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11451 // no match-rule, false predicate 11452 effect(DEF dst, USE crx, USE src); 11453 predicate(false); 11454 11455 ins_variable_size_depending_on_alignment(true); 11456 11457 format %{ "cmovL $crx, $dst, $src" %} 11458 // Worst case is branch + move + stop, no stop without scheduler. 11459 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11460 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11461 ins_pipe(pipe_class_default); 11462 %} 11463 11464 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11465 // no match-rule, false predicate 11466 effect(DEF dst, USE crx, USE mem); 11467 predicate(false); 11468 11469 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11470 postalloc_expand %{ 11471 // 11472 // replaces 11473 // 11474 // region dst crx mem 11475 // \ | | / 11476 // dst=cmovL_bso_stackSlotL_conLvalue0 11477 // 11478 // with 11479 // 11480 // region dst 11481 // \ / 11482 // dst=loadConL16(0) 11483 // | 11484 // ^ region dst crx mem 11485 // | \ | | / 11486 // dst=cmovL_bso_stackSlotL 11487 // 11488 11489 // Create new nodes. 11490 MachNode *m1 = new loadConL16Node(); 11491 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11492 11493 // inputs for new nodes 11494 m1->add_req(n_region); 11495 m2->add_req(n_region, n_crx, n_mem); 11496 m2->add_prec(m1); 11497 11498 // operands for new nodes 11499 m1->_opnds[0] = op_dst; 11500 m1->_opnds[1] = new immL16Oper(0); 11501 m2->_opnds[0] = op_dst; 11502 m2->_opnds[1] = op_crx; 11503 m2->_opnds[2] = op_mem; 11504 11505 // registers for new nodes 11506 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11507 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11508 11509 // Insert new nodes. 11510 nodes->push(m1); 11511 nodes->push(m2); 11512 %} 11513 %} 11514 11515 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11516 // no match-rule, false predicate 11517 effect(DEF dst, USE crx, USE src); 11518 predicate(false); 11519 11520 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11521 postalloc_expand %{ 11522 // 11523 // replaces 11524 // 11525 // region dst crx src 11526 // \ | | / 11527 // dst=cmovL_bso_reg_conLvalue0 11528 // 11529 // with 11530 // 11531 // region dst 11532 // \ / 11533 // dst=loadConL16(0) 11534 // | 11535 // ^ region dst crx src 11536 // | \ | | / 11537 // dst=cmovL_bso_reg 11538 // 11539 11540 // Create new nodes. 11541 MachNode *m1 = new loadConL16Node(); 11542 MachNode *m2 = new cmovL_bso_regNode(); 11543 11544 // inputs for new nodes 11545 m1->add_req(n_region); 11546 m2->add_req(n_region, n_crx, n_src); 11547 m2->add_prec(m1); 11548 11549 // operands for new nodes 11550 m1->_opnds[0] = op_dst; 11551 m1->_opnds[1] = new immL16Oper(0); 11552 m2->_opnds[0] = op_dst; 11553 m2->_opnds[1] = op_crx; 11554 m2->_opnds[2] = op_src; 11555 11556 // registers for new nodes 11557 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11558 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11559 11560 // Insert new nodes. 11561 nodes->push(m1); 11562 nodes->push(m2); 11563 %} 11564 %} 11565 11566 // Float to Long conversion, NaN is mapped to 0. 11567 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11568 match(Set dst (ConvF2L src)); 11569 predicate(!VM_Version::has_mtfprd()); 11570 ins_cost(DEFAULT_COST); 11571 11572 expand %{ 11573 regF tmpF; 11574 stackSlotL tmpS; 11575 flagsReg crx; 11576 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11577 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11578 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11579 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11580 %} 11581 %} 11582 11583 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11584 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11585 match(Set dst (ConvF2L src)); 11586 predicate(VM_Version::has_mtfprd()); 11587 ins_cost(DEFAULT_COST); 11588 11589 expand %{ 11590 regF tmpF; 11591 flagsReg crx; 11592 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11593 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11594 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11595 %} 11596 %} 11597 11598 instruct convD2LRaw_regD(regD dst, regD src) %{ 11599 // no match-rule, false predicate 11600 effect(DEF dst, USE src); 11601 predicate(false); 11602 11603 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11604 size(4); 11605 ins_encode %{ 11606 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11607 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11608 %} 11609 ins_pipe(pipe_class_default); 11610 %} 11611 11612 // Double to Long conversion, NaN is mapped to 0. 11613 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11614 match(Set dst (ConvD2L src)); 11615 predicate(!VM_Version::has_mtfprd()); 11616 ins_cost(DEFAULT_COST); 11617 11618 expand %{ 11619 regD tmpD; 11620 stackSlotL tmpS; 11621 flagsReg crx; 11622 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11623 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11624 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11625 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11626 %} 11627 %} 11628 11629 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11630 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11631 match(Set dst (ConvD2L src)); 11632 predicate(VM_Version::has_mtfprd()); 11633 ins_cost(DEFAULT_COST); 11634 11635 expand %{ 11636 regD tmpD; 11637 flagsReg crx; 11638 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11639 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11640 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11641 %} 11642 %} 11643 11644 // Convert to Float 11645 11646 // Placed here as needed in expand. 11647 instruct convL2DRaw_regD(regD dst, regD src) %{ 11648 // no match-rule, false predicate 11649 effect(DEF dst, USE src); 11650 predicate(false); 11651 11652 format %{ "FCFID $dst, $src \t// convL2D" %} 11653 size(4); 11654 ins_encode %{ 11655 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11656 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11657 %} 11658 ins_pipe(pipe_class_default); 11659 %} 11660 11661 // Placed here as needed in expand. 11662 instruct convD2F_reg(regF dst, regD src) %{ 11663 match(Set dst (ConvD2F src)); 11664 format %{ "FRSP $dst, $src \t// convD2F" %} 11665 size(4); 11666 ins_encode %{ 11667 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11668 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11669 %} 11670 ins_pipe(pipe_class_default); 11671 %} 11672 11673 // Integer to Float conversion. 11674 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11675 match(Set dst (ConvI2F src)); 11676 predicate(!VM_Version::has_fcfids()); 11677 ins_cost(DEFAULT_COST); 11678 11679 expand %{ 11680 iRegLdst tmpL; 11681 stackSlotL tmpS; 11682 regD tmpD; 11683 regD tmpD2; 11684 convI2L_reg(tmpL, src); // Sign-extension int to long. 11685 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11686 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11687 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11688 convD2F_reg(dst, tmpD2); // Convert double to float. 11689 %} 11690 %} 11691 11692 instruct convL2FRaw_regF(regF dst, regD src) %{ 11693 // no match-rule, false predicate 11694 effect(DEF dst, USE src); 11695 predicate(false); 11696 11697 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11698 size(4); 11699 ins_encode %{ 11700 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11701 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11702 %} 11703 ins_pipe(pipe_class_default); 11704 %} 11705 11706 // Integer to Float conversion. Special version for Power7. 11707 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11708 match(Set dst (ConvI2F src)); 11709 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11710 ins_cost(DEFAULT_COST); 11711 11712 expand %{ 11713 iRegLdst tmpL; 11714 stackSlotL tmpS; 11715 regD tmpD; 11716 convI2L_reg(tmpL, src); // Sign-extension int to long. 11717 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11718 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11719 convL2FRaw_regF(dst, tmpD); // Convert to float. 11720 %} 11721 %} 11722 11723 // Integer to Float conversion. Special version for Power8. 11724 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11725 match(Set dst (ConvI2F src)); 11726 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11727 ins_cost(DEFAULT_COST); 11728 11729 expand %{ 11730 regD tmpD; 11731 moveI2D_reg(tmpD, src); 11732 convL2FRaw_regF(dst, tmpD); // Convert to float. 11733 %} 11734 %} 11735 11736 // L2F to avoid runtime call. 11737 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11738 match(Set dst (ConvL2F src)); 11739 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11740 ins_cost(DEFAULT_COST); 11741 11742 expand %{ 11743 stackSlotL tmpS; 11744 regD tmpD; 11745 regL_to_stkL(tmpS, src); // Store long to stack. 11746 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11747 convL2FRaw_regF(dst, tmpD); // Convert to float. 11748 %} 11749 %} 11750 11751 // L2F to avoid runtime call. Special version for Power8. 11752 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11753 match(Set dst (ConvL2F src)); 11754 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11755 ins_cost(DEFAULT_COST); 11756 11757 expand %{ 11758 regD tmpD; 11759 moveL2D_reg(tmpD, src); 11760 convL2FRaw_regF(dst, tmpD); // Convert to float. 11761 %} 11762 %} 11763 11764 // Moved up as used in expand. 11765 //instruct convD2F_reg(regF dst, regD src) %{%} 11766 11767 // Convert to Double 11768 11769 // Integer to Double conversion. 11770 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11771 match(Set dst (ConvI2D src)); 11772 predicate(!VM_Version::has_mtfprd()); 11773 ins_cost(DEFAULT_COST); 11774 11775 expand %{ 11776 iRegLdst tmpL; 11777 stackSlotL tmpS; 11778 regD tmpD; 11779 convI2L_reg(tmpL, src); // Sign-extension int to long. 11780 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11781 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11782 convL2DRaw_regD(dst, tmpD); // Convert to double. 11783 %} 11784 %} 11785 11786 // Integer to Double conversion. Special version for Power8. 11787 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11788 match(Set dst (ConvI2D src)); 11789 predicate(VM_Version::has_mtfprd()); 11790 ins_cost(DEFAULT_COST); 11791 11792 expand %{ 11793 regD tmpD; 11794 moveI2D_reg(tmpD, src); 11795 convL2DRaw_regD(dst, tmpD); // Convert to double. 11796 %} 11797 %} 11798 11799 // Long to Double conversion 11800 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11801 match(Set dst (ConvL2D src)); 11802 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11803 11804 expand %{ 11805 regD tmpD; 11806 moveL2D_stack_reg(tmpD, src); 11807 convL2DRaw_regD(dst, tmpD); 11808 %} 11809 %} 11810 11811 // Long to Double conversion. Special version for Power8. 11812 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11813 match(Set dst (ConvL2D src)); 11814 predicate(VM_Version::has_mtfprd()); 11815 ins_cost(DEFAULT_COST); 11816 11817 expand %{ 11818 regD tmpD; 11819 moveL2D_reg(tmpD, src); 11820 convL2DRaw_regD(dst, tmpD); // Convert to double. 11821 %} 11822 %} 11823 11824 instruct convF2D_reg(regD dst, regF src) %{ 11825 match(Set dst (ConvF2D src)); 11826 format %{ "FMR $dst, $src \t// float->double" %} 11827 // variable size, 0 or 4 11828 ins_encode %{ 11829 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11830 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11831 %} 11832 ins_pipe(pipe_class_default); 11833 %} 11834 11835 //----------Control Flow Instructions------------------------------------------ 11836 // Compare Instructions 11837 11838 // Compare Integers 11839 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11840 match(Set crx (CmpI src1 src2)); 11841 size(4); 11842 format %{ "CMPW $crx, $src1, $src2" %} 11843 ins_encode %{ 11844 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11845 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11846 %} 11847 ins_pipe(pipe_class_compare); 11848 %} 11849 11850 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11851 match(Set crx (CmpI src1 src2)); 11852 format %{ "CMPWI $crx, $src1, $src2" %} 11853 size(4); 11854 ins_encode %{ 11855 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11856 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11857 %} 11858 ins_pipe(pipe_class_compare); 11859 %} 11860 11861 // (src1 & src2) == 0? 11862 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11863 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11864 // r0 is killed 11865 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11866 size(4); 11867 ins_encode %{ 11868 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11869 __ andi_(R0, $src1$$Register, $src2$$constant); 11870 %} 11871 ins_pipe(pipe_class_compare); 11872 %} 11873 11874 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11875 match(Set crx (CmpL src1 src2)); 11876 format %{ "CMPD $crx, $src1, $src2" %} 11877 size(4); 11878 ins_encode %{ 11879 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11880 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11881 %} 11882 ins_pipe(pipe_class_compare); 11883 %} 11884 11885 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11886 match(Set crx (CmpL src1 src2)); 11887 format %{ "CMPDI $crx, $src1, $src2" %} 11888 size(4); 11889 ins_encode %{ 11890 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11891 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11892 %} 11893 ins_pipe(pipe_class_compare); 11894 %} 11895 11896 // Added CmpUL for LoopPredicate. 11897 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11898 match(Set crx (CmpUL src1 src2)); 11899 format %{ "CMPLD $crx, $src1, $src2" %} 11900 size(4); 11901 ins_encode %{ 11902 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11903 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11904 %} 11905 ins_pipe(pipe_class_compare); 11906 %} 11907 11908 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11909 match(Set crx (CmpUL src1 src2)); 11910 format %{ "CMPLDI $crx, $src1, $src2" %} 11911 size(4); 11912 ins_encode %{ 11913 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11914 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11915 %} 11916 ins_pipe(pipe_class_compare); 11917 %} 11918 11919 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11920 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11921 // r0 is killed 11922 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11923 size(4); 11924 ins_encode %{ 11925 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11926 __ and_(R0, $src1$$Register, $src2$$Register); 11927 %} 11928 ins_pipe(pipe_class_compare); 11929 %} 11930 11931 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11932 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11933 // r0 is killed 11934 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11935 size(4); 11936 ins_encode %{ 11937 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11938 __ andi_(R0, $src1$$Register, $src2$$constant); 11939 %} 11940 ins_pipe(pipe_class_compare); 11941 %} 11942 11943 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11944 // no match-rule, false predicate 11945 effect(DEF dst, USE crx); 11946 predicate(false); 11947 11948 ins_variable_size_depending_on_alignment(true); 11949 11950 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11951 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11952 size((false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16)); 11953 ins_encode %{ 11954 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11955 Label done; 11956 // li(Rdst, 0); // equal -> 0 11957 __ beq($crx$$CondRegister, done); 11958 __ li($dst$$Register, 1); // greater -> +1 11959 __ bgt($crx$$CondRegister, done); 11960 __ li($dst$$Register, -1); // unordered or less -> -1 11961 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11962 __ bind(done); 11963 %} 11964 ins_pipe(pipe_class_compare); 11965 %} 11966 11967 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11968 // no match-rule, false predicate 11969 effect(DEF dst, USE crx); 11970 predicate(false); 11971 11972 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11973 postalloc_expand %{ 11974 // 11975 // replaces 11976 // 11977 // region crx 11978 // \ | 11979 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11980 // 11981 // with 11982 // 11983 // region 11984 // \ 11985 // dst=loadConI16(0) 11986 // | 11987 // ^ region crx 11988 // | \ | 11989 // dst=cmovI_conIvalueMinus1_conIvalue1 11990 // 11991 11992 // Create new nodes. 11993 MachNode *m1 = new loadConI16Node(); 11994 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11995 11996 // inputs for new nodes 11997 m1->add_req(n_region); 11998 m2->add_req(n_region, n_crx); 11999 m2->add_prec(m1); 12000 12001 // operands for new nodes 12002 m1->_opnds[0] = op_dst; 12003 m1->_opnds[1] = new immI16Oper(0); 12004 m2->_opnds[0] = op_dst; 12005 m2->_opnds[1] = op_crx; 12006 12007 // registers for new nodes 12008 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 12009 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 12010 12011 // Insert new nodes. 12012 nodes->push(m1); 12013 nodes->push(m2); 12014 %} 12015 %} 12016 12017 // Manifest a CmpL3 result in an integer register. Very painful. 12018 // This is the test to avoid. 12019 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 12020 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 12021 match(Set dst (CmpL3 src1 src2)); 12022 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12023 12024 expand %{ 12025 flagsReg tmp1; 12026 cmpL_reg_reg(tmp1, src1, src2); 12027 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12028 %} 12029 %} 12030 12031 // Implicit range checks. 12032 // A range check in the ideal world has one of the following shapes: 12033 // - (If le (CmpU length index)), (IfTrue throw exception) 12034 // - (If lt (CmpU index length)), (IfFalse throw exception) 12035 // 12036 // Match range check 'If le (CmpU length index)'. 12037 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 12038 match(If cmp (CmpU src_length index)); 12039 effect(USE labl); 12040 predicate(TrapBasedRangeChecks && 12041 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 12042 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 12043 (Matcher::branches_to_uncommon_trap(_leaf))); 12044 12045 ins_is_TrapBasedCheckNode(true); 12046 12047 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 12048 size(4); 12049 ins_encode %{ 12050 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12051 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 12052 __ trap_range_check_le($src_length$$Register, $index$$constant); 12053 } else { 12054 // Both successors are uncommon traps, probability is 0. 12055 // Node got flipped during fixup flow. 12056 assert($cmp$$cmpcode == 0x9, "must be greater"); 12057 __ trap_range_check_g($src_length$$Register, $index$$constant); 12058 } 12059 %} 12060 ins_pipe(pipe_class_trap); 12061 %} 12062 12063 // Match range check 'If lt (CmpU index length)'. 12064 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 12065 match(If cmp (CmpU src_index src_length)); 12066 effect(USE labl); 12067 predicate(TrapBasedRangeChecks && 12068 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12069 _leaf->as_If()->_prob >= PROB_ALWAYS && 12070 (Matcher::branches_to_uncommon_trap(_leaf))); 12071 12072 ins_is_TrapBasedCheckNode(true); 12073 12074 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 12075 size(4); 12076 ins_encode %{ 12077 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 12078 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12079 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 12080 } else { 12081 // Both successors are uncommon traps, probability is 0. 12082 // Node got flipped during fixup flow. 12083 assert($cmp$$cmpcode == 0x8, "must be less"); 12084 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 12085 } 12086 %} 12087 ins_pipe(pipe_class_trap); 12088 %} 12089 12090 // Match range check 'If lt (CmpU index length)'. 12091 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 12092 match(If cmp (CmpU src_index length)); 12093 effect(USE labl); 12094 predicate(TrapBasedRangeChecks && 12095 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12096 _leaf->as_If()->_prob >= PROB_ALWAYS && 12097 (Matcher::branches_to_uncommon_trap(_leaf))); 12098 12099 ins_is_TrapBasedCheckNode(true); 12100 12101 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 12102 size(4); 12103 ins_encode %{ 12104 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12105 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12106 __ trap_range_check_ge($src_index$$Register, $length$$constant); 12107 } else { 12108 // Both successors are uncommon traps, probability is 0. 12109 // Node got flipped during fixup flow. 12110 assert($cmp$$cmpcode == 0x8, "must be less"); 12111 __ trap_range_check_l($src_index$$Register, $length$$constant); 12112 } 12113 %} 12114 ins_pipe(pipe_class_trap); 12115 %} 12116 12117 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 12118 match(Set crx (CmpU src1 src2)); 12119 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 12120 size(4); 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 compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 12129 match(Set crx (CmpU src1 src2)); 12130 size(4); 12131 format %{ "CMPLWI $crx, $src1, $src2" %} 12132 ins_encode %{ 12133 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12134 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12135 %} 12136 ins_pipe(pipe_class_compare); 12137 %} 12138 12139 // Implicit zero checks (more implicit null checks). 12140 // No constant pool entries required. 12141 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12142 match(If cmp (CmpN value zero)); 12143 effect(USE labl); 12144 predicate(TrapBasedNullChecks && 12145 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12146 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12147 Matcher::branches_to_uncommon_trap(_leaf)); 12148 ins_cost(1); 12149 12150 ins_is_TrapBasedCheckNode(true); 12151 12152 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12153 size(4); 12154 ins_encode %{ 12155 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12156 if ($cmp$$cmpcode == 0xA) { 12157 __ trap_null_check($value$$Register); 12158 } else { 12159 // Both successors are uncommon traps, probability is 0. 12160 // Node got flipped during fixup flow. 12161 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12162 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12163 } 12164 %} 12165 ins_pipe(pipe_class_trap); 12166 %} 12167 12168 // Compare narrow oops. 12169 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12170 match(Set crx (CmpN src1 src2)); 12171 12172 size(4); 12173 ins_cost(2); 12174 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12175 ins_encode %{ 12176 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12177 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12178 %} 12179 ins_pipe(pipe_class_compare); 12180 %} 12181 12182 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12183 match(Set crx (CmpN src1 src2)); 12184 // Make this more expensive than zeroCheckN_iReg_imm0. 12185 ins_cost(2); 12186 12187 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12188 size(4); 12189 ins_encode %{ 12190 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12191 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12192 %} 12193 ins_pipe(pipe_class_compare); 12194 %} 12195 12196 // Implicit zero checks (more implicit null checks). 12197 // No constant pool entries required. 12198 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12199 match(If cmp (CmpP value zero)); 12200 effect(USE labl); 12201 predicate(TrapBasedNullChecks && 12202 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12203 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12204 Matcher::branches_to_uncommon_trap(_leaf)); 12205 ins_cost(1); // Should not be cheaper than zeroCheckN. 12206 12207 ins_is_TrapBasedCheckNode(true); 12208 12209 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12210 size(4); 12211 ins_encode %{ 12212 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12213 if ($cmp$$cmpcode == 0xA) { 12214 __ trap_null_check($value$$Register); 12215 } else { 12216 // Both successors are uncommon traps, probability is 0. 12217 // Node got flipped during fixup flow. 12218 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12219 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12220 } 12221 %} 12222 ins_pipe(pipe_class_trap); 12223 %} 12224 12225 // Compare Pointers 12226 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12227 match(Set crx (CmpP src1 src2)); 12228 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12229 size(4); 12230 ins_encode %{ 12231 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12232 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12233 %} 12234 ins_pipe(pipe_class_compare); 12235 %} 12236 12237 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12238 match(Set crx (CmpP src1 src2)); 12239 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12240 size(4); 12241 ins_encode %{ 12242 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12243 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12244 %} 12245 ins_pipe(pipe_class_compare); 12246 %} 12247 12248 // Used in postalloc expand. 12249 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12250 // This match rule prevents reordering of node before a safepoint. 12251 // This only makes sense if this instructions is used exclusively 12252 // for the expansion of EncodeP! 12253 match(Set crx (CmpP src1 src2)); 12254 predicate(false); 12255 12256 format %{ "CMPDI $crx, $src1, $src2" %} 12257 size(4); 12258 ins_encode %{ 12259 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12260 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12261 %} 12262 ins_pipe(pipe_class_compare); 12263 %} 12264 12265 //----------Float Compares---------------------------------------------------- 12266 12267 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12268 // Needs matchrule, see cmpDUnordered. 12269 match(Set crx (CmpF src1 src2)); 12270 // no match-rule, false predicate 12271 predicate(false); 12272 12273 format %{ "cmpFUrd $crx, $src1, $src2" %} 12274 size(4); 12275 ins_encode %{ 12276 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12277 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12278 %} 12279 ins_pipe(pipe_class_default); 12280 %} 12281 12282 instruct cmov_bns_less(flagsReg crx) %{ 12283 // no match-rule, false predicate 12284 effect(DEF crx); 12285 predicate(false); 12286 12287 ins_variable_size_depending_on_alignment(true); 12288 12289 format %{ "cmov $crx" %} 12290 // Worst case is branch + move + stop, no stop without scheduler. 12291 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12)); 12292 ins_encode %{ 12293 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12294 Label done; 12295 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12296 __ li(R0, 0); 12297 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12298 // TODO PPC port __ endgroup_if_needed(_size == 16); 12299 __ bind(done); 12300 %} 12301 ins_pipe(pipe_class_default); 12302 %} 12303 12304 // Compare floating, generate condition code. 12305 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12306 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12307 // 12308 // The following code sequence occurs a lot in mpegaudio: 12309 // 12310 // block BXX: 12311 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12312 // cmpFUrd CCR6, F11, F9 12313 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12314 // cmov CCR6 12315 // 8: instruct branchConSched: 12316 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12317 match(Set crx (CmpF src1 src2)); 12318 ins_cost(DEFAULT_COST+BRANCH_COST); 12319 12320 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12321 postalloc_expand %{ 12322 // 12323 // replaces 12324 // 12325 // region src1 src2 12326 // \ | | 12327 // crx=cmpF_reg_reg 12328 // 12329 // with 12330 // 12331 // region src1 src2 12332 // \ | | 12333 // crx=cmpFUnordered_reg_reg 12334 // | 12335 // ^ region 12336 // | \ 12337 // crx=cmov_bns_less 12338 // 12339 12340 // Create new nodes. 12341 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12342 MachNode *m2 = new cmov_bns_lessNode(); 12343 12344 // inputs for new nodes 12345 m1->add_req(n_region, n_src1, n_src2); 12346 m2->add_req(n_region); 12347 m2->add_prec(m1); 12348 12349 // operands for new nodes 12350 m1->_opnds[0] = op_crx; 12351 m1->_opnds[1] = op_src1; 12352 m1->_opnds[2] = op_src2; 12353 m2->_opnds[0] = op_crx; 12354 12355 // registers for new nodes 12356 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12357 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12358 12359 // Insert new nodes. 12360 nodes->push(m1); 12361 nodes->push(m2); 12362 %} 12363 %} 12364 12365 // Compare float, generate -1,0,1 12366 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12367 match(Set dst (CmpF3 src1 src2)); 12368 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12369 12370 expand %{ 12371 flagsReg tmp1; 12372 cmpFUnordered_reg_reg(tmp1, src1, src2); 12373 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12374 %} 12375 %} 12376 12377 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12378 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12379 // node right before the conditional move using it. 12380 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12381 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12382 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12383 // conditional move was supposed to be spilled. 12384 match(Set crx (CmpD src1 src2)); 12385 // False predicate, shall not be matched. 12386 predicate(false); 12387 12388 format %{ "cmpFUrd $crx, $src1, $src2" %} 12389 size(4); 12390 ins_encode %{ 12391 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12392 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12393 %} 12394 ins_pipe(pipe_class_default); 12395 %} 12396 12397 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12398 match(Set crx (CmpD src1 src2)); 12399 ins_cost(DEFAULT_COST+BRANCH_COST); 12400 12401 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12402 postalloc_expand %{ 12403 // 12404 // replaces 12405 // 12406 // region src1 src2 12407 // \ | | 12408 // crx=cmpD_reg_reg 12409 // 12410 // with 12411 // 12412 // region src1 src2 12413 // \ | | 12414 // crx=cmpDUnordered_reg_reg 12415 // | 12416 // ^ region 12417 // | \ 12418 // crx=cmov_bns_less 12419 // 12420 12421 // create new nodes 12422 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12423 MachNode *m2 = new cmov_bns_lessNode(); 12424 12425 // inputs for new nodes 12426 m1->add_req(n_region, n_src1, n_src2); 12427 m2->add_req(n_region); 12428 m2->add_prec(m1); 12429 12430 // operands for new nodes 12431 m1->_opnds[0] = op_crx; 12432 m1->_opnds[1] = op_src1; 12433 m1->_opnds[2] = op_src2; 12434 m2->_opnds[0] = op_crx; 12435 12436 // registers for new nodes 12437 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12438 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12439 12440 // Insert new nodes. 12441 nodes->push(m1); 12442 nodes->push(m2); 12443 %} 12444 %} 12445 12446 // Compare double, generate -1,0,1 12447 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12448 match(Set dst (CmpD3 src1 src2)); 12449 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12450 12451 expand %{ 12452 flagsReg tmp1; 12453 cmpDUnordered_reg_reg(tmp1, src1, src2); 12454 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12455 %} 12456 %} 12457 12458 // Compare char 12459 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12460 match(Set dst (Digit src1)); 12461 effect(TEMP src2, TEMP crx); 12462 ins_cost(3 * DEFAULT_COST); 12463 12464 format %{ "LI $src2, 0x3930\n\t" 12465 "CMPRB $crx, 0, $src1, $src2\n\t" 12466 "SETB $dst, $crx" %} 12467 size(12); 12468 ins_encode %{ 12469 // 0x30: 0, 0x39: 9 12470 __ li($src2$$Register, 0x3930); 12471 // compare src1 with ranges 0x30 to 0x39 12472 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12473 __ setb($dst$$Register, $crx$$CondRegister); 12474 %} 12475 ins_pipe(pipe_class_default); 12476 %} 12477 12478 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12479 match(Set dst (LowerCase src1)); 12480 effect(TEMP src2, TEMP crx); 12481 ins_cost(12 * DEFAULT_COST); 12482 12483 format %{ "LI $src2, 0x7A61\n\t" 12484 "CMPRB $crx, 0, $src1, $src2\n\t" 12485 "BGT $crx, done\n\t" 12486 "LIS $src2, (signed short)0xF6DF\n\t" 12487 "ORI $src2, $src2, 0xFFF8\n\t" 12488 "CMPRB $crx, 1, $src1, $src2\n\t" 12489 "BGT $crx, done\n\t" 12490 "LIS $src2, (signed short)0xAAB5\n\t" 12491 "ORI $src2, $src2, 0xBABA\n\t" 12492 "INSRDI $src2, $src2, 32, 0\n\t" 12493 "CMPEQB $crx, 1, $src1, $src2\n" 12494 "done:\n\t" 12495 "SETB $dst, $crx" %} 12496 12497 size(48); 12498 ins_encode %{ 12499 Label done; 12500 // 0x61: a, 0x7A: z 12501 __ li($src2$$Register, 0x7A61); 12502 // compare src1 with ranges 0x61 to 0x7A 12503 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12504 __ bgt($crx$$CondRegister, done); 12505 12506 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case 12507 __ lis($src2$$Register, (signed short)0xF6DF); 12508 __ ori($src2$$Register, $src2$$Register, 0xFFF8); 12509 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF 12510 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12511 __ bgt($crx$$CondRegister, done); 12512 12513 // 0xAA: feminine ordinal indicator 12514 // 0xB5: micro sign 12515 // 0xBA: masculine ordinal indicator 12516 __ lis($src2$$Register, (signed short)0xAAB5); 12517 __ ori($src2$$Register, $src2$$Register, 0xBABA); 12518 __ insrdi($src2$$Register, $src2$$Register, 32, 0); 12519 // compare src1 with 0xAA, 0xB5, and 0xBA 12520 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register); 12521 12522 __ bind(done); 12523 __ setb($dst$$Register, $crx$$CondRegister); 12524 %} 12525 ins_pipe(pipe_class_default); 12526 %} 12527 12528 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12529 match(Set dst (UpperCase src1)); 12530 effect(TEMP src2, TEMP crx); 12531 ins_cost(7 * DEFAULT_COST); 12532 12533 format %{ "LI $src2, 0x5A41\n\t" 12534 "CMPRB $crx, 0, $src1, $src2\n\t" 12535 "BGT $crx, done\n\t" 12536 "LIS $src2, (signed short)0xD6C0\n\t" 12537 "ORI $src2, $src2, 0xDED8\n\t" 12538 "CMPRB $crx, 1, $src1, $src2\n" 12539 "done:\n\t" 12540 "SETB $dst, $crx" %} 12541 12542 size(28); 12543 ins_encode %{ 12544 Label done; 12545 // 0x41: A, 0x5A: Z 12546 __ li($src2$$Register, 0x5A41); 12547 // compare src1 with a range 0x41 to 0x5A 12548 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12549 __ bgt($crx$$CondRegister, done); 12550 12551 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case 12552 __ lis($src2$$Register, (signed short)0xD6C0); 12553 __ ori($src2$$Register, $src2$$Register, 0xDED8); 12554 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE 12555 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12556 12557 __ bind(done); 12558 __ setb($dst$$Register, $crx$$CondRegister); 12559 %} 12560 ins_pipe(pipe_class_default); 12561 %} 12562 12563 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12564 match(Set dst (Whitespace src1)); 12565 effect(TEMP src2, TEMP crx); 12566 ins_cost(4 * DEFAULT_COST); 12567 12568 format %{ "LI $src2, 0x0D09\n\t" 12569 "ADDIS $src2, 0x201C\n\t" 12570 "CMPRB $crx, 1, $src1, $src2\n\t" 12571 "SETB $dst, $crx" %} 12572 size(16); 12573 ins_encode %{ 12574 // 0x09 to 0x0D, 0x1C to 0x20 12575 __ li($src2$$Register, 0x0D09); 12576 __ addis($src2$$Register, $src2$$Register, 0x0201C); 12577 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20 12578 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12579 __ setb($dst$$Register, $crx$$CondRegister); 12580 %} 12581 ins_pipe(pipe_class_default); 12582 %} 12583 12584 //----------Branches--------------------------------------------------------- 12585 // Jump 12586 12587 // Direct Branch. 12588 instruct branch(label labl) %{ 12589 match(Goto); 12590 effect(USE labl); 12591 ins_cost(BRANCH_COST); 12592 12593 format %{ "B $labl" %} 12594 size(4); 12595 ins_encode %{ 12596 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12597 Label d; // dummy 12598 __ bind(d); 12599 Label* p = $labl$$label; 12600 // `p' is `NULL' when this encoding class is used only to 12601 // determine the size of the encoded instruction. 12602 Label& l = (NULL == p)? d : *(p); 12603 __ b(l); 12604 %} 12605 ins_pipe(pipe_class_default); 12606 %} 12607 12608 // Conditional Near Branch 12609 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12610 // Same match rule as `branchConFar'. 12611 match(If cmp crx); 12612 effect(USE lbl); 12613 ins_cost(BRANCH_COST); 12614 12615 // If set to 1 this indicates that the current instruction is a 12616 // short variant of a long branch. This avoids using this 12617 // instruction in first-pass matching. It will then only be used in 12618 // the `Shorten_branches' pass. 12619 ins_short_branch(1); 12620 12621 format %{ "B$cmp $crx, $lbl" %} 12622 size(4); 12623 ins_encode( enc_bc(crx, cmp, lbl) ); 12624 ins_pipe(pipe_class_default); 12625 %} 12626 12627 // This is for cases when the ppc64 `bc' instruction does not 12628 // reach far enough. So we emit a far branch here, which is more 12629 // expensive. 12630 // 12631 // Conditional Far Branch 12632 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12633 // Same match rule as `branchCon'. 12634 match(If cmp crx); 12635 effect(USE crx, USE lbl); 12636 predicate(!false /* TODO: PPC port HB_Schedule*/); 12637 // Higher cost than `branchCon'. 12638 ins_cost(5*BRANCH_COST); 12639 12640 // This is not a short variant of a branch, but the long variant. 12641 ins_short_branch(0); 12642 12643 format %{ "B_FAR$cmp $crx, $lbl" %} 12644 size(8); 12645 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12646 ins_pipe(pipe_class_default); 12647 %} 12648 12649 // Conditional Branch used with Power6 scheduler (can be far or short). 12650 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12651 // Same match rule as `branchCon'. 12652 match(If cmp crx); 12653 effect(USE crx, USE lbl); 12654 predicate(false /* TODO: PPC port HB_Schedule*/); 12655 // Higher cost than `branchCon'. 12656 ins_cost(5*BRANCH_COST); 12657 12658 // Actually size doesn't depend on alignment but on shortening. 12659 ins_variable_size_depending_on_alignment(true); 12660 // long variant. 12661 ins_short_branch(0); 12662 12663 format %{ "B_FAR$cmp $crx, $lbl" %} 12664 size(8); // worst case 12665 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12666 ins_pipe(pipe_class_default); 12667 %} 12668 12669 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12670 match(CountedLoopEnd cmp crx); 12671 effect(USE labl); 12672 ins_cost(BRANCH_COST); 12673 12674 // short variant. 12675 ins_short_branch(1); 12676 12677 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12678 size(4); 12679 ins_encode( enc_bc(crx, cmp, labl) ); 12680 ins_pipe(pipe_class_default); 12681 %} 12682 12683 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12684 match(CountedLoopEnd cmp crx); 12685 effect(USE labl); 12686 predicate(!false /* TODO: PPC port HB_Schedule */); 12687 ins_cost(BRANCH_COST); 12688 12689 // Long variant. 12690 ins_short_branch(0); 12691 12692 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12693 size(8); 12694 ins_encode( enc_bc_far(crx, cmp, labl) ); 12695 ins_pipe(pipe_class_default); 12696 %} 12697 12698 // Conditional Branch used with Power6 scheduler (can be far or short). 12699 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12700 match(CountedLoopEnd cmp crx); 12701 effect(USE labl); 12702 predicate(false /* TODO: PPC port HB_Schedule */); 12703 // Higher cost than `branchCon'. 12704 ins_cost(5*BRANCH_COST); 12705 12706 // Actually size doesn't depend on alignment but on shortening. 12707 ins_variable_size_depending_on_alignment(true); 12708 // Long variant. 12709 ins_short_branch(0); 12710 12711 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12712 size(8); // worst case 12713 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12714 ins_pipe(pipe_class_default); 12715 %} 12716 12717 // ============================================================================ 12718 // Java runtime operations, intrinsics and other complex operations. 12719 12720 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12721 // array for an instance of the superklass. Set a hidden internal cache on a 12722 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12723 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12724 // 12725 // GL TODO: Improve this. 12726 // - result should not be a TEMP 12727 // - Add match rule as on sparc avoiding additional Cmp. 12728 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12729 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12730 match(Set result (PartialSubtypeCheck subklass superklass)); 12731 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12732 ins_cost(DEFAULT_COST*10); 12733 12734 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12735 ins_encode %{ 12736 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12737 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12738 $tmp_klass$$Register, NULL, $result$$Register); 12739 %} 12740 ins_pipe(pipe_class_default); 12741 %} 12742 12743 // inlined locking and unlocking 12744 12745 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12746 match(Set crx (FastLock oop box)); 12747 effect(TEMP tmp1, TEMP tmp2); 12748 predicate(!Compile::current()->use_rtm()); 12749 12750 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12751 ins_encode %{ 12752 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12753 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12754 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12755 UseBiasedLocking && !UseOptoBiasInlining); 12756 // If locking was successfull, crx should indicate 'EQ'. 12757 // The compiler generates a branch to the runtime call to 12758 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12759 %} 12760 ins_pipe(pipe_class_compare); 12761 %} 12762 12763 // Separate version for TM. Use bound register for box to enable USE_KILL. 12764 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12765 match(Set crx (FastLock oop box)); 12766 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12767 predicate(Compile::current()->use_rtm()); 12768 12769 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12770 ins_encode %{ 12771 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12772 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12773 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12774 /*Biased Locking*/ false, 12775 _rtm_counters, _stack_rtm_counters, 12776 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12777 /*TM*/ true, ra_->C->profile_rtm()); 12778 // If locking was successfull, crx should indicate 'EQ'. 12779 // The compiler generates a branch to the runtime call to 12780 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12781 %} 12782 ins_pipe(pipe_class_compare); 12783 %} 12784 12785 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12786 match(Set crx (FastUnlock oop box)); 12787 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12788 predicate(!Compile::current()->use_rtm()); 12789 12790 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12791 ins_encode %{ 12792 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12793 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12794 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12795 UseBiasedLocking && !UseOptoBiasInlining, 12796 false); 12797 // If unlocking was successfull, crx should indicate 'EQ'. 12798 // The compiler generates a branch to the runtime call to 12799 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12800 %} 12801 ins_pipe(pipe_class_compare); 12802 %} 12803 12804 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12805 match(Set crx (FastUnlock oop box)); 12806 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12807 predicate(Compile::current()->use_rtm()); 12808 12809 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12810 ins_encode %{ 12811 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12812 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12813 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12814 /*Biased Locking*/ false, /*TM*/ true); 12815 // If unlocking was successfull, crx should indicate 'EQ'. 12816 // The compiler generates a branch to the runtime call to 12817 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12818 %} 12819 ins_pipe(pipe_class_compare); 12820 %} 12821 12822 // Align address. 12823 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12824 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12825 12826 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12827 size(4); 12828 ins_encode %{ 12829 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12830 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12831 %} 12832 ins_pipe(pipe_class_default); 12833 %} 12834 12835 // Array size computation. 12836 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12837 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12838 12839 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12840 size(4); 12841 ins_encode %{ 12842 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12843 __ subf($dst$$Register, $start$$Register, $end$$Register); 12844 %} 12845 ins_pipe(pipe_class_default); 12846 %} 12847 12848 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12849 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12850 match(Set dummy (ClearArray cnt base)); 12851 effect(USE_KILL base, KILL ctr); 12852 ins_cost(2 * MEMORY_REF_COST); 12853 12854 format %{ "ClearArray $cnt, $base" %} 12855 ins_encode %{ 12856 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12857 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12858 %} 12859 ins_pipe(pipe_class_default); 12860 %} 12861 12862 // Clear-array with constant large array length. 12863 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12864 match(Set dummy (ClearArray cnt base)); 12865 effect(USE_KILL base, TEMP tmp, KILL ctr); 12866 ins_cost(3 * MEMORY_REF_COST); 12867 12868 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12869 ins_encode %{ 12870 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12871 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12872 %} 12873 ins_pipe(pipe_class_default); 12874 %} 12875 12876 // Clear-array with dynamic array length. 12877 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12878 match(Set dummy (ClearArray cnt base)); 12879 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12880 ins_cost(4 * MEMORY_REF_COST); 12881 12882 format %{ "ClearArray $cnt, $base" %} 12883 ins_encode %{ 12884 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12885 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12886 %} 12887 ins_pipe(pipe_class_default); 12888 %} 12889 12890 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12891 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12892 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12893 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12894 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12895 ins_cost(300); 12896 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12897 ins_encode %{ 12898 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12899 __ string_compare($str1$$Register, $str2$$Register, 12900 $cnt1$$Register, $cnt2$$Register, 12901 $tmp$$Register, 12902 $result$$Register, StrIntrinsicNode::LL); 12903 %} 12904 ins_pipe(pipe_class_default); 12905 %} 12906 12907 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12908 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12909 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12910 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12911 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12912 ins_cost(300); 12913 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12914 ins_encode %{ 12915 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12916 __ string_compare($str1$$Register, $str2$$Register, 12917 $cnt1$$Register, $cnt2$$Register, 12918 $tmp$$Register, 12919 $result$$Register, StrIntrinsicNode::UU); 12920 %} 12921 ins_pipe(pipe_class_default); 12922 %} 12923 12924 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12925 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12926 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12927 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12928 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12929 ins_cost(300); 12930 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12931 ins_encode %{ 12932 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12933 __ string_compare($str1$$Register, $str2$$Register, 12934 $cnt1$$Register, $cnt2$$Register, 12935 $tmp$$Register, 12936 $result$$Register, StrIntrinsicNode::LU); 12937 %} 12938 ins_pipe(pipe_class_default); 12939 %} 12940 12941 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12942 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12943 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12944 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12945 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12946 ins_cost(300); 12947 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12948 ins_encode %{ 12949 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12950 __ string_compare($str2$$Register, $str1$$Register, 12951 $cnt2$$Register, $cnt1$$Register, 12952 $tmp$$Register, 12953 $result$$Register, StrIntrinsicNode::UL); 12954 %} 12955 ins_pipe(pipe_class_default); 12956 %} 12957 12958 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12959 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12960 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12961 match(Set result (StrEquals (Binary str1 str2) cnt)); 12962 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12963 ins_cost(300); 12964 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12965 ins_encode %{ 12966 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12967 __ array_equals(false, $str1$$Register, $str2$$Register, 12968 $cnt$$Register, $tmp$$Register, 12969 $result$$Register, true /* byte */); 12970 %} 12971 ins_pipe(pipe_class_default); 12972 %} 12973 12974 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12975 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12976 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12977 match(Set result (StrEquals (Binary str1 str2) cnt)); 12978 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12979 ins_cost(300); 12980 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12981 ins_encode %{ 12982 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12983 __ array_equals(false, $str1$$Register, $str2$$Register, 12984 $cnt$$Register, $tmp$$Register, 12985 $result$$Register, false /* byte */); 12986 %} 12987 ins_pipe(pipe_class_default); 12988 %} 12989 12990 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12991 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12992 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12993 match(Set result (AryEq ary1 ary2)); 12994 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12995 ins_cost(300); 12996 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12997 ins_encode %{ 12998 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12999 __ array_equals(true, $ary1$$Register, $ary2$$Register, 13000 $tmp1$$Register, $tmp2$$Register, 13001 $result$$Register, true /* byte */); 13002 %} 13003 ins_pipe(pipe_class_default); 13004 %} 13005 13006 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 13007 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 13008 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 13009 match(Set result (AryEq ary1 ary2)); 13010 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 13011 ins_cost(300); 13012 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 13013 ins_encode %{ 13014 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13015 __ array_equals(true, $ary1$$Register, $ary2$$Register, 13016 $tmp1$$Register, $tmp2$$Register, 13017 $result$$Register, false /* byte */); 13018 %} 13019 ins_pipe(pipe_class_default); 13020 %} 13021 13022 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13023 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13024 iRegIdst tmp1, iRegIdst tmp2, 13025 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13026 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13027 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13028 // Required for EA: check if it is still a type_array. 13029 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13030 ins_cost(150); 13031 13032 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13033 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13034 13035 ins_encode %{ 13036 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13037 immPOper *needleOper = (immPOper *)$needleImm; 13038 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13039 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13040 jchar chr; 13041 #ifdef VM_LITTLE_ENDIAN 13042 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 13043 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 13044 #else 13045 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 13046 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 13047 #endif 13048 __ string_indexof_char($result$$Register, 13049 $haystack$$Register, $haycnt$$Register, 13050 R0, chr, 13051 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13052 %} 13053 ins_pipe(pipe_class_compare); 13054 %} 13055 13056 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13057 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13058 iRegIdst tmp1, iRegIdst tmp2, 13059 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13060 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13061 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13062 // Required for EA: check if it is still a type_array. 13063 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13064 ins_cost(150); 13065 13066 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13067 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13068 13069 ins_encode %{ 13070 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13071 immPOper *needleOper = (immPOper *)$needleImm; 13072 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13073 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13074 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13075 __ string_indexof_char($result$$Register, 13076 $haystack$$Register, $haycnt$$Register, 13077 R0, chr, 13078 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13079 %} 13080 ins_pipe(pipe_class_compare); 13081 %} 13082 13083 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13084 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13085 iRegIdst tmp1, iRegIdst tmp2, 13086 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13087 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13088 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13089 // Required for EA: check if it is still a type_array. 13090 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13091 ins_cost(150); 13092 13093 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13094 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13095 13096 ins_encode %{ 13097 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13098 immPOper *needleOper = (immPOper *)$needleImm; 13099 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13100 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13101 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13102 __ string_indexof_char($result$$Register, 13103 $haystack$$Register, $haycnt$$Register, 13104 R0, chr, 13105 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13106 %} 13107 ins_pipe(pipe_class_compare); 13108 %} 13109 13110 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13111 rscratch2RegP needle, immI_1 needlecntImm, 13112 iRegIdst tmp1, iRegIdst tmp2, 13113 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13114 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13115 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13116 // Required for EA: check if it is still a type_array. 13117 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13118 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13119 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13120 ins_cost(180); 13121 13122 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13123 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13124 ins_encode %{ 13125 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13126 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13127 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13128 guarantee(needle_values, "sanity"); 13129 jchar chr; 13130 #ifdef VM_LITTLE_ENDIAN 13131 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 13132 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 13133 #else 13134 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 13135 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 13136 #endif 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 indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13146 rscratch2RegP needle, immI_1 needlecntImm, 13147 iRegIdst tmp1, iRegIdst tmp2, 13148 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13149 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13150 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13151 // Required for EA: check if it is still a type_array. 13152 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13153 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13154 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13155 ins_cost(180); 13156 13157 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13158 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13159 ins_encode %{ 13160 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13161 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13162 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13163 guarantee(needle_values, "sanity"); 13164 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13165 __ string_indexof_char($result$$Register, 13166 $haystack$$Register, $haycnt$$Register, 13167 R0, chr, 13168 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13169 %} 13170 ins_pipe(pipe_class_compare); 13171 %} 13172 13173 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13174 rscratch2RegP needle, immI_1 needlecntImm, 13175 iRegIdst tmp1, iRegIdst tmp2, 13176 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13177 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13178 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13179 // Required for EA: check if it is still a type_array. 13180 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13181 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13182 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13183 ins_cost(180); 13184 13185 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13186 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13187 ins_encode %{ 13188 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13189 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13190 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13191 guarantee(needle_values, "sanity"); 13192 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13193 __ string_indexof_char($result$$Register, 13194 $haystack$$Register, $haycnt$$Register, 13195 R0, chr, 13196 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13197 %} 13198 ins_pipe(pipe_class_compare); 13199 %} 13200 13201 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13202 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 13203 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13204 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 13205 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13206 ins_cost(180); 13207 13208 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 13209 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13210 ins_encode %{ 13211 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13212 __ string_indexof_char($result$$Register, 13213 $haystack$$Register, $haycnt$$Register, 13214 $ch$$Register, 0 /* this is not used if the character is already in a register */, 13215 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13216 %} 13217 ins_pipe(pipe_class_compare); 13218 %} 13219 13220 instruct indexOf_imm_U(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::UU && 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::UU); 13244 %} 13245 ins_pipe(pipe_class_compare); 13246 %} 13247 13248 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13249 iRegPsrc needle, uimmI15 needlecntImm, 13250 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13251 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13252 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13253 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13254 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13255 // Required for EA: check if it is still a type_array. 13256 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13257 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13258 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13259 ins_cost(250); 13260 13261 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13262 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13263 ins_encode %{ 13264 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13265 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13266 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13267 13268 __ string_indexof($result$$Register, 13269 $haystack$$Register, $haycnt$$Register, 13270 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13271 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13272 %} 13273 ins_pipe(pipe_class_compare); 13274 %} 13275 13276 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13277 iRegPsrc needle, uimmI15 needlecntImm, 13278 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13279 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13280 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13281 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13282 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13283 // Required for EA: check if it is still a type_array. 13284 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13285 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13286 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13287 ins_cost(250); 13288 13289 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13290 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13291 ins_encode %{ 13292 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13293 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13294 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13295 13296 __ string_indexof($result$$Register, 13297 $haystack$$Register, $haycnt$$Register, 13298 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13299 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13300 %} 13301 ins_pipe(pipe_class_compare); 13302 %} 13303 13304 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13305 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13306 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13307 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13308 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13309 TEMP_DEF result, 13310 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13311 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13312 ins_cost(300); 13313 13314 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13315 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13316 ins_encode %{ 13317 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13318 __ string_indexof($result$$Register, 13319 $haystack$$Register, $haycnt$$Register, 13320 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13321 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13322 %} 13323 ins_pipe(pipe_class_compare); 13324 %} 13325 13326 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13327 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13328 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13329 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13330 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13331 TEMP_DEF result, 13332 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13333 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13334 ins_cost(300); 13335 13336 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13337 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13338 ins_encode %{ 13339 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13340 __ string_indexof($result$$Register, 13341 $haystack$$Register, $haycnt$$Register, 13342 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13343 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13344 %} 13345 ins_pipe(pipe_class_compare); 13346 %} 13347 13348 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13349 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13350 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13351 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13352 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13353 TEMP_DEF result, 13354 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13355 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13356 ins_cost(300); 13357 13358 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13359 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13360 ins_encode %{ 13361 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13362 __ string_indexof($result$$Register, 13363 $haystack$$Register, $haycnt$$Register, 13364 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13365 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13366 %} 13367 ins_pipe(pipe_class_compare); 13368 %} 13369 13370 // char[] to byte[] compression 13371 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13372 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13373 match(Set result (StrCompressedCopy src (Binary dst len))); 13374 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13375 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13376 ins_cost(300); 13377 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13378 ins_encode %{ 13379 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13380 Label Lskip, Ldone; 13381 __ li($result$$Register, 0); 13382 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13383 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13384 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13385 __ beq(CCR0, Lskip); 13386 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13387 __ bind(Lskip); 13388 __ mr($result$$Register, $len$$Register); 13389 __ bind(Ldone); 13390 %} 13391 ins_pipe(pipe_class_default); 13392 %} 13393 13394 // byte[] to char[] inflation 13395 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13396 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13397 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13398 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13399 ins_cost(300); 13400 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13401 ins_encode %{ 13402 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13403 Label Ldone; 13404 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13405 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13406 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13407 __ beq(CCR0, Ldone); 13408 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13409 __ bind(Ldone); 13410 %} 13411 ins_pipe(pipe_class_default); 13412 %} 13413 13414 // StringCoding.java intrinsics 13415 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13416 regCTR ctr, flagsRegCR0 cr0) 13417 %{ 13418 match(Set result (HasNegatives ary1 len)); 13419 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13420 ins_cost(300); 13421 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13422 ins_encode %{ 13423 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13424 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13425 $tmp1$$Register, $tmp2$$Register); 13426 %} 13427 ins_pipe(pipe_class_default); 13428 %} 13429 13430 // encode char[] to byte[] in ISO_8859_1 13431 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13432 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13433 match(Set result (EncodeISOArray src (Binary dst len))); 13434 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13435 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13436 ins_cost(300); 13437 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13438 ins_encode %{ 13439 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13440 Label Lslow, Lfailure1, Lfailure2, Ldone; 13441 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13442 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13443 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13444 __ beq(CCR0, Ldone); 13445 __ bind(Lslow); 13446 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13447 __ li($result$$Register, 0); 13448 __ b(Ldone); 13449 13450 __ bind(Lfailure1); 13451 __ mr($result$$Register, $len$$Register); 13452 __ mfctr($tmp1$$Register); 13453 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13454 __ beq(CCR0, Ldone); 13455 __ b(Lslow); 13456 13457 __ bind(Lfailure2); 13458 __ mfctr($result$$Register); // Remaining characters. 13459 13460 __ bind(Ldone); 13461 __ subf($result$$Register, $result$$Register, $len$$Register); 13462 %} 13463 ins_pipe(pipe_class_default); 13464 %} 13465 13466 13467 //---------- Min/Max Instructions --------------------------------------------- 13468 13469 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13470 match(Set dst (MinI src1 src2)); 13471 ins_cost(DEFAULT_COST*6); 13472 13473 expand %{ 13474 iRegLdst src1s; 13475 iRegLdst src2s; 13476 iRegLdst diff; 13477 iRegLdst sm; 13478 iRegLdst doz; // difference or zero 13479 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13480 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13481 subL_reg_reg(diff, src2s, src1s); 13482 // Need to consider >=33 bit result, therefore we need signmaskL. 13483 signmask64L_regL(sm, diff); 13484 andL_reg_reg(doz, diff, sm); // <=0 13485 addI_regL_regL(dst, doz, src1s); 13486 %} 13487 %} 13488 13489 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13490 match(Set dst (MinI src1 src2)); 13491 effect(KILL cr0); 13492 predicate(VM_Version::has_isel()); 13493 ins_cost(DEFAULT_COST*2); 13494 13495 ins_encode %{ 13496 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13497 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13498 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13499 %} 13500 ins_pipe(pipe_class_default); 13501 %} 13502 13503 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13504 match(Set dst (MaxI src1 src2)); 13505 ins_cost(DEFAULT_COST*6); 13506 13507 expand %{ 13508 iRegLdst src1s; 13509 iRegLdst src2s; 13510 iRegLdst diff; 13511 iRegLdst sm; 13512 iRegLdst doz; // difference or zero 13513 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13514 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13515 subL_reg_reg(diff, src2s, src1s); 13516 // Need to consider >=33 bit result, therefore we need signmaskL. 13517 signmask64L_regL(sm, diff); 13518 andcL_reg_reg(doz, diff, sm); // >=0 13519 addI_regL_regL(dst, doz, src1s); 13520 %} 13521 %} 13522 13523 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13524 match(Set dst (MaxI src1 src2)); 13525 effect(KILL cr0); 13526 predicate(VM_Version::has_isel()); 13527 ins_cost(DEFAULT_COST*2); 13528 13529 ins_encode %{ 13530 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13531 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13532 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13533 %} 13534 ins_pipe(pipe_class_default); 13535 %} 13536 13537 //---------- Population Count Instructions ------------------------------------ 13538 13539 // Popcnt for Power7. 13540 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13541 match(Set dst (PopCountI src)); 13542 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13543 ins_cost(DEFAULT_COST); 13544 13545 format %{ "POPCNTW $dst, $src" %} 13546 size(4); 13547 ins_encode %{ 13548 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13549 __ popcntw($dst$$Register, $src$$Register); 13550 %} 13551 ins_pipe(pipe_class_default); 13552 %} 13553 13554 // Popcnt for Power7. 13555 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13556 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13557 match(Set dst (PopCountL src)); 13558 ins_cost(DEFAULT_COST); 13559 13560 format %{ "POPCNTD $dst, $src" %} 13561 size(4); 13562 ins_encode %{ 13563 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13564 __ popcntd($dst$$Register, $src$$Register); 13565 %} 13566 ins_pipe(pipe_class_default); 13567 %} 13568 13569 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13570 match(Set dst (CountLeadingZerosI src)); 13571 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13572 ins_cost(DEFAULT_COST); 13573 13574 format %{ "CNTLZW $dst, $src" %} 13575 size(4); 13576 ins_encode %{ 13577 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13578 __ cntlzw($dst$$Register, $src$$Register); 13579 %} 13580 ins_pipe(pipe_class_default); 13581 %} 13582 13583 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13584 match(Set dst (CountLeadingZerosL src)); 13585 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13586 ins_cost(DEFAULT_COST); 13587 13588 format %{ "CNTLZD $dst, $src" %} 13589 size(4); 13590 ins_encode %{ 13591 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13592 __ cntlzd($dst$$Register, $src$$Register); 13593 %} 13594 ins_pipe(pipe_class_default); 13595 %} 13596 13597 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13598 // no match-rule, false predicate 13599 effect(DEF dst, USE src); 13600 predicate(false); 13601 13602 format %{ "CNTLZD $dst, $src" %} 13603 size(4); 13604 ins_encode %{ 13605 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13606 __ cntlzd($dst$$Register, $src$$Register); 13607 %} 13608 ins_pipe(pipe_class_default); 13609 %} 13610 13611 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13612 match(Set dst (CountTrailingZerosI src)); 13613 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13614 ins_cost(DEFAULT_COST); 13615 13616 expand %{ 13617 immI16 imm1 %{ (int)-1 %} 13618 immI16 imm2 %{ (int)32 %} 13619 immI_minus1 m1 %{ -1 %} 13620 iRegIdst tmpI1; 13621 iRegIdst tmpI2; 13622 iRegIdst tmpI3; 13623 addI_reg_imm16(tmpI1, src, imm1); 13624 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13625 countLeadingZerosI(tmpI3, tmpI2); 13626 subI_imm16_reg(dst, imm2, tmpI3); 13627 %} 13628 %} 13629 13630 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{ 13631 match(Set dst (CountTrailingZerosI src)); 13632 predicate(UseCountTrailingZerosInstructionsPPC64); 13633 ins_cost(DEFAULT_COST); 13634 13635 format %{ "CNTTZW $dst, $src" %} 13636 size(4); 13637 ins_encode %{ 13638 __ cnttzw($dst$$Register, $src$$Register); 13639 %} 13640 ins_pipe(pipe_class_default); 13641 %} 13642 13643 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13644 match(Set dst (CountTrailingZerosL src)); 13645 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13646 ins_cost(DEFAULT_COST); 13647 13648 expand %{ 13649 immL16 imm1 %{ (long)-1 %} 13650 immI16 imm2 %{ (int)64 %} 13651 iRegLdst tmpL1; 13652 iRegLdst tmpL2; 13653 iRegIdst tmpL3; 13654 addL_reg_imm16(tmpL1, src, imm1); 13655 andcL_reg_reg(tmpL2, tmpL1, src); 13656 countLeadingZerosL(tmpL3, tmpL2); 13657 subI_imm16_reg(dst, imm2, tmpL3); 13658 %} 13659 %} 13660 13661 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{ 13662 match(Set dst (CountTrailingZerosL src)); 13663 predicate(UseCountTrailingZerosInstructionsPPC64); 13664 ins_cost(DEFAULT_COST); 13665 13666 format %{ "CNTTZD $dst, $src" %} 13667 size(4); 13668 ins_encode %{ 13669 __ cnttzd($dst$$Register, $src$$Register); 13670 %} 13671 ins_pipe(pipe_class_default); 13672 %} 13673 13674 // Expand nodes for byte_reverse_int. 13675 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13676 effect(DEF dst, USE src, USE pos, USE shift); 13677 predicate(false); 13678 13679 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13680 size(4); 13681 ins_encode %{ 13682 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13683 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13684 %} 13685 ins_pipe(pipe_class_default); 13686 %} 13687 13688 // As insrwi_a, but with USE_DEF. 13689 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13690 effect(USE_DEF dst, USE src, USE pos, USE shift); 13691 predicate(false); 13692 13693 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13694 size(4); 13695 ins_encode %{ 13696 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13697 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13698 %} 13699 ins_pipe(pipe_class_default); 13700 %} 13701 13702 // Just slightly faster than java implementation. 13703 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13704 match(Set dst (ReverseBytesI src)); 13705 ins_cost(7*DEFAULT_COST); 13706 13707 expand %{ 13708 immI16 imm24 %{ (int) 24 %} 13709 immI16 imm16 %{ (int) 16 %} 13710 immI16 imm8 %{ (int) 8 %} 13711 immI16 imm4 %{ (int) 4 %} 13712 immI16 imm0 %{ (int) 0 %} 13713 iRegLdst tmpI1; 13714 iRegLdst tmpI2; 13715 iRegLdst tmpI3; 13716 13717 urShiftI_reg_imm(tmpI1, src, imm24); 13718 insrwi_a(dst, tmpI1, imm24, imm8); 13719 urShiftI_reg_imm(tmpI2, src, imm16); 13720 insrwi(dst, tmpI2, imm8, imm16); 13721 urShiftI_reg_imm(tmpI3, src, imm8); 13722 insrwi(dst, tmpI3, imm8, imm8); 13723 insrwi(dst, src, imm0, imm8); 13724 %} 13725 %} 13726 13727 instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{ 13728 match(Set dst (ReverseBytesI src)); 13729 predicate(UseVectorByteReverseInstructionsPPC64); 13730 effect(TEMP tmpV); 13731 ins_cost(DEFAULT_COST*3); 13732 size(12); 13733 format %{ "MTVSRWZ $tmpV, $src\n" 13734 "\tXXBRW $tmpV, $tmpV\n" 13735 "\tMFVSRWZ $dst, $tmpV" %} 13736 13737 ins_encode %{ 13738 __ mtvsrwz($tmpV$$VectorSRegister, $src$$Register); 13739 __ xxbrw($tmpV$$VectorSRegister, $tmpV$$VectorSRegister); 13740 __ mfvsrwz($dst$$Register, $tmpV$$VectorSRegister); 13741 %} 13742 ins_pipe(pipe_class_default); 13743 %} 13744 13745 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13746 match(Set dst (ReverseBytesL src)); 13747 ins_cost(15*DEFAULT_COST); 13748 13749 expand %{ 13750 immI16 imm56 %{ (int) 56 %} 13751 immI16 imm48 %{ (int) 48 %} 13752 immI16 imm40 %{ (int) 40 %} 13753 immI16 imm32 %{ (int) 32 %} 13754 immI16 imm24 %{ (int) 24 %} 13755 immI16 imm16 %{ (int) 16 %} 13756 immI16 imm8 %{ (int) 8 %} 13757 immI16 imm0 %{ (int) 0 %} 13758 iRegLdst tmpL1; 13759 iRegLdst tmpL2; 13760 iRegLdst tmpL3; 13761 iRegLdst tmpL4; 13762 iRegLdst tmpL5; 13763 iRegLdst tmpL6; 13764 13765 // src : |a|b|c|d|e|f|g|h| 13766 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13767 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13768 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13769 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13770 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13771 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13772 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13773 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13774 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13775 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13776 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13777 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13778 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13779 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13780 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13781 %} 13782 %} 13783 13784 instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{ 13785 match(Set dst (ReverseBytesL src)); 13786 predicate(UseVectorByteReverseInstructionsPPC64); 13787 effect(TEMP tmpV); 13788 ins_cost(DEFAULT_COST*3); 13789 size(12); 13790 format %{ "MTVSRD $tmpV, $src\n" 13791 "\tXXBRD $tmpV, $tmpV\n" 13792 "\tMFVSRD $dst, $tmpV" %} 13793 13794 ins_encode %{ 13795 __ mtvsrd($tmpV$$VectorSRegister, $src$$Register); 13796 __ xxbrd($tmpV$$VectorSRegister, $tmpV$$VectorSRegister); 13797 __ mfvsrd($dst$$Register, $tmpV$$VectorSRegister); 13798 %} 13799 ins_pipe(pipe_class_default); 13800 %} 13801 13802 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13803 match(Set dst (ReverseBytesUS src)); 13804 ins_cost(2*DEFAULT_COST); 13805 13806 expand %{ 13807 immI16 imm16 %{ (int) 16 %} 13808 immI16 imm8 %{ (int) 8 %} 13809 13810 urShiftI_reg_imm(dst, src, imm8); 13811 insrwi(dst, src, imm16, imm8); 13812 %} 13813 %} 13814 13815 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13816 match(Set dst (ReverseBytesS src)); 13817 ins_cost(3*DEFAULT_COST); 13818 13819 expand %{ 13820 immI16 imm16 %{ (int) 16 %} 13821 immI16 imm8 %{ (int) 8 %} 13822 iRegLdst tmpI1; 13823 13824 urShiftI_reg_imm(tmpI1, src, imm8); 13825 insrwi(tmpI1, src, imm16, imm8); 13826 extsh(dst, tmpI1); 13827 %} 13828 %} 13829 13830 // Load Integer reversed byte order 13831 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13832 match(Set dst (ReverseBytesI (LoadI mem))); 13833 ins_cost(MEMORY_REF_COST); 13834 13835 size(4); 13836 ins_encode %{ 13837 __ lwbrx($dst$$Register, $mem$$Register); 13838 %} 13839 ins_pipe(pipe_class_default); 13840 %} 13841 13842 // Load Long - aligned and reversed 13843 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13844 match(Set dst (ReverseBytesL (LoadL mem))); 13845 predicate(VM_Version::has_ldbrx()); 13846 ins_cost(MEMORY_REF_COST); 13847 13848 size(4); 13849 ins_encode %{ 13850 __ ldbrx($dst$$Register, $mem$$Register); 13851 %} 13852 ins_pipe(pipe_class_default); 13853 %} 13854 13855 // Load unsigned short / char reversed byte order 13856 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13857 match(Set dst (ReverseBytesUS (LoadUS mem))); 13858 ins_cost(MEMORY_REF_COST); 13859 13860 size(4); 13861 ins_encode %{ 13862 __ lhbrx($dst$$Register, $mem$$Register); 13863 %} 13864 ins_pipe(pipe_class_default); 13865 %} 13866 13867 // Load short reversed byte order 13868 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13869 match(Set dst (ReverseBytesS (LoadS mem))); 13870 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13871 13872 size(8); 13873 ins_encode %{ 13874 __ lhbrx($dst$$Register, $mem$$Register); 13875 __ extsh($dst$$Register, $dst$$Register); 13876 %} 13877 ins_pipe(pipe_class_default); 13878 %} 13879 13880 // Store Integer reversed byte order 13881 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13882 match(Set mem (StoreI mem (ReverseBytesI src))); 13883 ins_cost(MEMORY_REF_COST); 13884 13885 size(4); 13886 ins_encode %{ 13887 __ stwbrx($src$$Register, $mem$$Register); 13888 %} 13889 ins_pipe(pipe_class_default); 13890 %} 13891 13892 // Store Long reversed byte order 13893 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13894 match(Set mem (StoreL mem (ReverseBytesL src))); 13895 predicate(VM_Version::has_stdbrx()); 13896 ins_cost(MEMORY_REF_COST); 13897 13898 size(4); 13899 ins_encode %{ 13900 __ stdbrx($src$$Register, $mem$$Register); 13901 %} 13902 ins_pipe(pipe_class_default); 13903 %} 13904 13905 // Store unsigned short / char reversed byte order 13906 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13907 match(Set mem (StoreC mem (ReverseBytesUS src))); 13908 ins_cost(MEMORY_REF_COST); 13909 13910 size(4); 13911 ins_encode %{ 13912 __ sthbrx($src$$Register, $mem$$Register); 13913 %} 13914 ins_pipe(pipe_class_default); 13915 %} 13916 13917 // Store short reversed byte order 13918 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13919 match(Set mem (StoreC mem (ReverseBytesS src))); 13920 ins_cost(MEMORY_REF_COST); 13921 13922 size(4); 13923 ins_encode %{ 13924 __ sthbrx($src$$Register, $mem$$Register); 13925 %} 13926 ins_pipe(pipe_class_default); 13927 %} 13928 13929 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13930 effect(DEF temp1, USE src); 13931 13932 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %} 13933 size(4); 13934 ins_encode %{ 13935 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13936 %} 13937 ins_pipe(pipe_class_default); 13938 %} 13939 13940 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13941 effect(DEF dst, USE src, USE imm1); 13942 13943 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %} 13944 size(4); 13945 ins_encode %{ 13946 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13947 %} 13948 ins_pipe(pipe_class_default); 13949 %} 13950 13951 instruct xscvdpspn_regF(vecX dst, regF src) %{ 13952 effect(DEF dst, USE src); 13953 13954 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %} 13955 size(4); 13956 ins_encode %{ 13957 __ xscvdpspn($dst$$VectorSRegister, $src$$FloatRegister->to_vsr()); 13958 %} 13959 ins_pipe(pipe_class_default); 13960 %} 13961 13962 //---------- Replicate Vector Instructions ------------------------------------ 13963 13964 // Insrdi does replicate if src == dst. 13965 instruct repl32(iRegLdst dst) %{ 13966 predicate(false); 13967 effect(USE_DEF dst); 13968 13969 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13970 size(4); 13971 ins_encode %{ 13972 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13973 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13974 %} 13975 ins_pipe(pipe_class_default); 13976 %} 13977 13978 // Insrdi does replicate if src == dst. 13979 instruct repl48(iRegLdst dst) %{ 13980 predicate(false); 13981 effect(USE_DEF dst); 13982 13983 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13984 size(4); 13985 ins_encode %{ 13986 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13987 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13988 %} 13989 ins_pipe(pipe_class_default); 13990 %} 13991 13992 // Insrdi does replicate if src == dst. 13993 instruct repl56(iRegLdst dst) %{ 13994 predicate(false); 13995 effect(USE_DEF dst); 13996 13997 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13998 size(4); 13999 ins_encode %{ 14000 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 14001 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 14002 %} 14003 ins_pipe(pipe_class_default); 14004 %} 14005 14006 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14007 match(Set dst (ReplicateB src)); 14008 predicate(n->as_Vector()->length() == 8); 14009 expand %{ 14010 moveReg(dst, src); 14011 repl56(dst); 14012 repl48(dst); 14013 repl32(dst); 14014 %} 14015 %} 14016 14017 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 14018 match(Set dst (ReplicateB zero)); 14019 predicate(n->as_Vector()->length() == 8); 14020 format %{ "LI $dst, #0 \t// replicate8B" %} 14021 size(4); 14022 ins_encode %{ 14023 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14024 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14025 %} 14026 ins_pipe(pipe_class_default); 14027 %} 14028 14029 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14030 match(Set dst (ReplicateB src)); 14031 predicate(n->as_Vector()->length() == 8); 14032 format %{ "LI $dst, #-1 \t// replicate8B" %} 14033 size(4); 14034 ins_encode %{ 14035 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14036 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14037 %} 14038 ins_pipe(pipe_class_default); 14039 %} 14040 14041 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 14042 match(Set dst (ReplicateB src)); 14043 predicate(n->as_Vector()->length() == 16); 14044 14045 expand %{ 14046 iRegLdst tmpL; 14047 vecX tmpV; 14048 immI8 imm1 %{ (int) 1 %} 14049 moveReg(tmpL, src); 14050 repl56(tmpL); 14051 repl48(tmpL); 14052 mtvsrwz(tmpV, tmpL); 14053 xxspltw(dst, tmpV, imm1); 14054 %} 14055 %} 14056 14057 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 14058 match(Set dst (ReplicateB zero)); 14059 predicate(n->as_Vector()->length() == 16); 14060 14061 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 14062 size(4); 14063 ins_encode %{ 14064 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14065 %} 14066 ins_pipe(pipe_class_default); 14067 %} 14068 14069 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 14070 match(Set dst (ReplicateB src)); 14071 predicate(n->as_Vector()->length() == 16); 14072 14073 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14074 size(4); 14075 ins_encode %{ 14076 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14077 %} 14078 ins_pipe(pipe_class_default); 14079 %} 14080 14081 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14082 match(Set dst (ReplicateS src)); 14083 predicate(n->as_Vector()->length() == 4); 14084 expand %{ 14085 moveReg(dst, src); 14086 repl48(dst); 14087 repl32(dst); 14088 %} 14089 %} 14090 14091 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 14092 match(Set dst (ReplicateS zero)); 14093 predicate(n->as_Vector()->length() == 4); 14094 format %{ "LI $dst, #0 \t// replicate4S" %} 14095 size(4); 14096 ins_encode %{ 14097 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14098 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14099 %} 14100 ins_pipe(pipe_class_default); 14101 %} 14102 14103 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14104 match(Set dst (ReplicateS src)); 14105 predicate(n->as_Vector()->length() == 4); 14106 format %{ "LI $dst, -1 \t// replicate4S" %} 14107 size(4); 14108 ins_encode %{ 14109 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14110 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14111 %} 14112 ins_pipe(pipe_class_default); 14113 %} 14114 14115 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 14116 match(Set dst (ReplicateS src)); 14117 predicate(n->as_Vector()->length() == 8); 14118 14119 expand %{ 14120 iRegLdst tmpL; 14121 vecX tmpV; 14122 immI8 zero %{ (int) 0 %} 14123 moveReg(tmpL, src); 14124 repl48(tmpL); 14125 repl32(tmpL); 14126 mtvsrd(tmpV, tmpL); 14127 xxpermdi(dst, tmpV, tmpV, zero); 14128 %} 14129 %} 14130 14131 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 14132 match(Set dst (ReplicateS zero)); 14133 predicate(n->as_Vector()->length() == 8); 14134 14135 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 14136 size(4); 14137 ins_encode %{ 14138 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14139 %} 14140 ins_pipe(pipe_class_default); 14141 %} 14142 14143 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 14144 match(Set dst (ReplicateS src)); 14145 predicate(n->as_Vector()->length() == 8); 14146 14147 format %{ "XXLEQV $dst, $src \t// replicate8S" %} 14148 size(4); 14149 ins_encode %{ 14150 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14151 %} 14152 ins_pipe(pipe_class_default); 14153 %} 14154 14155 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14156 match(Set dst (ReplicateI src)); 14157 predicate(n->as_Vector()->length() == 2); 14158 ins_cost(2 * DEFAULT_COST); 14159 expand %{ 14160 moveReg(dst, src); 14161 repl32(dst); 14162 %} 14163 %} 14164 14165 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 14166 match(Set dst (ReplicateI zero)); 14167 predicate(n->as_Vector()->length() == 2); 14168 format %{ "LI $dst, #0 \t// replicate2I" %} 14169 size(4); 14170 ins_encode %{ 14171 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14172 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14173 %} 14174 ins_pipe(pipe_class_default); 14175 %} 14176 14177 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14178 match(Set dst (ReplicateI src)); 14179 predicate(n->as_Vector()->length() == 2); 14180 format %{ "LI $dst, -1 \t// replicate2I" %} 14181 size(4); 14182 ins_encode %{ 14183 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14184 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14185 %} 14186 ins_pipe(pipe_class_default); 14187 %} 14188 14189 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 14190 match(Set dst (ReplicateI src)); 14191 predicate(n->as_Vector()->length() == 4); 14192 ins_cost(2 * DEFAULT_COST); 14193 14194 expand %{ 14195 iRegLdst tmpL; 14196 vecX tmpV; 14197 immI8 zero %{ (int) 0 %} 14198 moveReg(tmpL, src); 14199 repl32(tmpL); 14200 mtvsrd(tmpV, tmpL); 14201 xxpermdi(dst, tmpV, tmpV, zero); 14202 %} 14203 %} 14204 14205 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 14206 match(Set dst (ReplicateI zero)); 14207 predicate(n->as_Vector()->length() == 4); 14208 14209 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 14210 size(4); 14211 ins_encode %{ 14212 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14213 %} 14214 ins_pipe(pipe_class_default); 14215 %} 14216 14217 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 14218 match(Set dst (ReplicateI src)); 14219 predicate(n->as_Vector()->length() == 4); 14220 14221 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 14222 size(4); 14223 ins_encode %{ 14224 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14225 %} 14226 ins_pipe(pipe_class_default); 14227 %} 14228 14229 // Move float to int register via stack, replicate. 14230 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 14231 match(Set dst (ReplicateF src)); 14232 predicate(n->as_Vector()->length() == 2); 14233 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14234 expand %{ 14235 stackSlotL tmpS; 14236 iRegIdst tmpI; 14237 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14238 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14239 moveReg(dst, tmpI); // Move int to long reg. 14240 repl32(dst); // Replicate bitpattern. 14241 %} 14242 %} 14243 14244 // Replicate scalar constant to packed float values in Double register 14245 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 14246 match(Set dst (ReplicateF src)); 14247 predicate(n->as_Vector()->length() == 2); 14248 ins_cost(5 * DEFAULT_COST); 14249 14250 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 14251 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 14252 %} 14253 14254 // Replicate scalar zero constant to packed float values in Double register 14255 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 14256 match(Set dst (ReplicateF zero)); 14257 predicate(n->as_Vector()->length() == 2); 14258 14259 format %{ "LI $dst, #0 \t// replicate2F" %} 14260 ins_encode %{ 14261 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14262 __ li($dst$$Register, 0x0); 14263 %} 14264 ins_pipe(pipe_class_default); 14265 %} 14266 14267 14268 //----------Vector Arithmetic Instructions-------------------------------------- 14269 14270 // Vector Addition Instructions 14271 14272 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{ 14273 match(Set dst (AddVB src1 src2)); 14274 predicate(n->as_Vector()->length() == 16); 14275 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %} 14276 size(4); 14277 ins_encode %{ 14278 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14279 %} 14280 ins_pipe(pipe_class_default); 14281 %} 14282 14283 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{ 14284 match(Set dst (AddVS src1 src2)); 14285 predicate(n->as_Vector()->length() == 8); 14286 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %} 14287 size(4); 14288 ins_encode %{ 14289 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14290 %} 14291 ins_pipe(pipe_class_default); 14292 %} 14293 14294 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{ 14295 match(Set dst (AddVI src1 src2)); 14296 predicate(n->as_Vector()->length() == 4); 14297 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %} 14298 size(4); 14299 ins_encode %{ 14300 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14301 %} 14302 ins_pipe(pipe_class_default); 14303 %} 14304 14305 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{ 14306 match(Set dst (AddVF src1 src2)); 14307 predicate(n->as_Vector()->length() == 4); 14308 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %} 14309 size(4); 14310 ins_encode %{ 14311 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14312 %} 14313 ins_pipe(pipe_class_default); 14314 %} 14315 14316 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{ 14317 match(Set dst (AddVL src1 src2)); 14318 predicate(n->as_Vector()->length() == 2); 14319 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %} 14320 size(4); 14321 ins_encode %{ 14322 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14323 %} 14324 ins_pipe(pipe_class_default); 14325 %} 14326 14327 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{ 14328 match(Set dst (AddVD src1 src2)); 14329 predicate(n->as_Vector()->length() == 2); 14330 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %} 14331 size(4); 14332 ins_encode %{ 14333 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14334 %} 14335 ins_pipe(pipe_class_default); 14336 %} 14337 14338 // Vector Subtraction Instructions 14339 14340 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{ 14341 match(Set dst (SubVB src1 src2)); 14342 predicate(n->as_Vector()->length() == 16); 14343 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %} 14344 size(4); 14345 ins_encode %{ 14346 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14347 %} 14348 ins_pipe(pipe_class_default); 14349 %} 14350 14351 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{ 14352 match(Set dst (SubVS src1 src2)); 14353 predicate(n->as_Vector()->length() == 8); 14354 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %} 14355 size(4); 14356 ins_encode %{ 14357 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14358 %} 14359 ins_pipe(pipe_class_default); 14360 %} 14361 14362 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{ 14363 match(Set dst (SubVI src1 src2)); 14364 predicate(n->as_Vector()->length() == 4); 14365 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %} 14366 size(4); 14367 ins_encode %{ 14368 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14369 %} 14370 ins_pipe(pipe_class_default); 14371 %} 14372 14373 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{ 14374 match(Set dst (SubVF src1 src2)); 14375 predicate(n->as_Vector()->length() == 4); 14376 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %} 14377 size(4); 14378 ins_encode %{ 14379 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14380 %} 14381 ins_pipe(pipe_class_default); 14382 %} 14383 14384 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{ 14385 match(Set dst (SubVL src1 src2)); 14386 predicate(n->as_Vector()->length() == 2); 14387 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %} 14388 size(4); 14389 ins_encode %{ 14390 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14391 %} 14392 ins_pipe(pipe_class_default); 14393 %} 14394 14395 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{ 14396 match(Set dst (SubVD src1 src2)); 14397 predicate(n->as_Vector()->length() == 2); 14398 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %} 14399 size(4); 14400 ins_encode %{ 14401 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14402 %} 14403 ins_pipe(pipe_class_default); 14404 %} 14405 14406 // Vector Multiplication Instructions 14407 14408 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 14409 match(Set dst (MulVS src1 src2)); 14410 predicate(n->as_Vector()->length() == 8); 14411 effect(TEMP tmp); 14412 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %} 14413 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %} 14414 size(8); 14415 ins_encode %{ 14416 __ vspltish($tmp$$VectorSRegister->to_vr(), 0); 14417 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr()); 14418 %} 14419 ins_pipe(pipe_class_default); 14420 %} 14421 14422 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{ 14423 match(Set dst (MulVI src1 src2)); 14424 predicate(n->as_Vector()->length() == 4); 14425 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %} 14426 size(4); 14427 ins_encode %{ 14428 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14429 %} 14430 ins_pipe(pipe_class_default); 14431 %} 14432 14433 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{ 14434 match(Set dst (MulVF src1 src2)); 14435 predicate(n->as_Vector()->length() == 4); 14436 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %} 14437 size(4); 14438 ins_encode %{ 14439 __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14440 %} 14441 ins_pipe(pipe_class_default); 14442 %} 14443 14444 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{ 14445 match(Set dst (MulVD src1 src2)); 14446 predicate(n->as_Vector()->length() == 2); 14447 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %} 14448 size(4); 14449 ins_encode %{ 14450 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14451 %} 14452 ins_pipe(pipe_class_default); 14453 %} 14454 14455 // Vector Division Instructions 14456 14457 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{ 14458 match(Set dst (DivVF src1 src2)); 14459 predicate(n->as_Vector()->length() == 4); 14460 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %} 14461 size(4); 14462 ins_encode %{ 14463 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14464 %} 14465 ins_pipe(pipe_class_default); 14466 %} 14467 14468 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ 14469 match(Set dst (DivVD src1 src2)); 14470 predicate(n->as_Vector()->length() == 2); 14471 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %} 14472 size(4); 14473 ins_encode %{ 14474 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14475 %} 14476 ins_pipe(pipe_class_default); 14477 %} 14478 14479 // Vector Absolute Instructions 14480 14481 instruct vabs4F_reg(vecX dst, vecX src) %{ 14482 match(Set dst (AbsVF src)); 14483 predicate(n->as_Vector()->length() == 4); 14484 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %} 14485 size(4); 14486 ins_encode %{ 14487 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister); 14488 %} 14489 ins_pipe(pipe_class_default); 14490 %} 14491 14492 instruct vabs2D_reg(vecX dst, vecX src) %{ 14493 match(Set dst (AbsVD src)); 14494 predicate(n->as_Vector()->length() == 2); 14495 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %} 14496 size(4); 14497 ins_encode %{ 14498 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister); 14499 %} 14500 ins_pipe(pipe_class_default); 14501 %} 14502 14503 // Round Instructions 14504 instruct roundD_reg(regD dst, regD src, immI8 rmode) %{ 14505 match(Set dst (RoundDoubleMode src rmode)); 14506 format %{ "RoundDoubleMode $src,$rmode" %} 14507 size(4); 14508 ins_encode %{ 14509 switch ($rmode$$constant) { 14510 case RoundDoubleModeNode::rmode_rint: 14511 __ frin($dst$$FloatRegister, $src$$FloatRegister); 14512 break; 14513 case RoundDoubleModeNode::rmode_floor: 14514 __ frim($dst$$FloatRegister, $src$$FloatRegister); 14515 break; 14516 case RoundDoubleModeNode::rmode_ceil: 14517 __ frip($dst$$FloatRegister, $src$$FloatRegister); 14518 break; 14519 default: 14520 ShouldNotReachHere(); 14521 } 14522 %} 14523 ins_pipe(pipe_class_default); 14524 %} 14525 14526 // Vector Round Instructions 14527 instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{ 14528 match(Set dst (RoundDoubleModeV src rmode)); 14529 predicate(n->as_Vector()->length() == 2); 14530 format %{ "RoundDoubleModeV $src,$rmode" %} 14531 size(4); 14532 ins_encode %{ 14533 switch ($rmode$$constant) { 14534 case RoundDoubleModeNode::rmode_rint: 14535 __ xvrdpi($dst$$VectorSRegister, $src$$VectorSRegister); 14536 break; 14537 case RoundDoubleModeNode::rmode_floor: 14538 __ xvrdpim($dst$$VectorSRegister, $src$$VectorSRegister); 14539 break; 14540 case RoundDoubleModeNode::rmode_ceil: 14541 __ xvrdpip($dst$$VectorSRegister, $src$$VectorSRegister); 14542 break; 14543 default: 14544 ShouldNotReachHere(); 14545 } 14546 %} 14547 ins_pipe(pipe_class_default); 14548 %} 14549 14550 // Vector Negate Instructions 14551 14552 instruct vneg4F_reg(vecX dst, vecX src) %{ 14553 match(Set dst (NegVF src)); 14554 predicate(n->as_Vector()->length() == 4); 14555 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %} 14556 size(4); 14557 ins_encode %{ 14558 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister); 14559 %} 14560 ins_pipe(pipe_class_default); 14561 %} 14562 14563 instruct vneg2D_reg(vecX dst, vecX src) %{ 14564 match(Set dst (NegVD src)); 14565 predicate(n->as_Vector()->length() == 2); 14566 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %} 14567 size(4); 14568 ins_encode %{ 14569 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister); 14570 %} 14571 ins_pipe(pipe_class_default); 14572 %} 14573 14574 // Vector Square Root Instructions 14575 14576 instruct vsqrt4F_reg(vecX dst, vecX src) %{ 14577 match(Set dst (SqrtVF src)); 14578 predicate(n->as_Vector()->length() == 4); 14579 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %} 14580 size(4); 14581 ins_encode %{ 14582 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister); 14583 %} 14584 ins_pipe(pipe_class_default); 14585 %} 14586 14587 instruct vsqrt2D_reg(vecX dst, vecX src) %{ 14588 match(Set dst (SqrtVD src)); 14589 predicate(n->as_Vector()->length() == 2); 14590 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %} 14591 size(4); 14592 ins_encode %{ 14593 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister); 14594 %} 14595 ins_pipe(pipe_class_default); 14596 %} 14597 14598 // Vector Population Count Instructions 14599 14600 instruct vpopcnt4I_reg(vecX dst, vecX src) %{ 14601 match(Set dst (PopCountVI src)); 14602 predicate(n->as_Vector()->length() == 4); 14603 format %{ "VPOPCNTW $dst,$src\t// pop count packed4I" %} 14604 size(4); 14605 ins_encode %{ 14606 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14607 %} 14608 ins_pipe(pipe_class_default); 14609 %} 14610 14611 // --------------------------------- FMA -------------------------------------- 14612 // dst + src1 * src2 14613 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{ 14614 match(Set dst (FmaVF dst (Binary src1 src2))); 14615 predicate(n->as_Vector()->length() == 4); 14616 14617 format %{ "XVMADDASP $dst, $src1, $src2" %} 14618 14619 size(4); 14620 ins_encode %{ 14621 __ xvmaddasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14622 %} 14623 ins_pipe(pipe_class_default); 14624 %} 14625 14626 // dst - src1 * src2 14627 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{ 14628 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 14629 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 14630 predicate(n->as_Vector()->length() == 4); 14631 14632 format %{ "XVNMSUBASP $dst, $src1, $src2" %} 14633 14634 size(4); 14635 ins_encode %{ 14636 __ xvnmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14637 %} 14638 ins_pipe(pipe_class_default); 14639 %} 14640 14641 // - dst + src1 * src2 14642 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{ 14643 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2))); 14644 predicate(n->as_Vector()->length() == 4); 14645 14646 format %{ "XVMSUBASP $dst, $src1, $src2" %} 14647 14648 size(4); 14649 ins_encode %{ 14650 __ xvmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14651 %} 14652 ins_pipe(pipe_class_default); 14653 %} 14654 14655 // dst + src1 * src2 14656 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{ 14657 match(Set dst (FmaVD dst (Binary src1 src2))); 14658 predicate(n->as_Vector()->length() == 2); 14659 14660 format %{ "XVMADDADP $dst, $src1, $src2" %} 14661 14662 size(4); 14663 ins_encode %{ 14664 __ xvmaddadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14665 %} 14666 ins_pipe(pipe_class_default); 14667 %} 14668 14669 // dst - src1 * src2 14670 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{ 14671 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 14672 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 14673 predicate(n->as_Vector()->length() == 2); 14674 14675 format %{ "XVNMSUBADP $dst, $src1, $src2" %} 14676 14677 size(4); 14678 ins_encode %{ 14679 __ xvnmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14680 %} 14681 ins_pipe(pipe_class_default); 14682 %} 14683 14684 // - dst + src1 * src2 14685 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{ 14686 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2))); 14687 predicate(n->as_Vector()->length() == 2); 14688 14689 format %{ "XVMSUBADP $dst, $src1, $src2" %} 14690 14691 size(4); 14692 ins_encode %{ 14693 __ xvmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14694 %} 14695 ins_pipe(pipe_class_default); 14696 %} 14697 14698 //----------Overflow Math Instructions----------------------------------------- 14699 14700 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 14701 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14702 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14703 14704 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14705 match(Set cr0 (OverflowAddL op1 op2)); 14706 14707 format %{ "add_ $op1, $op2\t# overflow check long" %} 14708 ins_encode %{ 14709 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14710 __ li(R0, 0); 14711 __ mtxer(R0); // clear XER.SO 14712 __ addo_(R0, $op1$$Register, $op2$$Register); 14713 %} 14714 ins_pipe(pipe_class_default); 14715 %} 14716 14717 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14718 match(Set cr0 (OverflowSubL op1 op2)); 14719 14720 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14721 ins_encode %{ 14722 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14723 __ li(R0, 0); 14724 __ mtxer(R0); // clear XER.SO 14725 __ subfo_(R0, $op2$$Register, $op1$$Register); 14726 %} 14727 ins_pipe(pipe_class_default); 14728 %} 14729 14730 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14731 match(Set cr0 (OverflowSubL zero op2)); 14732 14733 format %{ "nego_ R0, $op2\t# overflow check long" %} 14734 ins_encode %{ 14735 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14736 __ li(R0, 0); 14737 __ mtxer(R0); // clear XER.SO 14738 __ nego_(R0, $op2$$Register); 14739 %} 14740 ins_pipe(pipe_class_default); 14741 %} 14742 14743 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14744 match(Set cr0 (OverflowMulL op1 op2)); 14745 14746 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14747 ins_encode %{ 14748 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14749 __ li(R0, 0); 14750 __ mtxer(R0); // clear XER.SO 14751 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14752 %} 14753 ins_pipe(pipe_class_default); 14754 %} 14755 14756 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14757 match(Set dst (ReplicateF src)); 14758 predicate(n->as_Vector()->length() == 4); 14759 ins_cost(DEFAULT_COST); 14760 expand %{ 14761 vecX tmpV; 14762 immI8 zero %{ (int) 0 %} 14763 14764 xscvdpspn_regF(tmpV, src); 14765 xxspltw(dst, tmpV, zero); 14766 %} 14767 %} 14768 14769 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14770 match(Set dst (ReplicateF src)); 14771 predicate(n->as_Vector()->length() == 4); 14772 effect(TEMP tmp); 14773 ins_cost(10 * DEFAULT_COST); 14774 14775 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14776 %} 14777 14778 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14779 match(Set dst (ReplicateF zero)); 14780 predicate(n->as_Vector()->length() == 4); 14781 14782 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14783 ins_encode %{ 14784 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14785 %} 14786 ins_pipe(pipe_class_default); 14787 %} 14788 14789 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14790 match(Set dst (ReplicateD src)); 14791 predicate(n->as_Vector()->length() == 2); 14792 14793 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %} 14794 size(4); 14795 ins_encode %{ 14796 __ xxpermdi($dst$$VectorSRegister, $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0); 14797 %} 14798 ins_pipe(pipe_class_default); 14799 %} 14800 14801 instruct repl2D_immD0(vecX dst, immD_0 zero) %{ 14802 match(Set dst (ReplicateD zero)); 14803 predicate(n->as_Vector()->length() == 2); 14804 14805 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14806 size(4); 14807 ins_encode %{ 14808 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14809 %} 14810 ins_pipe(pipe_class_default); 14811 %} 14812 14813 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14814 predicate(false); 14815 effect(DEF dst, USE src); 14816 14817 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %} 14818 size(4); 14819 ins_encode %{ 14820 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14821 %} 14822 ins_pipe(pipe_class_default); 14823 %} 14824 14825 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14826 effect(DEF dst, USE src, USE zero); 14827 14828 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %} 14829 size(4); 14830 ins_encode %{ 14831 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14832 %} 14833 ins_pipe(pipe_class_default); 14834 %} 14835 14836 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14837 effect(DEF dst, USE src1, USE src2, USE zero); 14838 14839 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %} 14840 size(4); 14841 ins_encode %{ 14842 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14843 %} 14844 ins_pipe(pipe_class_default); 14845 %} 14846 14847 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14848 match(Set dst (ReplicateL src)); 14849 predicate(n->as_Vector()->length() == 2); 14850 expand %{ 14851 vecX tmpV; 14852 immI8 zero %{ (int) 0 %} 14853 mtvsrd(tmpV, src); 14854 xxpermdi(dst, tmpV, tmpV, zero); 14855 %} 14856 %} 14857 14858 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14859 match(Set dst (ReplicateL zero)); 14860 predicate(n->as_Vector()->length() == 2); 14861 14862 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14863 size(4); 14864 ins_encode %{ 14865 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14866 %} 14867 ins_pipe(pipe_class_default); 14868 %} 14869 14870 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14871 match(Set dst (ReplicateL src)); 14872 predicate(n->as_Vector()->length() == 2); 14873 14874 format %{ "XXLEQV $dst, $src \t// replicate2L" %} 14875 size(4); 14876 ins_encode %{ 14877 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14878 %} 14879 ins_pipe(pipe_class_default); 14880 %} 14881 14882 // ============================================================================ 14883 // Safepoint Instruction 14884 14885 instruct safePoint_poll(iRegPdst poll) %{ 14886 match(SafePoint poll); 14887 14888 // It caused problems to add the effect that r0 is killed, but this 14889 // effect no longer needs to be mentioned, since r0 is not contained 14890 // in a reg_class. 14891 14892 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14893 size(4); 14894 ins_encode( enc_poll(0x0, poll) ); 14895 ins_pipe(pipe_class_default); 14896 %} 14897 14898 // ============================================================================ 14899 // Call Instructions 14900 14901 // Call Java Static Instruction 14902 14903 // Schedulable version of call static node. 14904 instruct CallStaticJavaDirect(method meth) %{ 14905 match(CallStaticJava); 14906 effect(USE meth); 14907 ins_cost(CALL_COST); 14908 14909 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14910 14911 format %{ "CALL,static $meth \t// ==> " %} 14912 size(4); 14913 ins_encode( enc_java_static_call(meth) ); 14914 ins_pipe(pipe_class_call); 14915 %} 14916 14917 // Call Java Dynamic Instruction 14918 14919 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14920 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14921 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14922 // The call destination must still be placed in the constant pool. 14923 instruct CallDynamicJavaDirectSched(method meth) %{ 14924 match(CallDynamicJava); // To get all the data fields we need ... 14925 effect(USE meth); 14926 predicate(false); // ... but never match. 14927 14928 ins_field_load_ic_hi_node(loadConL_hiNode*); 14929 ins_field_load_ic_node(loadConLNode*); 14930 ins_num_consts(1 /* 1 patchable constant: call destination */); 14931 14932 format %{ "BL \t// dynamic $meth ==> " %} 14933 size(4); 14934 ins_encode( enc_java_dynamic_call_sched(meth) ); 14935 ins_pipe(pipe_class_call); 14936 %} 14937 14938 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14939 // We use postalloc expanded calls if we use inline caches 14940 // and do not update method data. 14941 // 14942 // This instruction has two constants: inline cache (IC) and call destination. 14943 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14944 // one constant. 14945 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14946 match(CallDynamicJava); 14947 effect(USE meth); 14948 predicate(UseInlineCaches); 14949 ins_cost(CALL_COST); 14950 14951 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14952 14953 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14954 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14955 %} 14956 14957 // Compound version of call dynamic java 14958 // We use postalloc expanded calls if we use inline caches 14959 // and do not update method data. 14960 instruct CallDynamicJavaDirect(method meth) %{ 14961 match(CallDynamicJava); 14962 effect(USE meth); 14963 predicate(!UseInlineCaches); 14964 ins_cost(CALL_COST); 14965 14966 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14967 ins_num_consts(4); 14968 14969 format %{ "CALL,dynamic $meth \t// ==> " %} 14970 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14971 ins_pipe(pipe_class_call); 14972 %} 14973 14974 // Call Runtime Instruction 14975 14976 instruct CallRuntimeDirect(method meth) %{ 14977 match(CallRuntime); 14978 effect(USE meth); 14979 ins_cost(CALL_COST); 14980 14981 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14982 // env for callee, C-toc. 14983 ins_num_consts(3); 14984 14985 format %{ "CALL,runtime" %} 14986 ins_encode( enc_java_to_runtime_call(meth) ); 14987 ins_pipe(pipe_class_call); 14988 %} 14989 14990 // Call Leaf 14991 14992 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14993 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14994 effect(DEF dst, USE src); 14995 14996 ins_num_consts(1); 14997 14998 format %{ "MTCTR $src" %} 14999 size(4); 15000 ins_encode( enc_leaf_call_mtctr(src) ); 15001 ins_pipe(pipe_class_default); 15002 %} 15003 15004 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 15005 instruct CallLeafDirect(method meth) %{ 15006 match(CallLeaf); // To get the data all the data fields we need ... 15007 effect(USE meth); 15008 predicate(false); // but never match. 15009 15010 format %{ "BCTRL \t// leaf call $meth ==> " %} 15011 size(4); 15012 ins_encode %{ 15013 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 15014 __ bctrl(); 15015 %} 15016 ins_pipe(pipe_class_call); 15017 %} 15018 15019 // postalloc expand of CallLeafDirect. 15020 // Load adress to call from TOC, then bl to it. 15021 instruct CallLeafDirect_Ex(method meth) %{ 15022 match(CallLeaf); 15023 effect(USE meth); 15024 ins_cost(CALL_COST); 15025 15026 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 15027 // env for callee, C-toc. 15028 ins_num_consts(3); 15029 15030 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 15031 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 15032 %} 15033 15034 // Call runtime without safepoint - same as CallLeaf. 15035 // postalloc expand of CallLeafNoFPDirect. 15036 // Load adress to call from TOC, then bl to it. 15037 instruct CallLeafNoFPDirect_Ex(method meth) %{ 15038 match(CallLeafNoFP); 15039 effect(USE meth); 15040 ins_cost(CALL_COST); 15041 15042 // Enc_java_to_runtime_call needs up to 3 constants: call target, 15043 // env for callee, C-toc. 15044 ins_num_consts(3); 15045 15046 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 15047 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 15048 %} 15049 15050 // Tail Call; Jump from runtime stub to Java code. 15051 // Also known as an 'interprocedural jump'. 15052 // Target of jump will eventually return to caller. 15053 // TailJump below removes the return address. 15054 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 15055 match(TailCall jump_target method_oop); 15056 ins_cost(CALL_COST); 15057 15058 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 15059 "BCTR \t// tail call" %} 15060 size(8); 15061 ins_encode %{ 15062 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 15063 __ mtctr($jump_target$$Register); 15064 __ bctr(); 15065 %} 15066 ins_pipe(pipe_class_call); 15067 %} 15068 15069 // Return Instruction 15070 instruct Ret() %{ 15071 match(Return); 15072 format %{ "BLR \t// branch to link register" %} 15073 size(4); 15074 ins_encode %{ 15075 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 15076 // LR is restored in MachEpilogNode. Just do the RET here. 15077 __ blr(); 15078 %} 15079 ins_pipe(pipe_class_default); 15080 %} 15081 15082 // Tail Jump; remove the return address; jump to target. 15083 // TailCall above leaves the return address around. 15084 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 15085 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 15086 // "restore" before this instruction (in Epilogue), we need to materialize it 15087 // in %i0. 15088 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 15089 match(TailJump jump_target ex_oop); 15090 ins_cost(CALL_COST); 15091 15092 format %{ "LD R4_ARG2 = LR\n\t" 15093 "MTCTR $jump_target\n\t" 15094 "BCTR \t// TailJump, exception oop: $ex_oop" %} 15095 size(12); 15096 ins_encode %{ 15097 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 15098 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 15099 __ mtctr($jump_target$$Register); 15100 __ bctr(); 15101 %} 15102 ins_pipe(pipe_class_call); 15103 %} 15104 15105 // Create exception oop: created by stack-crawling runtime code. 15106 // Created exception is now available to this handler, and is setup 15107 // just prior to jumping to this handler. No code emitted. 15108 instruct CreateException(rarg1RegP ex_oop) %{ 15109 match(Set ex_oop (CreateEx)); 15110 ins_cost(0); 15111 15112 format %{ " -- \t// exception oop; no code emitted" %} 15113 size(0); 15114 ins_encode( /*empty*/ ); 15115 ins_pipe(pipe_class_default); 15116 %} 15117 15118 // Rethrow exception: The exception oop will come in the first 15119 // argument position. Then JUMP (not call) to the rethrow stub code. 15120 instruct RethrowException() %{ 15121 match(Rethrow); 15122 ins_cost(CALL_COST); 15123 15124 format %{ "Jmp rethrow_stub" %} 15125 ins_encode %{ 15126 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 15127 cbuf.set_insts_mark(); 15128 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 15129 %} 15130 ins_pipe(pipe_class_call); 15131 %} 15132 15133 // Die now. 15134 instruct ShouldNotReachHere() %{ 15135 match(Halt); 15136 ins_cost(CALL_COST); 15137 15138 format %{ "ShouldNotReachHere" %} 15139 ins_encode %{ 15140 if (is_reachable()) { 15141 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 15142 __ trap_should_not_reach_here(); 15143 } 15144 %} 15145 ins_pipe(pipe_class_default); 15146 %} 15147 15148 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 15149 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 15150 // Get a DEF on threadRegP, no costs, no encoding, use 15151 // 'ins_should_rematerialize(true)' to avoid spilling. 15152 instruct tlsLoadP(threadRegP dst) %{ 15153 match(Set dst (ThreadLocal)); 15154 ins_cost(0); 15155 15156 ins_should_rematerialize(true); 15157 15158 format %{ " -- \t// $dst=Thread::current(), empty" %} 15159 size(0); 15160 ins_encode( /*empty*/ ); 15161 ins_pipe(pipe_class_empty); 15162 %} 15163 15164 //---Some PPC specific nodes--------------------------------------------------- 15165 15166 // Stop a group. 15167 instruct endGroup() %{ 15168 ins_cost(0); 15169 15170 ins_is_nop(true); 15171 15172 format %{ "End Bundle (ori r1, r1, 0)" %} 15173 size(4); 15174 ins_encode %{ 15175 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 15176 __ endgroup(); 15177 %} 15178 ins_pipe(pipe_class_default); 15179 %} 15180 15181 // Nop instructions 15182 15183 instruct fxNop() %{ 15184 ins_cost(0); 15185 15186 ins_is_nop(true); 15187 15188 format %{ "fxNop" %} 15189 size(4); 15190 ins_encode %{ 15191 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15192 __ nop(); 15193 %} 15194 ins_pipe(pipe_class_default); 15195 %} 15196 15197 instruct fpNop0() %{ 15198 ins_cost(0); 15199 15200 ins_is_nop(true); 15201 15202 format %{ "fpNop0" %} 15203 size(4); 15204 ins_encode %{ 15205 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15206 __ fpnop0(); 15207 %} 15208 ins_pipe(pipe_class_default); 15209 %} 15210 15211 instruct fpNop1() %{ 15212 ins_cost(0); 15213 15214 ins_is_nop(true); 15215 15216 format %{ "fpNop1" %} 15217 size(4); 15218 ins_encode %{ 15219 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15220 __ fpnop1(); 15221 %} 15222 ins_pipe(pipe_class_default); 15223 %} 15224 15225 instruct brNop0() %{ 15226 ins_cost(0); 15227 size(4); 15228 format %{ "brNop0" %} 15229 ins_encode %{ 15230 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15231 __ brnop0(); 15232 %} 15233 ins_is_nop(true); 15234 ins_pipe(pipe_class_default); 15235 %} 15236 15237 instruct brNop1() %{ 15238 ins_cost(0); 15239 15240 ins_is_nop(true); 15241 15242 format %{ "brNop1" %} 15243 size(4); 15244 ins_encode %{ 15245 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15246 __ brnop1(); 15247 %} 15248 ins_pipe(pipe_class_default); 15249 %} 15250 15251 instruct brNop2() %{ 15252 ins_cost(0); 15253 15254 ins_is_nop(true); 15255 15256 format %{ "brNop2" %} 15257 size(4); 15258 ins_encode %{ 15259 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15260 __ brnop2(); 15261 %} 15262 ins_pipe(pipe_class_default); 15263 %} 15264 15265 instruct cacheWB(indirect addr) 15266 %{ 15267 match(CacheWB addr); 15268 15269 ins_cost(100); 15270 format %{ "cache writeback, address = $addr" %} 15271 ins_encode %{ 15272 assert($addr->index_position() < 0, "should be"); 15273 assert($addr$$disp == 0, "should be"); 15274 __ cache_wb(Address($addr$$base$$Register)); 15275 %} 15276 ins_pipe(pipe_class_default); 15277 %} 15278 15279 instruct cacheWBPreSync() 15280 %{ 15281 match(CacheWBPreSync); 15282 15283 ins_cost(0); 15284 format %{ "cache writeback presync" %} 15285 ins_encode %{ 15286 __ cache_wbsync(true); 15287 %} 15288 ins_pipe(pipe_class_default); 15289 %} 15290 15291 instruct cacheWBPostSync() 15292 %{ 15293 match(CacheWBPostSync); 15294 15295 ins_cost(100); 15296 format %{ "cache writeback postsync" %} 15297 ins_encode %{ 15298 __ cache_wbsync(false); 15299 %} 15300 ins_pipe(pipe_class_default); 15301 %} 15302 15303 //----------PEEPHOLE RULES----------------------------------------------------- 15304 // These must follow all instruction definitions as they use the names 15305 // defined in the instructions definitions. 15306 // 15307 // peepmatch ( root_instr_name [preceeding_instruction]* ); 15308 // 15309 // peepconstraint %{ 15310 // (instruction_number.operand_name relational_op instruction_number.operand_name 15311 // [, ...] ); 15312 // // instruction numbers are zero-based using left to right order in peepmatch 15313 // 15314 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 15315 // // provide an instruction_number.operand_name for each operand that appears 15316 // // in the replacement instruction's match rule 15317 // 15318 // ---------VM FLAGS--------------------------------------------------------- 15319 // 15320 // All peephole optimizations can be turned off using -XX:-OptoPeephole 15321 // 15322 // Each peephole rule is given an identifying number starting with zero and 15323 // increasing by one in the order seen by the parser. An individual peephole 15324 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 15325 // on the command-line. 15326 // 15327 // ---------CURRENT LIMITATIONS---------------------------------------------- 15328 // 15329 // Only match adjacent instructions in same basic block 15330 // Only equality constraints 15331 // Only constraints between operands, not (0.dest_reg == EAX_enc) 15332 // Only one replacement instruction 15333 // 15334 // ---------EXAMPLE---------------------------------------------------------- 15335 // 15336 // // pertinent parts of existing instructions in architecture description 15337 // instruct movI(eRegI dst, eRegI src) %{ 15338 // match(Set dst (CopyI src)); 15339 // %} 15340 // 15341 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 15342 // match(Set dst (AddI dst src)); 15343 // effect(KILL cr); 15344 // %} 15345 // 15346 // // Change (inc mov) to lea 15347 // peephole %{ 15348 // // increment preceeded by register-register move 15349 // peepmatch ( incI_eReg movI ); 15350 // // require that the destination register of the increment 15351 // // match the destination register of the move 15352 // peepconstraint ( 0.dst == 1.dst ); 15353 // // construct a replacement instruction that sets 15354 // // the destination to ( move's source register + one ) 15355 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15356 // %} 15357 // 15358 // Implementation no longer uses movX instructions since 15359 // machine-independent system no longer uses CopyX nodes. 15360 // 15361 // peephole %{ 15362 // peepmatch ( incI_eReg movI ); 15363 // peepconstraint ( 0.dst == 1.dst ); 15364 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15365 // %} 15366 // 15367 // peephole %{ 15368 // peepmatch ( decI_eReg movI ); 15369 // peepconstraint ( 0.dst == 1.dst ); 15370 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15371 // %} 15372 // 15373 // peephole %{ 15374 // peepmatch ( addI_eReg_imm movI ); 15375 // peepconstraint ( 0.dst == 1.dst ); 15376 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15377 // %} 15378 // 15379 // peephole %{ 15380 // peepmatch ( addP_eReg_imm movP ); 15381 // peepconstraint ( 0.dst == 1.dst ); 15382 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 15383 // %} 15384 15385 // // Change load of spilled value to only a spill 15386 // instruct storeI(memory mem, eRegI src) %{ 15387 // match(Set mem (StoreI mem src)); 15388 // %} 15389 // 15390 // instruct loadI(eRegI dst, memory mem) %{ 15391 // match(Set dst (LoadI mem)); 15392 // %} 15393 // 15394 peephole %{ 15395 peepmatch ( loadI storeI ); 15396 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15397 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 15398 %} 15399 15400 peephole %{ 15401 peepmatch ( loadL storeL ); 15402 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15403 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 15404 %} 15405 15406 peephole %{ 15407 peepmatch ( loadP storeP ); 15408 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 15409 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 15410 %} 15411 15412 //----------SMARTSPILL RULES--------------------------------------------------- 15413 // These must follow all instruction definitions as they use the names 15414 // defined in the instructions definitions.