1 // 2 // Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2018 SAP SE. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // 27 // PPC64 Architecture Description File 28 // 29 30 //----------REGISTER DEFINITION BLOCK------------------------------------------ 31 // This information is used by the matcher and the register allocator to 32 // describe individual registers and classes of registers within the target 33 // architecture. 34 register %{ 35 //----------Architecture Description Register Definitions---------------------- 36 // General Registers 37 // "reg_def" name (register save type, C convention save type, 38 // ideal register type, encoding); 39 // 40 // Register Save Types: 41 // 42 // NS = No-Save: The register allocator assumes that these registers 43 // can be used without saving upon entry to the method, & 44 // that they do not need to be saved at call sites. 45 // 46 // SOC = Save-On-Call: The register allocator assumes that these registers 47 // can be used without saving upon entry to the method, 48 // but that they must be saved at call sites. 49 // These are called "volatiles" on ppc. 50 // 51 // SOE = Save-On-Entry: The register allocator assumes that these registers 52 // must be saved before using them upon entry to the 53 // method, but they do not need to be saved at call 54 // sites. 55 // These are called "nonvolatiles" on ppc. 56 // 57 // AS = Always-Save: The register allocator assumes that these registers 58 // must be saved before using them upon entry to the 59 // method, & that they must be saved at call sites. 60 // 61 // Ideal Register Type is used to determine how to save & restore a 62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 64 // 65 // The encoding number is the actual bit-pattern placed into the opcodes. 66 // 67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI 68 // Supplement Version 1.7 as of 2003-10-29. 69 // 70 // For each 64-bit register we must define two registers: the register 71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half', 72 // e.g. R3_H, which is needed by the allocator, but is not used 73 // for stores, loads, etc. 74 75 // ---------------------------- 76 // Integer/Long Registers 77 // ---------------------------- 78 79 // PPC64 has 32 64-bit integer registers. 80 81 // types: v = volatile, nv = non-volatile, s = system 82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs 83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() ); 84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP 85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() ); 86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC 87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() ); 88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret 89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() ); 90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2 91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() ); 92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3 93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() ); 94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4 95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() ); 96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5 97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() ); 98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6 99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() ); 100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7 101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() ); 102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8 103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next()); 104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch 105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next()); 106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch 107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next()); 108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id 109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next()); 110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv 111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next()); 112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv 113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next()); 114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv 115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next()); 116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv 117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next()); 118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv 119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next()); 120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv 121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next()); 122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv 123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next()); 124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv 125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next()); 126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv 127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next()); 128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv 129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next()); 130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv 131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next()); 132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv 133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next()); 134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv 135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next()); 136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv 137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next()); 138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv 139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next()); 140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv 141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next()); 142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv 143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next()); 144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv 145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next()); 146 147 148 // ---------------------------- 149 // Float/Double Registers 150 // ---------------------------- 151 152 // Double Registers 153 // The rules of ADL require that double registers be defined in pairs. 154 // Each pair must be two 32-bit values, but not necessarily a pair of 155 // single float registers. In each pair, ADLC-assigned register numbers 156 // must be adjacent, with the lower number even. Finally, when the 157 // CPU stores such a register pair to memory, the word associated with 158 // the lower ADLC-assigned number must be stored to the lower address. 159 160 // PPC64 has 32 64-bit floating-point registers. Each can store a single 161 // or double precision floating-point value. 162 163 // types: v = volatile, nv = non-volatile, s = system 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch 165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret 167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2 169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3 171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4 173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5 175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6 177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7 179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8 181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9 183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10 185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next()); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11 187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next()); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12 189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next()); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13 191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next()); 192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv 193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next()); 194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv 195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next()); 196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv 197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next()); 198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv 199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next()); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv 201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next()); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv 203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next()); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv 205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next()); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv 207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next()); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv 209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next()); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv 211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next()); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv 213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next()); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv 215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next()); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv 217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next()); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv 219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next()); 220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv 221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next()); 222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv 223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next()); 224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv 225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next()); 226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv 227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next()); 228 229 // ---------------------------- 230 // Special Registers 231 // ---------------------------- 232 233 // Condition Codes Flag Registers 234 235 // PPC64 has 8 condition code "registers" which are all contained 236 // in the CR register. 237 238 // types: v = volatile, nv = non-volatile, s = system 239 reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v 240 reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v 241 reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv 242 reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv 243 reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv 244 reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v 245 reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v 246 reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg()); // v 247 248 // Special registers of PPC64 249 250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v 251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v 252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v 253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v 254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v 255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v 256 257 // ---------------------------- 258 // Vector-Scalar Registers 259 // ---------------------------- 260 reg_def VSR0 ( SOC, SOC, Op_VecX, 0, NULL); 261 reg_def VSR1 ( SOC, SOC, Op_VecX, 1, NULL); 262 reg_def VSR2 ( SOC, SOC, Op_VecX, 2, NULL); 263 reg_def VSR3 ( SOC, SOC, Op_VecX, 3, NULL); 264 reg_def VSR4 ( SOC, SOC, Op_VecX, 4, NULL); 265 reg_def VSR5 ( SOC, SOC, Op_VecX, 5, NULL); 266 reg_def VSR6 ( SOC, SOC, Op_VecX, 6, NULL); 267 reg_def VSR7 ( SOC, SOC, Op_VecX, 7, NULL); 268 reg_def VSR8 ( SOC, SOC, Op_VecX, 8, NULL); 269 reg_def VSR9 ( SOC, SOC, Op_VecX, 9, NULL); 270 reg_def VSR10 ( SOC, SOC, Op_VecX, 10, NULL); 271 reg_def VSR11 ( SOC, SOC, Op_VecX, 11, NULL); 272 reg_def VSR12 ( SOC, SOC, Op_VecX, 12, NULL); 273 reg_def VSR13 ( SOC, SOC, Op_VecX, 13, NULL); 274 reg_def VSR14 ( SOC, SOC, Op_VecX, 14, NULL); 275 reg_def VSR15 ( SOC, SOC, Op_VecX, 15, NULL); 276 reg_def VSR16 ( SOC, SOC, Op_VecX, 16, NULL); 277 reg_def VSR17 ( SOC, SOC, Op_VecX, 17, NULL); 278 reg_def VSR18 ( SOC, SOC, Op_VecX, 18, NULL); 279 reg_def VSR19 ( SOC, SOC, Op_VecX, 19, NULL); 280 reg_def VSR20 ( SOC, SOC, Op_VecX, 20, NULL); 281 reg_def VSR21 ( SOC, SOC, Op_VecX, 21, NULL); 282 reg_def VSR22 ( SOC, SOC, Op_VecX, 22, NULL); 283 reg_def VSR23 ( SOC, SOC, Op_VecX, 23, NULL); 284 reg_def VSR24 ( SOC, SOC, Op_VecX, 24, NULL); 285 reg_def VSR25 ( SOC, SOC, Op_VecX, 25, NULL); 286 reg_def VSR26 ( SOC, SOC, Op_VecX, 26, NULL); 287 reg_def VSR27 ( SOC, SOC, Op_VecX, 27, NULL); 288 reg_def VSR28 ( SOC, SOC, Op_VecX, 28, NULL); 289 reg_def VSR29 ( SOC, SOC, Op_VecX, 29, NULL); 290 reg_def VSR30 ( SOC, SOC, Op_VecX, 30, NULL); 291 reg_def VSR31 ( SOC, SOC, Op_VecX, 31, NULL); 292 reg_def VSR32 ( SOC, SOC, Op_VecX, 32, NULL); 293 reg_def VSR33 ( SOC, SOC, Op_VecX, 33, NULL); 294 reg_def VSR34 ( SOC, SOC, Op_VecX, 34, NULL); 295 reg_def VSR35 ( SOC, SOC, Op_VecX, 35, NULL); 296 reg_def VSR36 ( SOC, SOC, Op_VecX, 36, NULL); 297 reg_def VSR37 ( SOC, SOC, Op_VecX, 37, NULL); 298 reg_def VSR38 ( SOC, SOC, Op_VecX, 38, NULL); 299 reg_def VSR39 ( SOC, SOC, Op_VecX, 39, NULL); 300 reg_def VSR40 ( SOC, SOC, Op_VecX, 40, NULL); 301 reg_def VSR41 ( SOC, SOC, Op_VecX, 41, NULL); 302 reg_def VSR42 ( SOC, SOC, Op_VecX, 42, NULL); 303 reg_def VSR43 ( SOC, SOC, Op_VecX, 43, NULL); 304 reg_def VSR44 ( SOC, SOC, Op_VecX, 44, NULL); 305 reg_def VSR45 ( SOC, SOC, Op_VecX, 45, NULL); 306 reg_def VSR46 ( SOC, SOC, Op_VecX, 46, NULL); 307 reg_def VSR47 ( SOC, SOC, Op_VecX, 47, NULL); 308 reg_def VSR48 ( SOC, SOC, Op_VecX, 48, NULL); 309 reg_def VSR49 ( SOC, SOC, Op_VecX, 49, NULL); 310 reg_def VSR50 ( SOC, SOC, Op_VecX, 50, NULL); 311 reg_def VSR51 ( SOC, SOC, Op_VecX, 51, NULL); 312 reg_def VSR52 ( SOC, SOC, Op_VecX, 52, NULL); 313 reg_def VSR53 ( SOC, SOC, Op_VecX, 53, NULL); 314 reg_def VSR54 ( SOC, SOC, Op_VecX, 54, NULL); 315 reg_def VSR55 ( SOC, SOC, Op_VecX, 55, NULL); 316 reg_def VSR56 ( SOC, SOC, Op_VecX, 56, NULL); 317 reg_def VSR57 ( SOC, SOC, Op_VecX, 57, NULL); 318 reg_def VSR58 ( SOC, SOC, Op_VecX, 58, NULL); 319 reg_def VSR59 ( SOC, SOC, Op_VecX, 59, NULL); 320 reg_def VSR60 ( SOC, SOC, Op_VecX, 60, NULL); 321 reg_def VSR61 ( SOC, SOC, Op_VecX, 61, NULL); 322 reg_def VSR62 ( SOC, SOC, Op_VecX, 62, NULL); 323 reg_def VSR63 ( SOC, SOC, Op_VecX, 63, NULL); 324 325 // ---------------------------- 326 // Specify priority of register selection within phases of register 327 // allocation. Highest priority is first. A useful heuristic is to 328 // give registers a low priority when they are required by machine 329 // instructions, like EAX and EDX on I486, and choose no-save registers 330 // before save-on-call, & save-on-call before save-on-entry. Registers 331 // which participate in fixed calling sequences should come last. 332 // Registers which are used as pairs must fall on an even boundary. 333 334 // It's worth about 1% on SPEC geomean to get this right. 335 336 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 337 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 338 // R3_num. Therefore, R3_num may not be (and in reality is not) 339 // the same as R3->encoding()! Furthermore, we cannot make any 340 // assumptions on ordering, e.g. R3_num may be less than R2_num. 341 // Additionally, the function 342 // static enum RC rc_class(OptoReg::Name reg ) 343 // maps a given <register>_num value to its chunk type (except for flags) 344 // and its current implementation relies on chunk0 and chunk1 having a 345 // size of 64 each. 346 347 // If you change this allocation class, please have a look at the 348 // default values for the parameters RoundRobinIntegerRegIntervalStart 349 // and RoundRobinFloatRegIntervalStart 350 351 alloc_class chunk0 ( 352 // Chunk0 contains *all* 64 integer registers halves. 353 354 // "non-volatile" registers 355 R14, R14_H, 356 R15, R15_H, 357 R17, R17_H, 358 R18, R18_H, 359 R19, R19_H, 360 R20, R20_H, 361 R21, R21_H, 362 R22, R22_H, 363 R23, R23_H, 364 R24, R24_H, 365 R25, R25_H, 366 R26, R26_H, 367 R27, R27_H, 368 R28, R28_H, 369 R29, R29_H, 370 R30, R30_H, 371 R31, R31_H, 372 373 // scratch/special registers 374 R11, R11_H, 375 R12, R12_H, 376 377 // argument registers 378 R10, R10_H, 379 R9, R9_H, 380 R8, R8_H, 381 R7, R7_H, 382 R6, R6_H, 383 R5, R5_H, 384 R4, R4_H, 385 R3, R3_H, 386 387 // special registers, not available for allocation 388 R16, R16_H, // R16_thread 389 R13, R13_H, // system thread id 390 R2, R2_H, // may be used for TOC 391 R1, R1_H, // SP 392 R0, R0_H // R0 (scratch) 393 ); 394 395 // If you change this allocation class, please have a look at the 396 // default values for the parameters RoundRobinIntegerRegIntervalStart 397 // and RoundRobinFloatRegIntervalStart 398 399 alloc_class chunk1 ( 400 // Chunk1 contains *all* 64 floating-point registers halves. 401 402 // scratch register 403 F0, F0_H, 404 405 // argument registers 406 F13, F13_H, 407 F12, F12_H, 408 F11, F11_H, 409 F10, F10_H, 410 F9, F9_H, 411 F8, F8_H, 412 F7, F7_H, 413 F6, F6_H, 414 F5, F5_H, 415 F4, F4_H, 416 F3, F3_H, 417 F2, F2_H, 418 F1, F1_H, 419 420 // non-volatile registers 421 F14, F14_H, 422 F15, F15_H, 423 F16, F16_H, 424 F17, F17_H, 425 F18, F18_H, 426 F19, F19_H, 427 F20, F20_H, 428 F21, F21_H, 429 F22, F22_H, 430 F23, F23_H, 431 F24, F24_H, 432 F25, F25_H, 433 F26, F26_H, 434 F27, F27_H, 435 F28, F28_H, 436 F29, F29_H, 437 F30, F30_H, 438 F31, F31_H 439 ); 440 441 alloc_class chunk2 ( 442 // Chunk2 contains *all* 8 condition code registers. 443 444 CCR0, 445 CCR1, 446 CCR2, 447 CCR3, 448 CCR4, 449 CCR5, 450 CCR6, 451 CCR7 452 ); 453 454 alloc_class chunk3 ( 455 VSR0, 456 VSR1, 457 VSR2, 458 VSR3, 459 VSR4, 460 VSR5, 461 VSR6, 462 VSR7, 463 VSR8, 464 VSR9, 465 VSR10, 466 VSR11, 467 VSR12, 468 VSR13, 469 VSR14, 470 VSR15, 471 VSR16, 472 VSR17, 473 VSR18, 474 VSR19, 475 VSR20, 476 VSR21, 477 VSR22, 478 VSR23, 479 VSR24, 480 VSR25, 481 VSR26, 482 VSR27, 483 VSR28, 484 VSR29, 485 VSR30, 486 VSR31, 487 VSR32, 488 VSR33, 489 VSR34, 490 VSR35, 491 VSR36, 492 VSR37, 493 VSR38, 494 VSR39, 495 VSR40, 496 VSR41, 497 VSR42, 498 VSR43, 499 VSR44, 500 VSR45, 501 VSR46, 502 VSR47, 503 VSR48, 504 VSR49, 505 VSR50, 506 VSR51, 507 VSR52, 508 VSR53, 509 VSR54, 510 VSR55, 511 VSR56, 512 VSR57, 513 VSR58, 514 VSR59, 515 VSR60, 516 VSR61, 517 VSR62, 518 VSR63 519 ); 520 521 alloc_class chunk4 ( 522 // special registers 523 // These registers are not allocated, but used for nodes generated by postalloc expand. 524 SR_XER, 525 SR_LR, 526 SR_CTR, 527 SR_VRSAVE, 528 SR_SPEFSCR, 529 SR_PPR 530 ); 531 532 //-------Architecture Description Register Classes----------------------- 533 534 // Several register classes are automatically defined based upon 535 // information in this architecture description. 536 537 // 1) reg_class inline_cache_reg ( as defined in frame section ) 538 // 2) reg_class compiler_method_oop_reg ( as defined in frame section ) 539 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 540 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 541 // 542 543 // ---------------------------- 544 // 32 Bit Register Classes 545 // ---------------------------- 546 547 // We specify registers twice, once as read/write, and once read-only. 548 // We use the read-only registers for source operands. With this, we 549 // can include preset read only registers in this class, as a hard-coded 550 // '0'-register. (We used to simulate this on ppc.) 551 552 // 32 bit registers that can be read and written i.e. these registers 553 // can be dest (or src) of normal instructions. 554 reg_class bits32_reg_rw( 555 /*R0*/ // R0 556 /*R1*/ // SP 557 R2, // TOC 558 R3, 559 R4, 560 R5, 561 R6, 562 R7, 563 R8, 564 R9, 565 R10, 566 R11, 567 R12, 568 /*R13*/ // system thread id 569 R14, 570 R15, 571 /*R16*/ // R16_thread 572 R17, 573 R18, 574 R19, 575 R20, 576 R21, 577 R22, 578 R23, 579 R24, 580 R25, 581 R26, 582 R27, 583 R28, 584 /*R29,*/ // global TOC 585 R30, 586 R31 587 ); 588 589 // 32 bit registers that can only be read i.e. these registers can 590 // only be src of all instructions. 591 reg_class bits32_reg_ro( 592 /*R0*/ // R0 593 /*R1*/ // SP 594 R2 // TOC 595 R3, 596 R4, 597 R5, 598 R6, 599 R7, 600 R8, 601 R9, 602 R10, 603 R11, 604 R12, 605 /*R13*/ // system thread id 606 R14, 607 R15, 608 /*R16*/ // R16_thread 609 R17, 610 R18, 611 R19, 612 R20, 613 R21, 614 R22, 615 R23, 616 R24, 617 R25, 618 R26, 619 R27, 620 R28, 621 /*R29,*/ 622 R30, 623 R31 624 ); 625 626 reg_class rscratch1_bits32_reg(R11); 627 reg_class rscratch2_bits32_reg(R12); 628 reg_class rarg1_bits32_reg(R3); 629 reg_class rarg2_bits32_reg(R4); 630 reg_class rarg3_bits32_reg(R5); 631 reg_class rarg4_bits32_reg(R6); 632 633 // ---------------------------- 634 // 64 Bit Register Classes 635 // ---------------------------- 636 // 64-bit build means 64-bit pointers means hi/lo pairs 637 638 reg_class rscratch1_bits64_reg(R11_H, R11); 639 reg_class rscratch2_bits64_reg(R12_H, R12); 640 reg_class rarg1_bits64_reg(R3_H, R3); 641 reg_class rarg2_bits64_reg(R4_H, R4); 642 reg_class rarg3_bits64_reg(R5_H, R5); 643 reg_class rarg4_bits64_reg(R6_H, R6); 644 // Thread register, 'written' by tlsLoadP, see there. 645 reg_class thread_bits64_reg(R16_H, R16); 646 647 reg_class r19_bits64_reg(R19_H, R19); 648 649 // 64 bit registers that can be read and written i.e. these registers 650 // can be dest (or src) of normal instructions. 651 reg_class bits64_reg_rw( 652 /*R0_H, R0*/ // R0 653 /*R1_H, R1*/ // SP 654 R2_H, R2, // TOC 655 R3_H, R3, 656 R4_H, R4, 657 R5_H, R5, 658 R6_H, R6, 659 R7_H, R7, 660 R8_H, R8, 661 R9_H, R9, 662 R10_H, R10, 663 R11_H, R11, 664 R12_H, R12, 665 /*R13_H, R13*/ // system thread id 666 R14_H, R14, 667 R15_H, R15, 668 /*R16_H, R16*/ // R16_thread 669 R17_H, R17, 670 R18_H, R18, 671 R19_H, R19, 672 R20_H, R20, 673 R21_H, R21, 674 R22_H, R22, 675 R23_H, R23, 676 R24_H, R24, 677 R25_H, R25, 678 R26_H, R26, 679 R27_H, R27, 680 R28_H, R28, 681 /*R29_H, R29,*/ 682 R30_H, R30, 683 R31_H, R31 684 ); 685 686 // 64 bit registers used excluding r2, r11 and r12 687 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses 688 // r2, r11 and r12 internally. 689 reg_class bits64_reg_leaf_call( 690 /*R0_H, R0*/ // R0 691 /*R1_H, R1*/ // SP 692 /*R2_H, R2*/ // TOC 693 R3_H, R3, 694 R4_H, R4, 695 R5_H, R5, 696 R6_H, R6, 697 R7_H, R7, 698 R8_H, R8, 699 R9_H, R9, 700 R10_H, R10, 701 /*R11_H, R11*/ 702 /*R12_H, R12*/ 703 /*R13_H, R13*/ // system thread id 704 R14_H, R14, 705 R15_H, R15, 706 /*R16_H, R16*/ // R16_thread 707 R17_H, R17, 708 R18_H, R18, 709 R19_H, R19, 710 R20_H, R20, 711 R21_H, R21, 712 R22_H, R22, 713 R23_H, R23, 714 R24_H, R24, 715 R25_H, R25, 716 R26_H, R26, 717 R27_H, R27, 718 R28_H, R28, 719 /*R29_H, R29,*/ 720 R30_H, R30, 721 R31_H, R31 722 ); 723 724 // Used to hold the TOC to avoid collisions with expanded DynamicCall 725 // which uses r19 as inline cache internally and expanded LeafCall which uses 726 // r2, r11 and r12 internally. 727 reg_class bits64_constant_table_base( 728 /*R0_H, R0*/ // R0 729 /*R1_H, R1*/ // SP 730 /*R2_H, R2*/ // TOC 731 R3_H, R3, 732 R4_H, R4, 733 R5_H, R5, 734 R6_H, R6, 735 R7_H, R7, 736 R8_H, R8, 737 R9_H, R9, 738 R10_H, R10, 739 /*R11_H, R11*/ 740 /*R12_H, R12*/ 741 /*R13_H, R13*/ // system thread id 742 R14_H, R14, 743 R15_H, R15, 744 /*R16_H, R16*/ // R16_thread 745 R17_H, R17, 746 R18_H, R18, 747 /*R19_H, R19*/ 748 R20_H, R20, 749 R21_H, R21, 750 R22_H, R22, 751 R23_H, R23, 752 R24_H, R24, 753 R25_H, R25, 754 R26_H, R26, 755 R27_H, R27, 756 R28_H, R28, 757 /*R29_H, R29,*/ 758 R30_H, R30, 759 R31_H, R31 760 ); 761 762 // 64 bit registers that can only be read i.e. these registers can 763 // only be src of all instructions. 764 reg_class bits64_reg_ro( 765 /*R0_H, R0*/ // R0 766 R1_H, R1, 767 R2_H, R2, // TOC 768 R3_H, R3, 769 R4_H, R4, 770 R5_H, R5, 771 R6_H, R6, 772 R7_H, R7, 773 R8_H, R8, 774 R9_H, R9, 775 R10_H, R10, 776 R11_H, R11, 777 R12_H, R12, 778 /*R13_H, R13*/ // system thread id 779 R14_H, R14, 780 R15_H, R15, 781 R16_H, R16, // R16_thread 782 R17_H, R17, 783 R18_H, R18, 784 R19_H, R19, 785 R20_H, R20, 786 R21_H, R21, 787 R22_H, R22, 788 R23_H, R23, 789 R24_H, R24, 790 R25_H, R25, 791 R26_H, R26, 792 R27_H, R27, 793 R28_H, R28, 794 /*R29_H, R29,*/ // TODO: let allocator handle TOC!! 795 R30_H, R30, 796 R31_H, R31 797 ); 798 799 800 // ---------------------------- 801 // Special Class for Condition Code Flags Register 802 803 reg_class int_flags( 804 /*CCR0*/ // scratch 805 /*CCR1*/ // scratch 806 /*CCR2*/ // nv! 807 /*CCR3*/ // nv! 808 /*CCR4*/ // nv! 809 CCR5, 810 CCR6, 811 CCR7 812 ); 813 814 reg_class int_flags_ro( 815 CCR0, 816 CCR1, 817 CCR2, 818 CCR3, 819 CCR4, 820 CCR5, 821 CCR6, 822 CCR7 823 ); 824 825 reg_class int_flags_CR0(CCR0); 826 reg_class int_flags_CR1(CCR1); 827 reg_class int_flags_CR6(CCR6); 828 reg_class ctr_reg(SR_CTR); 829 830 // ---------------------------- 831 // Float Register Classes 832 // ---------------------------- 833 834 reg_class flt_reg( 835 F0, 836 F1, 837 F2, 838 F3, 839 F4, 840 F5, 841 F6, 842 F7, 843 F8, 844 F9, 845 F10, 846 F11, 847 F12, 848 F13, 849 F14, // nv! 850 F15, // nv! 851 F16, // nv! 852 F17, // nv! 853 F18, // nv! 854 F19, // nv! 855 F20, // nv! 856 F21, // nv! 857 F22, // nv! 858 F23, // nv! 859 F24, // nv! 860 F25, // nv! 861 F26, // nv! 862 F27, // nv! 863 F28, // nv! 864 F29, // nv! 865 F30, // nv! 866 F31 // nv! 867 ); 868 869 // Double precision float registers have virtual `high halves' that 870 // are needed by the allocator. 871 reg_class dbl_reg( 872 F0, F0_H, 873 F1, F1_H, 874 F2, F2_H, 875 F3, F3_H, 876 F4, F4_H, 877 F5, F5_H, 878 F6, F6_H, 879 F7, F7_H, 880 F8, F8_H, 881 F9, F9_H, 882 F10, F10_H, 883 F11, F11_H, 884 F12, F12_H, 885 F13, F13_H, 886 F14, F14_H, // nv! 887 F15, F15_H, // nv! 888 F16, F16_H, // nv! 889 F17, F17_H, // nv! 890 F18, F18_H, // nv! 891 F19, F19_H, // nv! 892 F20, F20_H, // nv! 893 F21, F21_H, // nv! 894 F22, F22_H, // nv! 895 F23, F23_H, // nv! 896 F24, F24_H, // nv! 897 F25, F25_H, // nv! 898 F26, F26_H, // nv! 899 F27, F27_H, // nv! 900 F28, F28_H, // nv! 901 F29, F29_H, // nv! 902 F30, F30_H, // nv! 903 F31, F31_H // nv! 904 ); 905 906 // ---------------------------- 907 // Vector-Scalar Register Class 908 // ---------------------------- 909 910 reg_class vs_reg( 911 // Attention: Only these ones are saved & restored at safepoint by RegisterSaver. 912 VSR32, 913 VSR33, 914 VSR34, 915 VSR35, 916 VSR36, 917 VSR37, 918 VSR38, 919 VSR39, 920 VSR40, 921 VSR41, 922 VSR42, 923 VSR43, 924 VSR44, 925 VSR45, 926 VSR46, 927 VSR47, 928 VSR48, 929 VSR49, 930 VSR50, 931 VSR51 932 // VSR52-VSR63 // nv! 933 ); 934 935 %} 936 937 //----------DEFINITION BLOCK--------------------------------------------------- 938 // Define name --> value mappings to inform the ADLC of an integer valued name 939 // Current support includes integer values in the range [0, 0x7FFFFFFF] 940 // Format: 941 // int_def <name> ( <int_value>, <expression>); 942 // Generated Code in ad_<arch>.hpp 943 // #define <name> (<expression>) 944 // // value == <int_value> 945 // Generated code in ad_<arch>.cpp adlc_verification() 946 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 947 // 948 definitions %{ 949 // The default cost (of an ALU instruction). 950 int_def DEFAULT_COST_LOW ( 30, 30); 951 int_def DEFAULT_COST ( 100, 100); 952 int_def HUGE_COST (1000000, 1000000); 953 954 // Memory refs 955 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 956 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 957 958 // Branches are even more expensive. 959 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 960 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 961 %} 962 963 964 //----------SOURCE BLOCK------------------------------------------------------- 965 // This is a block of C++ code which provides values, functions, and 966 // definitions necessary in the rest of the architecture description. 967 source_hpp %{ 968 // Header information of the source block. 969 // Method declarations/definitions which are used outside 970 // the ad-scope can conveniently be defined here. 971 // 972 // To keep related declarations/definitions/uses close together, 973 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 974 975 // Returns true if Node n is followed by a MemBar node that 976 // will do an acquire. If so, this node must not do the acquire 977 // operation. 978 bool followed_by_acquire(const Node *n); 979 %} 980 981 source %{ 982 983 // Should the Matcher clone shifts on addressing modes, expecting them 984 // to be subsumed into complex addressing expressions or compute them 985 // into registers? 986 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 987 return clone_base_plus_offset_address(m, mstack, address_visited); 988 } 989 990 void Compile::reshape_address(AddPNode* addp) { 991 } 992 993 // Optimize load-acquire. 994 // 995 // Check if acquire is unnecessary due to following operation that does 996 // acquire anyways. 997 // Walk the pattern: 998 // 999 // n: Load.acq 1000 // | 1001 // MemBarAcquire 1002 // | | 1003 // Proj(ctrl) Proj(mem) 1004 // | | 1005 // MemBarRelease/Volatile 1006 // 1007 bool followed_by_acquire(const Node *load) { 1008 assert(load->is_Load(), "So far implemented only for loads."); 1009 1010 // Find MemBarAcquire. 1011 const Node *mba = NULL; 1012 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 1013 const Node *out = load->fast_out(i); 1014 if (out->Opcode() == Op_MemBarAcquire) { 1015 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 1016 mba = out; 1017 break; 1018 } 1019 } 1020 if (!mba) return false; 1021 1022 // Find following MemBar node. 1023 // 1024 // The following node must be reachable by control AND memory 1025 // edge to assure no other operations are in between the two nodes. 1026 // 1027 // So first get the Proj node, mem_proj, to use it to iterate forward. 1028 Node *mem_proj = NULL; 1029 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 1030 mem_proj = mba->fast_out(i); // Runs out of bounds and asserts if Proj not found. 1031 assert(mem_proj->is_Proj(), "only projections here"); 1032 ProjNode *proj = mem_proj->as_Proj(); 1033 if (proj->_con == TypeFunc::Memory && 1034 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 1035 break; 1036 } 1037 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 1038 1039 // Search MemBar behind Proj. If there are other memory operations 1040 // behind the Proj we lost. 1041 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 1042 Node *x = mem_proj->fast_out(j); 1043 // Proj might have an edge to a store or load node which precedes the membar. 1044 if (x->is_Mem()) return false; 1045 1046 // On PPC64 release and volatile are implemented by an instruction 1047 // that also has acquire semantics. I.e. there is no need for an 1048 // acquire before these. 1049 int xop = x->Opcode(); 1050 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 1051 // Make sure we're not missing Call/Phi/MergeMem by checking 1052 // control edges. The control edge must directly lead back 1053 // to the MemBarAcquire 1054 Node *ctrl_proj = x->in(0); 1055 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 1056 return true; 1057 } 1058 } 1059 } 1060 1061 return false; 1062 } 1063 1064 #define __ _masm. 1065 1066 // Tertiary op of a LoadP or StoreP encoding. 1067 #define REGP_OP true 1068 1069 // **************************************************************************** 1070 1071 // REQUIRED FUNCTIONALITY 1072 1073 // !!!!! Special hack to get all type of calls to specify the byte offset 1074 // from the start of the call to the point where the return address 1075 // will point. 1076 1077 // PPC port: Removed use of lazy constant construct. 1078 1079 int MachCallStaticJavaNode::ret_addr_offset() { 1080 // It's only a single branch-and-link instruction. 1081 return 4; 1082 } 1083 1084 int MachCallDynamicJavaNode::ret_addr_offset() { 1085 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 1086 // postalloc expanded calls if we use inline caches and do not update method data. 1087 if (UseInlineCaches) 1088 return 4; 1089 1090 int vtable_index = this->_vtable_index; 1091 if (vtable_index < 0) { 1092 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 1093 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 1094 return 12; 1095 } else { 1096 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 1097 return 24; 1098 } 1099 } 1100 1101 int MachCallRuntimeNode::ret_addr_offset() { 1102 #if defined(ABI_ELFv2) 1103 return 28; 1104 #else 1105 return 40; 1106 #endif 1107 } 1108 1109 //============================================================================= 1110 1111 // condition code conversions 1112 1113 static int cc_to_boint(int cc) { 1114 return Assembler::bcondCRbiIs0 | (cc & 8); 1115 } 1116 1117 static int cc_to_inverse_boint(int cc) { 1118 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 1119 } 1120 1121 static int cc_to_biint(int cc, int flags_reg) { 1122 return (flags_reg << 2) | (cc & 3); 1123 } 1124 1125 //============================================================================= 1126 1127 // Compute padding required for nodes which need alignment. The padding 1128 // is the number of bytes (not instructions) which will be inserted before 1129 // the instruction. The padding must match the size of a NOP instruction. 1130 1131 // Currently not used on this platform. 1132 1133 //============================================================================= 1134 1135 // Indicate if the safepoint node needs the polling page as an input. 1136 bool SafePointNode::needs_polling_address_input() { 1137 // The address is loaded from thread by a seperate node. 1138 return true; 1139 } 1140 1141 //============================================================================= 1142 1143 // Emit an interrupt that is caught by the debugger (for debugging compiler). 1144 void emit_break(CodeBuffer &cbuf) { 1145 MacroAssembler _masm(&cbuf); 1146 __ illtrap(); 1147 } 1148 1149 #ifndef PRODUCT 1150 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1151 st->print("BREAKPOINT"); 1152 } 1153 #endif 1154 1155 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1156 emit_break(cbuf); 1157 } 1158 1159 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1160 return MachNode::size(ra_); 1161 } 1162 1163 //============================================================================= 1164 1165 void emit_nop(CodeBuffer &cbuf) { 1166 MacroAssembler _masm(&cbuf); 1167 __ nop(); 1168 } 1169 1170 static inline void emit_long(CodeBuffer &cbuf, int value) { 1171 *((int*)(cbuf.insts_end())) = value; 1172 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1173 } 1174 1175 //============================================================================= 1176 1177 %} // interrupt source 1178 1179 source_hpp %{ // Header information of the source block. 1180 1181 //-------------------------------------------------------------- 1182 //---< Used for optimization in Compile::Shorten_branches >--- 1183 //-------------------------------------------------------------- 1184 1185 class CallStubImpl { 1186 1187 public: 1188 1189 // Emit call stub, compiled java to interpreter. 1190 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1191 1192 // Size of call trampoline stub. 1193 // This doesn't need to be accurate to the byte, but it 1194 // must be larger than or equal to the real size of the stub. 1195 static uint size_call_trampoline() { 1196 return MacroAssembler::trampoline_stub_size; 1197 } 1198 1199 // number of relocations needed by a call trampoline stub 1200 static uint reloc_call_trampoline() { 1201 return 5; 1202 } 1203 1204 }; 1205 1206 %} // end source_hpp 1207 1208 source %{ 1209 1210 // Emit a trampoline stub for a call to a target which is too far away. 1211 // 1212 // code sequences: 1213 // 1214 // call-site: 1215 // branch-and-link to <destination> or <trampoline stub> 1216 // 1217 // Related trampoline stub for this call-site in the stub section: 1218 // load the call target from the constant pool 1219 // branch via CTR (LR/link still points to the call-site above) 1220 1221 void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1222 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1223 if (stub == NULL) { 1224 ciEnv::current()->record_out_of_memory_failure(); 1225 } 1226 } 1227 1228 //============================================================================= 1229 1230 // Emit an inline branch-and-link call and a related trampoline stub. 1231 // 1232 // code sequences: 1233 // 1234 // call-site: 1235 // branch-and-link to <destination> or <trampoline stub> 1236 // 1237 // Related trampoline stub for this call-site in the stub section: 1238 // load the call target from the constant pool 1239 // branch via CTR (LR/link still points to the call-site above) 1240 // 1241 1242 typedef struct { 1243 int insts_call_instruction_offset; 1244 int ret_addr_offset; 1245 } EmitCallOffsets; 1246 1247 // Emit a branch-and-link instruction that branches to a trampoline. 1248 // - Remember the offset of the branch-and-link instruction. 1249 // - Add a relocation at the branch-and-link instruction. 1250 // - Emit a branch-and-link. 1251 // - Remember the return pc offset. 1252 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1253 EmitCallOffsets offsets = { -1, -1 }; 1254 const int start_offset = __ offset(); 1255 offsets.insts_call_instruction_offset = __ offset(); 1256 1257 // No entry point given, use the current pc. 1258 if (entry_point == NULL) entry_point = __ pc(); 1259 1260 // Put the entry point as a constant into the constant pool. 1261 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1262 if (entry_point_toc_addr == NULL) { 1263 ciEnv::current()->record_out_of_memory_failure(); 1264 return offsets; 1265 } 1266 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1267 1268 // Emit the trampoline stub which will be related to the branch-and-link below. 1269 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1270 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1271 __ relocate(rtype); 1272 1273 // Note: At this point we do not have the address of the trampoline 1274 // stub, and the entry point might be too far away for bl, so __ pc() 1275 // serves as dummy and the bl will be patched later. 1276 __ bl((address) __ pc()); 1277 1278 offsets.ret_addr_offset = __ offset() - start_offset; 1279 1280 return offsets; 1281 } 1282 1283 //============================================================================= 1284 1285 // Factory for creating loadConL* nodes for large/small constant pool. 1286 1287 static inline jlong replicate_immF(float con) { 1288 // Replicate float con 2 times and pack into vector. 1289 int val = *((int*)&con); 1290 jlong lval = val; 1291 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1292 return lval; 1293 } 1294 1295 //============================================================================= 1296 1297 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1298 int Compile::ConstantTable::calculate_table_base_offset() const { 1299 return 0; // absolute addressing, no offset 1300 } 1301 1302 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1303 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1304 iRegPdstOper *op_dst = new iRegPdstOper(); 1305 MachNode *m1 = new loadToc_hiNode(); 1306 MachNode *m2 = new loadToc_loNode(); 1307 1308 m1->add_req(NULL); 1309 m2->add_req(NULL, m1); 1310 m1->_opnds[0] = op_dst; 1311 m2->_opnds[0] = op_dst; 1312 m2->_opnds[1] = op_dst; 1313 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1314 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1315 nodes->push(m1); 1316 nodes->push(m2); 1317 } 1318 1319 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1320 // Is postalloc expanded. 1321 ShouldNotReachHere(); 1322 } 1323 1324 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1325 return 0; 1326 } 1327 1328 #ifndef PRODUCT 1329 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1330 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1331 } 1332 #endif 1333 1334 //============================================================================= 1335 1336 #ifndef PRODUCT 1337 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1338 Compile* C = ra_->C; 1339 const long framesize = C->frame_slots() << LogBytesPerInt; 1340 1341 st->print("PROLOG\n\t"); 1342 if (C->need_stack_bang(framesize)) { 1343 st->print("stack_overflow_check\n\t"); 1344 } 1345 1346 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1347 st->print("save return pc\n\t"); 1348 st->print("push frame %ld\n\t", -framesize); 1349 } 1350 } 1351 #endif 1352 1353 // Macro used instead of the common __ to emulate the pipes of PPC. 1354 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1355 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1356 // still no scheduling of this code is possible, the micro scheduler is aware of the 1357 // code and can update its internal data. The following mechanism is used to achieve this: 1358 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1359 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1360 #if 0 // TODO: PPC port 1361 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1362 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1363 _masm. 1364 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1365 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1366 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1367 C->hb_scheduling()->_pdScheduling->advance_offset 1368 #else 1369 #define ___(op) if (UsePower6SchedulerPPC64) \ 1370 Unimplemented(); \ 1371 _masm. 1372 #define ___stop if (UsePower6SchedulerPPC64) \ 1373 Unimplemented() 1374 #define ___advance if (UsePower6SchedulerPPC64) \ 1375 Unimplemented() 1376 #endif 1377 1378 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1379 Compile* C = ra_->C; 1380 MacroAssembler _masm(&cbuf); 1381 1382 const long framesize = C->frame_size_in_bytes(); 1383 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1384 1385 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1386 1387 const Register return_pc = R20; // Must match return_addr() in frame section. 1388 const Register callers_sp = R21; 1389 const Register push_frame_temp = R22; 1390 const Register toc_temp = R23; 1391 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1392 1393 if (method_is_frameless) { 1394 // Add nop at beginning of all frameless methods to prevent any 1395 // oop instructions from getting overwritten by make_not_entrant 1396 // (patching attempt would fail). 1397 ___(nop) nop(); 1398 } else { 1399 // Get return pc. 1400 ___(mflr) mflr(return_pc); 1401 } 1402 1403 // Calls to C2R adapters often do not accept exceptional returns. 1404 // We require that their callers must bang for them. But be 1405 // careful, because some VM calls (such as call site linkage) can 1406 // use several kilobytes of stack. But the stack safety zone should 1407 // account for that. See bugs 4446381, 4468289, 4497237. 1408 1409 int bangsize = C->bang_size_in_bytes(); 1410 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1411 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1412 // Unfortunately we cannot use the function provided in 1413 // assembler.cpp as we have to emulate the pipes. So I had to 1414 // insert the code of generate_stack_overflow_check(), see 1415 // assembler.cpp for some illuminative comments. 1416 const int page_size = os::vm_page_size(); 1417 int bang_end = JavaThread::stack_shadow_zone_size(); 1418 1419 // This is how far the previous frame's stack banging extended. 1420 const int bang_end_safe = bang_end; 1421 1422 if (bangsize > page_size) { 1423 bang_end += bangsize; 1424 } 1425 1426 int bang_offset = bang_end_safe; 1427 1428 while (bang_offset <= bang_end) { 1429 // Need at least one stack bang at end of shadow zone. 1430 1431 // Again I had to copy code, this time from assembler_ppc.cpp, 1432 // bang_stack_with_offset - see there for comments. 1433 1434 // Stack grows down, caller passes positive offset. 1435 assert(bang_offset > 0, "must bang with positive offset"); 1436 1437 long stdoffset = -bang_offset; 1438 1439 if (Assembler::is_simm(stdoffset, 16)) { 1440 // Signed 16 bit offset, a simple std is ok. 1441 if (UseLoadInstructionsForStackBangingPPC64) { 1442 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1443 } else { 1444 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1445 } 1446 } else if (Assembler::is_simm(stdoffset, 31)) { 1447 // Use largeoffset calculations for addis & ld/std. 1448 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1449 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1450 1451 Register tmp = R11; 1452 ___(addis) addis(tmp, R1_SP, hi); 1453 if (UseLoadInstructionsForStackBangingPPC64) { 1454 ___(ld) ld(R0, lo, tmp); 1455 } else { 1456 ___(std) std(R0, lo, tmp); 1457 } 1458 } else { 1459 ShouldNotReachHere(); 1460 } 1461 1462 bang_offset += page_size; 1463 } 1464 // R11 trashed 1465 } // C->need_stack_bang(framesize) && UseStackBanging 1466 1467 unsigned int bytes = (unsigned int)framesize; 1468 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1469 ciMethod *currMethod = C->method(); 1470 1471 // Optimized version for most common case. 1472 if (UsePower6SchedulerPPC64 && 1473 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1474 !(false /* ConstantsALot TODO: PPC port*/)) { 1475 ___(or) mr(callers_sp, R1_SP); 1476 ___(std) std(return_pc, _abi(lr), R1_SP); 1477 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1478 return; 1479 } 1480 1481 if (!method_is_frameless) { 1482 // Get callers sp. 1483 ___(or) mr(callers_sp, R1_SP); 1484 1485 // Push method's frame, modifies SP. 1486 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1487 // The ABI is already accounted for in 'framesize' via the 1488 // 'out_preserve' area. 1489 Register tmp = push_frame_temp; 1490 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1491 if (Assembler::is_simm(-offset, 16)) { 1492 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1493 } else { 1494 long x = -offset; 1495 // Had to insert load_const(tmp, -offset). 1496 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1497 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1498 ___(rldicr) sldi(tmp, tmp, 32); 1499 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1500 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1501 1502 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1503 } 1504 } 1505 #if 0 // TODO: PPC port 1506 // For testing large constant pools, emit a lot of constants to constant pool. 1507 // "Randomize" const_size. 1508 if (ConstantsALot) { 1509 const int num_consts = const_size(); 1510 for (int i = 0; i < num_consts; i++) { 1511 __ long_constant(0xB0B5B00BBABE); 1512 } 1513 } 1514 #endif 1515 if (!method_is_frameless) { 1516 // Save return pc. 1517 ___(std) std(return_pc, _abi(lr), callers_sp); 1518 } 1519 1520 C->set_frame_complete(cbuf.insts_size()); 1521 } 1522 #undef ___ 1523 #undef ___stop 1524 #undef ___advance 1525 1526 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1527 // Variable size. determine dynamically. 1528 return MachNode::size(ra_); 1529 } 1530 1531 int MachPrologNode::reloc() const { 1532 // Return number of relocatable values contained in this instruction. 1533 return 1; // 1 reloc entry for load_const(toc). 1534 } 1535 1536 //============================================================================= 1537 1538 #ifndef PRODUCT 1539 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1540 Compile* C = ra_->C; 1541 1542 st->print("EPILOG\n\t"); 1543 st->print("restore return pc\n\t"); 1544 st->print("pop frame\n\t"); 1545 1546 if (do_polling() && C->is_method_compilation()) { 1547 st->print("touch polling page\n\t"); 1548 } 1549 } 1550 #endif 1551 1552 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1553 Compile* C = ra_->C; 1554 MacroAssembler _masm(&cbuf); 1555 1556 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1557 assert(framesize >= 0, "negative frame-size?"); 1558 1559 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1560 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1561 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1562 const Register polling_page = R12; 1563 1564 if (!method_is_frameless) { 1565 // Restore return pc relative to callers' sp. 1566 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1567 } 1568 1569 if (method_needs_polling) { 1570 if (SafepointMechanism::uses_thread_local_poll()) { 1571 __ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread); 1572 } else { 1573 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); 1574 } 1575 } 1576 1577 if (!method_is_frameless) { 1578 // Move return pc to LR. 1579 __ mtlr(return_pc); 1580 // Pop frame (fixed frame-size). 1581 __ addi(R1_SP, R1_SP, (int)framesize); 1582 } 1583 1584 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1585 __ reserved_stack_check(return_pc); 1586 } 1587 1588 if (method_needs_polling) { 1589 // We need to mark the code position where the load from the safepoint 1590 // polling page was emitted as relocInfo::poll_return_type here. 1591 __ relocate(relocInfo::poll_return_type); 1592 __ load_from_polling_page(polling_page); 1593 } 1594 } 1595 1596 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1597 // Variable size. Determine dynamically. 1598 return MachNode::size(ra_); 1599 } 1600 1601 int MachEpilogNode::reloc() const { 1602 // Return number of relocatable values contained in this instruction. 1603 return 1; // 1 for load_from_polling_page. 1604 } 1605 1606 const Pipeline * MachEpilogNode::pipeline() const { 1607 return MachNode::pipeline_class(); 1608 } 1609 1610 // This method seems to be obsolete. It is declared in machnode.hpp 1611 // and defined in all *.ad files, but it is never called. Should we 1612 // get rid of it? 1613 int MachEpilogNode::safepoint_offset() const { 1614 assert(do_polling(), "no return for this epilog node"); 1615 return 0; 1616 } 1617 1618 #if 0 // TODO: PPC port 1619 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1620 MacroAssembler _masm(&cbuf); 1621 if (LoadPollAddressFromThread) { 1622 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1623 } else { 1624 _masm.nop(); 1625 } 1626 } 1627 1628 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1629 if (LoadPollAddressFromThread) { 1630 return 4; 1631 } else { 1632 return 4; 1633 } 1634 } 1635 1636 #ifndef PRODUCT 1637 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1638 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1639 } 1640 #endif 1641 1642 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1643 return RSCRATCH1_BITS64_REG_mask(); 1644 } 1645 #endif // PPC port 1646 1647 // ============================================================================= 1648 1649 // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or 1650 // rc_stack. 1651 enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack }; 1652 1653 static enum RC rc_class(OptoReg::Name reg) { 1654 // Return the register class for the given register. The given register 1655 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1656 // enumeration in adGlobals_ppc.hpp. 1657 1658 if (reg == OptoReg::Bad) return rc_bad; 1659 1660 // We have 64 integer register halves, starting at index 0. 1661 if (reg < 64) return rc_int; 1662 1663 // We have 64 floating-point register halves, starting at index 64. 1664 if (reg < 64+64) return rc_float; 1665 1666 // We have 64 vector-scalar registers, starting at index 128. 1667 if (reg < 64+64+64) return rc_vs; 1668 1669 // Between float regs & stack are the flags regs. 1670 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1671 1672 return rc_stack; 1673 } 1674 1675 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1676 bool do_print, Compile* C, outputStream *st) { 1677 1678 assert(opcode == Assembler::LD_OPCODE || 1679 opcode == Assembler::STD_OPCODE || 1680 opcode == Assembler::LWZ_OPCODE || 1681 opcode == Assembler::STW_OPCODE || 1682 opcode == Assembler::LFD_OPCODE || 1683 opcode == Assembler::STFD_OPCODE || 1684 opcode == Assembler::LFS_OPCODE || 1685 opcode == Assembler::STFS_OPCODE, 1686 "opcode not supported"); 1687 1688 if (cbuf) { 1689 int d = 1690 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1691 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1692 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1693 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1694 } 1695 #ifndef PRODUCT 1696 else if (do_print) { 1697 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1698 op_str, 1699 Matcher::regName[reg], 1700 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1701 } 1702 #endif 1703 return 4; // size 1704 } 1705 1706 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1707 Compile* C = ra_->C; 1708 1709 // Get registers to move. 1710 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1711 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1712 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1713 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1714 1715 enum RC src_hi_rc = rc_class(src_hi); 1716 enum RC src_lo_rc = rc_class(src_lo); 1717 enum RC dst_hi_rc = rc_class(dst_hi); 1718 enum RC dst_lo_rc = rc_class(dst_lo); 1719 1720 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1721 if (src_hi != OptoReg::Bad) 1722 assert((src_lo&1)==0 && src_lo+1==src_hi && 1723 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1724 "expected aligned-adjacent pairs"); 1725 // Generate spill code! 1726 int size = 0; 1727 1728 if (src_lo == dst_lo && src_hi == dst_hi) 1729 return size; // Self copy, no move. 1730 1731 if (bottom_type()->isa_vect() != NULL && ideal_reg() == Op_VecX) { 1732 // Memory->Memory Spill. 1733 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1734 int src_offset = ra_->reg2offset(src_lo); 1735 int dst_offset = ra_->reg2offset(dst_lo); 1736 if (cbuf) { 1737 MacroAssembler _masm(cbuf); 1738 __ ld(R0, src_offset, R1_SP); 1739 __ std(R0, dst_offset, R1_SP); 1740 __ ld(R0, src_offset+8, R1_SP); 1741 __ std(R0, dst_offset+8, R1_SP); 1742 } 1743 size += 16; 1744 } 1745 // VectorSRegister->Memory Spill. 1746 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) { 1747 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1748 int dst_offset = ra_->reg2offset(dst_lo); 1749 if (cbuf) { 1750 MacroAssembler _masm(cbuf); 1751 __ addi(R0, R1_SP, dst_offset); 1752 __ stxvd2x(Rsrc, R0); 1753 } 1754 size += 8; 1755 } 1756 // Memory->VectorSRegister Spill. 1757 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) { 1758 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1759 int src_offset = ra_->reg2offset(src_lo); 1760 if (cbuf) { 1761 MacroAssembler _masm(cbuf); 1762 __ addi(R0, R1_SP, src_offset); 1763 __ lxvd2x(Rdst, R0); 1764 } 1765 size += 8; 1766 } 1767 // VectorSRegister->VectorSRegister. 1768 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) { 1769 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1770 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1771 if (cbuf) { 1772 MacroAssembler _masm(cbuf); 1773 __ xxlor(Rdst, Rsrc, Rsrc); 1774 } 1775 size += 4; 1776 } 1777 else { 1778 ShouldNotReachHere(); // No VSR spill. 1779 } 1780 return size; 1781 } 1782 1783 // -------------------------------------- 1784 // Memory->Memory Spill. Use R0 to hold the value. 1785 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1786 int src_offset = ra_->reg2offset(src_lo); 1787 int dst_offset = ra_->reg2offset(dst_lo); 1788 if (src_hi != OptoReg::Bad) { 1789 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1790 "expected same type of move for high parts"); 1791 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1792 if (!cbuf && !do_size) st->print("\n\t"); 1793 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1794 } else { 1795 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1796 if (!cbuf && !do_size) st->print("\n\t"); 1797 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1798 } 1799 return size; 1800 } 1801 1802 // -------------------------------------- 1803 // Check for float->int copy; requires a trip through memory. 1804 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1805 Unimplemented(); 1806 } 1807 1808 // -------------------------------------- 1809 // Check for integer reg-reg copy. 1810 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1811 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1812 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1813 size = (Rsrc != Rdst) ? 4 : 0; 1814 1815 if (cbuf) { 1816 MacroAssembler _masm(cbuf); 1817 if (size) { 1818 __ mr(Rdst, Rsrc); 1819 } 1820 } 1821 #ifndef PRODUCT 1822 else if (!do_size) { 1823 if (size) { 1824 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1825 } else { 1826 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1827 } 1828 } 1829 #endif 1830 return size; 1831 } 1832 1833 // Check for integer store. 1834 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1835 int dst_offset = ra_->reg2offset(dst_lo); 1836 if (src_hi != OptoReg::Bad) { 1837 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1838 "expected same type of move for high parts"); 1839 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1840 } else { 1841 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1842 } 1843 return size; 1844 } 1845 1846 // Check for integer load. 1847 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1848 int src_offset = ra_->reg2offset(src_lo); 1849 if (src_hi != OptoReg::Bad) { 1850 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1851 "expected same type of move for high parts"); 1852 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1853 } else { 1854 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1855 } 1856 return size; 1857 } 1858 1859 // Check for float reg-reg copy. 1860 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1861 if (cbuf) { 1862 MacroAssembler _masm(cbuf); 1863 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1864 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1865 __ fmr(Rdst, Rsrc); 1866 } 1867 #ifndef PRODUCT 1868 else if (!do_size) { 1869 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1870 } 1871 #endif 1872 return 4; 1873 } 1874 1875 // Check for float store. 1876 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1877 int dst_offset = ra_->reg2offset(dst_lo); 1878 if (src_hi != OptoReg::Bad) { 1879 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1880 "expected same type of move for high parts"); 1881 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1882 } else { 1883 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1884 } 1885 return size; 1886 } 1887 1888 // Check for float load. 1889 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1890 int src_offset = ra_->reg2offset(src_lo); 1891 if (src_hi != OptoReg::Bad) { 1892 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1893 "expected same type of move for high parts"); 1894 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1895 } else { 1896 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1897 } 1898 return size; 1899 } 1900 1901 // -------------------------------------------------------------------- 1902 // Check for hi bits still needing moving. Only happens for misaligned 1903 // arguments to native calls. 1904 if (src_hi == dst_hi) 1905 return size; // Self copy; no move. 1906 1907 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1908 ShouldNotReachHere(); // Unimplemented 1909 return 0; 1910 } 1911 1912 #ifndef PRODUCT 1913 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1914 if (!ra_) 1915 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1916 else 1917 implementation(NULL, ra_, false, st); 1918 } 1919 #endif 1920 1921 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1922 implementation(&cbuf, ra_, false, NULL); 1923 } 1924 1925 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1926 return implementation(NULL, ra_, true, NULL); 1927 } 1928 1929 #if 0 // TODO: PPC port 1930 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1931 #ifndef PRODUCT 1932 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1933 #endif 1934 assert(ra_->node_regs_max_index() != 0, ""); 1935 1936 // Get registers to move. 1937 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1938 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1939 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1940 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1941 1942 enum RC src_lo_rc = rc_class(src_lo); 1943 enum RC dst_lo_rc = rc_class(dst_lo); 1944 1945 if (src_lo == dst_lo && src_hi == dst_hi) 1946 return ppc64Opcode_none; // Self copy, no move. 1947 1948 // -------------------------------------- 1949 // Memory->Memory Spill. Use R0 to hold the value. 1950 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1951 return ppc64Opcode_compound; 1952 } 1953 1954 // -------------------------------------- 1955 // Check for float->int copy; requires a trip through memory. 1956 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1957 Unimplemented(); 1958 } 1959 1960 // -------------------------------------- 1961 // Check for integer reg-reg copy. 1962 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1963 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1964 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1965 if (Rsrc == Rdst) { 1966 return ppc64Opcode_none; 1967 } else { 1968 return ppc64Opcode_or; 1969 } 1970 } 1971 1972 // Check for integer store. 1973 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1974 if (src_hi != OptoReg::Bad) { 1975 return ppc64Opcode_std; 1976 } else { 1977 return ppc64Opcode_stw; 1978 } 1979 } 1980 1981 // Check for integer load. 1982 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1983 if (src_hi != OptoReg::Bad) { 1984 return ppc64Opcode_ld; 1985 } else { 1986 return ppc64Opcode_lwz; 1987 } 1988 } 1989 1990 // Check for float reg-reg copy. 1991 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1992 return ppc64Opcode_fmr; 1993 } 1994 1995 // Check for float store. 1996 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1997 if (src_hi != OptoReg::Bad) { 1998 return ppc64Opcode_stfd; 1999 } else { 2000 return ppc64Opcode_stfs; 2001 } 2002 } 2003 2004 // Check for float load. 2005 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 2006 if (src_hi != OptoReg::Bad) { 2007 return ppc64Opcode_lfd; 2008 } else { 2009 return ppc64Opcode_lfs; 2010 } 2011 } 2012 2013 // -------------------------------------------------------------------- 2014 // Check for hi bits still needing moving. Only happens for misaligned 2015 // arguments to native calls. 2016 if (src_hi == dst_hi) { 2017 return ppc64Opcode_none; // Self copy; no move. 2018 } 2019 2020 ShouldNotReachHere(); 2021 return ppc64Opcode_undefined; 2022 } 2023 #endif // PPC port 2024 2025 #ifndef PRODUCT 2026 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2027 st->print("NOP \t// %d nops to pad for loops.", _count); 2028 } 2029 #endif 2030 2031 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 2032 MacroAssembler _masm(&cbuf); 2033 // _count contains the number of nops needed for padding. 2034 for (int i = 0; i < _count; i++) { 2035 __ nop(); 2036 } 2037 } 2038 2039 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 2040 return _count * 4; 2041 } 2042 2043 #ifndef PRODUCT 2044 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2045 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2046 char reg_str[128]; 2047 ra_->dump_register(this, reg_str); 2048 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 2049 } 2050 #endif 2051 2052 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2053 MacroAssembler _masm(&cbuf); 2054 2055 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2056 int reg = ra_->get_encode(this); 2057 2058 if (Assembler::is_simm(offset, 16)) { 2059 __ addi(as_Register(reg), R1, offset); 2060 } else { 2061 ShouldNotReachHere(); 2062 } 2063 } 2064 2065 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2066 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2067 return 4; 2068 } 2069 2070 #ifndef PRODUCT 2071 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2072 st->print_cr("---- MachUEPNode ----"); 2073 st->print_cr("..."); 2074 } 2075 #endif 2076 2077 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2078 // This is the unverified entry point. 2079 MacroAssembler _masm(&cbuf); 2080 2081 // Inline_cache contains a klass. 2082 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 2083 Register receiver_klass = R12_scratch2; // tmp 2084 2085 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 2086 assert(R11_scratch1 == R11, "need prologue scratch register"); 2087 2088 // Check for NULL argument if we don't have implicit null checks. 2089 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 2090 if (TrapBasedNullChecks) { 2091 __ trap_null_check(R3_ARG1); 2092 } else { 2093 Label valid; 2094 __ cmpdi(CCR0, R3_ARG1, 0); 2095 __ bne_predict_taken(CCR0, valid); 2096 // We have a null argument, branch to ic_miss_stub. 2097 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2098 relocInfo::runtime_call_type); 2099 __ bind(valid); 2100 } 2101 } 2102 // Assume argument is not NULL, load klass from receiver. 2103 __ load_klass(receiver_klass, R3_ARG1); 2104 2105 if (TrapBasedICMissChecks) { 2106 __ trap_ic_miss_check(receiver_klass, ic_klass); 2107 } else { 2108 Label valid; 2109 __ cmpd(CCR0, receiver_klass, ic_klass); 2110 __ beq_predict_taken(CCR0, valid); 2111 // We have an unexpected klass, branch to ic_miss_stub. 2112 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2113 relocInfo::runtime_call_type); 2114 __ bind(valid); 2115 } 2116 2117 // Argument is valid and klass is as expected, continue. 2118 } 2119 2120 #if 0 // TODO: PPC port 2121 // Optimize UEP code on z (save a load_const() call in main path). 2122 int MachUEPNode::ep_offset() { 2123 return 0; 2124 } 2125 #endif 2126 2127 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2128 // Variable size. Determine dynamically. 2129 return MachNode::size(ra_); 2130 } 2131 2132 //============================================================================= 2133 2134 %} // interrupt source 2135 2136 source_hpp %{ // Header information of the source block. 2137 2138 class HandlerImpl { 2139 2140 public: 2141 2142 static int emit_exception_handler(CodeBuffer &cbuf); 2143 static int emit_deopt_handler(CodeBuffer& cbuf); 2144 2145 static uint size_exception_handler() { 2146 // The exception_handler is a b64_patchable. 2147 return MacroAssembler::b64_patchable_size; 2148 } 2149 2150 static uint size_deopt_handler() { 2151 // The deopt_handler is a bl64_patchable. 2152 return MacroAssembler::bl64_patchable_size; 2153 } 2154 2155 }; 2156 2157 %} // end source_hpp 2158 2159 source %{ 2160 2161 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2162 MacroAssembler _masm(&cbuf); 2163 2164 address base = __ start_a_stub(size_exception_handler()); 2165 if (base == NULL) return 0; // CodeBuffer::expand failed 2166 2167 int offset = __ offset(); 2168 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2169 relocInfo::runtime_call_type); 2170 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2171 __ end_a_stub(); 2172 2173 return offset; 2174 } 2175 2176 // The deopt_handler is like the exception handler, but it calls to 2177 // the deoptimization blob instead of jumping to the exception blob. 2178 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2179 MacroAssembler _masm(&cbuf); 2180 2181 address base = __ start_a_stub(size_deopt_handler()); 2182 if (base == NULL) return 0; // CodeBuffer::expand failed 2183 2184 int offset = __ offset(); 2185 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2186 relocInfo::runtime_call_type); 2187 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2188 __ end_a_stub(); 2189 2190 return offset; 2191 } 2192 2193 //============================================================================= 2194 2195 // Use a frame slots bias for frameless methods if accessing the stack. 2196 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2197 if (as_Register(reg_enc) == R1_SP) { 2198 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2199 } 2200 return 0; 2201 } 2202 2203 const bool Matcher::match_rule_supported(int opcode) { 2204 if (!has_match_rule(opcode)) 2205 return false; 2206 2207 switch (opcode) { 2208 case Op_SqrtD: 2209 return VM_Version::has_fsqrt(); 2210 case Op_CountLeadingZerosI: 2211 case Op_CountLeadingZerosL: 2212 if (!UseCountLeadingZerosInstructionsPPC64) 2213 return false; 2214 break; 2215 case Op_CountTrailingZerosI: 2216 case Op_CountTrailingZerosL: 2217 if (!UseCountLeadingZerosInstructionsPPC64 && 2218 !UseCountTrailingZerosInstructionsPPC64) 2219 return false; 2220 break; 2221 2222 case Op_PopCountI: 2223 case Op_PopCountL: 2224 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2225 2226 case Op_StrComp: 2227 return SpecialStringCompareTo; 2228 case Op_StrEquals: 2229 return SpecialStringEquals; 2230 case Op_StrIndexOf: 2231 case Op_StrIndexOfChar: 2232 return SpecialStringIndexOf; 2233 case Op_AddVB: 2234 case Op_AddVS: 2235 case Op_AddVI: 2236 case Op_AddVF: 2237 case Op_AddVD: 2238 case Op_SubVB: 2239 case Op_SubVS: 2240 case Op_SubVI: 2241 case Op_SubVF: 2242 case Op_SubVD: 2243 case Op_MulVS: 2244 case Op_MulVF: 2245 case Op_MulVD: 2246 case Op_DivVF: 2247 case Op_DivVD: 2248 case Op_AbsVF: 2249 case Op_AbsVD: 2250 case Op_NegVF: 2251 case Op_NegVD: 2252 case Op_SqrtVF: 2253 case Op_SqrtVD: 2254 case Op_AddVL: 2255 case Op_SubVL: 2256 case Op_MulVI: 2257 return SuperwordUseVSX; 2258 case Op_PopCountVI: 2259 return (SuperwordUseVSX && UsePopCountInstruction); 2260 case Op_Digit: 2261 case Op_LowerCase: 2262 case Op_UpperCase: 2263 case Op_Whitespace: 2264 return VM_Version::has_darn(); 2265 } 2266 2267 return true; // Per default match rules are supported. 2268 } 2269 2270 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2271 2272 // TODO 2273 // identify extra cases that we might want to provide match rules for 2274 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2275 bool ret_value = match_rule_supported(opcode); 2276 // Add rules here. 2277 2278 return ret_value; // Per default match rules are supported. 2279 } 2280 2281 const bool Matcher::has_predicated_vectors(void) { 2282 return false; 2283 } 2284 2285 const int Matcher::float_pressure(int default_pressure_threshold) { 2286 return default_pressure_threshold; 2287 } 2288 2289 int Matcher::regnum_to_fpu_offset(int regnum) { 2290 // No user for this method? 2291 Unimplemented(); 2292 return 999; 2293 } 2294 2295 const bool Matcher::convL2FSupported(void) { 2296 // fcfids can do the conversion (>= Power7). 2297 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2298 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2299 } 2300 2301 // Vector width in bytes. 2302 const int Matcher::vector_width_in_bytes(BasicType bt) { 2303 if (SuperwordUseVSX) { 2304 assert(MaxVectorSize == 16, ""); 2305 return 16; 2306 } else { 2307 assert(MaxVectorSize == 8, ""); 2308 return 8; 2309 } 2310 } 2311 2312 // Vector ideal reg. 2313 const uint Matcher::vector_ideal_reg(int size) { 2314 if (SuperwordUseVSX) { 2315 assert(MaxVectorSize == 16 && size == 16, ""); 2316 return Op_VecX; 2317 } else { 2318 assert(MaxVectorSize == 8 && size == 8, ""); 2319 return Op_RegL; 2320 } 2321 } 2322 2323 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2324 fatal("vector shift is not supported"); 2325 return Node::NotAMachineReg; 2326 } 2327 2328 // Limits on vector size (number of elements) loaded into vector. 2329 const int Matcher::max_vector_size(const BasicType bt) { 2330 assert(is_java_primitive(bt), "only primitive type vectors"); 2331 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2332 } 2333 2334 const int Matcher::min_vector_size(const BasicType bt) { 2335 return max_vector_size(bt); // Same as max. 2336 } 2337 2338 // PPC doesn't support misaligned vectors store/load. 2339 const bool Matcher::misaligned_vectors_ok() { 2340 return !AlignVector; // can be changed by flag 2341 } 2342 2343 // PPC AES support not yet implemented 2344 const bool Matcher::pass_original_key_for_aes() { 2345 return false; 2346 } 2347 2348 // RETURNS: whether this branch offset is short enough that a short 2349 // branch can be used. 2350 // 2351 // If the platform does not provide any short branch variants, then 2352 // this method should return `false' for offset 0. 2353 // 2354 // `Compile::Fill_buffer' will decide on basis of this information 2355 // whether to do the pass `Compile::Shorten_branches' at all. 2356 // 2357 // And `Compile::Shorten_branches' will decide on basis of this 2358 // information whether to replace particular branch sites by short 2359 // ones. 2360 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2361 // Is the offset within the range of a ppc64 pc relative branch? 2362 bool b; 2363 2364 const int safety_zone = 3 * BytesPerInstWord; 2365 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2366 29 - 16 + 1 + 2); 2367 return b; 2368 } 2369 2370 const bool Matcher::isSimpleConstant64(jlong value) { 2371 // Probably always true, even if a temp register is required. 2372 return true; 2373 } 2374 /* TODO: PPC port 2375 // Make a new machine dependent decode node (with its operands). 2376 MachTypeNode *Matcher::make_decode_node() { 2377 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2378 "This method is only implemented for unscaled cOops mode so far"); 2379 MachTypeNode *decode = new decodeN_unscaledNode(); 2380 decode->set_opnd_array(0, new iRegPdstOper()); 2381 decode->set_opnd_array(1, new iRegNsrcOper()); 2382 return decode; 2383 } 2384 */ 2385 2386 // false => size gets scaled to BytesPerLong, ok. 2387 const bool Matcher::init_array_count_is_in_bytes = false; 2388 2389 // Use conditional move (CMOVL) on Power7. 2390 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2391 2392 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2393 // fsel doesn't accept a condition register as input, so this would be slightly different. 2394 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2395 2396 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2397 const bool Matcher::require_postalloc_expand = true; 2398 2399 // Do we need to mask the count passed to shift instructions or does 2400 // the cpu only look at the lower 5/6 bits anyway? 2401 // PowerPC requires masked shift counts. 2402 const bool Matcher::need_masked_shift_count = true; 2403 2404 // This affects two different things: 2405 // - how Decode nodes are matched 2406 // - how ImplicitNullCheck opportunities are recognized 2407 // If true, the matcher will try to remove all Decodes and match them 2408 // (as operands) into nodes. NullChecks are not prepared to deal with 2409 // Decodes by final_graph_reshaping(). 2410 // If false, final_graph_reshaping() forces the decode behind the Cmp 2411 // for a NullCheck. The matcher matches the Decode node into a register. 2412 // Implicit_null_check optimization moves the Decode along with the 2413 // memory operation back up before the NullCheck. 2414 bool Matcher::narrow_oop_use_complex_address() { 2415 // TODO: PPC port if (MatchDecodeNodes) return true; 2416 return false; 2417 } 2418 2419 bool Matcher::narrow_klass_use_complex_address() { 2420 NOT_LP64(ShouldNotCallThis()); 2421 assert(UseCompressedClassPointers, "only for compressed klass code"); 2422 // TODO: PPC port if (MatchDecodeNodes) return true; 2423 return false; 2424 } 2425 2426 bool Matcher::const_oop_prefer_decode() { 2427 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2428 return Universe::narrow_oop_base() == NULL; 2429 } 2430 2431 bool Matcher::const_klass_prefer_decode() { 2432 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2433 return Universe::narrow_klass_base() == NULL; 2434 } 2435 2436 // Is it better to copy float constants, or load them directly from memory? 2437 // Intel can load a float constant from a direct address, requiring no 2438 // extra registers. Most RISCs will have to materialize an address into a 2439 // register first, so they would do better to copy the constant from stack. 2440 const bool Matcher::rematerialize_float_constants = false; 2441 2442 // If CPU can load and store mis-aligned doubles directly then no fixup is 2443 // needed. Else we split the double into 2 integer pieces and move it 2444 // piece-by-piece. Only happens when passing doubles into C code as the 2445 // Java calling convention forces doubles to be aligned. 2446 const bool Matcher::misaligned_doubles_ok = true; 2447 2448 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2449 Unimplemented(); 2450 } 2451 2452 // Advertise here if the CPU requires explicit rounding operations 2453 // to implement the UseStrictFP mode. 2454 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2455 2456 // Do floats take an entire double register or just half? 2457 // 2458 // A float occupies a ppc64 double register. For the allocator, a 2459 // ppc64 double register appears as a pair of float registers. 2460 bool Matcher::float_in_double() { return true; } 2461 2462 // Do ints take an entire long register or just half? 2463 // The relevant question is how the int is callee-saved: 2464 // the whole long is written but de-opt'ing will have to extract 2465 // the relevant 32 bits. 2466 const bool Matcher::int_in_long = true; 2467 2468 // Constants for c2c and c calling conventions. 2469 2470 const MachRegisterNumbers iarg_reg[8] = { 2471 R3_num, R4_num, R5_num, R6_num, 2472 R7_num, R8_num, R9_num, R10_num 2473 }; 2474 2475 const MachRegisterNumbers farg_reg[13] = { 2476 F1_num, F2_num, F3_num, F4_num, 2477 F5_num, F6_num, F7_num, F8_num, 2478 F9_num, F10_num, F11_num, F12_num, 2479 F13_num 2480 }; 2481 2482 const MachRegisterNumbers vsarg_reg[64] = { 2483 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2484 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2485 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2486 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2487 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2488 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2489 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2490 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2491 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2492 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2493 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2494 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2495 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2496 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2497 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2498 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2499 }; 2500 2501 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2502 2503 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2504 2505 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2506 2507 // Return whether or not this register is ever used as an argument. This 2508 // function is used on startup to build the trampoline stubs in generateOptoStub. 2509 // Registers not mentioned will be killed by the VM call in the trampoline, and 2510 // arguments in those registers not be available to the callee. 2511 bool Matcher::can_be_java_arg(int reg) { 2512 // We return true for all registers contained in iarg_reg[] and 2513 // farg_reg[] and their virtual halves. 2514 // We must include the virtual halves in order to get STDs and LDs 2515 // instead of STWs and LWs in the trampoline stubs. 2516 2517 if ( reg == R3_num || reg == R3_H_num 2518 || reg == R4_num || reg == R4_H_num 2519 || reg == R5_num || reg == R5_H_num 2520 || reg == R6_num || reg == R6_H_num 2521 || reg == R7_num || reg == R7_H_num 2522 || reg == R8_num || reg == R8_H_num 2523 || reg == R9_num || reg == R9_H_num 2524 || reg == R10_num || reg == R10_H_num) 2525 return true; 2526 2527 if ( reg == F1_num || reg == F1_H_num 2528 || reg == F2_num || reg == F2_H_num 2529 || reg == F3_num || reg == F3_H_num 2530 || reg == F4_num || reg == F4_H_num 2531 || reg == F5_num || reg == F5_H_num 2532 || reg == F6_num || reg == F6_H_num 2533 || reg == F7_num || reg == F7_H_num 2534 || reg == F8_num || reg == F8_H_num 2535 || reg == F9_num || reg == F9_H_num 2536 || reg == F10_num || reg == F10_H_num 2537 || reg == F11_num || reg == F11_H_num 2538 || reg == F12_num || reg == F12_H_num 2539 || reg == F13_num || reg == F13_H_num) 2540 return true; 2541 2542 return false; 2543 } 2544 2545 bool Matcher::is_spillable_arg(int reg) { 2546 return can_be_java_arg(reg); 2547 } 2548 2549 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2550 return false; 2551 } 2552 2553 // Register for DIVI projection of divmodI. 2554 RegMask Matcher::divI_proj_mask() { 2555 ShouldNotReachHere(); 2556 return RegMask(); 2557 } 2558 2559 // Register for MODI projection of divmodI. 2560 RegMask Matcher::modI_proj_mask() { 2561 ShouldNotReachHere(); 2562 return RegMask(); 2563 } 2564 2565 // Register for DIVL projection of divmodL. 2566 RegMask Matcher::divL_proj_mask() { 2567 ShouldNotReachHere(); 2568 return RegMask(); 2569 } 2570 2571 // Register for MODL projection of divmodL. 2572 RegMask Matcher::modL_proj_mask() { 2573 ShouldNotReachHere(); 2574 return RegMask(); 2575 } 2576 2577 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2578 return RegMask(); 2579 } 2580 2581 const bool Matcher::convi2l_type_required = true; 2582 2583 %} 2584 2585 //----------ENCODING BLOCK----------------------------------------------------- 2586 // This block specifies the encoding classes used by the compiler to output 2587 // byte streams. Encoding classes are parameterized macros used by 2588 // Machine Instruction Nodes in order to generate the bit encoding of the 2589 // instruction. Operands specify their base encoding interface with the 2590 // interface keyword. There are currently supported four interfaces, 2591 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2592 // operand to generate a function which returns its register number when 2593 // queried. CONST_INTER causes an operand to generate a function which 2594 // returns the value of the constant when queried. MEMORY_INTER causes an 2595 // operand to generate four functions which return the Base Register, the 2596 // Index Register, the Scale Value, and the Offset Value of the operand when 2597 // queried. COND_INTER causes an operand to generate six functions which 2598 // return the encoding code (ie - encoding bits for the instruction) 2599 // associated with each basic boolean condition for a conditional instruction. 2600 // 2601 // Instructions specify two basic values for encoding. Again, a function 2602 // is available to check if the constant displacement is an oop. They use the 2603 // ins_encode keyword to specify their encoding classes (which must be 2604 // a sequence of enc_class names, and their parameters, specified in 2605 // the encoding block), and they use the 2606 // opcode keyword to specify, in order, their primary, secondary, and 2607 // tertiary opcode. Only the opcode sections which a particular instruction 2608 // needs for encoding need to be specified. 2609 encode %{ 2610 enc_class enc_unimplemented %{ 2611 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2612 MacroAssembler _masm(&cbuf); 2613 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2614 %} 2615 2616 enc_class enc_untested %{ 2617 #ifdef ASSERT 2618 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2619 MacroAssembler _masm(&cbuf); 2620 __ untested("Untested mach node encoding in AD file."); 2621 #else 2622 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2623 #endif 2624 %} 2625 2626 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2627 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2628 MacroAssembler _masm(&cbuf); 2629 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2630 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2631 %} 2632 2633 // Load acquire. 2634 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2635 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2636 MacroAssembler _masm(&cbuf); 2637 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2638 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2639 __ twi_0($dst$$Register); 2640 __ isync(); 2641 %} 2642 2643 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2644 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2645 2646 MacroAssembler _masm(&cbuf); 2647 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2648 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2649 %} 2650 2651 // Load acquire. 2652 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2653 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2654 2655 MacroAssembler _masm(&cbuf); 2656 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2657 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2658 __ twi_0($dst$$Register); 2659 __ isync(); 2660 %} 2661 2662 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2663 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2664 2665 MacroAssembler _masm(&cbuf); 2666 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2667 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2668 %} 2669 2670 // Load acquire. 2671 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2672 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2673 2674 MacroAssembler _masm(&cbuf); 2675 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2676 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2677 __ twi_0($dst$$Register); 2678 __ isync(); 2679 %} 2680 2681 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2682 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2683 MacroAssembler _masm(&cbuf); 2684 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2685 // Operand 'ds' requires 4-alignment. 2686 assert((Idisp & 0x3) == 0, "unaligned offset"); 2687 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2688 %} 2689 2690 // Load acquire. 2691 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2692 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2693 MacroAssembler _masm(&cbuf); 2694 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2695 // Operand 'ds' requires 4-alignment. 2696 assert((Idisp & 0x3) == 0, "unaligned offset"); 2697 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2698 __ twi_0($dst$$Register); 2699 __ isync(); 2700 %} 2701 2702 enc_class enc_lfd(RegF dst, memory mem) %{ 2703 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2704 MacroAssembler _masm(&cbuf); 2705 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2706 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2707 %} 2708 2709 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2710 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2711 2712 MacroAssembler _masm(&cbuf); 2713 int toc_offset = 0; 2714 2715 address const_toc_addr; 2716 // Create a non-oop constant, no relocation needed. 2717 // If it is an IC, it has a virtual_call_Relocation. 2718 const_toc_addr = __ long_constant((jlong)$src$$constant); 2719 if (const_toc_addr == NULL) { 2720 ciEnv::current()->record_out_of_memory_failure(); 2721 return; 2722 } 2723 2724 // Get the constant's TOC offset. 2725 toc_offset = __ offset_to_method_toc(const_toc_addr); 2726 2727 // Keep the current instruction offset in mind. 2728 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2729 2730 __ ld($dst$$Register, toc_offset, $toc$$Register); 2731 %} 2732 2733 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2734 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2735 2736 MacroAssembler _masm(&cbuf); 2737 2738 if (!ra_->C->in_scratch_emit_size()) { 2739 address const_toc_addr; 2740 // Create a non-oop constant, no relocation needed. 2741 // If it is an IC, it has a virtual_call_Relocation. 2742 const_toc_addr = __ long_constant((jlong)$src$$constant); 2743 if (const_toc_addr == NULL) { 2744 ciEnv::current()->record_out_of_memory_failure(); 2745 return; 2746 } 2747 2748 // Get the constant's TOC offset. 2749 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2750 // Store the toc offset of the constant. 2751 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2752 2753 // Also keep the current instruction offset in mind. 2754 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2755 } 2756 2757 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2758 %} 2759 2760 %} // encode 2761 2762 source %{ 2763 2764 typedef struct { 2765 loadConL_hiNode *_large_hi; 2766 loadConL_loNode *_large_lo; 2767 loadConLNode *_small; 2768 MachNode *_last; 2769 } loadConLNodesTuple; 2770 2771 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2772 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2773 loadConLNodesTuple nodes; 2774 2775 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2776 if (large_constant_pool) { 2777 // Create new nodes. 2778 loadConL_hiNode *m1 = new loadConL_hiNode(); 2779 loadConL_loNode *m2 = new loadConL_loNode(); 2780 2781 // inputs for new nodes 2782 m1->add_req(NULL, toc); 2783 m2->add_req(NULL, m1); 2784 2785 // operands for new nodes 2786 m1->_opnds[0] = new iRegLdstOper(); // dst 2787 m1->_opnds[1] = immSrc; // src 2788 m1->_opnds[2] = new iRegPdstOper(); // toc 2789 m2->_opnds[0] = new iRegLdstOper(); // dst 2790 m2->_opnds[1] = immSrc; // src 2791 m2->_opnds[2] = new iRegLdstOper(); // base 2792 2793 // Initialize ins_attrib TOC fields. 2794 m1->_const_toc_offset = -1; 2795 m2->_const_toc_offset_hi_node = m1; 2796 2797 // Initialize ins_attrib instruction offset. 2798 m1->_cbuf_insts_offset = -1; 2799 2800 // register allocation for new nodes 2801 ra_->set_pair(m1->_idx, reg_second, reg_first); 2802 ra_->set_pair(m2->_idx, reg_second, reg_first); 2803 2804 // Create result. 2805 nodes._large_hi = m1; 2806 nodes._large_lo = m2; 2807 nodes._small = NULL; 2808 nodes._last = nodes._large_lo; 2809 assert(m2->bottom_type()->isa_long(), "must be long"); 2810 } else { 2811 loadConLNode *m2 = new loadConLNode(); 2812 2813 // inputs for new nodes 2814 m2->add_req(NULL, toc); 2815 2816 // operands for new nodes 2817 m2->_opnds[0] = new iRegLdstOper(); // dst 2818 m2->_opnds[1] = immSrc; // src 2819 m2->_opnds[2] = new iRegPdstOper(); // toc 2820 2821 // Initialize ins_attrib instruction offset. 2822 m2->_cbuf_insts_offset = -1; 2823 2824 // register allocation for new nodes 2825 ra_->set_pair(m2->_idx, reg_second, reg_first); 2826 2827 // Create result. 2828 nodes._large_hi = NULL; 2829 nodes._large_lo = NULL; 2830 nodes._small = m2; 2831 nodes._last = nodes._small; 2832 assert(m2->bottom_type()->isa_long(), "must be long"); 2833 } 2834 2835 return nodes; 2836 } 2837 2838 typedef struct { 2839 loadConL_hiNode *_large_hi; 2840 loadConL_loNode *_large_lo; 2841 mtvsrdNode *_moved; 2842 xxspltdNode *_replicated; 2843 loadConLNode *_small; 2844 MachNode *_last; 2845 } loadConLReplicatedNodesTuple; 2846 2847 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2848 vecXOper *dst, immI_0Oper *zero, 2849 OptoReg::Name reg_second, OptoReg::Name reg_first, 2850 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2851 loadConLReplicatedNodesTuple nodes; 2852 2853 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2854 if (large_constant_pool) { 2855 // Create new nodes. 2856 loadConL_hiNode *m1 = new loadConL_hiNode(); 2857 loadConL_loNode *m2 = new loadConL_loNode(); 2858 mtvsrdNode *m3 = new mtvsrdNode(); 2859 xxspltdNode *m4 = new xxspltdNode(); 2860 2861 // inputs for new nodes 2862 m1->add_req(NULL, toc); 2863 m2->add_req(NULL, m1); 2864 m3->add_req(NULL, m2); 2865 m4->add_req(NULL, m3); 2866 2867 // operands for new nodes 2868 m1->_opnds[0] = new iRegLdstOper(); // dst 2869 m1->_opnds[1] = immSrc; // src 2870 m1->_opnds[2] = new iRegPdstOper(); // toc 2871 2872 m2->_opnds[0] = new iRegLdstOper(); // dst 2873 m2->_opnds[1] = immSrc; // src 2874 m2->_opnds[2] = new iRegLdstOper(); // base 2875 2876 m3->_opnds[0] = new vecXOper(); // dst 2877 m3->_opnds[1] = new iRegLdstOper(); // src 2878 2879 m4->_opnds[0] = new vecXOper(); // dst 2880 m4->_opnds[1] = new vecXOper(); // src 2881 m4->_opnds[2] = zero; 2882 2883 // Initialize ins_attrib TOC fields. 2884 m1->_const_toc_offset = -1; 2885 m2->_const_toc_offset_hi_node = m1; 2886 2887 // Initialize ins_attrib instruction offset. 2888 m1->_cbuf_insts_offset = -1; 2889 2890 // register allocation for new nodes 2891 ra_->set_pair(m1->_idx, reg_second, reg_first); 2892 ra_->set_pair(m2->_idx, reg_second, reg_first); 2893 ra_->set1(m3->_idx, reg_second); 2894 ra_->set2(m3->_idx, reg_vec_first); 2895 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2896 2897 // Create result. 2898 nodes._large_hi = m1; 2899 nodes._large_lo = m2; 2900 nodes._moved = m3; 2901 nodes._replicated = m4; 2902 nodes._small = NULL; 2903 nodes._last = nodes._replicated; 2904 assert(m2->bottom_type()->isa_long(), "must be long"); 2905 } else { 2906 loadConLNode *m2 = new loadConLNode(); 2907 mtvsrdNode *m3 = new mtvsrdNode(); 2908 xxspltdNode *m4 = new xxspltdNode(); 2909 2910 // inputs for new nodes 2911 m2->add_req(NULL, toc); 2912 2913 // operands for new nodes 2914 m2->_opnds[0] = new iRegLdstOper(); // dst 2915 m2->_opnds[1] = immSrc; // src 2916 m2->_opnds[2] = new iRegPdstOper(); // toc 2917 2918 m3->_opnds[0] = new vecXOper(); // dst 2919 m3->_opnds[1] = new iRegLdstOper(); // src 2920 2921 m4->_opnds[0] = new vecXOper(); // dst 2922 m4->_opnds[1] = new vecXOper(); // src 2923 m4->_opnds[2] = zero; 2924 2925 // Initialize ins_attrib instruction offset. 2926 m2->_cbuf_insts_offset = -1; 2927 ra_->set1(m3->_idx, reg_second); 2928 ra_->set2(m3->_idx, reg_vec_first); 2929 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2930 2931 // register allocation for new nodes 2932 ra_->set_pair(m2->_idx, reg_second, reg_first); 2933 2934 // Create result. 2935 nodes._large_hi = NULL; 2936 nodes._large_lo = NULL; 2937 nodes._small = m2; 2938 nodes._moved = m3; 2939 nodes._replicated = m4; 2940 nodes._last = nodes._replicated; 2941 assert(m2->bottom_type()->isa_long(), "must be long"); 2942 } 2943 2944 return nodes; 2945 } 2946 2947 %} // source 2948 2949 encode %{ 2950 // Postalloc expand emitter for loading a long constant from the method's TOC. 2951 // Enc_class needed as consttanttablebase is not supported by postalloc 2952 // expand. 2953 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2954 // Create new nodes. 2955 loadConLNodesTuple loadConLNodes = 2956 loadConLNodesTuple_create(ra_, n_toc, op_src, 2957 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2958 2959 // Push new nodes. 2960 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2961 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2962 2963 // some asserts 2964 assert(nodes->length() >= 1, "must have created at least 1 node"); 2965 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2966 %} 2967 2968 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2969 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2970 2971 MacroAssembler _masm(&cbuf); 2972 int toc_offset = 0; 2973 2974 intptr_t val = $src$$constant; 2975 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2976 address const_toc_addr; 2977 if (constant_reloc == relocInfo::oop_type) { 2978 // Create an oop constant and a corresponding relocation. 2979 AddressLiteral a = __ allocate_oop_address((jobject)val); 2980 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2981 __ relocate(a.rspec()); 2982 } else if (constant_reloc == relocInfo::metadata_type) { 2983 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2984 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2985 __ relocate(a.rspec()); 2986 } else { 2987 // Create a non-oop constant, no relocation needed. 2988 const_toc_addr = __ long_constant((jlong)$src$$constant); 2989 } 2990 2991 if (const_toc_addr == NULL) { 2992 ciEnv::current()->record_out_of_memory_failure(); 2993 return; 2994 } 2995 // Get the constant's TOC offset. 2996 toc_offset = __ offset_to_method_toc(const_toc_addr); 2997 2998 __ ld($dst$$Register, toc_offset, $toc$$Register); 2999 %} 3000 3001 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 3002 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 3003 3004 MacroAssembler _masm(&cbuf); 3005 if (!ra_->C->in_scratch_emit_size()) { 3006 intptr_t val = $src$$constant; 3007 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 3008 address const_toc_addr; 3009 if (constant_reloc == relocInfo::oop_type) { 3010 // Create an oop constant and a corresponding relocation. 3011 AddressLiteral a = __ allocate_oop_address((jobject)val); 3012 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3013 __ relocate(a.rspec()); 3014 } else if (constant_reloc == relocInfo::metadata_type) { 3015 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 3016 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3017 __ relocate(a.rspec()); 3018 } else { // non-oop pointers, e.g. card mark base, heap top 3019 // Create a non-oop constant, no relocation needed. 3020 const_toc_addr = __ long_constant((jlong)$src$$constant); 3021 } 3022 3023 if (const_toc_addr == NULL) { 3024 ciEnv::current()->record_out_of_memory_failure(); 3025 return; 3026 } 3027 // Get the constant's TOC offset. 3028 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 3029 // Store the toc offset of the constant. 3030 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 3031 } 3032 3033 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 3034 %} 3035 3036 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 3037 // Enc_class needed as consttanttablebase is not supported by postalloc 3038 // expand. 3039 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 3040 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3041 if (large_constant_pool) { 3042 // Create new nodes. 3043 loadConP_hiNode *m1 = new loadConP_hiNode(); 3044 loadConP_loNode *m2 = new loadConP_loNode(); 3045 3046 // inputs for new nodes 3047 m1->add_req(NULL, n_toc); 3048 m2->add_req(NULL, m1); 3049 3050 // operands for new nodes 3051 m1->_opnds[0] = new iRegPdstOper(); // dst 3052 m1->_opnds[1] = op_src; // src 3053 m1->_opnds[2] = new iRegPdstOper(); // toc 3054 m2->_opnds[0] = new iRegPdstOper(); // dst 3055 m2->_opnds[1] = op_src; // src 3056 m2->_opnds[2] = new iRegLdstOper(); // base 3057 3058 // Initialize ins_attrib TOC fields. 3059 m1->_const_toc_offset = -1; 3060 m2->_const_toc_offset_hi_node = m1; 3061 3062 // Register allocation for new nodes. 3063 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3064 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3065 3066 nodes->push(m1); 3067 nodes->push(m2); 3068 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3069 } else { 3070 loadConPNode *m2 = new loadConPNode(); 3071 3072 // inputs for new nodes 3073 m2->add_req(NULL, n_toc); 3074 3075 // operands for new nodes 3076 m2->_opnds[0] = new iRegPdstOper(); // dst 3077 m2->_opnds[1] = op_src; // src 3078 m2->_opnds[2] = new iRegPdstOper(); // toc 3079 3080 // Register allocation for new nodes. 3081 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3082 3083 nodes->push(m2); 3084 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3085 } 3086 %} 3087 3088 // Enc_class needed as consttanttablebase is not supported by postalloc 3089 // expand. 3090 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3091 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3092 3093 MachNode *m2; 3094 if (large_constant_pool) { 3095 m2 = new loadConFCompNode(); 3096 } else { 3097 m2 = new loadConFNode(); 3098 } 3099 // inputs for new nodes 3100 m2->add_req(NULL, n_toc); 3101 3102 // operands for new nodes 3103 m2->_opnds[0] = op_dst; 3104 m2->_opnds[1] = op_src; 3105 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3106 3107 // register allocation for new nodes 3108 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3109 nodes->push(m2); 3110 %} 3111 3112 // Enc_class needed as consttanttablebase is not supported by postalloc 3113 // expand. 3114 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3115 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3116 3117 MachNode *m2; 3118 if (large_constant_pool) { 3119 m2 = new loadConDCompNode(); 3120 } else { 3121 m2 = new loadConDNode(); 3122 } 3123 // inputs for new nodes 3124 m2->add_req(NULL, n_toc); 3125 3126 // operands for new nodes 3127 m2->_opnds[0] = op_dst; 3128 m2->_opnds[1] = op_src; 3129 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3130 3131 // register allocation for new nodes 3132 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3133 nodes->push(m2); 3134 %} 3135 3136 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3137 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3138 MacroAssembler _masm(&cbuf); 3139 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3140 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3141 %} 3142 3143 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3144 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3145 MacroAssembler _masm(&cbuf); 3146 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3147 // Operand 'ds' requires 4-alignment. 3148 assert((Idisp & 0x3) == 0, "unaligned offset"); 3149 __ std($src$$Register, Idisp, $mem$$base$$Register); 3150 %} 3151 3152 enc_class enc_stfs(RegF src, memory mem) %{ 3153 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3154 MacroAssembler _masm(&cbuf); 3155 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3156 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3157 %} 3158 3159 enc_class enc_stfd(RegF src, memory mem) %{ 3160 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3161 MacroAssembler _masm(&cbuf); 3162 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3163 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3164 %} 3165 3166 // Use release_store for card-marking to ensure that previous 3167 // oop-stores are visible before the card-mark change. 3168 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3169 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3170 // FIXME: Implement this as a cmove and use a fixed condition code 3171 // register which is written on every transition to compiled code, 3172 // e.g. in call-stub and when returning from runtime stubs. 3173 // 3174 // Proposed code sequence for the cmove implementation: 3175 // 3176 // Label skip_release; 3177 // __ beq(CCRfixed, skip_release); 3178 // __ release(); 3179 // __ bind(skip_release); 3180 // __ stb(card mark); 3181 3182 MacroAssembler _masm(&cbuf); 3183 Label skip_storestore; 3184 3185 #if 0 // TODO: PPC port 3186 // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the 3187 // StoreStore barrier conditionally. 3188 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3189 __ cmpwi($crx$$CondRegister, R0, 0); 3190 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3191 #endif 3192 __ li(R0, 0); 3193 __ membar(Assembler::StoreStore); 3194 #if 0 // TODO: PPC port 3195 __ bind(skip_storestore); 3196 #endif 3197 3198 // Do the store. 3199 if ($mem$$index == 0) { 3200 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3201 } else { 3202 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3203 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3204 } 3205 %} 3206 3207 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3208 3209 if (VM_Version::has_isel()) { 3210 // use isel instruction with Power 7 3211 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3212 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3213 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3214 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3215 3216 n_compare->add_req(n_region, n_src); 3217 n_compare->_opnds[0] = op_crx; 3218 n_compare->_opnds[1] = op_src; 3219 n_compare->_opnds[2] = new immL16Oper(0); 3220 3221 n_sub_base->add_req(n_region, n_src); 3222 n_sub_base->_opnds[0] = op_dst; 3223 n_sub_base->_opnds[1] = op_src; 3224 n_sub_base->_bottom_type = _bottom_type; 3225 3226 n_shift->add_req(n_region, n_sub_base); 3227 n_shift->_opnds[0] = op_dst; 3228 n_shift->_opnds[1] = op_dst; 3229 n_shift->_bottom_type = _bottom_type; 3230 3231 n_cond_set->add_req(n_region, n_compare, n_shift); 3232 n_cond_set->_opnds[0] = op_dst; 3233 n_cond_set->_opnds[1] = op_crx; 3234 n_cond_set->_opnds[2] = op_dst; 3235 n_cond_set->_bottom_type = _bottom_type; 3236 3237 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3238 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3239 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3240 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3241 3242 nodes->push(n_compare); 3243 nodes->push(n_sub_base); 3244 nodes->push(n_shift); 3245 nodes->push(n_cond_set); 3246 3247 } else { 3248 // before Power 7 3249 moveRegNode *n_move = new moveRegNode(); 3250 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3251 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3252 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3253 3254 n_move->add_req(n_region, n_src); 3255 n_move->_opnds[0] = op_dst; 3256 n_move->_opnds[1] = op_src; 3257 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3258 3259 n_compare->add_req(n_region, n_src); 3260 n_compare->add_prec(n_move); 3261 3262 n_compare->_opnds[0] = op_crx; 3263 n_compare->_opnds[1] = op_src; 3264 n_compare->_opnds[2] = new immL16Oper(0); 3265 3266 n_sub_base->add_req(n_region, n_compare, n_src); 3267 n_sub_base->_opnds[0] = op_dst; 3268 n_sub_base->_opnds[1] = op_crx; 3269 n_sub_base->_opnds[2] = op_src; 3270 n_sub_base->_bottom_type = _bottom_type; 3271 3272 n_shift->add_req(n_region, n_sub_base); 3273 n_shift->_opnds[0] = op_dst; 3274 n_shift->_opnds[1] = op_dst; 3275 n_shift->_bottom_type = _bottom_type; 3276 3277 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3278 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3279 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3280 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3281 3282 nodes->push(n_move); 3283 nodes->push(n_compare); 3284 nodes->push(n_sub_base); 3285 nodes->push(n_shift); 3286 } 3287 3288 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3289 %} 3290 3291 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3292 3293 encodeP_subNode *n1 = new encodeP_subNode(); 3294 n1->add_req(n_region, n_src); 3295 n1->_opnds[0] = op_dst; 3296 n1->_opnds[1] = op_src; 3297 n1->_bottom_type = _bottom_type; 3298 3299 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3300 n2->add_req(n_region, n1); 3301 n2->_opnds[0] = op_dst; 3302 n2->_opnds[1] = op_dst; 3303 n2->_bottom_type = _bottom_type; 3304 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3305 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3306 3307 nodes->push(n1); 3308 nodes->push(n2); 3309 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3310 %} 3311 3312 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3313 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3314 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3315 3316 n_compare->add_req(n_region, n_src); 3317 n_compare->_opnds[0] = op_crx; 3318 n_compare->_opnds[1] = op_src; 3319 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3320 3321 n_shift->add_req(n_region, n_src); 3322 n_shift->_opnds[0] = op_dst; 3323 n_shift->_opnds[1] = op_src; 3324 n_shift->_bottom_type = _bottom_type; 3325 3326 if (VM_Version::has_isel()) { 3327 // use isel instruction with Power 7 3328 3329 decodeN_addNode *n_add_base = new decodeN_addNode(); 3330 n_add_base->add_req(n_region, n_shift); 3331 n_add_base->_opnds[0] = op_dst; 3332 n_add_base->_opnds[1] = op_dst; 3333 n_add_base->_bottom_type = _bottom_type; 3334 3335 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3336 n_cond_set->add_req(n_region, n_compare, n_add_base); 3337 n_cond_set->_opnds[0] = op_dst; 3338 n_cond_set->_opnds[1] = op_crx; 3339 n_cond_set->_opnds[2] = op_dst; 3340 n_cond_set->_bottom_type = _bottom_type; 3341 3342 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3343 ra_->set_oop(n_cond_set, true); 3344 3345 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3346 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3347 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3348 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3349 3350 nodes->push(n_compare); 3351 nodes->push(n_shift); 3352 nodes->push(n_add_base); 3353 nodes->push(n_cond_set); 3354 3355 } else { 3356 // before Power 7 3357 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3358 3359 n_add_base->add_req(n_region, n_compare, n_shift); 3360 n_add_base->_opnds[0] = op_dst; 3361 n_add_base->_opnds[1] = op_crx; 3362 n_add_base->_opnds[2] = op_dst; 3363 n_add_base->_bottom_type = _bottom_type; 3364 3365 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3366 ra_->set_oop(n_add_base, true); 3367 3368 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3369 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3370 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3371 3372 nodes->push(n_compare); 3373 nodes->push(n_shift); 3374 nodes->push(n_add_base); 3375 } 3376 %} 3377 3378 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3379 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3380 n1->add_req(n_region, n_src); 3381 n1->_opnds[0] = op_dst; 3382 n1->_opnds[1] = op_src; 3383 n1->_bottom_type = _bottom_type; 3384 3385 decodeN_addNode *n2 = new decodeN_addNode(); 3386 n2->add_req(n_region, n1); 3387 n2->_opnds[0] = op_dst; 3388 n2->_opnds[1] = op_dst; 3389 n2->_bottom_type = _bottom_type; 3390 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3391 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3392 3393 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3394 ra_->set_oop(n2, true); 3395 3396 nodes->push(n1); 3397 nodes->push(n2); 3398 %} 3399 3400 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3401 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3402 3403 MacroAssembler _masm(&cbuf); 3404 int cc = $cmp$$cmpcode; 3405 int flags_reg = $crx$$reg; 3406 Label done; 3407 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3408 // Branch if not (cmp crx). 3409 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3410 __ mr($dst$$Register, $src$$Register); 3411 // TODO PPC port __ endgroup_if_needed(_size == 12); 3412 __ bind(done); 3413 %} 3414 3415 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3416 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3417 3418 MacroAssembler _masm(&cbuf); 3419 Label done; 3420 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3421 // Branch if not (cmp crx). 3422 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3423 __ li($dst$$Register, $src$$constant); 3424 // TODO PPC port __ endgroup_if_needed(_size == 12); 3425 __ bind(done); 3426 %} 3427 3428 // This enc_class is needed so that scheduler gets proper 3429 // input mapping for latency computation. 3430 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3431 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3432 MacroAssembler _masm(&cbuf); 3433 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3434 %} 3435 3436 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3437 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3438 3439 MacroAssembler _masm(&cbuf); 3440 3441 Label done; 3442 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3443 __ li($dst$$Register, $zero$$constant); 3444 __ beq($crx$$CondRegister, done); 3445 __ li($dst$$Register, $notzero$$constant); 3446 __ bind(done); 3447 %} 3448 3449 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3450 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3451 3452 MacroAssembler _masm(&cbuf); 3453 3454 Label done; 3455 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3456 __ li($dst$$Register, $zero$$constant); 3457 __ beq($crx$$CondRegister, done); 3458 __ li($dst$$Register, $notzero$$constant); 3459 __ bind(done); 3460 %} 3461 3462 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3463 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3464 3465 MacroAssembler _masm(&cbuf); 3466 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3467 Label done; 3468 __ bso($crx$$CondRegister, done); 3469 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3470 // TODO PPC port __ endgroup_if_needed(_size == 12); 3471 __ bind(done); 3472 %} 3473 3474 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3475 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3476 3477 MacroAssembler _masm(&cbuf); 3478 Label done; 3479 __ bso($crx$$CondRegister, done); 3480 __ mffprd($dst$$Register, $src$$FloatRegister); 3481 // TODO PPC port __ endgroup_if_needed(_size == 12); 3482 __ bind(done); 3483 %} 3484 3485 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3486 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3487 3488 MacroAssembler _masm(&cbuf); 3489 Label d; // dummy 3490 __ bind(d); 3491 Label* p = ($lbl$$label); 3492 // `p' is `NULL' when this encoding class is used only to 3493 // determine the size of the encoded instruction. 3494 Label& l = (NULL == p)? d : *(p); 3495 int cc = $cmp$$cmpcode; 3496 int flags_reg = $crx$$reg; 3497 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3498 int bhint = Assembler::bhintNoHint; 3499 3500 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3501 if (_prob <= PROB_NEVER) { 3502 bhint = Assembler::bhintIsNotTaken; 3503 } else if (_prob >= PROB_ALWAYS) { 3504 bhint = Assembler::bhintIsTaken; 3505 } 3506 } 3507 3508 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3509 cc_to_biint(cc, flags_reg), 3510 l); 3511 %} 3512 3513 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3514 // The scheduler doesn't know about branch shortening, so we set the opcode 3515 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3516 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3517 3518 MacroAssembler _masm(&cbuf); 3519 Label d; // dummy 3520 __ bind(d); 3521 Label* p = ($lbl$$label); 3522 // `p' is `NULL' when this encoding class is used only to 3523 // determine the size of the encoded instruction. 3524 Label& l = (NULL == p)? d : *(p); 3525 int cc = $cmp$$cmpcode; 3526 int flags_reg = $crx$$reg; 3527 int bhint = Assembler::bhintNoHint; 3528 3529 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3530 if (_prob <= PROB_NEVER) { 3531 bhint = Assembler::bhintIsNotTaken; 3532 } else if (_prob >= PROB_ALWAYS) { 3533 bhint = Assembler::bhintIsTaken; 3534 } 3535 } 3536 3537 // Tell the conditional far branch to optimize itself when being relocated. 3538 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3539 cc_to_biint(cc, flags_reg), 3540 l, 3541 MacroAssembler::bc_far_optimize_on_relocate); 3542 %} 3543 3544 // Branch used with Power6 scheduling (can be shortened without changing the node). 3545 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3546 // The scheduler doesn't know about branch shortening, so we set the opcode 3547 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3548 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3549 3550 MacroAssembler _masm(&cbuf); 3551 Label d; // dummy 3552 __ bind(d); 3553 Label* p = ($lbl$$label); 3554 // `p' is `NULL' when this encoding class is used only to 3555 // determine the size of the encoded instruction. 3556 Label& l = (NULL == p)? d : *(p); 3557 int cc = $cmp$$cmpcode; 3558 int flags_reg = $crx$$reg; 3559 int bhint = Assembler::bhintNoHint; 3560 3561 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3562 if (_prob <= PROB_NEVER) { 3563 bhint = Assembler::bhintIsNotTaken; 3564 } else if (_prob >= PROB_ALWAYS) { 3565 bhint = Assembler::bhintIsTaken; 3566 } 3567 } 3568 3569 #if 0 // TODO: PPC port 3570 if (_size == 8) { 3571 // Tell the conditional far branch to optimize itself when being relocated. 3572 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3573 cc_to_biint(cc, flags_reg), 3574 l, 3575 MacroAssembler::bc_far_optimize_on_relocate); 3576 } else { 3577 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3578 cc_to_biint(cc, flags_reg), 3579 l); 3580 } 3581 #endif 3582 Unimplemented(); 3583 %} 3584 3585 // Postalloc expand emitter for loading a replicatef float constant from 3586 // the method's TOC. 3587 // Enc_class needed as consttanttablebase is not supported by postalloc 3588 // expand. 3589 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3590 // Create new nodes. 3591 3592 // Make an operand with the bit pattern to load as float. 3593 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3594 3595 loadConLNodesTuple loadConLNodes = 3596 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3597 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3598 3599 // Push new nodes. 3600 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3601 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3602 3603 assert(nodes->length() >= 1, "must have created at least 1 node"); 3604 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3605 %} 3606 3607 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3608 // Create new nodes. 3609 3610 // Make an operand with the bit pattern to load as float. 3611 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3612 immI_0Oper *op_zero = new immI_0Oper(0); 3613 3614 loadConLReplicatedNodesTuple loadConLNodes = 3615 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3616 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3617 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3618 3619 // Push new nodes. 3620 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3621 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3622 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3623 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3624 3625 assert(nodes->length() >= 1, "must have created at least 1 node"); 3626 %} 3627 3628 // This enc_class is needed so that scheduler gets proper 3629 // input mapping for latency computation. 3630 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3631 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3632 // Fake operand dst needed for PPC scheduler. 3633 assert($dst$$constant == 0x0, "dst must be 0x0"); 3634 3635 MacroAssembler _masm(&cbuf); 3636 // Mark the code position where the load from the safepoint 3637 // polling page was emitted as relocInfo::poll_type. 3638 __ relocate(relocInfo::poll_type); 3639 __ load_from_polling_page($poll$$Register); 3640 %} 3641 3642 // A Java static call or a runtime call. 3643 // 3644 // Branch-and-link relative to a trampoline. 3645 // The trampoline loads the target address and does a long branch to there. 3646 // In case we call java, the trampoline branches to a interpreter_stub 3647 // which loads the inline cache and the real call target from the constant pool. 3648 // 3649 // This basically looks like this: 3650 // 3651 // >>>> consts -+ -+ 3652 // | |- offset1 3653 // [call target1] | <-+ 3654 // [IC cache] |- offset2 3655 // [call target2] <--+ 3656 // 3657 // <<<< consts 3658 // >>>> insts 3659 // 3660 // bl offset16 -+ -+ ??? // How many bits available? 3661 // | | 3662 // <<<< insts | | 3663 // >>>> stubs | | 3664 // | |- trampoline_stub_Reloc 3665 // trampoline stub: | <-+ 3666 // r2 = toc | 3667 // r2 = [r2 + offset1] | // Load call target1 from const section 3668 // mtctr r2 | 3669 // bctr |- static_stub_Reloc 3670 // comp_to_interp_stub: <---+ 3671 // r1 = toc 3672 // ICreg = [r1 + IC_offset] // Load IC from const section 3673 // r1 = [r1 + offset2] // Load call target2 from const section 3674 // mtctr r1 3675 // bctr 3676 // 3677 // <<<< stubs 3678 // 3679 // The call instruction in the code either 3680 // - Branches directly to a compiled method if the offset is encodable in instruction. 3681 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3682 // - Branches to the compiled_to_interp stub if the target is interpreted. 3683 // 3684 // Further there are three relocations from the loads to the constants in 3685 // the constant section. 3686 // 3687 // Usage of r1 and r2 in the stubs allows to distinguish them. 3688 enc_class enc_java_static_call(method meth) %{ 3689 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3690 3691 MacroAssembler _masm(&cbuf); 3692 address entry_point = (address)$meth$$method; 3693 3694 if (!_method) { 3695 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3696 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3697 } else { 3698 // Remember the offset not the address. 3699 const int start_offset = __ offset(); 3700 3701 // The trampoline stub. 3702 // No entry point given, use the current pc. 3703 // Make sure branch fits into 3704 if (entry_point == 0) entry_point = __ pc(); 3705 3706 // Put the entry point as a constant into the constant pool. 3707 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3708 if (entry_point_toc_addr == NULL) { 3709 ciEnv::current()->record_out_of_memory_failure(); 3710 return; 3711 } 3712 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3713 3714 // Emit the trampoline stub which will be related to the branch-and-link below. 3715 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3716 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3717 int method_index = resolved_method_index(cbuf); 3718 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3719 : static_call_Relocation::spec(method_index)); 3720 3721 // The real call. 3722 // Note: At this point we do not have the address of the trampoline 3723 // stub, and the entry point might be too far away for bl, so __ pc() 3724 // serves as dummy and the bl will be patched later. 3725 cbuf.set_insts_mark(); 3726 __ bl(__ pc()); // Emits a relocation. 3727 3728 // The stub for call to interpreter. 3729 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3730 if (stub == NULL) { 3731 ciEnv::current()->record_failure("CodeCache is full"); 3732 return; 3733 } 3734 } 3735 %} 3736 3737 // Second node of expanded dynamic call - the call. 3738 enc_class enc_java_dynamic_call_sched(method meth) %{ 3739 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3740 3741 MacroAssembler _masm(&cbuf); 3742 3743 if (!ra_->C->in_scratch_emit_size()) { 3744 // Create a call trampoline stub for the given method. 3745 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3746 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3747 if (entry_point_const == NULL) { 3748 ciEnv::current()->record_out_of_memory_failure(); 3749 return; 3750 } 3751 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3752 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3753 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3754 3755 // Build relocation at call site with ic position as data. 3756 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3757 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3758 "must have one, but can't have both"); 3759 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3760 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3761 "must contain instruction offset"); 3762 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3763 ? _load_ic_hi_node->_cbuf_insts_offset 3764 : _load_ic_node->_cbuf_insts_offset; 3765 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3766 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3767 "should be load from TOC"); 3768 int method_index = resolved_method_index(cbuf); 3769 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3770 } 3771 3772 // At this point I do not have the address of the trampoline stub, 3773 // and the entry point might be too far away for bl. Pc() serves 3774 // as dummy and bl will be patched later. 3775 __ bl((address) __ pc()); 3776 %} 3777 3778 // postalloc expand emitter for virtual calls. 3779 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3780 3781 // Create the nodes for loading the IC from the TOC. 3782 loadConLNodesTuple loadConLNodes_IC = 3783 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3784 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3785 3786 // Create the call node. 3787 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3788 call->_method_handle_invoke = _method_handle_invoke; 3789 call->_vtable_index = _vtable_index; 3790 call->_method = _method; 3791 call->_bci = _bci; 3792 call->_optimized_virtual = _optimized_virtual; 3793 call->_tf = _tf; 3794 call->_entry_point = _entry_point; 3795 call->_cnt = _cnt; 3796 call->_argsize = _argsize; 3797 call->_oop_map = _oop_map; 3798 call->_jvms = _jvms; 3799 call->_jvmadj = _jvmadj; 3800 call->_in_rms = _in_rms; 3801 call->_nesting = _nesting; 3802 call->_override_symbolic_info = _override_symbolic_info; 3803 3804 // New call needs all inputs of old call. 3805 // Req... 3806 for (uint i = 0; i < req(); ++i) { 3807 // The expanded node does not need toc any more. 3808 // Add the inline cache constant here instead. This expresses the 3809 // register of the inline cache must be live at the call. 3810 // Else we would have to adapt JVMState by -1. 3811 if (i == mach_constant_base_node_input()) { 3812 call->add_req(loadConLNodes_IC._last); 3813 } else { 3814 call->add_req(in(i)); 3815 } 3816 } 3817 // ...as well as prec 3818 for (uint i = req(); i < len(); ++i) { 3819 call->add_prec(in(i)); 3820 } 3821 3822 // Remember nodes loading the inline cache into r19. 3823 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3824 call->_load_ic_node = loadConLNodes_IC._small; 3825 3826 // Operands for new nodes. 3827 call->_opnds[0] = _opnds[0]; 3828 call->_opnds[1] = _opnds[1]; 3829 3830 // Only the inline cache is associated with a register. 3831 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3832 3833 // Push new nodes. 3834 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3835 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3836 nodes->push(call); 3837 %} 3838 3839 // Compound version of call dynamic 3840 // Toc is only passed so that it can be used in ins_encode statement. 3841 // In the code we have to use $constanttablebase. 3842 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3843 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3844 MacroAssembler _masm(&cbuf); 3845 int start_offset = __ offset(); 3846 3847 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3848 #if 0 3849 int vtable_index = this->_vtable_index; 3850 if (_vtable_index < 0) { 3851 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3852 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3853 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3854 3855 // Virtual call relocation will point to ic load. 3856 address virtual_call_meta_addr = __ pc(); 3857 // Load a clear inline cache. 3858 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3859 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3860 if (!success) { 3861 ciEnv::current()->record_out_of_memory_failure(); 3862 return; 3863 } 3864 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3865 // to determine who we intended to call. 3866 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3867 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3868 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3869 "Fix constant in ret_addr_offset()"); 3870 } else { 3871 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3872 // Go thru the vtable. Get receiver klass. Receiver already 3873 // checked for non-null. If we'll go thru a C2I adapter, the 3874 // interpreter expects method in R19_method. 3875 3876 __ load_klass(R11_scratch1, R3); 3877 3878 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3879 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3880 __ li(R19_method, v_off); 3881 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3882 // NOTE: for vtable dispatches, the vtable entry will never be 3883 // null. However it may very well end up in handle_wrong_method 3884 // if the method is abstract for the particular class. 3885 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3886 // Call target. Either compiled code or C2I adapter. 3887 __ mtctr(R11_scratch1); 3888 __ bctrl(); 3889 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3890 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3891 } 3892 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3893 "Fix constant in ret_addr_offset()"); 3894 } 3895 #endif 3896 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3897 %} 3898 3899 // a runtime call 3900 enc_class enc_java_to_runtime_call (method meth) %{ 3901 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3902 3903 MacroAssembler _masm(&cbuf); 3904 const address start_pc = __ pc(); 3905 3906 #if defined(ABI_ELFv2) 3907 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3908 __ call_c(entry, relocInfo::runtime_call_type); 3909 #else 3910 // The function we're going to call. 3911 FunctionDescriptor fdtemp; 3912 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3913 3914 Register Rtoc = R12_scratch2; 3915 // Calculate the method's TOC. 3916 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3917 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3918 // pool entries; call_c_using_toc will optimize the call. 3919 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3920 if (!success) { 3921 ciEnv::current()->record_out_of_memory_failure(); 3922 return; 3923 } 3924 #endif 3925 3926 // Check the ret_addr_offset. 3927 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3928 "Fix constant in ret_addr_offset()"); 3929 %} 3930 3931 // Move to ctr for leaf call. 3932 // This enc_class is needed so that scheduler gets proper 3933 // input mapping for latency computation. 3934 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3935 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3936 MacroAssembler _masm(&cbuf); 3937 __ mtctr($src$$Register); 3938 %} 3939 3940 // Postalloc expand emitter for runtime leaf calls. 3941 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3942 loadConLNodesTuple loadConLNodes_Entry; 3943 #if defined(ABI_ELFv2) 3944 jlong entry_address = (jlong) this->entry_point(); 3945 assert(entry_address, "need address here"); 3946 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3947 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3948 #else 3949 // Get the struct that describes the function we are about to call. 3950 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3951 assert(fd, "need fd here"); 3952 jlong entry_address = (jlong) fd->entry(); 3953 // new nodes 3954 loadConLNodesTuple loadConLNodes_Env; 3955 loadConLNodesTuple loadConLNodes_Toc; 3956 3957 // Create nodes and operands for loading the entry point. 3958 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3959 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3960 3961 3962 // Create nodes and operands for loading the env pointer. 3963 if (fd->env() != NULL) { 3964 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3965 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3966 } else { 3967 loadConLNodes_Env._large_hi = NULL; 3968 loadConLNodes_Env._large_lo = NULL; 3969 loadConLNodes_Env._small = NULL; 3970 loadConLNodes_Env._last = new loadConL16Node(); 3971 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3972 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3973 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3974 } 3975 3976 // Create nodes and operands for loading the Toc point. 3977 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3978 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3979 #endif // ABI_ELFv2 3980 // mtctr node 3981 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3982 3983 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3984 mtctr->add_req(0, loadConLNodes_Entry._last); 3985 3986 mtctr->_opnds[0] = new iRegLdstOper(); 3987 mtctr->_opnds[1] = new iRegLdstOper(); 3988 3989 // call node 3990 MachCallLeafNode *call = new CallLeafDirectNode(); 3991 3992 call->_opnds[0] = _opnds[0]; 3993 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3994 3995 // Make the new call node look like the old one. 3996 call->_name = _name; 3997 call->_tf = _tf; 3998 call->_entry_point = _entry_point; 3999 call->_cnt = _cnt; 4000 call->_argsize = _argsize; 4001 call->_oop_map = _oop_map; 4002 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 4003 call->_jvms = NULL; 4004 call->_jvmadj = _jvmadj; 4005 call->_in_rms = _in_rms; 4006 call->_nesting = _nesting; 4007 4008 4009 // New call needs all inputs of old call. 4010 // Req... 4011 for (uint i = 0; i < req(); ++i) { 4012 if (i != mach_constant_base_node_input()) { 4013 call->add_req(in(i)); 4014 } 4015 } 4016 4017 // These must be reqired edges, as the registers are live up to 4018 // the call. Else the constants are handled as kills. 4019 call->add_req(mtctr); 4020 #if !defined(ABI_ELFv2) 4021 call->add_req(loadConLNodes_Env._last); 4022 call->add_req(loadConLNodes_Toc._last); 4023 #endif 4024 4025 // ...as well as prec 4026 for (uint i = req(); i < len(); ++i) { 4027 call->add_prec(in(i)); 4028 } 4029 4030 // registers 4031 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 4032 4033 // Insert the new nodes. 4034 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 4035 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 4036 #if !defined(ABI_ELFv2) 4037 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 4038 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 4039 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 4040 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 4041 #endif 4042 nodes->push(mtctr); 4043 nodes->push(call); 4044 %} 4045 %} 4046 4047 //----------FRAME-------------------------------------------------------------- 4048 // Definition of frame structure and management information. 4049 4050 frame %{ 4051 // What direction does stack grow in (assumed to be same for native & Java). 4052 stack_direction(TOWARDS_LOW); 4053 4054 // These two registers define part of the calling convention between 4055 // compiled code and the interpreter. 4056 4057 // Inline Cache Register or method for I2C. 4058 inline_cache_reg(R19); // R19_method 4059 4060 // Method Oop Register when calling interpreter. 4061 interpreter_method_oop_reg(R19); // R19_method 4062 4063 // Optional: name the operand used by cisc-spilling to access 4064 // [stack_pointer + offset]. 4065 cisc_spilling_operand_name(indOffset); 4066 4067 // Number of stack slots consumed by a Monitor enter. 4068 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 4069 4070 // Compiled code's Frame Pointer. 4071 frame_pointer(R1); // R1_SP 4072 4073 // Interpreter stores its frame pointer in a register which is 4074 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 4075 // interpreted java to compiled java. 4076 // 4077 // R14_state holds pointer to caller's cInterpreter. 4078 interpreter_frame_pointer(R14); // R14_state 4079 4080 stack_alignment(frame::alignment_in_bytes); 4081 4082 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4083 4084 // Number of outgoing stack slots killed above the 4085 // out_preserve_stack_slots for calls to C. Supports the var-args 4086 // backing area for register parms. 4087 // 4088 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4089 4090 // The after-PROLOG location of the return address. Location of 4091 // return address specifies a type (REG or STACK) and a number 4092 // representing the register number (i.e. - use a register name) or 4093 // stack slot. 4094 // 4095 // A: Link register is stored in stack slot ... 4096 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4097 // J: Therefore, we make sure that the link register is also in R11_scratch1 4098 // at the end of the prolog. 4099 // B: We use R20, now. 4100 //return_addr(REG R20); 4101 4102 // G: After reading the comments made by all the luminaries on their 4103 // failure to tell the compiler where the return address really is, 4104 // I hardly dare to try myself. However, I'm convinced it's in slot 4105 // 4 what apparently works and saves us some spills. 4106 return_addr(STACK 4); 4107 4108 // This is the body of the function 4109 // 4110 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4111 // uint length, // length of array 4112 // bool is_outgoing) 4113 // 4114 // The `sig' array is to be updated. sig[j] represents the location 4115 // of the j-th argument, either a register or a stack slot. 4116 4117 // Comment taken from i486.ad: 4118 // Body of function which returns an integer array locating 4119 // arguments either in registers or in stack slots. Passed an array 4120 // of ideal registers called "sig" and a "length" count. Stack-slot 4121 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4122 // arguments for a CALLEE. Incoming stack arguments are 4123 // automatically biased by the preserve_stack_slots field above. 4124 calling_convention %{ 4125 // No difference between ingoing/outgoing. Just pass false. 4126 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4127 %} 4128 4129 // Comment taken from i486.ad: 4130 // Body of function which returns an integer array locating 4131 // arguments either in registers or in stack slots. Passed an array 4132 // of ideal registers called "sig" and a "length" count. Stack-slot 4133 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4134 // arguments for a CALLEE. Incoming stack arguments are 4135 // automatically biased by the preserve_stack_slots field above. 4136 c_calling_convention %{ 4137 // This is obviously always outgoing. 4138 // C argument in register AND stack slot. 4139 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4140 %} 4141 4142 // Location of native (C/C++) and interpreter return values. This 4143 // is specified to be the same as Java. In the 32-bit VM, long 4144 // values are actually returned from native calls in O0:O1 and 4145 // returned to the interpreter in I0:I1. The copying to and from 4146 // the register pairs is done by the appropriate call and epilog 4147 // opcodes. This simplifies the register allocator. 4148 c_return_value %{ 4149 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4150 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4151 "only return normal values"); 4152 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4153 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4154 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4155 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4156 %} 4157 4158 // Location of compiled Java return values. Same as C 4159 return_value %{ 4160 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4161 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4162 "only return normal values"); 4163 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4164 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4165 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4166 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4167 %} 4168 %} 4169 4170 4171 //----------ATTRIBUTES--------------------------------------------------------- 4172 4173 //----------Operand Attributes------------------------------------------------- 4174 op_attrib op_cost(1); // Required cost attribute. 4175 4176 //----------Instruction Attributes--------------------------------------------- 4177 4178 // Cost attribute. required. 4179 ins_attrib ins_cost(DEFAULT_COST); 4180 4181 // Is this instruction a non-matching short branch variant of some 4182 // long branch? Not required. 4183 ins_attrib ins_short_branch(0); 4184 4185 ins_attrib ins_is_TrapBasedCheckNode(true); 4186 4187 // Number of constants. 4188 // This instruction uses the given number of constants 4189 // (optional attribute). 4190 // This is needed to determine in time whether the constant pool will 4191 // exceed 4000 entries. Before postalloc_expand the overall number of constants 4192 // is determined. It's also used to compute the constant pool size 4193 // in Output(). 4194 ins_attrib ins_num_consts(0); 4195 4196 // Required alignment attribute (must be a power of 2) specifies the 4197 // alignment that some part of the instruction (not necessarily the 4198 // start) requires. If > 1, a compute_padding() function must be 4199 // provided for the instruction. 4200 ins_attrib ins_alignment(1); 4201 4202 // Enforce/prohibit rematerializations. 4203 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4204 // then rematerialization of that instruction is prohibited and the 4205 // instruction's value will be spilled if necessary. 4206 // Causes that MachNode::rematerialize() returns false. 4207 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 4208 // then rematerialization should be enforced and a copy of the instruction 4209 // should be inserted if possible; rematerialization is not guaranteed. 4210 // Note: this may result in rematerializations in front of every use. 4211 // Causes that MachNode::rematerialize() can return true. 4212 // (optional attribute) 4213 ins_attrib ins_cannot_rematerialize(false); 4214 ins_attrib ins_should_rematerialize(false); 4215 4216 // Instruction has variable size depending on alignment. 4217 ins_attrib ins_variable_size_depending_on_alignment(false); 4218 4219 // Instruction is a nop. 4220 ins_attrib ins_is_nop(false); 4221 4222 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4223 ins_attrib ins_use_mach_if_fast_lock_node(false); 4224 4225 // Field for the toc offset of a constant. 4226 // 4227 // This is needed if the toc offset is not encodable as an immediate in 4228 // the PPC load instruction. If so, the upper (hi) bits of the offset are 4229 // added to the toc, and from this a load with immediate is performed. 4230 // With postalloc expand, we get two nodes that require the same offset 4231 // but which don't know about each other. The offset is only known 4232 // when the constant is added to the constant pool during emitting. 4233 // It is generated in the 'hi'-node adding the upper bits, and saved 4234 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 4235 // the offset from there when it gets encoded. 4236 ins_attrib ins_field_const_toc_offset(0); 4237 ins_attrib ins_field_const_toc_offset_hi_node(0); 4238 4239 // A field that can hold the instructions offset in the code buffer. 4240 // Set in the nodes emitter. 4241 ins_attrib ins_field_cbuf_insts_offset(-1); 4242 4243 // Fields for referencing a call's load-IC-node. 4244 // If the toc offset can not be encoded as an immediate in a load, we 4245 // use two nodes. 4246 ins_attrib ins_field_load_ic_hi_node(0); 4247 ins_attrib ins_field_load_ic_node(0); 4248 4249 //----------OPERANDS----------------------------------------------------------- 4250 // Operand definitions must precede instruction definitions for correct 4251 // parsing in the ADLC because operands constitute user defined types 4252 // which are used in instruction definitions. 4253 // 4254 // Formats are generated automatically for constants and base registers. 4255 4256 operand vecX() %{ 4257 constraint(ALLOC_IN_RC(vs_reg)); 4258 match(VecX); 4259 4260 format %{ %} 4261 interface(REG_INTER); 4262 %} 4263 4264 //----------Simple Operands---------------------------------------------------- 4265 // Immediate Operands 4266 4267 // Integer Immediate: 32-bit 4268 operand immI() %{ 4269 match(ConI); 4270 op_cost(40); 4271 format %{ %} 4272 interface(CONST_INTER); 4273 %} 4274 4275 operand immI8() %{ 4276 predicate(Assembler::is_simm(n->get_int(), 8)); 4277 op_cost(0); 4278 match(ConI); 4279 format %{ %} 4280 interface(CONST_INTER); 4281 %} 4282 4283 // Integer Immediate: 16-bit 4284 operand immI16() %{ 4285 predicate(Assembler::is_simm(n->get_int(), 16)); 4286 op_cost(0); 4287 match(ConI); 4288 format %{ %} 4289 interface(CONST_INTER); 4290 %} 4291 4292 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4293 operand immIhi16() %{ 4294 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4295 match(ConI); 4296 op_cost(0); 4297 format %{ %} 4298 interface(CONST_INTER); 4299 %} 4300 4301 operand immInegpow2() %{ 4302 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 4303 match(ConI); 4304 op_cost(0); 4305 format %{ %} 4306 interface(CONST_INTER); 4307 %} 4308 4309 operand immIpow2minus1() %{ 4310 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 4311 match(ConI); 4312 op_cost(0); 4313 format %{ %} 4314 interface(CONST_INTER); 4315 %} 4316 4317 operand immIpowerOf2() %{ 4318 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 4319 match(ConI); 4320 op_cost(0); 4321 format %{ %} 4322 interface(CONST_INTER); 4323 %} 4324 4325 // Unsigned Integer Immediate: the values 0-31 4326 operand uimmI5() %{ 4327 predicate(Assembler::is_uimm(n->get_int(), 5)); 4328 match(ConI); 4329 op_cost(0); 4330 format %{ %} 4331 interface(CONST_INTER); 4332 %} 4333 4334 // Unsigned Integer Immediate: 6-bit 4335 operand uimmI6() %{ 4336 predicate(Assembler::is_uimm(n->get_int(), 6)); 4337 match(ConI); 4338 op_cost(0); 4339 format %{ %} 4340 interface(CONST_INTER); 4341 %} 4342 4343 // Unsigned Integer Immediate: 6-bit int, greater than 32 4344 operand uimmI6_ge32() %{ 4345 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4346 match(ConI); 4347 op_cost(0); 4348 format %{ %} 4349 interface(CONST_INTER); 4350 %} 4351 4352 // Unsigned Integer Immediate: 15-bit 4353 operand uimmI15() %{ 4354 predicate(Assembler::is_uimm(n->get_int(), 15)); 4355 match(ConI); 4356 op_cost(0); 4357 format %{ %} 4358 interface(CONST_INTER); 4359 %} 4360 4361 // Unsigned Integer Immediate: 16-bit 4362 operand uimmI16() %{ 4363 predicate(Assembler::is_uimm(n->get_int(), 16)); 4364 match(ConI); 4365 op_cost(0); 4366 format %{ %} 4367 interface(CONST_INTER); 4368 %} 4369 4370 // constant 'int 0'. 4371 operand immI_0() %{ 4372 predicate(n->get_int() == 0); 4373 match(ConI); 4374 op_cost(0); 4375 format %{ %} 4376 interface(CONST_INTER); 4377 %} 4378 4379 // constant 'int 1'. 4380 operand immI_1() %{ 4381 predicate(n->get_int() == 1); 4382 match(ConI); 4383 op_cost(0); 4384 format %{ %} 4385 interface(CONST_INTER); 4386 %} 4387 4388 // constant 'int -1'. 4389 operand immI_minus1() %{ 4390 predicate(n->get_int() == -1); 4391 match(ConI); 4392 op_cost(0); 4393 format %{ %} 4394 interface(CONST_INTER); 4395 %} 4396 4397 // int value 16. 4398 operand immI_16() %{ 4399 predicate(n->get_int() == 16); 4400 match(ConI); 4401 op_cost(0); 4402 format %{ %} 4403 interface(CONST_INTER); 4404 %} 4405 4406 // int value 24. 4407 operand immI_24() %{ 4408 predicate(n->get_int() == 24); 4409 match(ConI); 4410 op_cost(0); 4411 format %{ %} 4412 interface(CONST_INTER); 4413 %} 4414 4415 // Compressed oops constants 4416 // Pointer Immediate 4417 operand immN() %{ 4418 match(ConN); 4419 4420 op_cost(10); 4421 format %{ %} 4422 interface(CONST_INTER); 4423 %} 4424 4425 // NULL Pointer Immediate 4426 operand immN_0() %{ 4427 predicate(n->get_narrowcon() == 0); 4428 match(ConN); 4429 4430 op_cost(0); 4431 format %{ %} 4432 interface(CONST_INTER); 4433 %} 4434 4435 // Compressed klass constants 4436 operand immNKlass() %{ 4437 match(ConNKlass); 4438 4439 op_cost(0); 4440 format %{ %} 4441 interface(CONST_INTER); 4442 %} 4443 4444 // This operand can be used to avoid matching of an instruct 4445 // with chain rule. 4446 operand immNKlass_NM() %{ 4447 match(ConNKlass); 4448 predicate(false); 4449 op_cost(0); 4450 format %{ %} 4451 interface(CONST_INTER); 4452 %} 4453 4454 // Pointer Immediate: 64-bit 4455 operand immP() %{ 4456 match(ConP); 4457 op_cost(0); 4458 format %{ %} 4459 interface(CONST_INTER); 4460 %} 4461 4462 // Operand to avoid match of loadConP. 4463 // This operand can be used to avoid matching of an instruct 4464 // with chain rule. 4465 operand immP_NM() %{ 4466 match(ConP); 4467 predicate(false); 4468 op_cost(0); 4469 format %{ %} 4470 interface(CONST_INTER); 4471 %} 4472 4473 // costant 'pointer 0'. 4474 operand immP_0() %{ 4475 predicate(n->get_ptr() == 0); 4476 match(ConP); 4477 op_cost(0); 4478 format %{ %} 4479 interface(CONST_INTER); 4480 %} 4481 4482 // pointer 0x0 or 0x1 4483 operand immP_0or1() %{ 4484 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4485 match(ConP); 4486 op_cost(0); 4487 format %{ %} 4488 interface(CONST_INTER); 4489 %} 4490 4491 operand immL() %{ 4492 match(ConL); 4493 op_cost(40); 4494 format %{ %} 4495 interface(CONST_INTER); 4496 %} 4497 4498 operand immLmax30() %{ 4499 predicate((n->get_long() <= 30)); 4500 match(ConL); 4501 op_cost(0); 4502 format %{ %} 4503 interface(CONST_INTER); 4504 %} 4505 4506 // Long Immediate: 16-bit 4507 operand immL16() %{ 4508 predicate(Assembler::is_simm(n->get_long(), 16)); 4509 match(ConL); 4510 op_cost(0); 4511 format %{ %} 4512 interface(CONST_INTER); 4513 %} 4514 4515 // Long Immediate: 16-bit, 4-aligned 4516 operand immL16Alg4() %{ 4517 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4518 match(ConL); 4519 op_cost(0); 4520 format %{ %} 4521 interface(CONST_INTER); 4522 %} 4523 4524 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4525 operand immL32hi16() %{ 4526 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4527 match(ConL); 4528 op_cost(0); 4529 format %{ %} 4530 interface(CONST_INTER); 4531 %} 4532 4533 // Long Immediate: 32-bit 4534 operand immL32() %{ 4535 predicate(Assembler::is_simm(n->get_long(), 32)); 4536 match(ConL); 4537 op_cost(0); 4538 format %{ %} 4539 interface(CONST_INTER); 4540 %} 4541 4542 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4543 operand immLhighest16() %{ 4544 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4545 match(ConL); 4546 op_cost(0); 4547 format %{ %} 4548 interface(CONST_INTER); 4549 %} 4550 4551 operand immLnegpow2() %{ 4552 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4553 match(ConL); 4554 op_cost(0); 4555 format %{ %} 4556 interface(CONST_INTER); 4557 %} 4558 4559 operand immLpow2minus1() %{ 4560 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4561 (n->get_long() != (jlong)0xffffffffffffffffL)); 4562 match(ConL); 4563 op_cost(0); 4564 format %{ %} 4565 interface(CONST_INTER); 4566 %} 4567 4568 // constant 'long 0'. 4569 operand immL_0() %{ 4570 predicate(n->get_long() == 0L); 4571 match(ConL); 4572 op_cost(0); 4573 format %{ %} 4574 interface(CONST_INTER); 4575 %} 4576 4577 // constat ' long -1'. 4578 operand immL_minus1() %{ 4579 predicate(n->get_long() == -1L); 4580 match(ConL); 4581 op_cost(0); 4582 format %{ %} 4583 interface(CONST_INTER); 4584 %} 4585 4586 // Long Immediate: low 32-bit mask 4587 operand immL_32bits() %{ 4588 predicate(n->get_long() == 0xFFFFFFFFL); 4589 match(ConL); 4590 op_cost(0); 4591 format %{ %} 4592 interface(CONST_INTER); 4593 %} 4594 4595 // Unsigned Long Immediate: 16-bit 4596 operand uimmL16() %{ 4597 predicate(Assembler::is_uimm(n->get_long(), 16)); 4598 match(ConL); 4599 op_cost(0); 4600 format %{ %} 4601 interface(CONST_INTER); 4602 %} 4603 4604 // Float Immediate 4605 operand immF() %{ 4606 match(ConF); 4607 op_cost(40); 4608 format %{ %} 4609 interface(CONST_INTER); 4610 %} 4611 4612 // Float Immediate: +0.0f. 4613 operand immF_0() %{ 4614 predicate(jint_cast(n->getf()) == 0); 4615 match(ConF); 4616 4617 op_cost(0); 4618 format %{ %} 4619 interface(CONST_INTER); 4620 %} 4621 4622 // Double Immediate 4623 operand immD() %{ 4624 match(ConD); 4625 op_cost(40); 4626 format %{ %} 4627 interface(CONST_INTER); 4628 %} 4629 4630 // Integer Register Operands 4631 // Integer Destination Register 4632 // See definition of reg_class bits32_reg_rw. 4633 operand iRegIdst() %{ 4634 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4635 match(RegI); 4636 match(rscratch1RegI); 4637 match(rscratch2RegI); 4638 match(rarg1RegI); 4639 match(rarg2RegI); 4640 match(rarg3RegI); 4641 match(rarg4RegI); 4642 format %{ %} 4643 interface(REG_INTER); 4644 %} 4645 4646 // Integer Source Register 4647 // See definition of reg_class bits32_reg_ro. 4648 operand iRegIsrc() %{ 4649 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4650 match(RegI); 4651 match(rscratch1RegI); 4652 match(rscratch2RegI); 4653 match(rarg1RegI); 4654 match(rarg2RegI); 4655 match(rarg3RegI); 4656 match(rarg4RegI); 4657 format %{ %} 4658 interface(REG_INTER); 4659 %} 4660 4661 operand rscratch1RegI() %{ 4662 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4663 match(iRegIdst); 4664 format %{ %} 4665 interface(REG_INTER); 4666 %} 4667 4668 operand rscratch2RegI() %{ 4669 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4670 match(iRegIdst); 4671 format %{ %} 4672 interface(REG_INTER); 4673 %} 4674 4675 operand rarg1RegI() %{ 4676 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4677 match(iRegIdst); 4678 format %{ %} 4679 interface(REG_INTER); 4680 %} 4681 4682 operand rarg2RegI() %{ 4683 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4684 match(iRegIdst); 4685 format %{ %} 4686 interface(REG_INTER); 4687 %} 4688 4689 operand rarg3RegI() %{ 4690 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4691 match(iRegIdst); 4692 format %{ %} 4693 interface(REG_INTER); 4694 %} 4695 4696 operand rarg4RegI() %{ 4697 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4698 match(iRegIdst); 4699 format %{ %} 4700 interface(REG_INTER); 4701 %} 4702 4703 operand rarg1RegL() %{ 4704 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4705 match(iRegLdst); 4706 format %{ %} 4707 interface(REG_INTER); 4708 %} 4709 4710 operand rarg2RegL() %{ 4711 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4712 match(iRegLdst); 4713 format %{ %} 4714 interface(REG_INTER); 4715 %} 4716 4717 operand rarg3RegL() %{ 4718 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4719 match(iRegLdst); 4720 format %{ %} 4721 interface(REG_INTER); 4722 %} 4723 4724 operand rarg4RegL() %{ 4725 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4726 match(iRegLdst); 4727 format %{ %} 4728 interface(REG_INTER); 4729 %} 4730 4731 // Pointer Destination Register 4732 // See definition of reg_class bits64_reg_rw. 4733 operand iRegPdst() %{ 4734 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4735 match(RegP); 4736 match(rscratch1RegP); 4737 match(rscratch2RegP); 4738 match(rarg1RegP); 4739 match(rarg2RegP); 4740 match(rarg3RegP); 4741 match(rarg4RegP); 4742 format %{ %} 4743 interface(REG_INTER); 4744 %} 4745 4746 // Pointer Destination Register 4747 // Operand not using r11 and r12 (killed in epilog). 4748 operand iRegPdstNoScratch() %{ 4749 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4750 match(RegP); 4751 match(rarg1RegP); 4752 match(rarg2RegP); 4753 match(rarg3RegP); 4754 match(rarg4RegP); 4755 format %{ %} 4756 interface(REG_INTER); 4757 %} 4758 4759 // Pointer Source Register 4760 // See definition of reg_class bits64_reg_ro. 4761 operand iRegPsrc() %{ 4762 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4763 match(RegP); 4764 match(iRegPdst); 4765 match(rscratch1RegP); 4766 match(rscratch2RegP); 4767 match(rarg1RegP); 4768 match(rarg2RegP); 4769 match(rarg3RegP); 4770 match(rarg4RegP); 4771 match(threadRegP); 4772 format %{ %} 4773 interface(REG_INTER); 4774 %} 4775 4776 // Thread operand. 4777 operand threadRegP() %{ 4778 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4779 match(iRegPdst); 4780 format %{ "R16" %} 4781 interface(REG_INTER); 4782 %} 4783 4784 operand rscratch1RegP() %{ 4785 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4786 match(iRegPdst); 4787 format %{ "R11" %} 4788 interface(REG_INTER); 4789 %} 4790 4791 operand rscratch2RegP() %{ 4792 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4793 match(iRegPdst); 4794 format %{ %} 4795 interface(REG_INTER); 4796 %} 4797 4798 operand rarg1RegP() %{ 4799 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4800 match(iRegPdst); 4801 format %{ %} 4802 interface(REG_INTER); 4803 %} 4804 4805 operand rarg2RegP() %{ 4806 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4807 match(iRegPdst); 4808 format %{ %} 4809 interface(REG_INTER); 4810 %} 4811 4812 operand rarg3RegP() %{ 4813 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4814 match(iRegPdst); 4815 format %{ %} 4816 interface(REG_INTER); 4817 %} 4818 4819 operand rarg4RegP() %{ 4820 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4821 match(iRegPdst); 4822 format %{ %} 4823 interface(REG_INTER); 4824 %} 4825 4826 operand iRegNsrc() %{ 4827 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4828 match(RegN); 4829 match(iRegNdst); 4830 4831 format %{ %} 4832 interface(REG_INTER); 4833 %} 4834 4835 operand iRegNdst() %{ 4836 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4837 match(RegN); 4838 4839 format %{ %} 4840 interface(REG_INTER); 4841 %} 4842 4843 // Long Destination Register 4844 // See definition of reg_class bits64_reg_rw. 4845 operand iRegLdst() %{ 4846 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4847 match(RegL); 4848 match(rscratch1RegL); 4849 match(rscratch2RegL); 4850 format %{ %} 4851 interface(REG_INTER); 4852 %} 4853 4854 // Long Source Register 4855 // See definition of reg_class bits64_reg_ro. 4856 operand iRegLsrc() %{ 4857 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4858 match(RegL); 4859 match(iRegLdst); 4860 match(rscratch1RegL); 4861 match(rscratch2RegL); 4862 format %{ %} 4863 interface(REG_INTER); 4864 %} 4865 4866 // Special operand for ConvL2I. 4867 operand iRegL2Isrc(iRegLsrc reg) %{ 4868 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4869 match(ConvL2I reg); 4870 format %{ "ConvL2I($reg)" %} 4871 interface(REG_INTER) 4872 %} 4873 4874 operand rscratch1RegL() %{ 4875 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4876 match(RegL); 4877 format %{ %} 4878 interface(REG_INTER); 4879 %} 4880 4881 operand rscratch2RegL() %{ 4882 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4883 match(RegL); 4884 format %{ %} 4885 interface(REG_INTER); 4886 %} 4887 4888 // Condition Code Flag Registers 4889 operand flagsReg() %{ 4890 constraint(ALLOC_IN_RC(int_flags)); 4891 match(RegFlags); 4892 format %{ %} 4893 interface(REG_INTER); 4894 %} 4895 4896 operand flagsRegSrc() %{ 4897 constraint(ALLOC_IN_RC(int_flags_ro)); 4898 match(RegFlags); 4899 match(flagsReg); 4900 match(flagsRegCR0); 4901 format %{ %} 4902 interface(REG_INTER); 4903 %} 4904 4905 // Condition Code Flag Register CR0 4906 operand flagsRegCR0() %{ 4907 constraint(ALLOC_IN_RC(int_flags_CR0)); 4908 match(RegFlags); 4909 format %{ "CR0" %} 4910 interface(REG_INTER); 4911 %} 4912 4913 operand flagsRegCR1() %{ 4914 constraint(ALLOC_IN_RC(int_flags_CR1)); 4915 match(RegFlags); 4916 format %{ "CR1" %} 4917 interface(REG_INTER); 4918 %} 4919 4920 operand flagsRegCR6() %{ 4921 constraint(ALLOC_IN_RC(int_flags_CR6)); 4922 match(RegFlags); 4923 format %{ "CR6" %} 4924 interface(REG_INTER); 4925 %} 4926 4927 operand regCTR() %{ 4928 constraint(ALLOC_IN_RC(ctr_reg)); 4929 // RegFlags should work. Introducing a RegSpecial type would cause a 4930 // lot of changes. 4931 match(RegFlags); 4932 format %{"SR_CTR" %} 4933 interface(REG_INTER); 4934 %} 4935 4936 operand regD() %{ 4937 constraint(ALLOC_IN_RC(dbl_reg)); 4938 match(RegD); 4939 format %{ %} 4940 interface(REG_INTER); 4941 %} 4942 4943 operand regF() %{ 4944 constraint(ALLOC_IN_RC(flt_reg)); 4945 match(RegF); 4946 format %{ %} 4947 interface(REG_INTER); 4948 %} 4949 4950 // Special Registers 4951 4952 // Method Register 4953 operand inline_cache_regP(iRegPdst reg) %{ 4954 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4955 match(reg); 4956 format %{ %} 4957 interface(REG_INTER); 4958 %} 4959 4960 operand compiler_method_oop_regP(iRegPdst reg) %{ 4961 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4962 match(reg); 4963 format %{ %} 4964 interface(REG_INTER); 4965 %} 4966 4967 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4968 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4969 match(reg); 4970 format %{ %} 4971 interface(REG_INTER); 4972 %} 4973 4974 // Operands to remove register moves in unscaled mode. 4975 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4976 operand iRegP2N(iRegPsrc reg) %{ 4977 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4978 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4979 match(EncodeP reg); 4980 format %{ "$reg" %} 4981 interface(REG_INTER) 4982 %} 4983 4984 operand iRegN2P(iRegNsrc reg) %{ 4985 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4986 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4987 match(DecodeN reg); 4988 format %{ "$reg" %} 4989 interface(REG_INTER) 4990 %} 4991 4992 operand iRegN2P_klass(iRegNsrc reg) %{ 4993 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4994 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4995 match(DecodeNKlass reg); 4996 format %{ "$reg" %} 4997 interface(REG_INTER) 4998 %} 4999 5000 //----------Complex Operands--------------------------------------------------- 5001 // Indirect Memory Reference 5002 operand indirect(iRegPsrc reg) %{ 5003 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5004 match(reg); 5005 op_cost(100); 5006 format %{ "[$reg]" %} 5007 interface(MEMORY_INTER) %{ 5008 base($reg); 5009 index(0x0); 5010 scale(0x0); 5011 disp(0x0); 5012 %} 5013 %} 5014 5015 // Indirect with Offset 5016 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 5017 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5018 match(AddP reg offset); 5019 op_cost(100); 5020 format %{ "[$reg + $offset]" %} 5021 interface(MEMORY_INTER) %{ 5022 base($reg); 5023 index(0x0); 5024 scale(0x0); 5025 disp($offset); 5026 %} 5027 %} 5028 5029 // Indirect with 4-aligned Offset 5030 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 5031 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5032 match(AddP reg offset); 5033 op_cost(100); 5034 format %{ "[$reg + $offset]" %} 5035 interface(MEMORY_INTER) %{ 5036 base($reg); 5037 index(0x0); 5038 scale(0x0); 5039 disp($offset); 5040 %} 5041 %} 5042 5043 //----------Complex Operands for Compressed OOPs------------------------------- 5044 // Compressed OOPs with narrow_oop_shift == 0. 5045 5046 // Indirect Memory Reference, compressed OOP 5047 operand indirectNarrow(iRegNsrc reg) %{ 5048 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5049 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5050 match(DecodeN reg); 5051 op_cost(100); 5052 format %{ "[$reg]" %} 5053 interface(MEMORY_INTER) %{ 5054 base($reg); 5055 index(0x0); 5056 scale(0x0); 5057 disp(0x0); 5058 %} 5059 %} 5060 5061 operand indirectNarrow_klass(iRegNsrc reg) %{ 5062 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5063 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5064 match(DecodeNKlass reg); 5065 op_cost(100); 5066 format %{ "[$reg]" %} 5067 interface(MEMORY_INTER) %{ 5068 base($reg); 5069 index(0x0); 5070 scale(0x0); 5071 disp(0x0); 5072 %} 5073 %} 5074 5075 // Indirect with Offset, compressed OOP 5076 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 5077 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5078 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5079 match(AddP (DecodeN reg) offset); 5080 op_cost(100); 5081 format %{ "[$reg + $offset]" %} 5082 interface(MEMORY_INTER) %{ 5083 base($reg); 5084 index(0x0); 5085 scale(0x0); 5086 disp($offset); 5087 %} 5088 %} 5089 5090 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5091 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5092 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5093 match(AddP (DecodeNKlass reg) offset); 5094 op_cost(100); 5095 format %{ "[$reg + $offset]" %} 5096 interface(MEMORY_INTER) %{ 5097 base($reg); 5098 index(0x0); 5099 scale(0x0); 5100 disp($offset); 5101 %} 5102 %} 5103 5104 // Indirect with 4-aligned Offset, compressed OOP 5105 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 5106 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5107 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5108 match(AddP (DecodeN reg) offset); 5109 op_cost(100); 5110 format %{ "[$reg + $offset]" %} 5111 interface(MEMORY_INTER) %{ 5112 base($reg); 5113 index(0x0); 5114 scale(0x0); 5115 disp($offset); 5116 %} 5117 %} 5118 5119 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5120 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5121 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5122 match(AddP (DecodeNKlass reg) offset); 5123 op_cost(100); 5124 format %{ "[$reg + $offset]" %} 5125 interface(MEMORY_INTER) %{ 5126 base($reg); 5127 index(0x0); 5128 scale(0x0); 5129 disp($offset); 5130 %} 5131 %} 5132 5133 //----------Special Memory Operands-------------------------------------------- 5134 // Stack Slot Operand 5135 // 5136 // This operand is used for loading and storing temporary values on 5137 // the stack where a match requires a value to flow through memory. 5138 operand stackSlotI(sRegI reg) %{ 5139 constraint(ALLOC_IN_RC(stack_slots)); 5140 op_cost(100); 5141 //match(RegI); 5142 format %{ "[sp+$reg]" %} 5143 interface(MEMORY_INTER) %{ 5144 base(0x1); // R1_SP 5145 index(0x0); 5146 scale(0x0); 5147 disp($reg); // Stack Offset 5148 %} 5149 %} 5150 5151 operand stackSlotL(sRegL reg) %{ 5152 constraint(ALLOC_IN_RC(stack_slots)); 5153 op_cost(100); 5154 //match(RegL); 5155 format %{ "[sp+$reg]" %} 5156 interface(MEMORY_INTER) %{ 5157 base(0x1); // R1_SP 5158 index(0x0); 5159 scale(0x0); 5160 disp($reg); // Stack Offset 5161 %} 5162 %} 5163 5164 operand stackSlotP(sRegP reg) %{ 5165 constraint(ALLOC_IN_RC(stack_slots)); 5166 op_cost(100); 5167 //match(RegP); 5168 format %{ "[sp+$reg]" %} 5169 interface(MEMORY_INTER) %{ 5170 base(0x1); // R1_SP 5171 index(0x0); 5172 scale(0x0); 5173 disp($reg); // Stack Offset 5174 %} 5175 %} 5176 5177 operand stackSlotF(sRegF reg) %{ 5178 constraint(ALLOC_IN_RC(stack_slots)); 5179 op_cost(100); 5180 //match(RegF); 5181 format %{ "[sp+$reg]" %} 5182 interface(MEMORY_INTER) %{ 5183 base(0x1); // R1_SP 5184 index(0x0); 5185 scale(0x0); 5186 disp($reg); // Stack Offset 5187 %} 5188 %} 5189 5190 operand stackSlotD(sRegD reg) %{ 5191 constraint(ALLOC_IN_RC(stack_slots)); 5192 op_cost(100); 5193 //match(RegD); 5194 format %{ "[sp+$reg]" %} 5195 interface(MEMORY_INTER) %{ 5196 base(0x1); // R1_SP 5197 index(0x0); 5198 scale(0x0); 5199 disp($reg); // Stack Offset 5200 %} 5201 %} 5202 5203 // Operands for expressing Control Flow 5204 // NOTE: Label is a predefined operand which should not be redefined in 5205 // the AD file. It is generically handled within the ADLC. 5206 5207 //----------Conditional Branch Operands---------------------------------------- 5208 // Comparison Op 5209 // 5210 // This is the operation of the comparison, and is limited to the 5211 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5212 // (!=). 5213 // 5214 // Other attributes of the comparison, such as unsignedness, are specified 5215 // by the comparison instruction that sets a condition code flags register. 5216 // That result is represented by a flags operand whose subtype is appropriate 5217 // to the unsignedness (etc.) of the comparison. 5218 // 5219 // Later, the instruction which matches both the Comparison Op (a Bool) and 5220 // the flags (produced by the Cmp) specifies the coding of the comparison op 5221 // by matching a specific subtype of Bool operand below. 5222 5223 // When used for floating point comparisons: unordered same as less. 5224 operand cmpOp() %{ 5225 match(Bool); 5226 format %{ "" %} 5227 interface(COND_INTER) %{ 5228 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5229 // BO & BI 5230 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5231 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5232 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5233 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5234 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5235 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5236 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5237 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5238 %} 5239 %} 5240 5241 //----------OPERAND CLASSES---------------------------------------------------- 5242 // Operand Classes are groups of operands that are used to simplify 5243 // instruction definitions by not requiring the AD writer to specify 5244 // seperate instructions for every form of operand when the 5245 // instruction accepts multiple operand types with the same basic 5246 // encoding and format. The classic case of this is memory operands. 5247 // Indirect is not included since its use is limited to Compare & Swap. 5248 5249 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5250 // Memory operand where offsets are 4-aligned. Required for ld, std. 5251 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5252 opclass indirectMemory(indirect, indirectNarrow); 5253 5254 // Special opclass for I and ConvL2I. 5255 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5256 5257 // Operand classes to match encode and decode. iRegN_P2N is only used 5258 // for storeN. I have never seen an encode node elsewhere. 5259 opclass iRegN_P2N(iRegNsrc, iRegP2N); 5260 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5261 5262 //----------PIPELINE----------------------------------------------------------- 5263 5264 pipeline %{ 5265 5266 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5267 // J. Res. & Dev., No. 1, Jan. 2002. 5268 5269 //----------ATTRIBUTES--------------------------------------------------------- 5270 attributes %{ 5271 5272 // Power4 instructions are of fixed length. 5273 fixed_size_instructions; 5274 5275 // TODO: if `bundle' means number of instructions fetched 5276 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5277 // max instructions issued per cycle, this is 5. 5278 max_instructions_per_bundle = 8; 5279 5280 // A Power4 instruction is 4 bytes long. 5281 instruction_unit_size = 4; 5282 5283 // The Power4 processor fetches 64 bytes... 5284 instruction_fetch_unit_size = 64; 5285 5286 // ...in one line 5287 instruction_fetch_units = 1 5288 5289 // Unused, list one so that array generated by adlc is not empty. 5290 // Aix compiler chokes if _nop_count = 0. 5291 nops(fxNop); 5292 %} 5293 5294 //----------RESOURCES---------------------------------------------------------- 5295 // Resources are the functional units available to the machine 5296 resources( 5297 PPC_BR, // branch unit 5298 PPC_CR, // condition unit 5299 PPC_FX1, // integer arithmetic unit 1 5300 PPC_FX2, // integer arithmetic unit 2 5301 PPC_LDST1, // load/store unit 1 5302 PPC_LDST2, // load/store unit 2 5303 PPC_FP1, // float arithmetic unit 1 5304 PPC_FP2, // float arithmetic unit 2 5305 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5306 PPC_FX = PPC_FX1 | PPC_FX2, 5307 PPC_FP = PPC_FP1 | PPC_FP2 5308 ); 5309 5310 //----------PIPELINE DESCRIPTION----------------------------------------------- 5311 // Pipeline Description specifies the stages in the machine's pipeline 5312 pipe_desc( 5313 // Power4 longest pipeline path 5314 PPC_IF, // instruction fetch 5315 PPC_IC, 5316 //PPC_BP, // branch prediction 5317 PPC_D0, // decode 5318 PPC_D1, // decode 5319 PPC_D2, // decode 5320 PPC_D3, // decode 5321 PPC_Xfer1, 5322 PPC_GD, // group definition 5323 PPC_MP, // map 5324 PPC_ISS, // issue 5325 PPC_RF, // resource fetch 5326 PPC_EX1, // execute (all units) 5327 PPC_EX2, // execute (FP, LDST) 5328 PPC_EX3, // execute (FP, LDST) 5329 PPC_EX4, // execute (FP) 5330 PPC_EX5, // execute (FP) 5331 PPC_EX6, // execute (FP) 5332 PPC_WB, // write back 5333 PPC_Xfer2, 5334 PPC_CP 5335 ); 5336 5337 //----------PIPELINE CLASSES--------------------------------------------------- 5338 // Pipeline Classes describe the stages in which input and output are 5339 // referenced by the hardware pipeline. 5340 5341 // Simple pipeline classes. 5342 5343 // Default pipeline class. 5344 pipe_class pipe_class_default() %{ 5345 single_instruction; 5346 fixed_latency(2); 5347 %} 5348 5349 // Pipeline class for empty instructions. 5350 pipe_class pipe_class_empty() %{ 5351 single_instruction; 5352 fixed_latency(0); 5353 %} 5354 5355 // Pipeline class for compares. 5356 pipe_class pipe_class_compare() %{ 5357 single_instruction; 5358 fixed_latency(16); 5359 %} 5360 5361 // Pipeline class for traps. 5362 pipe_class pipe_class_trap() %{ 5363 single_instruction; 5364 fixed_latency(100); 5365 %} 5366 5367 // Pipeline class for memory operations. 5368 pipe_class pipe_class_memory() %{ 5369 single_instruction; 5370 fixed_latency(16); 5371 %} 5372 5373 // Pipeline class for call. 5374 pipe_class pipe_class_call() %{ 5375 single_instruction; 5376 fixed_latency(100); 5377 %} 5378 5379 // Define the class for the Nop node. 5380 define %{ 5381 MachNop = pipe_class_default; 5382 %} 5383 5384 %} 5385 5386 //----------INSTRUCTIONS------------------------------------------------------- 5387 5388 // Naming of instructions: 5389 // opA_operB / opA_operB_operC: 5390 // Operation 'op' with one or two source operands 'oper'. Result 5391 // type is A, source operand types are B and C. 5392 // Iff A == B == C, B and C are left out. 5393 // 5394 // The instructions are ordered according to the following scheme: 5395 // - loads 5396 // - load constants 5397 // - prefetch 5398 // - store 5399 // - encode/decode 5400 // - membar 5401 // - conditional moves 5402 // - compare & swap 5403 // - arithmetic and logic operations 5404 // * int: Add, Sub, Mul, Div, Mod 5405 // * int: lShift, arShift, urShift, rot 5406 // * float: Add, Sub, Mul, Div 5407 // * and, or, xor ... 5408 // - register moves: float <-> int, reg <-> stack, repl 5409 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5410 // - conv (low level type cast requiring bit changes (sign extend etc) 5411 // - compares, range & zero checks. 5412 // - branches 5413 // - complex operations, intrinsics, min, max, replicate 5414 // - lock 5415 // - Calls 5416 // 5417 // If there are similar instructions with different types they are sorted: 5418 // int before float 5419 // small before big 5420 // signed before unsigned 5421 // e.g., loadS before loadUS before loadI before loadF. 5422 5423 5424 //----------Load/Store Instructions-------------------------------------------- 5425 5426 //----------Load Instructions-------------------------------------------------- 5427 5428 // Converts byte to int. 5429 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5430 // reuses the 'amount' operand, but adlc expects that operand specification 5431 // and operands in match rule are equivalent. 5432 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5433 effect(DEF dst, USE src); 5434 format %{ "EXTSB $dst, $src \t// byte->int" %} 5435 size(4); 5436 ins_encode %{ 5437 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5438 __ extsb($dst$$Register, $src$$Register); 5439 %} 5440 ins_pipe(pipe_class_default); 5441 %} 5442 5443 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5444 // match-rule, false predicate 5445 match(Set dst (LoadB mem)); 5446 predicate(false); 5447 5448 format %{ "LBZ $dst, $mem" %} 5449 size(4); 5450 ins_encode( enc_lbz(dst, mem) ); 5451 ins_pipe(pipe_class_memory); 5452 %} 5453 5454 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5455 // match-rule, false predicate 5456 match(Set dst (LoadB mem)); 5457 predicate(false); 5458 5459 format %{ "LBZ $dst, $mem\n\t" 5460 "TWI $dst\n\t" 5461 "ISYNC" %} 5462 size(12); 5463 ins_encode( enc_lbz_ac(dst, mem) ); 5464 ins_pipe(pipe_class_memory); 5465 %} 5466 5467 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5468 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5469 match(Set dst (LoadB mem)); 5470 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5471 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5472 expand %{ 5473 iRegIdst tmp; 5474 loadUB_indirect(tmp, mem); 5475 convB2I_reg_2(dst, tmp); 5476 %} 5477 %} 5478 5479 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5480 match(Set dst (LoadB mem)); 5481 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5482 expand %{ 5483 iRegIdst tmp; 5484 loadUB_indirect_ac(tmp, mem); 5485 convB2I_reg_2(dst, tmp); 5486 %} 5487 %} 5488 5489 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5490 // match-rule, false predicate 5491 match(Set dst (LoadB mem)); 5492 predicate(false); 5493 5494 format %{ "LBZ $dst, $mem" %} 5495 size(4); 5496 ins_encode( enc_lbz(dst, mem) ); 5497 ins_pipe(pipe_class_memory); 5498 %} 5499 5500 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5501 // match-rule, false predicate 5502 match(Set dst (LoadB mem)); 5503 predicate(false); 5504 5505 format %{ "LBZ $dst, $mem\n\t" 5506 "TWI $dst\n\t" 5507 "ISYNC" %} 5508 size(12); 5509 ins_encode( enc_lbz_ac(dst, mem) ); 5510 ins_pipe(pipe_class_memory); 5511 %} 5512 5513 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5514 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5515 match(Set dst (LoadB mem)); 5516 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5517 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5518 5519 expand %{ 5520 iRegIdst tmp; 5521 loadUB_indOffset16(tmp, mem); 5522 convB2I_reg_2(dst, tmp); 5523 %} 5524 %} 5525 5526 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5527 match(Set dst (LoadB mem)); 5528 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5529 5530 expand %{ 5531 iRegIdst tmp; 5532 loadUB_indOffset16_ac(tmp, mem); 5533 convB2I_reg_2(dst, tmp); 5534 %} 5535 %} 5536 5537 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5538 instruct loadUB(iRegIdst dst, memory mem) %{ 5539 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5540 match(Set dst (LoadUB mem)); 5541 ins_cost(MEMORY_REF_COST); 5542 5543 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5544 size(4); 5545 ins_encode( enc_lbz(dst, mem) ); 5546 ins_pipe(pipe_class_memory); 5547 %} 5548 5549 // Load Unsigned Byte (8bit UNsigned) acquire. 5550 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5551 match(Set dst (LoadUB mem)); 5552 ins_cost(3*MEMORY_REF_COST); 5553 5554 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5555 "TWI $dst\n\t" 5556 "ISYNC" %} 5557 size(12); 5558 ins_encode( enc_lbz_ac(dst, mem) ); 5559 ins_pipe(pipe_class_memory); 5560 %} 5561 5562 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5563 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5564 match(Set dst (ConvI2L (LoadUB mem))); 5565 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5566 ins_cost(MEMORY_REF_COST); 5567 5568 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5569 size(4); 5570 ins_encode( enc_lbz(dst, mem) ); 5571 ins_pipe(pipe_class_memory); 5572 %} 5573 5574 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5575 match(Set dst (ConvI2L (LoadUB mem))); 5576 ins_cost(3*MEMORY_REF_COST); 5577 5578 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5579 "TWI $dst\n\t" 5580 "ISYNC" %} 5581 size(12); 5582 ins_encode( enc_lbz_ac(dst, mem) ); 5583 ins_pipe(pipe_class_memory); 5584 %} 5585 5586 // Load Short (16bit signed) 5587 instruct loadS(iRegIdst dst, memory mem) %{ 5588 match(Set dst (LoadS mem)); 5589 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5590 ins_cost(MEMORY_REF_COST); 5591 5592 format %{ "LHA $dst, $mem" %} 5593 size(4); 5594 ins_encode %{ 5595 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5596 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5597 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5598 %} 5599 ins_pipe(pipe_class_memory); 5600 %} 5601 5602 // Load Short (16bit signed) acquire. 5603 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5604 match(Set dst (LoadS mem)); 5605 ins_cost(3*MEMORY_REF_COST); 5606 5607 format %{ "LHA $dst, $mem\t acquire\n\t" 5608 "TWI $dst\n\t" 5609 "ISYNC" %} 5610 size(12); 5611 ins_encode %{ 5612 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5613 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5614 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5615 __ twi_0($dst$$Register); 5616 __ isync(); 5617 %} 5618 ins_pipe(pipe_class_memory); 5619 %} 5620 5621 // Load Char (16bit unsigned) 5622 instruct loadUS(iRegIdst dst, memory mem) %{ 5623 match(Set dst (LoadUS mem)); 5624 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5625 ins_cost(MEMORY_REF_COST); 5626 5627 format %{ "LHZ $dst, $mem" %} 5628 size(4); 5629 ins_encode( enc_lhz(dst, mem) ); 5630 ins_pipe(pipe_class_memory); 5631 %} 5632 5633 // Load Char (16bit unsigned) acquire. 5634 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5635 match(Set dst (LoadUS mem)); 5636 ins_cost(3*MEMORY_REF_COST); 5637 5638 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5639 "TWI $dst\n\t" 5640 "ISYNC" %} 5641 size(12); 5642 ins_encode( enc_lhz_ac(dst, mem) ); 5643 ins_pipe(pipe_class_memory); 5644 %} 5645 5646 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5647 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5648 match(Set dst (ConvI2L (LoadUS mem))); 5649 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5650 ins_cost(MEMORY_REF_COST); 5651 5652 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5653 size(4); 5654 ins_encode( enc_lhz(dst, mem) ); 5655 ins_pipe(pipe_class_memory); 5656 %} 5657 5658 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5659 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5660 match(Set dst (ConvI2L (LoadUS mem))); 5661 ins_cost(3*MEMORY_REF_COST); 5662 5663 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5664 "TWI $dst\n\t" 5665 "ISYNC" %} 5666 size(12); 5667 ins_encode( enc_lhz_ac(dst, mem) ); 5668 ins_pipe(pipe_class_memory); 5669 %} 5670 5671 // Load Integer. 5672 instruct loadI(iRegIdst dst, memory mem) %{ 5673 match(Set dst (LoadI mem)); 5674 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5675 ins_cost(MEMORY_REF_COST); 5676 5677 format %{ "LWZ $dst, $mem" %} 5678 size(4); 5679 ins_encode( enc_lwz(dst, mem) ); 5680 ins_pipe(pipe_class_memory); 5681 %} 5682 5683 // Load Integer acquire. 5684 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5685 match(Set dst (LoadI mem)); 5686 ins_cost(3*MEMORY_REF_COST); 5687 5688 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5689 "TWI $dst\n\t" 5690 "ISYNC" %} 5691 size(12); 5692 ins_encode( enc_lwz_ac(dst, mem) ); 5693 ins_pipe(pipe_class_memory); 5694 %} 5695 5696 // Match loading integer and casting it to unsigned int in 5697 // long register. 5698 // LoadI + ConvI2L + AndL 0xffffffff. 5699 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5700 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5701 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5702 ins_cost(MEMORY_REF_COST); 5703 5704 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5705 size(4); 5706 ins_encode( enc_lwz(dst, mem) ); 5707 ins_pipe(pipe_class_memory); 5708 %} 5709 5710 // Match loading integer and casting it to long. 5711 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5712 match(Set dst (ConvI2L (LoadI mem))); 5713 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5714 ins_cost(MEMORY_REF_COST); 5715 5716 format %{ "LWA $dst, $mem \t// loadI2L" %} 5717 size(4); 5718 ins_encode %{ 5719 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5720 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5721 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5722 %} 5723 ins_pipe(pipe_class_memory); 5724 %} 5725 5726 // Match loading integer and casting it to long - acquire. 5727 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5728 match(Set dst (ConvI2L (LoadI mem))); 5729 ins_cost(3*MEMORY_REF_COST); 5730 5731 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5732 "TWI $dst\n\t" 5733 "ISYNC" %} 5734 size(12); 5735 ins_encode %{ 5736 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5737 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5738 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5739 __ twi_0($dst$$Register); 5740 __ isync(); 5741 %} 5742 ins_pipe(pipe_class_memory); 5743 %} 5744 5745 // Load Long - aligned 5746 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5747 match(Set dst (LoadL mem)); 5748 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5749 ins_cost(MEMORY_REF_COST); 5750 5751 format %{ "LD $dst, $mem \t// long" %} 5752 size(4); 5753 ins_encode( enc_ld(dst, mem) ); 5754 ins_pipe(pipe_class_memory); 5755 %} 5756 5757 // Load Long - aligned acquire. 5758 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5759 match(Set dst (LoadL mem)); 5760 ins_cost(3*MEMORY_REF_COST); 5761 5762 format %{ "LD $dst, $mem \t// long acquire\n\t" 5763 "TWI $dst\n\t" 5764 "ISYNC" %} 5765 size(12); 5766 ins_encode( enc_ld_ac(dst, mem) ); 5767 ins_pipe(pipe_class_memory); 5768 %} 5769 5770 // Load Long - UNaligned 5771 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5772 match(Set dst (LoadL_unaligned mem)); 5773 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5774 ins_cost(MEMORY_REF_COST); 5775 5776 format %{ "LD $dst, $mem \t// unaligned long" %} 5777 size(4); 5778 ins_encode( enc_ld(dst, mem) ); 5779 ins_pipe(pipe_class_memory); 5780 %} 5781 5782 // Load nodes for superwords 5783 5784 // Load Aligned Packed Byte 5785 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5786 predicate(n->as_LoadVector()->memory_size() == 8); 5787 match(Set dst (LoadVector mem)); 5788 ins_cost(MEMORY_REF_COST); 5789 5790 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5791 size(4); 5792 ins_encode( enc_ld(dst, mem) ); 5793 ins_pipe(pipe_class_memory); 5794 %} 5795 5796 // Load Aligned Packed Byte 5797 instruct loadV16(vecX dst, indirect mem) %{ 5798 predicate(n->as_LoadVector()->memory_size() == 16); 5799 match(Set dst (LoadVector mem)); 5800 ins_cost(MEMORY_REF_COST); 5801 5802 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5803 size(4); 5804 ins_encode %{ 5805 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5806 %} 5807 ins_pipe(pipe_class_default); 5808 %} 5809 5810 // Load Range, range = array length (=jint) 5811 instruct loadRange(iRegIdst dst, memory mem) %{ 5812 match(Set dst (LoadRange mem)); 5813 ins_cost(MEMORY_REF_COST); 5814 5815 format %{ "LWZ $dst, $mem \t// range" %} 5816 size(4); 5817 ins_encode( enc_lwz(dst, mem) ); 5818 ins_pipe(pipe_class_memory); 5819 %} 5820 5821 // Load Compressed Pointer 5822 instruct loadN(iRegNdst dst, memory mem) %{ 5823 match(Set dst (LoadN mem)); 5824 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5825 ins_cost(MEMORY_REF_COST); 5826 5827 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5828 size(4); 5829 ins_encode( enc_lwz(dst, mem) ); 5830 ins_pipe(pipe_class_memory); 5831 %} 5832 5833 // Load Compressed Pointer acquire. 5834 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5835 match(Set dst (LoadN mem)); 5836 ins_cost(3*MEMORY_REF_COST); 5837 5838 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5839 "TWI $dst\n\t" 5840 "ISYNC" %} 5841 size(12); 5842 ins_encode( enc_lwz_ac(dst, mem) ); 5843 ins_pipe(pipe_class_memory); 5844 %} 5845 5846 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5847 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5848 match(Set dst (DecodeN (LoadN mem))); 5849 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5850 ins_cost(MEMORY_REF_COST); 5851 5852 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5853 size(4); 5854 ins_encode( enc_lwz(dst, mem) ); 5855 ins_pipe(pipe_class_memory); 5856 %} 5857 5858 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5859 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5860 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5861 _kids[0]->_leaf->as_Load()->is_unordered()); 5862 ins_cost(MEMORY_REF_COST); 5863 5864 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5865 size(4); 5866 ins_encode( enc_lwz(dst, mem) ); 5867 ins_pipe(pipe_class_memory); 5868 %} 5869 5870 // Load Pointer 5871 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5872 match(Set dst (LoadP mem)); 5873 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5874 ins_cost(MEMORY_REF_COST); 5875 5876 format %{ "LD $dst, $mem \t// ptr" %} 5877 size(4); 5878 ins_encode( enc_ld(dst, mem) ); 5879 ins_pipe(pipe_class_memory); 5880 %} 5881 5882 // Load Pointer acquire. 5883 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5884 match(Set dst (LoadP mem)); 5885 ins_cost(3*MEMORY_REF_COST); 5886 5887 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5888 "TWI $dst\n\t" 5889 "ISYNC" %} 5890 size(12); 5891 ins_encode( enc_ld_ac(dst, mem) ); 5892 ins_pipe(pipe_class_memory); 5893 %} 5894 5895 // LoadP + CastP2L 5896 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5897 match(Set dst (CastP2X (LoadP mem))); 5898 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5899 ins_cost(MEMORY_REF_COST); 5900 5901 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5902 size(4); 5903 ins_encode( enc_ld(dst, mem) ); 5904 ins_pipe(pipe_class_memory); 5905 %} 5906 5907 // Load compressed klass pointer. 5908 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5909 match(Set dst (LoadNKlass mem)); 5910 ins_cost(MEMORY_REF_COST); 5911 5912 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5913 size(4); 5914 ins_encode( enc_lwz(dst, mem) ); 5915 ins_pipe(pipe_class_memory); 5916 %} 5917 5918 // Load Klass Pointer 5919 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5920 match(Set dst (LoadKlass mem)); 5921 ins_cost(MEMORY_REF_COST); 5922 5923 format %{ "LD $dst, $mem \t// klass ptr" %} 5924 size(4); 5925 ins_encode( enc_ld(dst, mem) ); 5926 ins_pipe(pipe_class_memory); 5927 %} 5928 5929 // Load Float 5930 instruct loadF(regF dst, memory mem) %{ 5931 match(Set dst (LoadF mem)); 5932 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5933 ins_cost(MEMORY_REF_COST); 5934 5935 format %{ "LFS $dst, $mem" %} 5936 size(4); 5937 ins_encode %{ 5938 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5939 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5940 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5941 %} 5942 ins_pipe(pipe_class_memory); 5943 %} 5944 5945 // Load Float acquire. 5946 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5947 match(Set dst (LoadF mem)); 5948 effect(TEMP cr0); 5949 ins_cost(3*MEMORY_REF_COST); 5950 5951 format %{ "LFS $dst, $mem \t// acquire\n\t" 5952 "FCMPU cr0, $dst, $dst\n\t" 5953 "BNE cr0, next\n" 5954 "next:\n\t" 5955 "ISYNC" %} 5956 size(16); 5957 ins_encode %{ 5958 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5959 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5960 Label next; 5961 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5962 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5963 __ bne(CCR0, next); 5964 __ bind(next); 5965 __ isync(); 5966 %} 5967 ins_pipe(pipe_class_memory); 5968 %} 5969 5970 // Load Double - aligned 5971 instruct loadD(regD dst, memory mem) %{ 5972 match(Set dst (LoadD mem)); 5973 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5974 ins_cost(MEMORY_REF_COST); 5975 5976 format %{ "LFD $dst, $mem" %} 5977 size(4); 5978 ins_encode( enc_lfd(dst, mem) ); 5979 ins_pipe(pipe_class_memory); 5980 %} 5981 5982 // Load Double - aligned acquire. 5983 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5984 match(Set dst (LoadD mem)); 5985 effect(TEMP cr0); 5986 ins_cost(3*MEMORY_REF_COST); 5987 5988 format %{ "LFD $dst, $mem \t// acquire\n\t" 5989 "FCMPU cr0, $dst, $dst\n\t" 5990 "BNE cr0, next\n" 5991 "next:\n\t" 5992 "ISYNC" %} 5993 size(16); 5994 ins_encode %{ 5995 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5996 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5997 Label next; 5998 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5999 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 6000 __ bne(CCR0, next); 6001 __ bind(next); 6002 __ isync(); 6003 %} 6004 ins_pipe(pipe_class_memory); 6005 %} 6006 6007 // Load Double - UNaligned 6008 instruct loadD_unaligned(regD dst, memory mem) %{ 6009 match(Set dst (LoadD_unaligned mem)); 6010 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 6011 ins_cost(MEMORY_REF_COST); 6012 6013 format %{ "LFD $dst, $mem" %} 6014 size(4); 6015 ins_encode( enc_lfd(dst, mem) ); 6016 ins_pipe(pipe_class_memory); 6017 %} 6018 6019 //----------Constants-------------------------------------------------------- 6020 6021 // Load MachConstantTableBase: add hi offset to global toc. 6022 // TODO: Handle hidden register r29 in bundler! 6023 instruct loadToc_hi(iRegLdst dst) %{ 6024 effect(DEF dst); 6025 ins_cost(DEFAULT_COST); 6026 6027 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 6028 size(4); 6029 ins_encode %{ 6030 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6031 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 6032 %} 6033 ins_pipe(pipe_class_default); 6034 %} 6035 6036 // Load MachConstantTableBase: add lo offset to global toc. 6037 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 6038 effect(DEF dst, USE src); 6039 ins_cost(DEFAULT_COST); 6040 6041 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 6042 size(4); 6043 ins_encode %{ 6044 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6045 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 6046 %} 6047 ins_pipe(pipe_class_default); 6048 %} 6049 6050 // Load 16-bit integer constant 0xssss???? 6051 instruct loadConI16(iRegIdst dst, immI16 src) %{ 6052 match(Set dst src); 6053 6054 format %{ "LI $dst, $src" %} 6055 size(4); 6056 ins_encode %{ 6057 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6058 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6059 %} 6060 ins_pipe(pipe_class_default); 6061 %} 6062 6063 // Load integer constant 0x????0000 6064 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 6065 match(Set dst src); 6066 ins_cost(DEFAULT_COST); 6067 6068 format %{ "LIS $dst, $src.hi" %} 6069 size(4); 6070 ins_encode %{ 6071 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6072 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 6073 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6074 %} 6075 ins_pipe(pipe_class_default); 6076 %} 6077 6078 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 6079 // and sign extended), this adds the low 16 bits. 6080 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6081 // no match-rule, false predicate 6082 effect(DEF dst, USE src1, USE src2); 6083 predicate(false); 6084 6085 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6086 size(4); 6087 ins_encode %{ 6088 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6089 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6090 %} 6091 ins_pipe(pipe_class_default); 6092 %} 6093 6094 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6095 match(Set dst src); 6096 ins_cost(DEFAULT_COST*2); 6097 6098 expand %{ 6099 // Would like to use $src$$constant. 6100 immI16 srcLo %{ _opnds[1]->constant() %} 6101 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6102 immIhi16 srcHi %{ _opnds[1]->constant() %} 6103 iRegIdst tmpI; 6104 loadConIhi16(tmpI, srcHi); 6105 loadConI32_lo16(dst, tmpI, srcLo); 6106 %} 6107 %} 6108 6109 // No constant pool entries required. 6110 instruct loadConL16(iRegLdst dst, immL16 src) %{ 6111 match(Set dst src); 6112 6113 format %{ "LI $dst, $src \t// long" %} 6114 size(4); 6115 ins_encode %{ 6116 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6117 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6118 %} 6119 ins_pipe(pipe_class_default); 6120 %} 6121 6122 // Load long constant 0xssssssss????0000 6123 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6124 match(Set dst src); 6125 ins_cost(DEFAULT_COST); 6126 6127 format %{ "LIS $dst, $src.hi \t// long" %} 6128 size(4); 6129 ins_encode %{ 6130 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6131 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6132 %} 6133 ins_pipe(pipe_class_default); 6134 %} 6135 6136 // To load a 32 bit constant: merge lower 16 bits into already loaded 6137 // high 16 bits. 6138 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6139 // no match-rule, false predicate 6140 effect(DEF dst, USE src1, USE src2); 6141 predicate(false); 6142 6143 format %{ "ORI $dst, $src1, $src2.lo" %} 6144 size(4); 6145 ins_encode %{ 6146 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6147 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6148 %} 6149 ins_pipe(pipe_class_default); 6150 %} 6151 6152 // Load 32-bit long constant 6153 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6154 match(Set dst src); 6155 ins_cost(DEFAULT_COST*2); 6156 6157 expand %{ 6158 // Would like to use $src$$constant. 6159 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6160 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6161 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6162 iRegLdst tmpL; 6163 loadConL32hi16(tmpL, srcHi); 6164 loadConL32_lo16(dst, tmpL, srcLo); 6165 %} 6166 %} 6167 6168 // Load long constant 0x????000000000000. 6169 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6170 match(Set dst src); 6171 ins_cost(DEFAULT_COST); 6172 6173 expand %{ 6174 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6175 immI shift32 %{ 32 %} 6176 iRegLdst tmpL; 6177 loadConL32hi16(tmpL, srcHi); 6178 lshiftL_regL_immI(dst, tmpL, shift32); 6179 %} 6180 %} 6181 6182 // Expand node for constant pool load: small offset. 6183 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6184 effect(DEF dst, USE src, USE toc); 6185 ins_cost(MEMORY_REF_COST); 6186 6187 ins_num_consts(1); 6188 // Needed so that CallDynamicJavaDirect can compute the address of this 6189 // instruction for relocation. 6190 ins_field_cbuf_insts_offset(int); 6191 6192 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6193 size(4); 6194 ins_encode( enc_load_long_constL(dst, src, toc) ); 6195 ins_pipe(pipe_class_memory); 6196 %} 6197 6198 // Expand node for constant pool load: large offset. 6199 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6200 effect(DEF dst, USE src, USE toc); 6201 predicate(false); 6202 6203 ins_num_consts(1); 6204 ins_field_const_toc_offset(int); 6205 // Needed so that CallDynamicJavaDirect can compute the address of this 6206 // instruction for relocation. 6207 ins_field_cbuf_insts_offset(int); 6208 6209 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6210 size(4); 6211 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6212 ins_pipe(pipe_class_default); 6213 %} 6214 6215 // Expand node for constant pool load: large offset. 6216 // No constant pool entries required. 6217 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6218 effect(DEF dst, USE src, USE base); 6219 predicate(false); 6220 6221 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6222 6223 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6224 size(4); 6225 ins_encode %{ 6226 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6227 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6228 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6229 %} 6230 ins_pipe(pipe_class_memory); 6231 %} 6232 6233 // Load long constant from constant table. Expand in case of 6234 // offset > 16 bit is needed. 6235 // Adlc adds toc node MachConstantTableBase. 6236 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6237 match(Set dst src); 6238 ins_cost(MEMORY_REF_COST); 6239 6240 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6241 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6242 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6243 %} 6244 6245 // Load NULL as compressed oop. 6246 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6247 match(Set dst src); 6248 ins_cost(DEFAULT_COST); 6249 6250 format %{ "LI $dst, $src \t// compressed ptr" %} 6251 size(4); 6252 ins_encode %{ 6253 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6254 __ li($dst$$Register, 0); 6255 %} 6256 ins_pipe(pipe_class_default); 6257 %} 6258 6259 // Load hi part of compressed oop constant. 6260 instruct loadConN_hi(iRegNdst dst, immN src) %{ 6261 effect(DEF dst, USE src); 6262 ins_cost(DEFAULT_COST); 6263 6264 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6265 size(4); 6266 ins_encode %{ 6267 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6268 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6269 %} 6270 ins_pipe(pipe_class_default); 6271 %} 6272 6273 // Add lo part of compressed oop constant to already loaded hi part. 6274 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6275 effect(DEF dst, USE src1, USE src2); 6276 ins_cost(DEFAULT_COST); 6277 6278 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6279 size(4); 6280 ins_encode %{ 6281 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6282 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6283 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6284 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6285 __ relocate(rspec, 1); 6286 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6287 %} 6288 ins_pipe(pipe_class_default); 6289 %} 6290 6291 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6292 effect(DEF dst, USE src, USE shift, USE mask_begin); 6293 6294 size(4); 6295 ins_encode %{ 6296 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6297 %} 6298 ins_pipe(pipe_class_default); 6299 %} 6300 6301 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6302 // leaving the upper 32 bits with sign-extension bits. 6303 // This clears these bits: dst = src & 0xFFFFFFFF. 6304 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6305 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6306 effect(DEF dst, USE src); 6307 predicate(false); 6308 6309 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6310 size(4); 6311 ins_encode %{ 6312 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6313 __ clrldi($dst$$Register, $src$$Register, 0x20); 6314 %} 6315 ins_pipe(pipe_class_default); 6316 %} 6317 6318 // Optimize DecodeN for disjoint base. 6319 // Load base of compressed oops into a register 6320 instruct loadBase(iRegLdst dst) %{ 6321 effect(DEF dst); 6322 6323 format %{ "LoadConst $dst, heapbase" %} 6324 ins_encode %{ 6325 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6326 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 6327 %} 6328 ins_pipe(pipe_class_default); 6329 %} 6330 6331 // Loading ConN must be postalloc expanded so that edges between 6332 // the nodes are safe. They may not interfere with a safepoint. 6333 // GL TODO: This needs three instructions: better put this into the constant pool. 6334 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6335 match(Set dst src); 6336 ins_cost(DEFAULT_COST*2); 6337 6338 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6339 postalloc_expand %{ 6340 MachNode *m1 = new loadConN_hiNode(); 6341 MachNode *m2 = new loadConN_loNode(); 6342 MachNode *m3 = new clearMs32bNode(); 6343 m1->add_req(NULL); 6344 m2->add_req(NULL, m1); 6345 m3->add_req(NULL, m2); 6346 m1->_opnds[0] = op_dst; 6347 m1->_opnds[1] = op_src; 6348 m2->_opnds[0] = op_dst; 6349 m2->_opnds[1] = op_dst; 6350 m2->_opnds[2] = op_src; 6351 m3->_opnds[0] = op_dst; 6352 m3->_opnds[1] = op_dst; 6353 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6354 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6355 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6356 nodes->push(m1); 6357 nodes->push(m2); 6358 nodes->push(m3); 6359 %} 6360 %} 6361 6362 // We have seen a safepoint between the hi and lo parts, and this node was handled 6363 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6364 // not a narrow oop. 6365 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6366 match(Set dst src); 6367 effect(DEF dst, USE src); 6368 ins_cost(DEFAULT_COST); 6369 6370 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6371 size(4); 6372 ins_encode %{ 6373 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6374 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 6375 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6376 %} 6377 ins_pipe(pipe_class_default); 6378 %} 6379 6380 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6381 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6382 match(Set dst src1); 6383 effect(TEMP src2); 6384 ins_cost(DEFAULT_COST); 6385 6386 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6387 size(4); 6388 ins_encode %{ 6389 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6390 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6391 %} 6392 ins_pipe(pipe_class_default); 6393 %} 6394 6395 // This needs a match rule so that build_oop_map knows this is 6396 // not a narrow oop. 6397 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6398 match(Set dst src1); 6399 effect(TEMP src2); 6400 ins_cost(DEFAULT_COST); 6401 6402 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6403 size(4); 6404 ins_encode %{ 6405 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6406 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 6407 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6408 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6409 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6410 6411 __ relocate(rspec, 1); 6412 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6413 %} 6414 ins_pipe(pipe_class_default); 6415 %} 6416 6417 // Loading ConNKlass must be postalloc expanded so that edges between 6418 // the nodes are safe. They may not interfere with a safepoint. 6419 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6420 match(Set dst src); 6421 ins_cost(DEFAULT_COST*2); 6422 6423 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6424 postalloc_expand %{ 6425 // Load high bits into register. Sign extended. 6426 MachNode *m1 = new loadConNKlass_hiNode(); 6427 m1->add_req(NULL); 6428 m1->_opnds[0] = op_dst; 6429 m1->_opnds[1] = op_src; 6430 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6431 nodes->push(m1); 6432 6433 MachNode *m2 = m1; 6434 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 6435 // Value might be 1-extended. Mask out these bits. 6436 m2 = new loadConNKlass_maskNode(); 6437 m2->add_req(NULL, m1); 6438 m2->_opnds[0] = op_dst; 6439 m2->_opnds[1] = op_src; 6440 m2->_opnds[2] = op_dst; 6441 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6442 nodes->push(m2); 6443 } 6444 6445 MachNode *m3 = new loadConNKlass_loNode(); 6446 m3->add_req(NULL, m2); 6447 m3->_opnds[0] = op_dst; 6448 m3->_opnds[1] = op_src; 6449 m3->_opnds[2] = op_dst; 6450 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6451 nodes->push(m3); 6452 %} 6453 %} 6454 6455 // 0x1 is used in object initialization (initial object header). 6456 // No constant pool entries required. 6457 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6458 match(Set dst src); 6459 6460 format %{ "LI $dst, $src \t// ptr" %} 6461 size(4); 6462 ins_encode %{ 6463 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6464 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6465 %} 6466 ins_pipe(pipe_class_default); 6467 %} 6468 6469 // Expand node for constant pool load: small offset. 6470 // The match rule is needed to generate the correct bottom_type(), 6471 // however this node should never match. The use of predicate is not 6472 // possible since ADLC forbids predicates for chain rules. The higher 6473 // costs do not prevent matching in this case. For that reason the 6474 // operand immP_NM with predicate(false) is used. 6475 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6476 match(Set dst src); 6477 effect(TEMP toc); 6478 6479 ins_num_consts(1); 6480 6481 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6482 size(4); 6483 ins_encode( enc_load_long_constP(dst, src, toc) ); 6484 ins_pipe(pipe_class_memory); 6485 %} 6486 6487 // Expand node for constant pool load: large offset. 6488 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6489 effect(DEF dst, USE src, USE toc); 6490 predicate(false); 6491 6492 ins_num_consts(1); 6493 ins_field_const_toc_offset(int); 6494 6495 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6496 size(4); 6497 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6498 ins_pipe(pipe_class_default); 6499 %} 6500 6501 // Expand node for constant pool load: large offset. 6502 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6503 match(Set dst src); 6504 effect(TEMP base); 6505 6506 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6507 6508 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6509 size(4); 6510 ins_encode %{ 6511 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6512 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6513 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6514 %} 6515 ins_pipe(pipe_class_memory); 6516 %} 6517 6518 // Load pointer constant from constant table. Expand in case an 6519 // offset > 16 bit is needed. 6520 // Adlc adds toc node MachConstantTableBase. 6521 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6522 match(Set dst src); 6523 ins_cost(MEMORY_REF_COST); 6524 6525 // This rule does not use "expand" because then 6526 // the result type is not known to be an Oop. An ADLC 6527 // enhancement will be needed to make that work - not worth it! 6528 6529 // If this instruction rematerializes, it prolongs the live range 6530 // of the toc node, causing illegal graphs. 6531 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6532 ins_cannot_rematerialize(true); 6533 6534 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6535 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6536 %} 6537 6538 // Expand node for constant pool load: small offset. 6539 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6540 effect(DEF dst, USE src, USE toc); 6541 ins_cost(MEMORY_REF_COST); 6542 6543 ins_num_consts(1); 6544 6545 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6546 size(4); 6547 ins_encode %{ 6548 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6549 address float_address = __ float_constant($src$$constant); 6550 if (float_address == NULL) { 6551 ciEnv::current()->record_out_of_memory_failure(); 6552 return; 6553 } 6554 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6555 %} 6556 ins_pipe(pipe_class_memory); 6557 %} 6558 6559 // Expand node for constant pool load: large offset. 6560 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6561 effect(DEF dst, USE src, USE toc); 6562 ins_cost(MEMORY_REF_COST); 6563 6564 ins_num_consts(1); 6565 6566 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6567 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6568 "ADDIS $toc, $toc, -offset_hi"%} 6569 size(12); 6570 ins_encode %{ 6571 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6572 FloatRegister Rdst = $dst$$FloatRegister; 6573 Register Rtoc = $toc$$Register; 6574 address float_address = __ float_constant($src$$constant); 6575 if (float_address == NULL) { 6576 ciEnv::current()->record_out_of_memory_failure(); 6577 return; 6578 } 6579 int offset = __ offset_to_method_toc(float_address); 6580 int hi = (offset + (1<<15))>>16; 6581 int lo = offset - hi * (1<<16); 6582 6583 __ addis(Rtoc, Rtoc, hi); 6584 __ lfs(Rdst, lo, Rtoc); 6585 __ addis(Rtoc, Rtoc, -hi); 6586 %} 6587 ins_pipe(pipe_class_memory); 6588 %} 6589 6590 // Adlc adds toc node MachConstantTableBase. 6591 instruct loadConF_Ex(regF dst, immF src) %{ 6592 match(Set dst src); 6593 ins_cost(MEMORY_REF_COST); 6594 6595 // See loadConP. 6596 ins_cannot_rematerialize(true); 6597 6598 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6599 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6600 %} 6601 6602 // Expand node for constant pool load: small offset. 6603 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6604 effect(DEF dst, USE src, USE toc); 6605 ins_cost(MEMORY_REF_COST); 6606 6607 ins_num_consts(1); 6608 6609 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6610 size(4); 6611 ins_encode %{ 6612 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6613 address float_address = __ double_constant($src$$constant); 6614 if (float_address == NULL) { 6615 ciEnv::current()->record_out_of_memory_failure(); 6616 return; 6617 } 6618 int offset = __ offset_to_method_toc(float_address); 6619 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6620 %} 6621 ins_pipe(pipe_class_memory); 6622 %} 6623 6624 // Expand node for constant pool load: large offset. 6625 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6626 effect(DEF dst, USE src, USE toc); 6627 ins_cost(MEMORY_REF_COST); 6628 6629 ins_num_consts(1); 6630 6631 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6632 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6633 "ADDIS $toc, $toc, -offset_hi" %} 6634 size(12); 6635 ins_encode %{ 6636 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6637 FloatRegister Rdst = $dst$$FloatRegister; 6638 Register Rtoc = $toc$$Register; 6639 address float_address = __ double_constant($src$$constant); 6640 if (float_address == NULL) { 6641 ciEnv::current()->record_out_of_memory_failure(); 6642 return; 6643 } 6644 int offset = __ offset_to_method_toc(float_address); 6645 int hi = (offset + (1<<15))>>16; 6646 int lo = offset - hi * (1<<16); 6647 6648 __ addis(Rtoc, Rtoc, hi); 6649 __ lfd(Rdst, lo, Rtoc); 6650 __ addis(Rtoc, Rtoc, -hi); 6651 %} 6652 ins_pipe(pipe_class_memory); 6653 %} 6654 6655 // Adlc adds toc node MachConstantTableBase. 6656 instruct loadConD_Ex(regD dst, immD src) %{ 6657 match(Set dst src); 6658 ins_cost(MEMORY_REF_COST); 6659 6660 // See loadConP. 6661 ins_cannot_rematerialize(true); 6662 6663 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6664 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6665 %} 6666 6667 // Prefetch instructions. 6668 // Must be safe to execute with invalid address (cannot fault). 6669 6670 // Special prefetch versions which use the dcbz instruction. 6671 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6672 match(PrefetchAllocation (AddP mem src)); 6673 predicate(AllocatePrefetchStyle == 3); 6674 ins_cost(MEMORY_REF_COST); 6675 6676 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6677 size(4); 6678 ins_encode %{ 6679 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6680 __ dcbz($src$$Register, $mem$$base$$Register); 6681 %} 6682 ins_pipe(pipe_class_memory); 6683 %} 6684 6685 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6686 match(PrefetchAllocation mem); 6687 predicate(AllocatePrefetchStyle == 3); 6688 ins_cost(MEMORY_REF_COST); 6689 6690 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6691 size(4); 6692 ins_encode %{ 6693 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6694 __ dcbz($mem$$base$$Register); 6695 %} 6696 ins_pipe(pipe_class_memory); 6697 %} 6698 6699 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6700 match(PrefetchAllocation (AddP mem src)); 6701 predicate(AllocatePrefetchStyle != 3); 6702 ins_cost(MEMORY_REF_COST); 6703 6704 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6705 size(4); 6706 ins_encode %{ 6707 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6708 __ dcbtst($src$$Register, $mem$$base$$Register); 6709 %} 6710 ins_pipe(pipe_class_memory); 6711 %} 6712 6713 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6714 match(PrefetchAllocation mem); 6715 predicate(AllocatePrefetchStyle != 3); 6716 ins_cost(MEMORY_REF_COST); 6717 6718 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6719 size(4); 6720 ins_encode %{ 6721 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6722 __ dcbtst($mem$$base$$Register); 6723 %} 6724 ins_pipe(pipe_class_memory); 6725 %} 6726 6727 //----------Store Instructions------------------------------------------------- 6728 6729 // Store Byte 6730 instruct storeB(memory mem, iRegIsrc src) %{ 6731 match(Set mem (StoreB mem src)); 6732 ins_cost(MEMORY_REF_COST); 6733 6734 format %{ "STB $src, $mem \t// byte" %} 6735 size(4); 6736 ins_encode %{ 6737 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6738 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6739 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6740 %} 6741 ins_pipe(pipe_class_memory); 6742 %} 6743 6744 // Store Char/Short 6745 instruct storeC(memory mem, iRegIsrc src) %{ 6746 match(Set mem (StoreC mem src)); 6747 ins_cost(MEMORY_REF_COST); 6748 6749 format %{ "STH $src, $mem \t// short" %} 6750 size(4); 6751 ins_encode %{ 6752 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6753 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6754 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6755 %} 6756 ins_pipe(pipe_class_memory); 6757 %} 6758 6759 // Store Integer 6760 instruct storeI(memory mem, iRegIsrc src) %{ 6761 match(Set mem (StoreI mem src)); 6762 ins_cost(MEMORY_REF_COST); 6763 6764 format %{ "STW $src, $mem" %} 6765 size(4); 6766 ins_encode( enc_stw(src, mem) ); 6767 ins_pipe(pipe_class_memory); 6768 %} 6769 6770 // ConvL2I + StoreI. 6771 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6772 match(Set mem (StoreI mem (ConvL2I src))); 6773 ins_cost(MEMORY_REF_COST); 6774 6775 format %{ "STW l2i($src), $mem" %} 6776 size(4); 6777 ins_encode( enc_stw(src, mem) ); 6778 ins_pipe(pipe_class_memory); 6779 %} 6780 6781 // Store Long 6782 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6783 match(Set mem (StoreL mem src)); 6784 ins_cost(MEMORY_REF_COST); 6785 6786 format %{ "STD $src, $mem \t// long" %} 6787 size(4); 6788 ins_encode( enc_std(src, mem) ); 6789 ins_pipe(pipe_class_memory); 6790 %} 6791 6792 // Store super word nodes. 6793 6794 // Store Aligned Packed Byte long register to memory 6795 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6796 predicate(n->as_StoreVector()->memory_size() == 8); 6797 match(Set mem (StoreVector mem src)); 6798 ins_cost(MEMORY_REF_COST); 6799 6800 format %{ "STD $mem, $src \t// packed8B" %} 6801 size(4); 6802 ins_encode( enc_std(src, mem) ); 6803 ins_pipe(pipe_class_memory); 6804 %} 6805 6806 // Store Packed Byte long register to memory 6807 instruct storeV16(indirect mem, vecX src) %{ 6808 predicate(n->as_StoreVector()->memory_size() == 16); 6809 match(Set mem (StoreVector mem src)); 6810 ins_cost(MEMORY_REF_COST); 6811 6812 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6813 size(4); 6814 ins_encode %{ 6815 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6816 %} 6817 ins_pipe(pipe_class_default); 6818 %} 6819 6820 // Store Compressed Oop 6821 instruct storeN(memory dst, iRegN_P2N src) %{ 6822 match(Set dst (StoreN dst src)); 6823 ins_cost(MEMORY_REF_COST); 6824 6825 format %{ "STW $src, $dst \t// compressed oop" %} 6826 size(4); 6827 ins_encode( enc_stw(src, dst) ); 6828 ins_pipe(pipe_class_memory); 6829 %} 6830 6831 // Store Compressed KLass 6832 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6833 match(Set dst (StoreNKlass dst src)); 6834 ins_cost(MEMORY_REF_COST); 6835 6836 format %{ "STW $src, $dst \t// compressed klass" %} 6837 size(4); 6838 ins_encode( enc_stw(src, dst) ); 6839 ins_pipe(pipe_class_memory); 6840 %} 6841 6842 // Store Pointer 6843 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6844 match(Set dst (StoreP dst src)); 6845 ins_cost(MEMORY_REF_COST); 6846 6847 format %{ "STD $src, $dst \t// ptr" %} 6848 size(4); 6849 ins_encode( enc_std(src, dst) ); 6850 ins_pipe(pipe_class_memory); 6851 %} 6852 6853 // Store Float 6854 instruct storeF(memory mem, regF src) %{ 6855 match(Set mem (StoreF mem src)); 6856 ins_cost(MEMORY_REF_COST); 6857 6858 format %{ "STFS $src, $mem" %} 6859 size(4); 6860 ins_encode( enc_stfs(src, mem) ); 6861 ins_pipe(pipe_class_memory); 6862 %} 6863 6864 // Store Double 6865 instruct storeD(memory mem, regD src) %{ 6866 match(Set mem (StoreD mem src)); 6867 ins_cost(MEMORY_REF_COST); 6868 6869 format %{ "STFD $src, $mem" %} 6870 size(4); 6871 ins_encode( enc_stfd(src, mem) ); 6872 ins_pipe(pipe_class_memory); 6873 %} 6874 6875 //----------Store Instructions With Zeros-------------------------------------- 6876 6877 // Card-mark for CMS garbage collection. 6878 // This cardmark does an optimization so that it must not always 6879 // do a releasing store. For this, it gets the address of 6880 // CMSCollectorCardTableBarrierSetBSExt::_requires_release as input. 6881 // (Using releaseFieldAddr in the match rule is a hack.) 6882 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6883 match(Set mem (StoreCM mem releaseFieldAddr)); 6884 effect(TEMP crx); 6885 predicate(false); 6886 ins_cost(MEMORY_REF_COST); 6887 6888 // See loadConP. 6889 ins_cannot_rematerialize(true); 6890 6891 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6892 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6893 ins_pipe(pipe_class_memory); 6894 %} 6895 6896 // Card-mark for CMS garbage collection. 6897 // This cardmark does an optimization so that it must not always 6898 // do a releasing store. For this, it needs the constant address of 6899 // CMSCollectorCardTableBarrierSetBSExt::_requires_release. 6900 // This constant address is split off here by expand so we can use 6901 // adlc / matcher functionality to load it from the constant section. 6902 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6903 match(Set mem (StoreCM mem zero)); 6904 predicate(UseConcMarkSweepGC); 6905 6906 expand %{ 6907 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableBarrierSetBSExt::requires_release_address() */ %} 6908 iRegLdst releaseFieldAddress; 6909 flagsReg crx; 6910 loadConL_Ex(releaseFieldAddress, baseImm); 6911 storeCM_CMS(mem, releaseFieldAddress, crx); 6912 %} 6913 %} 6914 6915 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6916 match(Set mem (StoreCM mem zero)); 6917 predicate(UseG1GC); 6918 ins_cost(MEMORY_REF_COST); 6919 6920 ins_cannot_rematerialize(true); 6921 6922 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6923 size(8); 6924 ins_encode %{ 6925 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6926 __ li(R0, 0); 6927 //__ release(); // G1: oops are allowed to get visible after dirty marking 6928 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6929 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6930 %} 6931 ins_pipe(pipe_class_memory); 6932 %} 6933 6934 // Convert oop pointer into compressed form. 6935 6936 // Nodes for postalloc expand. 6937 6938 // Shift node for expand. 6939 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6940 // The match rule is needed to make it a 'MachTypeNode'! 6941 match(Set dst (EncodeP src)); 6942 predicate(false); 6943 6944 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6945 size(4); 6946 ins_encode %{ 6947 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6948 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6949 %} 6950 ins_pipe(pipe_class_default); 6951 %} 6952 6953 // Add node for expand. 6954 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6955 // The match rule is needed to make it a 'MachTypeNode'! 6956 match(Set dst (EncodeP src)); 6957 predicate(false); 6958 6959 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6960 ins_encode %{ 6961 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6962 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6963 %} 6964 ins_pipe(pipe_class_default); 6965 %} 6966 6967 // Conditional sub base. 6968 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6969 // The match rule is needed to make it a 'MachTypeNode'! 6970 match(Set dst (EncodeP (Binary crx src1))); 6971 predicate(false); 6972 6973 format %{ "BEQ $crx, done\n\t" 6974 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6975 "done:" %} 6976 ins_encode %{ 6977 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6978 Label done; 6979 __ beq($crx$$CondRegister, done); 6980 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6981 __ bind(done); 6982 %} 6983 ins_pipe(pipe_class_default); 6984 %} 6985 6986 // Power 7 can use isel instruction 6987 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6988 // The match rule is needed to make it a 'MachTypeNode'! 6989 match(Set dst (EncodeP (Binary crx src1))); 6990 predicate(false); 6991 6992 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6993 size(4); 6994 ins_encode %{ 6995 // This is a Power7 instruction for which no machine description exists. 6996 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6997 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6998 %} 6999 ins_pipe(pipe_class_default); 7000 %} 7001 7002 // Disjoint narrow oop base. 7003 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7004 match(Set dst (EncodeP src)); 7005 predicate(Universe::narrow_oop_base_disjoint()); 7006 7007 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7008 size(4); 7009 ins_encode %{ 7010 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7011 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 7012 %} 7013 ins_pipe(pipe_class_default); 7014 %} 7015 7016 // shift != 0, base != 0 7017 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 7018 match(Set dst (EncodeP src)); 7019 effect(TEMP crx); 7020 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 7021 Universe::narrow_oop_shift() != 0 && 7022 Universe::narrow_oop_base_overlaps()); 7023 7024 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 7025 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 7026 %} 7027 7028 // shift != 0, base != 0 7029 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 7030 match(Set dst (EncodeP src)); 7031 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 7032 Universe::narrow_oop_shift() != 0 && 7033 Universe::narrow_oop_base_overlaps()); 7034 7035 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 7036 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 7037 %} 7038 7039 // shift != 0, base == 0 7040 // TODO: This is the same as encodeP_shift. Merge! 7041 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 7042 match(Set dst (EncodeP src)); 7043 predicate(Universe::narrow_oop_shift() != 0 && 7044 Universe::narrow_oop_base() ==0); 7045 7046 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 7047 size(4); 7048 ins_encode %{ 7049 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7050 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 7051 %} 7052 ins_pipe(pipe_class_default); 7053 %} 7054 7055 // Compressed OOPs with narrow_oop_shift == 0. 7056 // shift == 0, base == 0 7057 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 7058 match(Set dst (EncodeP src)); 7059 predicate(Universe::narrow_oop_shift() == 0); 7060 7061 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 7062 // variable size, 0 or 4. 7063 ins_encode %{ 7064 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7065 __ mr_if_needed($dst$$Register, $src$$Register); 7066 %} 7067 ins_pipe(pipe_class_default); 7068 %} 7069 7070 // Decode nodes. 7071 7072 // Shift node for expand. 7073 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 7074 // The match rule is needed to make it a 'MachTypeNode'! 7075 match(Set dst (DecodeN src)); 7076 predicate(false); 7077 7078 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 7079 size(4); 7080 ins_encode %{ 7081 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7082 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7083 %} 7084 ins_pipe(pipe_class_default); 7085 %} 7086 7087 // Add node for expand. 7088 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7089 // The match rule is needed to make it a 'MachTypeNode'! 7090 match(Set dst (DecodeN src)); 7091 predicate(false); 7092 7093 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7094 ins_encode %{ 7095 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7096 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7097 %} 7098 ins_pipe(pipe_class_default); 7099 %} 7100 7101 // conditianal add base for expand 7102 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7103 // The match rule is needed to make it a 'MachTypeNode'! 7104 // NOTICE that the rule is nonsense - we just have to make sure that: 7105 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7106 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7107 match(Set dst (DecodeN (Binary crx src))); 7108 predicate(false); 7109 7110 format %{ "BEQ $crx, done\n\t" 7111 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7112 "done:" %} 7113 ins_encode %{ 7114 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7115 Label done; 7116 __ beq($crx$$CondRegister, done); 7117 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7118 __ bind(done); 7119 %} 7120 ins_pipe(pipe_class_default); 7121 %} 7122 7123 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7124 // The match rule is needed to make it a 'MachTypeNode'! 7125 // NOTICE that the rule is nonsense - we just have to make sure that: 7126 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7127 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7128 match(Set dst (DecodeN (Binary crx src1))); 7129 predicate(false); 7130 7131 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7132 size(4); 7133 ins_encode %{ 7134 // This is a Power7 instruction for which no machine description exists. 7135 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7136 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7137 %} 7138 ins_pipe(pipe_class_default); 7139 %} 7140 7141 // shift != 0, base != 0 7142 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7143 match(Set dst (DecodeN src)); 7144 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7145 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7146 Universe::narrow_oop_shift() != 0 && 7147 Universe::narrow_oop_base() != 0); 7148 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7149 effect(TEMP crx); 7150 7151 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7152 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7153 %} 7154 7155 // shift != 0, base == 0 7156 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7157 match(Set dst (DecodeN src)); 7158 predicate(Universe::narrow_oop_shift() != 0 && 7159 Universe::narrow_oop_base() == 0); 7160 7161 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7162 size(4); 7163 ins_encode %{ 7164 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7165 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7166 %} 7167 ins_pipe(pipe_class_default); 7168 %} 7169 7170 // Optimize DecodeN for disjoint base. 7171 // Shift narrow oop and or it into register that already contains the heap base. 7172 // Base == dst must hold, and is assured by construction in postaloc_expand. 7173 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7174 match(Set dst (DecodeN src)); 7175 effect(TEMP base); 7176 predicate(false); 7177 7178 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7179 size(4); 7180 ins_encode %{ 7181 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7182 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 7183 %} 7184 ins_pipe(pipe_class_default); 7185 %} 7186 7187 // Optimize DecodeN for disjoint base. 7188 // This node requires only one cycle on the critical path. 7189 // We must postalloc_expand as we can not express use_def effects where 7190 // the used register is L and the def'ed register P. 7191 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7192 match(Set dst (DecodeN src)); 7193 effect(TEMP_DEF dst); 7194 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7195 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7196 Universe::narrow_oop_base_disjoint()); 7197 ins_cost(DEFAULT_COST); 7198 7199 format %{ "MOV $dst, heapbase \t\n" 7200 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7201 postalloc_expand %{ 7202 loadBaseNode *n1 = new loadBaseNode(); 7203 n1->add_req(NULL); 7204 n1->_opnds[0] = op_dst; 7205 7206 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7207 n2->add_req(n_region, n_src, n1); 7208 n2->_opnds[0] = op_dst; 7209 n2->_opnds[1] = op_src; 7210 n2->_opnds[2] = op_dst; 7211 n2->_bottom_type = _bottom_type; 7212 7213 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7214 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7215 7216 nodes->push(n1); 7217 nodes->push(n2); 7218 %} 7219 %} 7220 7221 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7222 match(Set dst (DecodeN src)); 7223 effect(TEMP_DEF dst, TEMP crx); 7224 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7225 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7226 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 7227 ins_cost(3 * DEFAULT_COST); 7228 7229 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7230 postalloc_expand %{ 7231 loadBaseNode *n1 = new loadBaseNode(); 7232 n1->add_req(NULL); 7233 n1->_opnds[0] = op_dst; 7234 7235 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7236 n_compare->add_req(n_region, n_src); 7237 n_compare->_opnds[0] = op_crx; 7238 n_compare->_opnds[1] = op_src; 7239 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7240 7241 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7242 n2->add_req(n_region, n_src, n1); 7243 n2->_opnds[0] = op_dst; 7244 n2->_opnds[1] = op_src; 7245 n2->_opnds[2] = op_dst; 7246 n2->_bottom_type = _bottom_type; 7247 7248 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7249 n_cond_set->add_req(n_region, n_compare, n2); 7250 n_cond_set->_opnds[0] = op_dst; 7251 n_cond_set->_opnds[1] = op_crx; 7252 n_cond_set->_opnds[2] = op_dst; 7253 n_cond_set->_bottom_type = _bottom_type; 7254 7255 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7256 ra_->set_oop(n_cond_set, true); 7257 7258 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7259 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7260 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7261 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7262 7263 nodes->push(n1); 7264 nodes->push(n_compare); 7265 nodes->push(n2); 7266 nodes->push(n_cond_set); 7267 %} 7268 %} 7269 7270 // src != 0, shift != 0, base != 0 7271 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7272 match(Set dst (DecodeN src)); 7273 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7274 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7275 Universe::narrow_oop_shift() != 0 && 7276 Universe::narrow_oop_base() != 0); 7277 ins_cost(2 * DEFAULT_COST); 7278 7279 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7280 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7281 %} 7282 7283 // Compressed OOPs with narrow_oop_shift == 0. 7284 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7285 match(Set dst (DecodeN src)); 7286 predicate(Universe::narrow_oop_shift() == 0); 7287 ins_cost(DEFAULT_COST); 7288 7289 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7290 // variable size, 0 or 4. 7291 ins_encode %{ 7292 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7293 __ mr_if_needed($dst$$Register, $src$$Register); 7294 %} 7295 ins_pipe(pipe_class_default); 7296 %} 7297 7298 // Convert compressed oop into int for vectors alignment masking. 7299 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7300 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7301 predicate(Universe::narrow_oop_shift() == 0); 7302 ins_cost(DEFAULT_COST); 7303 7304 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7305 // variable size, 0 or 4. 7306 ins_encode %{ 7307 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7308 __ mr_if_needed($dst$$Register, $src$$Register); 7309 %} 7310 ins_pipe(pipe_class_default); 7311 %} 7312 7313 // Convert klass pointer into compressed form. 7314 7315 // Nodes for postalloc expand. 7316 7317 // Shift node for expand. 7318 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7319 // The match rule is needed to make it a 'MachTypeNode'! 7320 match(Set dst (EncodePKlass src)); 7321 predicate(false); 7322 7323 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7324 size(4); 7325 ins_encode %{ 7326 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7327 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7328 %} 7329 ins_pipe(pipe_class_default); 7330 %} 7331 7332 // Add node for expand. 7333 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7334 // The match rule is needed to make it a 'MachTypeNode'! 7335 match(Set dst (EncodePKlass (Binary base src))); 7336 predicate(false); 7337 7338 format %{ "SUB $dst, $base, $src \t// encode" %} 7339 size(4); 7340 ins_encode %{ 7341 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7342 __ subf($dst$$Register, $base$$Register, $src$$Register); 7343 %} 7344 ins_pipe(pipe_class_default); 7345 %} 7346 7347 // Disjoint narrow oop base. 7348 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7349 match(Set dst (EncodePKlass src)); 7350 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 7351 7352 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7353 size(4); 7354 ins_encode %{ 7355 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7356 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 7357 %} 7358 ins_pipe(pipe_class_default); 7359 %} 7360 7361 // shift != 0, base != 0 7362 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7363 match(Set dst (EncodePKlass (Binary base src))); 7364 predicate(false); 7365 7366 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7367 postalloc_expand %{ 7368 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7369 n1->add_req(n_region, n_base, n_src); 7370 n1->_opnds[0] = op_dst; 7371 n1->_opnds[1] = op_base; 7372 n1->_opnds[2] = op_src; 7373 n1->_bottom_type = _bottom_type; 7374 7375 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7376 n2->add_req(n_region, n1); 7377 n2->_opnds[0] = op_dst; 7378 n2->_opnds[1] = op_dst; 7379 n2->_bottom_type = _bottom_type; 7380 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7381 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7382 7383 nodes->push(n1); 7384 nodes->push(n2); 7385 %} 7386 %} 7387 7388 // shift != 0, base != 0 7389 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7390 match(Set dst (EncodePKlass src)); 7391 //predicate(Universe::narrow_klass_shift() != 0 && 7392 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 7393 7394 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7395 ins_cost(DEFAULT_COST*2); // Don't count constant. 7396 expand %{ 7397 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 7398 iRegLdst base; 7399 loadConL_Ex(base, baseImm); 7400 encodePKlass_not_null_Ex(dst, base, src); 7401 %} 7402 %} 7403 7404 // Decode nodes. 7405 7406 // Shift node for expand. 7407 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7408 // The match rule is needed to make it a 'MachTypeNode'! 7409 match(Set dst (DecodeNKlass src)); 7410 predicate(false); 7411 7412 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7413 size(4); 7414 ins_encode %{ 7415 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7416 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7417 %} 7418 ins_pipe(pipe_class_default); 7419 %} 7420 7421 // Add node for expand. 7422 7423 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7424 // The match rule is needed to make it a 'MachTypeNode'! 7425 match(Set dst (DecodeNKlass (Binary base src))); 7426 predicate(false); 7427 7428 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7429 size(4); 7430 ins_encode %{ 7431 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7432 __ add($dst$$Register, $base$$Register, $src$$Register); 7433 %} 7434 ins_pipe(pipe_class_default); 7435 %} 7436 7437 // src != 0, shift != 0, base != 0 7438 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7439 match(Set dst (DecodeNKlass (Binary base src))); 7440 //effect(kill src); // We need a register for the immediate result after shifting. 7441 predicate(false); 7442 7443 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7444 postalloc_expand %{ 7445 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7446 n1->add_req(n_region, n_base, n_src); 7447 n1->_opnds[0] = op_dst; 7448 n1->_opnds[1] = op_base; 7449 n1->_opnds[2] = op_src; 7450 n1->_bottom_type = _bottom_type; 7451 7452 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7453 n2->add_req(n_region, n1); 7454 n2->_opnds[0] = op_dst; 7455 n2->_opnds[1] = op_dst; 7456 n2->_bottom_type = _bottom_type; 7457 7458 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7459 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7460 7461 nodes->push(n1); 7462 nodes->push(n2); 7463 %} 7464 %} 7465 7466 // src != 0, shift != 0, base != 0 7467 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7468 match(Set dst (DecodeNKlass src)); 7469 // predicate(Universe::narrow_klass_shift() != 0 && 7470 // Universe::narrow_klass_base() != 0); 7471 7472 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7473 7474 ins_cost(DEFAULT_COST*2); // Don't count constant. 7475 expand %{ 7476 // We add first, then we shift. Like this, we can get along with one register less. 7477 // But we have to load the base pre-shifted. 7478 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7479 iRegLdst base; 7480 loadConL_Ex(base, baseImm); 7481 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7482 %} 7483 %} 7484 7485 //----------MemBar Instructions----------------------------------------------- 7486 // Memory barrier flavors 7487 7488 instruct membar_acquire() %{ 7489 match(LoadFence); 7490 ins_cost(4*MEMORY_REF_COST); 7491 7492 format %{ "MEMBAR-acquire" %} 7493 size(4); 7494 ins_encode %{ 7495 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7496 __ acquire(); 7497 %} 7498 ins_pipe(pipe_class_default); 7499 %} 7500 7501 instruct unnecessary_membar_acquire() %{ 7502 match(MemBarAcquire); 7503 ins_cost(0); 7504 7505 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7506 size(0); 7507 ins_encode( /*empty*/ ); 7508 ins_pipe(pipe_class_default); 7509 %} 7510 7511 instruct membar_acquire_lock() %{ 7512 match(MemBarAcquireLock); 7513 ins_cost(0); 7514 7515 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7516 size(0); 7517 ins_encode( /*empty*/ ); 7518 ins_pipe(pipe_class_default); 7519 %} 7520 7521 instruct membar_release() %{ 7522 match(MemBarRelease); 7523 match(StoreFence); 7524 ins_cost(4*MEMORY_REF_COST); 7525 7526 format %{ "MEMBAR-release" %} 7527 size(4); 7528 ins_encode %{ 7529 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7530 __ release(); 7531 %} 7532 ins_pipe(pipe_class_default); 7533 %} 7534 7535 instruct membar_storestore() %{ 7536 match(MemBarStoreStore); 7537 ins_cost(4*MEMORY_REF_COST); 7538 7539 format %{ "MEMBAR-store-store" %} 7540 size(4); 7541 ins_encode %{ 7542 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7543 __ membar(Assembler::StoreStore); 7544 %} 7545 ins_pipe(pipe_class_default); 7546 %} 7547 7548 instruct membar_release_lock() %{ 7549 match(MemBarReleaseLock); 7550 ins_cost(0); 7551 7552 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7553 size(0); 7554 ins_encode( /*empty*/ ); 7555 ins_pipe(pipe_class_default); 7556 %} 7557 7558 instruct membar_volatile() %{ 7559 match(MemBarVolatile); 7560 ins_cost(4*MEMORY_REF_COST); 7561 7562 format %{ "MEMBAR-volatile" %} 7563 size(4); 7564 ins_encode %{ 7565 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7566 __ fence(); 7567 %} 7568 ins_pipe(pipe_class_default); 7569 %} 7570 7571 // This optimization is wrong on PPC. The following pattern is not supported: 7572 // MemBarVolatile 7573 // ^ ^ 7574 // | | 7575 // CtrlProj MemProj 7576 // ^ ^ 7577 // | | 7578 // | Load 7579 // | 7580 // MemBarVolatile 7581 // 7582 // The first MemBarVolatile could get optimized out! According to 7583 // Vladimir, this pattern can not occur on Oracle platforms. 7584 // However, it does occur on PPC64 (because of membars in 7585 // inline_unsafe_load_store). 7586 // 7587 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7588 // Don't forget to look at the implementation of post_store_load_barrier again, 7589 // we did other fixes in that method. 7590 //instruct unnecessary_membar_volatile() %{ 7591 // match(MemBarVolatile); 7592 // predicate(Matcher::post_store_load_barrier(n)); 7593 // ins_cost(0); 7594 // 7595 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7596 // size(0); 7597 // ins_encode( /*empty*/ ); 7598 // ins_pipe(pipe_class_default); 7599 //%} 7600 7601 instruct membar_CPUOrder() %{ 7602 match(MemBarCPUOrder); 7603 ins_cost(0); 7604 7605 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7606 size(0); 7607 ins_encode( /*empty*/ ); 7608 ins_pipe(pipe_class_default); 7609 %} 7610 7611 //----------Conditional Move--------------------------------------------------- 7612 7613 // Cmove using isel. 7614 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7615 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7616 predicate(VM_Version::has_isel()); 7617 ins_cost(DEFAULT_COST); 7618 7619 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7620 size(4); 7621 ins_encode %{ 7622 // This is a Power7 instruction for which no machine description 7623 // exists. Anyways, the scheduler should be off on Power7. 7624 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7625 int cc = $cmp$$cmpcode; 7626 __ isel($dst$$Register, $crx$$CondRegister, 7627 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7628 %} 7629 ins_pipe(pipe_class_default); 7630 %} 7631 7632 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7633 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7634 predicate(!VM_Version::has_isel()); 7635 ins_cost(DEFAULT_COST+BRANCH_COST); 7636 7637 ins_variable_size_depending_on_alignment(true); 7638 7639 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7640 // Worst case is branch + move + stop, no stop without scheduler 7641 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7642 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7643 ins_pipe(pipe_class_default); 7644 %} 7645 7646 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7647 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7648 ins_cost(DEFAULT_COST+BRANCH_COST); 7649 7650 ins_variable_size_depending_on_alignment(true); 7651 7652 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7653 // Worst case is branch + move + stop, no stop without scheduler 7654 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7655 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7656 ins_pipe(pipe_class_default); 7657 %} 7658 7659 // Cmove using isel. 7660 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7661 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7662 predicate(VM_Version::has_isel()); 7663 ins_cost(DEFAULT_COST); 7664 7665 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7666 size(4); 7667 ins_encode %{ 7668 // This is a Power7 instruction for which no machine description 7669 // exists. Anyways, the scheduler should be off on Power7. 7670 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7671 int cc = $cmp$$cmpcode; 7672 __ isel($dst$$Register, $crx$$CondRegister, 7673 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7674 %} 7675 ins_pipe(pipe_class_default); 7676 %} 7677 7678 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7679 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7680 predicate(!VM_Version::has_isel()); 7681 ins_cost(DEFAULT_COST+BRANCH_COST); 7682 7683 ins_variable_size_depending_on_alignment(true); 7684 7685 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7686 // Worst case is branch + move + stop, no stop without scheduler. 7687 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7688 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7689 ins_pipe(pipe_class_default); 7690 %} 7691 7692 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7693 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7694 ins_cost(DEFAULT_COST+BRANCH_COST); 7695 7696 ins_variable_size_depending_on_alignment(true); 7697 7698 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7699 // Worst case is branch + move + stop, no stop without scheduler. 7700 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7701 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7702 ins_pipe(pipe_class_default); 7703 %} 7704 7705 // Cmove using isel. 7706 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7707 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7708 predicate(VM_Version::has_isel()); 7709 ins_cost(DEFAULT_COST); 7710 7711 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7712 size(4); 7713 ins_encode %{ 7714 // This is a Power7 instruction for which no machine description 7715 // exists. Anyways, the scheduler should be off on Power7. 7716 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7717 int cc = $cmp$$cmpcode; 7718 __ isel($dst$$Register, $crx$$CondRegister, 7719 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7720 %} 7721 ins_pipe(pipe_class_default); 7722 %} 7723 7724 // Conditional move for RegN. Only cmov(reg, reg). 7725 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7726 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7727 predicate(!VM_Version::has_isel()); 7728 ins_cost(DEFAULT_COST+BRANCH_COST); 7729 7730 ins_variable_size_depending_on_alignment(true); 7731 7732 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7733 // Worst case is branch + move + stop, no stop without scheduler. 7734 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7735 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7736 ins_pipe(pipe_class_default); 7737 %} 7738 7739 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7740 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7741 ins_cost(DEFAULT_COST+BRANCH_COST); 7742 7743 ins_variable_size_depending_on_alignment(true); 7744 7745 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7746 // Worst case is branch + move + stop, no stop without scheduler. 7747 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7748 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7749 ins_pipe(pipe_class_default); 7750 %} 7751 7752 // Cmove using isel. 7753 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7754 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7755 predicate(VM_Version::has_isel()); 7756 ins_cost(DEFAULT_COST); 7757 7758 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7759 size(4); 7760 ins_encode %{ 7761 // This is a Power7 instruction for which no machine description 7762 // exists. Anyways, the scheduler should be off on Power7. 7763 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7764 int cc = $cmp$$cmpcode; 7765 __ isel($dst$$Register, $crx$$CondRegister, 7766 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7767 %} 7768 ins_pipe(pipe_class_default); 7769 %} 7770 7771 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7772 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7773 predicate(!VM_Version::has_isel()); 7774 ins_cost(DEFAULT_COST+BRANCH_COST); 7775 7776 ins_variable_size_depending_on_alignment(true); 7777 7778 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7779 // Worst case is branch + move + stop, no stop without scheduler. 7780 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7781 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7782 ins_pipe(pipe_class_default); 7783 %} 7784 7785 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7786 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7787 ins_cost(DEFAULT_COST+BRANCH_COST); 7788 7789 ins_variable_size_depending_on_alignment(true); 7790 7791 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7792 // Worst case is branch + move + stop, no stop without scheduler. 7793 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7794 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7795 ins_pipe(pipe_class_default); 7796 %} 7797 7798 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7799 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7800 ins_cost(DEFAULT_COST+BRANCH_COST); 7801 7802 ins_variable_size_depending_on_alignment(true); 7803 7804 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7805 // Worst case is branch + move + stop, no stop without scheduler. 7806 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7807 ins_encode %{ 7808 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7809 Label done; 7810 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7811 // Branch if not (cmp crx). 7812 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7813 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7814 // TODO PPC port __ endgroup_if_needed(_size == 12); 7815 __ bind(done); 7816 %} 7817 ins_pipe(pipe_class_default); 7818 %} 7819 7820 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7821 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7822 ins_cost(DEFAULT_COST+BRANCH_COST); 7823 7824 ins_variable_size_depending_on_alignment(true); 7825 7826 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7827 // Worst case is branch + move + stop, no stop without scheduler. 7828 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7829 ins_encode %{ 7830 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7831 Label done; 7832 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7833 // Branch if not (cmp crx). 7834 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7835 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7836 // TODO PPC port __ endgroup_if_needed(_size == 12); 7837 __ bind(done); 7838 %} 7839 ins_pipe(pipe_class_default); 7840 %} 7841 7842 //----------Conditional_store-------------------------------------------------- 7843 // Conditional-store of the updated heap-top. 7844 // Used during allocation of the shared heap. 7845 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7846 7847 // As compareAndSwapL, but return flag register instead of boolean value in 7848 // int register. 7849 // Used by sun/misc/AtomicLongCSImpl.java. 7850 // Mem_ptr must be a memory operand, else this node does not get 7851 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7852 // can be rematerialized which leads to errors. 7853 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7854 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7855 effect(TEMP cr0); 7856 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7857 ins_encode %{ 7858 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7859 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7860 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7861 noreg, NULL, true); 7862 %} 7863 ins_pipe(pipe_class_default); 7864 %} 7865 7866 // As compareAndSwapP, but return flag register instead of boolean value in 7867 // int register. 7868 // This instruction is matched if UseTLAB is off. 7869 // Mem_ptr must be a memory operand, else this node does not get 7870 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7871 // can be rematerialized which leads to errors. 7872 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7873 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7874 ins_cost(2*MEMORY_REF_COST); 7875 7876 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7877 ins_encode %{ 7878 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7879 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7880 %} 7881 ins_pipe(pipe_class_memory); 7882 %} 7883 7884 // Implement LoadPLocked. Must be ordered against changes of the memory location 7885 // by storePConditional. 7886 // Don't know whether this is ever used. 7887 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7888 match(Set dst (LoadPLocked mem)); 7889 ins_cost(2*MEMORY_REF_COST); 7890 7891 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7892 size(4); 7893 ins_encode %{ 7894 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7895 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7896 %} 7897 ins_pipe(pipe_class_memory); 7898 %} 7899 7900 //----------Compare-And-Swap--------------------------------------------------- 7901 7902 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7903 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7904 // matched. 7905 7906 // Strong versions: 7907 7908 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7909 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7910 predicate(VM_Version::has_lqarx()); 7911 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7912 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7913 ins_encode %{ 7914 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7915 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7916 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7917 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7918 $res$$Register, true); 7919 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7920 __ isync(); 7921 } else { 7922 __ sync(); 7923 } 7924 %} 7925 ins_pipe(pipe_class_default); 7926 %} 7927 7928 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7929 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7930 predicate(!VM_Version::has_lqarx()); 7931 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7932 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7933 ins_encode %{ 7934 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7935 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7936 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7937 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7938 $res$$Register, true); 7939 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7940 __ isync(); 7941 } else { 7942 __ sync(); 7943 } 7944 %} 7945 ins_pipe(pipe_class_default); 7946 %} 7947 7948 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7949 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7950 predicate(VM_Version::has_lqarx()); 7951 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7952 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7953 ins_encode %{ 7954 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7955 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7956 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7957 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7958 $res$$Register, true); 7959 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7960 __ isync(); 7961 } else { 7962 __ sync(); 7963 } 7964 %} 7965 ins_pipe(pipe_class_default); 7966 %} 7967 7968 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7969 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7970 predicate(!VM_Version::has_lqarx()); 7971 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7972 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7973 ins_encode %{ 7974 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7975 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7976 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7977 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7978 $res$$Register, true); 7979 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7980 __ isync(); 7981 } else { 7982 __ sync(); 7983 } 7984 %} 7985 ins_pipe(pipe_class_default); 7986 %} 7987 7988 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7989 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7990 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7991 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7992 ins_encode %{ 7993 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7994 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7995 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7996 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7997 $res$$Register, true); 7998 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7999 __ isync(); 8000 } else { 8001 __ sync(); 8002 } 8003 %} 8004 ins_pipe(pipe_class_default); 8005 %} 8006 8007 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8008 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 8009 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8010 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8011 ins_encode %{ 8012 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8013 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8014 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8015 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8016 $res$$Register, true); 8017 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8018 __ isync(); 8019 } else { 8020 __ sync(); 8021 } 8022 %} 8023 ins_pipe(pipe_class_default); 8024 %} 8025 8026 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8027 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 8028 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8029 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8030 ins_encode %{ 8031 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8032 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8033 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8034 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8035 $res$$Register, NULL, true); 8036 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8037 __ isync(); 8038 } else { 8039 __ sync(); 8040 } 8041 %} 8042 ins_pipe(pipe_class_default); 8043 %} 8044 8045 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8046 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 8047 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8048 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8049 ins_encode %{ 8050 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8051 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8052 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8053 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8054 $res$$Register, NULL, true); 8055 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8056 __ isync(); 8057 } else { 8058 __ sync(); 8059 } 8060 %} 8061 ins_pipe(pipe_class_default); 8062 %} 8063 8064 // Weak versions: 8065 8066 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8067 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8068 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8069 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8070 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8071 ins_encode %{ 8072 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8073 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8074 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8075 MacroAssembler::MemBarNone, 8076 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8077 %} 8078 ins_pipe(pipe_class_default); 8079 %} 8080 8081 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8082 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8083 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8084 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8085 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8086 ins_encode %{ 8087 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8088 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8089 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8090 MacroAssembler::MemBarNone, 8091 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8092 %} 8093 ins_pipe(pipe_class_default); 8094 %} 8095 8096 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8097 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8098 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8099 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8100 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8101 ins_encode %{ 8102 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8103 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8104 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8105 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8106 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8107 %} 8108 ins_pipe(pipe_class_default); 8109 %} 8110 8111 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8112 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8113 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8114 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8115 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8116 ins_encode %{ 8117 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8118 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8119 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8120 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8121 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8122 %} 8123 ins_pipe(pipe_class_default); 8124 %} 8125 8126 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8127 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8128 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8129 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8130 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8131 ins_encode %{ 8132 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8133 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8134 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8135 MacroAssembler::MemBarNone, 8136 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8137 %} 8138 ins_pipe(pipe_class_default); 8139 %} 8140 8141 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8142 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8143 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8144 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8145 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8146 ins_encode %{ 8147 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8148 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8149 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8150 MacroAssembler::MemBarNone, 8151 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8152 %} 8153 ins_pipe(pipe_class_default); 8154 %} 8155 8156 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8157 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8158 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8159 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8160 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8161 ins_encode %{ 8162 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8163 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8164 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8165 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8166 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8167 %} 8168 ins_pipe(pipe_class_default); 8169 %} 8170 8171 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8172 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8173 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8174 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8175 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8176 ins_encode %{ 8177 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8178 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8179 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8180 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8181 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8182 %} 8183 ins_pipe(pipe_class_default); 8184 %} 8185 8186 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8187 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8188 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8189 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8190 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8191 ins_encode %{ 8192 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8193 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8194 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8195 MacroAssembler::MemBarNone, 8196 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8197 %} 8198 ins_pipe(pipe_class_default); 8199 %} 8200 8201 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8202 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8203 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8204 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8205 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8206 ins_encode %{ 8207 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8208 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8209 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8210 // value is never passed to caller. 8211 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8212 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8213 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8214 %} 8215 ins_pipe(pipe_class_default); 8216 %} 8217 8218 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8219 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8220 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8221 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8222 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8223 ins_encode %{ 8224 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8225 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8226 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8227 MacroAssembler::MemBarNone, 8228 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8229 %} 8230 ins_pipe(pipe_class_default); 8231 %} 8232 8233 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8234 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8235 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8236 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8237 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8238 ins_encode %{ 8239 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8240 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8241 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8242 // value is never passed to caller. 8243 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8244 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8245 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8246 %} 8247 ins_pipe(pipe_class_default); 8248 %} 8249 8250 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8251 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8252 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8253 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8254 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8255 ins_encode %{ 8256 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8257 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8258 // value is never passed to caller. 8259 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8260 MacroAssembler::MemBarNone, 8261 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8262 %} 8263 ins_pipe(pipe_class_default); 8264 %} 8265 8266 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8267 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8268 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8269 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8270 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 8271 ins_encode %{ 8272 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8273 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8274 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8275 // value is never passed to caller. 8276 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8277 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8278 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8279 %} 8280 ins_pipe(pipe_class_default); 8281 %} 8282 8283 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8284 match(Set res (WeakCompareAndSwapP 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 CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8288 ins_encode %{ 8289 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8290 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8291 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8292 MacroAssembler::MemBarNone, 8293 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8294 %} 8295 ins_pipe(pipe_class_default); 8296 %} 8297 8298 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8299 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8300 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8301 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8302 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8303 ins_encode %{ 8304 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8305 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8306 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8307 // value is never passed to caller. 8308 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8309 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8310 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8311 %} 8312 ins_pipe(pipe_class_default); 8313 %} 8314 8315 // CompareAndExchange 8316 8317 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8318 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8319 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8320 effect(TEMP_DEF res, TEMP cr0); 8321 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8322 ins_encode %{ 8323 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8324 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8325 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8326 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8327 noreg, true); 8328 %} 8329 ins_pipe(pipe_class_default); 8330 %} 8331 8332 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8333 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8334 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8335 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8336 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8337 ins_encode %{ 8338 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8339 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8340 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8341 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8342 noreg, true); 8343 %} 8344 ins_pipe(pipe_class_default); 8345 %} 8346 8347 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8348 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8349 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8350 effect(TEMP_DEF res, TEMP cr0); 8351 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8352 ins_encode %{ 8353 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8354 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8355 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8356 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8357 noreg, true); 8358 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8359 __ isync(); 8360 } else { 8361 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8362 __ sync(); 8363 } 8364 %} 8365 ins_pipe(pipe_class_default); 8366 %} 8367 8368 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8369 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8370 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8371 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8372 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8373 ins_encode %{ 8374 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8375 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8376 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8377 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8378 noreg, true); 8379 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8380 __ isync(); 8381 } else { 8382 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8383 __ sync(); 8384 } 8385 %} 8386 ins_pipe(pipe_class_default); 8387 %} 8388 8389 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8390 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8391 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8392 effect(TEMP_DEF res, TEMP cr0); 8393 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8394 ins_encode %{ 8395 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8396 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8397 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8398 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8399 noreg, true); 8400 %} 8401 ins_pipe(pipe_class_default); 8402 %} 8403 8404 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8405 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8406 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8407 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8408 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8409 ins_encode %{ 8410 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8411 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8412 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8413 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8414 noreg, true); 8415 %} 8416 ins_pipe(pipe_class_default); 8417 %} 8418 8419 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8420 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8421 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8422 effect(TEMP_DEF res, TEMP cr0); 8423 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8424 ins_encode %{ 8425 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8426 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8427 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8428 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8429 noreg, true); 8430 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8431 __ isync(); 8432 } else { 8433 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8434 __ sync(); 8435 } 8436 %} 8437 ins_pipe(pipe_class_default); 8438 %} 8439 8440 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8441 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8442 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8443 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8444 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8445 ins_encode %{ 8446 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8447 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8448 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8449 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8450 noreg, true); 8451 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8452 __ isync(); 8453 } else { 8454 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8455 __ sync(); 8456 } 8457 %} 8458 ins_pipe(pipe_class_default); 8459 %} 8460 8461 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8462 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8463 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8464 effect(TEMP_DEF res, TEMP cr0); 8465 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8466 ins_encode %{ 8467 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8468 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8469 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8470 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8471 noreg, true); 8472 %} 8473 ins_pipe(pipe_class_default); 8474 %} 8475 8476 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8477 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8478 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8479 effect(TEMP_DEF res, TEMP cr0); 8480 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8481 ins_encode %{ 8482 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8483 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8484 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8485 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8486 noreg, true); 8487 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8488 __ isync(); 8489 } else { 8490 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8491 __ sync(); 8492 } 8493 %} 8494 ins_pipe(pipe_class_default); 8495 %} 8496 8497 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8498 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8499 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8500 effect(TEMP_DEF res, TEMP cr0); 8501 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8502 ins_encode %{ 8503 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8504 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8505 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8506 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8507 noreg, true); 8508 %} 8509 ins_pipe(pipe_class_default); 8510 %} 8511 8512 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8513 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8514 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8515 effect(TEMP_DEF res, TEMP cr0); 8516 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8517 ins_encode %{ 8518 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8519 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8520 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8521 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8522 noreg, true); 8523 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8524 __ isync(); 8525 } else { 8526 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8527 __ sync(); 8528 } 8529 %} 8530 ins_pipe(pipe_class_default); 8531 %} 8532 8533 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8534 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8535 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8536 effect(TEMP_DEF res, TEMP cr0); 8537 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8538 ins_encode %{ 8539 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8540 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8541 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8542 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8543 noreg, NULL, true); 8544 %} 8545 ins_pipe(pipe_class_default); 8546 %} 8547 8548 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8549 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8550 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8551 effect(TEMP_DEF res, TEMP cr0); 8552 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8553 ins_encode %{ 8554 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8555 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8556 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8557 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8558 noreg, NULL, true); 8559 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8560 __ isync(); 8561 } else { 8562 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8563 __ sync(); 8564 } 8565 %} 8566 ins_pipe(pipe_class_default); 8567 %} 8568 8569 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8570 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8571 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8572 effect(TEMP_DEF res, TEMP cr0); 8573 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8574 ins_encode %{ 8575 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8576 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8577 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8578 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8579 noreg, NULL, true); 8580 %} 8581 ins_pipe(pipe_class_default); 8582 %} 8583 8584 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8585 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8586 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8587 effect(TEMP_DEF res, TEMP cr0); 8588 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8589 ins_encode %{ 8590 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8591 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8592 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8593 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8594 noreg, NULL, true); 8595 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8596 __ isync(); 8597 } else { 8598 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8599 __ sync(); 8600 } 8601 %} 8602 ins_pipe(pipe_class_default); 8603 %} 8604 8605 // Special RMW 8606 8607 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8608 match(Set res (GetAndAddB mem_ptr src)); 8609 predicate(VM_Version::has_lqarx()); 8610 effect(TEMP_DEF res, TEMP cr0); 8611 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8612 ins_encode %{ 8613 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8614 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8615 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8616 __ isync(); 8617 } else { 8618 __ sync(); 8619 } 8620 %} 8621 ins_pipe(pipe_class_default); 8622 %} 8623 8624 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8625 match(Set res (GetAndAddB mem_ptr src)); 8626 predicate(!VM_Version::has_lqarx()); 8627 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8628 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8629 ins_encode %{ 8630 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8631 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8632 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8633 __ isync(); 8634 } else { 8635 __ sync(); 8636 } 8637 %} 8638 ins_pipe(pipe_class_default); 8639 %} 8640 8641 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8642 match(Set res (GetAndAddS mem_ptr src)); 8643 predicate(VM_Version::has_lqarx()); 8644 effect(TEMP_DEF res, TEMP cr0); 8645 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8646 ins_encode %{ 8647 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8648 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8649 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8650 __ isync(); 8651 } else { 8652 __ sync(); 8653 } 8654 %} 8655 ins_pipe(pipe_class_default); 8656 %} 8657 8658 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8659 match(Set res (GetAndAddS mem_ptr src)); 8660 predicate(!VM_Version::has_lqarx()); 8661 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8662 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8663 ins_encode %{ 8664 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8665 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8666 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8667 __ isync(); 8668 } else { 8669 __ sync(); 8670 } 8671 %} 8672 ins_pipe(pipe_class_default); 8673 %} 8674 8675 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8676 match(Set res (GetAndAddI mem_ptr src)); 8677 effect(TEMP_DEF res, TEMP cr0); 8678 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8679 ins_encode %{ 8680 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8681 R0, 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 getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8692 match(Set res (GetAndAddL mem_ptr src)); 8693 effect(TEMP_DEF res, TEMP cr0); 8694 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8695 ins_encode %{ 8696 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8697 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8698 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8699 __ isync(); 8700 } else { 8701 __ sync(); 8702 } 8703 %} 8704 ins_pipe(pipe_class_default); 8705 %} 8706 8707 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8708 match(Set res (GetAndSetB mem_ptr src)); 8709 predicate(VM_Version::has_lqarx()); 8710 effect(TEMP_DEF res, TEMP cr0); 8711 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8712 ins_encode %{ 8713 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8714 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8715 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8716 __ isync(); 8717 } else { 8718 __ sync(); 8719 } 8720 %} 8721 ins_pipe(pipe_class_default); 8722 %} 8723 8724 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8725 match(Set res (GetAndSetB mem_ptr src)); 8726 predicate(!VM_Version::has_lqarx()); 8727 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8728 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8729 ins_encode %{ 8730 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8731 R0, $tmp1$$Register, $tmp2$$Register, 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 getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8742 match(Set res (GetAndSetS mem_ptr src)); 8743 predicate(VM_Version::has_lqarx()); 8744 effect(TEMP_DEF res, TEMP cr0); 8745 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8746 ins_encode %{ 8747 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8748 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8749 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8750 __ isync(); 8751 } else { 8752 __ sync(); 8753 } 8754 %} 8755 ins_pipe(pipe_class_default); 8756 %} 8757 8758 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8759 match(Set res (GetAndSetS mem_ptr src)); 8760 predicate(!VM_Version::has_lqarx()); 8761 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8762 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8763 ins_encode %{ 8764 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8765 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8766 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8767 __ isync(); 8768 } else { 8769 __ sync(); 8770 } 8771 %} 8772 ins_pipe(pipe_class_default); 8773 %} 8774 8775 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8776 match(Set res (GetAndSetI mem_ptr src)); 8777 effect(TEMP_DEF res, TEMP cr0); 8778 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8779 ins_encode %{ 8780 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8781 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 getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8792 match(Set res (GetAndSetL mem_ptr src)); 8793 effect(TEMP_DEF res, TEMP cr0); 8794 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8795 ins_encode %{ 8796 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8797 MacroAssembler::cmpxchgx_hint_atomic_update()); 8798 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8799 __ isync(); 8800 } else { 8801 __ sync(); 8802 } 8803 %} 8804 ins_pipe(pipe_class_default); 8805 %} 8806 8807 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8808 match(Set res (GetAndSetP mem_ptr src)); 8809 effect(TEMP_DEF res, TEMP cr0); 8810 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8811 ins_encode %{ 8812 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8813 MacroAssembler::cmpxchgx_hint_atomic_update()); 8814 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8815 __ isync(); 8816 } else { 8817 __ sync(); 8818 } 8819 %} 8820 ins_pipe(pipe_class_default); 8821 %} 8822 8823 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8824 match(Set res (GetAndSetN mem_ptr src)); 8825 effect(TEMP_DEF res, TEMP cr0); 8826 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8827 ins_encode %{ 8828 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8829 MacroAssembler::cmpxchgx_hint_atomic_update()); 8830 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8831 __ isync(); 8832 } else { 8833 __ sync(); 8834 } 8835 %} 8836 ins_pipe(pipe_class_default); 8837 %} 8838 8839 //----------Arithmetic Instructions-------------------------------------------- 8840 // Addition Instructions 8841 8842 // Register Addition 8843 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8844 match(Set dst (AddI src1 src2)); 8845 format %{ "ADD $dst, $src1, $src2" %} 8846 size(4); 8847 ins_encode %{ 8848 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8849 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8850 %} 8851 ins_pipe(pipe_class_default); 8852 %} 8853 8854 // Expand does not work with above instruct. (??) 8855 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8856 // no match-rule 8857 effect(DEF dst, USE src1, USE src2); 8858 format %{ "ADD $dst, $src1, $src2" %} 8859 size(4); 8860 ins_encode %{ 8861 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8862 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8863 %} 8864 ins_pipe(pipe_class_default); 8865 %} 8866 8867 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8868 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8869 ins_cost(DEFAULT_COST*3); 8870 8871 expand %{ 8872 // FIXME: we should do this in the ideal world. 8873 iRegIdst tmp1; 8874 iRegIdst tmp2; 8875 addI_reg_reg(tmp1, src1, src2); 8876 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8877 addI_reg_reg(dst, tmp1, tmp2); 8878 %} 8879 %} 8880 8881 // Immediate Addition 8882 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8883 match(Set dst (AddI src1 src2)); 8884 format %{ "ADDI $dst, $src1, $src2" %} 8885 size(4); 8886 ins_encode %{ 8887 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8888 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8889 %} 8890 ins_pipe(pipe_class_default); 8891 %} 8892 8893 // Immediate Addition with 16-bit shifted operand 8894 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8895 match(Set dst (AddI src1 src2)); 8896 format %{ "ADDIS $dst, $src1, $src2" %} 8897 size(4); 8898 ins_encode %{ 8899 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8900 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8901 %} 8902 ins_pipe(pipe_class_default); 8903 %} 8904 8905 // Long Addition 8906 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8907 match(Set dst (AddL src1 src2)); 8908 format %{ "ADD $dst, $src1, $src2 \t// long" %} 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 // Expand does not work with above instruct. (??) 8918 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8919 // no match-rule 8920 effect(DEF dst, USE src1, USE src2); 8921 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8922 size(4); 8923 ins_encode %{ 8924 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8925 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8926 %} 8927 ins_pipe(pipe_class_default); 8928 %} 8929 8930 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8931 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8932 ins_cost(DEFAULT_COST*3); 8933 8934 expand %{ 8935 // FIXME: we should do this in the ideal world. 8936 iRegLdst tmp1; 8937 iRegLdst tmp2; 8938 addL_reg_reg(tmp1, src1, src2); 8939 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8940 addL_reg_reg(dst, tmp1, tmp2); 8941 %} 8942 %} 8943 8944 // AddL + ConvL2I. 8945 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8946 match(Set dst (ConvL2I (AddL src1 src2))); 8947 8948 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8949 size(4); 8950 ins_encode %{ 8951 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8952 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8953 %} 8954 ins_pipe(pipe_class_default); 8955 %} 8956 8957 // No constant pool entries required. 8958 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8959 match(Set dst (AddL src1 src2)); 8960 8961 format %{ "ADDI $dst, $src1, $src2" %} 8962 size(4); 8963 ins_encode %{ 8964 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8965 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8966 %} 8967 ins_pipe(pipe_class_default); 8968 %} 8969 8970 // Long Immediate Addition with 16-bit shifted operand. 8971 // No constant pool entries required. 8972 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8973 match(Set dst (AddL src1 src2)); 8974 8975 format %{ "ADDIS $dst, $src1, $src2" %} 8976 size(4); 8977 ins_encode %{ 8978 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8979 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8980 %} 8981 ins_pipe(pipe_class_default); 8982 %} 8983 8984 // Pointer Register Addition 8985 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8986 match(Set dst (AddP src1 src2)); 8987 format %{ "ADD $dst, $src1, $src2" %} 8988 size(4); 8989 ins_encode %{ 8990 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8991 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8992 %} 8993 ins_pipe(pipe_class_default); 8994 %} 8995 8996 // Pointer Immediate Addition 8997 // No constant pool entries required. 8998 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8999 match(Set dst (AddP src1 src2)); 9000 9001 format %{ "ADDI $dst, $src1, $src2" %} 9002 size(4); 9003 ins_encode %{ 9004 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 9005 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 9006 %} 9007 ins_pipe(pipe_class_default); 9008 %} 9009 9010 // Pointer Immediate Addition with 16-bit shifted operand. 9011 // No constant pool entries required. 9012 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 9013 match(Set dst (AddP src1 src2)); 9014 9015 format %{ "ADDIS $dst, $src1, $src2" %} 9016 size(4); 9017 ins_encode %{ 9018 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 9019 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 9020 %} 9021 ins_pipe(pipe_class_default); 9022 %} 9023 9024 //--------------------- 9025 // Subtraction Instructions 9026 9027 // Register Subtraction 9028 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9029 match(Set dst (SubI src1 src2)); 9030 format %{ "SUBF $dst, $src2, $src1" %} 9031 size(4); 9032 ins_encode %{ 9033 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9034 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9035 %} 9036 ins_pipe(pipe_class_default); 9037 %} 9038 9039 // Immediate Subtraction 9040 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 9041 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 9042 9043 // SubI from constant (using subfic). 9044 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 9045 match(Set dst (SubI src1 src2)); 9046 format %{ "SUBI $dst, $src1, $src2" %} 9047 9048 size(4); 9049 ins_encode %{ 9050 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 9051 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 9052 %} 9053 ins_pipe(pipe_class_default); 9054 %} 9055 9056 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 9057 // positive integers and 0xF...F for negative ones. 9058 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 9059 // no match-rule, false predicate 9060 effect(DEF dst, USE src); 9061 predicate(false); 9062 9063 format %{ "SRAWI $dst, $src, #31" %} 9064 size(4); 9065 ins_encode %{ 9066 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9067 __ srawi($dst$$Register, $src$$Register, 0x1f); 9068 %} 9069 ins_pipe(pipe_class_default); 9070 %} 9071 9072 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 9073 match(Set dst (AbsI src)); 9074 ins_cost(DEFAULT_COST*3); 9075 9076 expand %{ 9077 iRegIdst tmp1; 9078 iRegIdst tmp2; 9079 signmask32I_regI(tmp1, src); 9080 xorI_reg_reg(tmp2, tmp1, src); 9081 subI_reg_reg(dst, tmp2, tmp1); 9082 %} 9083 %} 9084 9085 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9086 match(Set dst (SubI zero src2)); 9087 format %{ "NEG $dst, $src2" %} 9088 size(4); 9089 ins_encode %{ 9090 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9091 __ neg($dst$$Register, $src2$$Register); 9092 %} 9093 ins_pipe(pipe_class_default); 9094 %} 9095 9096 // Long subtraction 9097 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9098 match(Set dst (SubL src1 src2)); 9099 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9100 size(4); 9101 ins_encode %{ 9102 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9103 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9104 %} 9105 ins_pipe(pipe_class_default); 9106 %} 9107 9108 // SubL + convL2I. 9109 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9110 match(Set dst (ConvL2I (SubL src1 src2))); 9111 9112 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9113 size(4); 9114 ins_encode %{ 9115 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9116 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9117 %} 9118 ins_pipe(pipe_class_default); 9119 %} 9120 9121 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9122 // positive longs and 0xF...F for negative ones. 9123 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9124 // no match-rule, false predicate 9125 effect(DEF dst, USE src); 9126 predicate(false); 9127 9128 format %{ "SRADI $dst, $src, #63" %} 9129 size(4); 9130 ins_encode %{ 9131 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9132 __ sradi($dst$$Register, $src$$Register, 0x3f); 9133 %} 9134 ins_pipe(pipe_class_default); 9135 %} 9136 9137 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9138 // positive longs and 0xF...F for negative ones. 9139 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9140 // no match-rule, false predicate 9141 effect(DEF dst, USE src); 9142 predicate(false); 9143 9144 format %{ "SRADI $dst, $src, #63" %} 9145 size(4); 9146 ins_encode %{ 9147 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9148 __ sradi($dst$$Register, $src$$Register, 0x3f); 9149 %} 9150 ins_pipe(pipe_class_default); 9151 %} 9152 9153 // Long negation 9154 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9155 match(Set dst (SubL zero src2)); 9156 format %{ "NEG $dst, $src2 \t// long" %} 9157 size(4); 9158 ins_encode %{ 9159 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9160 __ neg($dst$$Register, $src2$$Register); 9161 %} 9162 ins_pipe(pipe_class_default); 9163 %} 9164 9165 // NegL + ConvL2I. 9166 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9167 match(Set dst (ConvL2I (SubL zero src2))); 9168 9169 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9170 size(4); 9171 ins_encode %{ 9172 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9173 __ neg($dst$$Register, $src2$$Register); 9174 %} 9175 ins_pipe(pipe_class_default); 9176 %} 9177 9178 // Multiplication Instructions 9179 // Integer Multiplication 9180 9181 // Register Multiplication 9182 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9183 match(Set dst (MulI src1 src2)); 9184 ins_cost(DEFAULT_COST); 9185 9186 format %{ "MULLW $dst, $src1, $src2" %} 9187 size(4); 9188 ins_encode %{ 9189 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9190 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9191 %} 9192 ins_pipe(pipe_class_default); 9193 %} 9194 9195 // Immediate Multiplication 9196 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9197 match(Set dst (MulI src1 src2)); 9198 ins_cost(DEFAULT_COST); 9199 9200 format %{ "MULLI $dst, $src1, $src2" %} 9201 size(4); 9202 ins_encode %{ 9203 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9204 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9205 %} 9206 ins_pipe(pipe_class_default); 9207 %} 9208 9209 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9210 match(Set dst (MulL src1 src2)); 9211 ins_cost(DEFAULT_COST); 9212 9213 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9214 size(4); 9215 ins_encode %{ 9216 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9217 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9218 %} 9219 ins_pipe(pipe_class_default); 9220 %} 9221 9222 // Multiply high for optimized long division by constant. 9223 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9224 match(Set dst (MulHiL src1 src2)); 9225 ins_cost(DEFAULT_COST); 9226 9227 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9228 size(4); 9229 ins_encode %{ 9230 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9231 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9232 %} 9233 ins_pipe(pipe_class_default); 9234 %} 9235 9236 // Immediate Multiplication 9237 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9238 match(Set dst (MulL src1 src2)); 9239 ins_cost(DEFAULT_COST); 9240 9241 format %{ "MULLI $dst, $src1, $src2" %} 9242 size(4); 9243 ins_encode %{ 9244 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9245 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9246 %} 9247 ins_pipe(pipe_class_default); 9248 %} 9249 9250 // Integer Division with Immediate -1: Negate. 9251 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9252 match(Set dst (DivI src1 src2)); 9253 ins_cost(DEFAULT_COST); 9254 9255 format %{ "NEG $dst, $src1 \t// /-1" %} 9256 size(4); 9257 ins_encode %{ 9258 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9259 __ neg($dst$$Register, $src1$$Register); 9260 %} 9261 ins_pipe(pipe_class_default); 9262 %} 9263 9264 // Integer Division with constant, but not -1. 9265 // We should be able to improve this by checking the type of src2. 9266 // It might well be that src2 is known to be positive. 9267 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9268 match(Set dst (DivI src1 src2)); 9269 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9270 ins_cost(2*DEFAULT_COST); 9271 9272 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9273 size(4); 9274 ins_encode %{ 9275 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9276 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9277 %} 9278 ins_pipe(pipe_class_default); 9279 %} 9280 9281 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9282 effect(USE_DEF dst, USE src1, USE crx); 9283 predicate(false); 9284 9285 ins_variable_size_depending_on_alignment(true); 9286 9287 format %{ "CMOVE $dst, neg($src1), $crx" %} 9288 // Worst case is branch + move + stop, no stop without scheduler. 9289 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9290 ins_encode %{ 9291 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9292 Label done; 9293 __ bne($crx$$CondRegister, done); 9294 __ neg($dst$$Register, $src1$$Register); 9295 // TODO PPC port __ endgroup_if_needed(_size == 12); 9296 __ bind(done); 9297 %} 9298 ins_pipe(pipe_class_default); 9299 %} 9300 9301 // Integer Division with Registers not containing constants. 9302 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9303 match(Set dst (DivI src1 src2)); 9304 ins_cost(10*DEFAULT_COST); 9305 9306 expand %{ 9307 immI16 imm %{ (int)-1 %} 9308 flagsReg tmp1; 9309 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9310 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9311 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9312 %} 9313 %} 9314 9315 // Long Division with Immediate -1: Negate. 9316 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9317 match(Set dst (DivL src1 src2)); 9318 ins_cost(DEFAULT_COST); 9319 9320 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9321 size(4); 9322 ins_encode %{ 9323 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9324 __ neg($dst$$Register, $src1$$Register); 9325 %} 9326 ins_pipe(pipe_class_default); 9327 %} 9328 9329 // Long Division with constant, but not -1. 9330 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9331 match(Set dst (DivL src1 src2)); 9332 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9333 ins_cost(2*DEFAULT_COST); 9334 9335 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9336 size(4); 9337 ins_encode %{ 9338 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9339 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9340 %} 9341 ins_pipe(pipe_class_default); 9342 %} 9343 9344 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9345 effect(USE_DEF dst, USE src1, USE crx); 9346 predicate(false); 9347 9348 ins_variable_size_depending_on_alignment(true); 9349 9350 format %{ "CMOVE $dst, neg($src1), $crx" %} 9351 // Worst case is branch + move + stop, no stop without scheduler. 9352 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9353 ins_encode %{ 9354 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9355 Label done; 9356 __ bne($crx$$CondRegister, done); 9357 __ neg($dst$$Register, $src1$$Register); 9358 // TODO PPC port __ endgroup_if_needed(_size == 12); 9359 __ bind(done); 9360 %} 9361 ins_pipe(pipe_class_default); 9362 %} 9363 9364 // Long Division with Registers not containing constants. 9365 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9366 match(Set dst (DivL src1 src2)); 9367 ins_cost(10*DEFAULT_COST); 9368 9369 expand %{ 9370 immL16 imm %{ (int)-1 %} 9371 flagsReg tmp1; 9372 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9373 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9374 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9375 %} 9376 %} 9377 9378 // Integer Remainder with registers. 9379 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9380 match(Set dst (ModI src1 src2)); 9381 ins_cost(10*DEFAULT_COST); 9382 9383 expand %{ 9384 immI16 imm %{ (int)-1 %} 9385 flagsReg tmp1; 9386 iRegIdst tmp2; 9387 iRegIdst tmp3; 9388 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9389 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9390 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9391 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9392 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9393 %} 9394 %} 9395 9396 // Long Remainder with registers 9397 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9398 match(Set dst (ModL src1 src2)); 9399 ins_cost(10*DEFAULT_COST); 9400 9401 expand %{ 9402 immL16 imm %{ (int)-1 %} 9403 flagsReg tmp1; 9404 iRegLdst tmp2; 9405 iRegLdst tmp3; 9406 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9407 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9408 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9409 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9410 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9411 %} 9412 %} 9413 9414 // Integer Shift Instructions 9415 9416 // Register Shift Left 9417 9418 // Clear all but the lowest #mask bits. 9419 // Used to normalize shift amounts in registers. 9420 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9421 // no match-rule, false predicate 9422 effect(DEF dst, USE src, USE mask); 9423 predicate(false); 9424 9425 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9426 size(4); 9427 ins_encode %{ 9428 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9429 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9430 %} 9431 ins_pipe(pipe_class_default); 9432 %} 9433 9434 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9435 // no match-rule, false predicate 9436 effect(DEF dst, USE src1, USE src2); 9437 predicate(false); 9438 9439 format %{ "SLW $dst, $src1, $src2" %} 9440 size(4); 9441 ins_encode %{ 9442 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9443 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9444 %} 9445 ins_pipe(pipe_class_default); 9446 %} 9447 9448 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9449 match(Set dst (LShiftI src1 src2)); 9450 ins_cost(DEFAULT_COST*2); 9451 expand %{ 9452 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9453 iRegIdst tmpI; 9454 maskI_reg_imm(tmpI, src2, mask); 9455 lShiftI_reg_reg(dst, src1, tmpI); 9456 %} 9457 %} 9458 9459 // Register Shift Left Immediate 9460 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9461 match(Set dst (LShiftI src1 src2)); 9462 9463 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9464 size(4); 9465 ins_encode %{ 9466 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9467 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9468 %} 9469 ins_pipe(pipe_class_default); 9470 %} 9471 9472 // AndI with negpow2-constant + LShiftI 9473 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9474 match(Set dst (LShiftI (AndI src1 src2) src3)); 9475 predicate(UseRotateAndMaskInstructionsPPC64); 9476 9477 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9478 size(4); 9479 ins_encode %{ 9480 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9481 long src2 = $src2$$constant; 9482 long src3 = $src3$$constant; 9483 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9484 if (maskbits >= 32) { 9485 __ li($dst$$Register, 0); // addi 9486 } else { 9487 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9488 } 9489 %} 9490 ins_pipe(pipe_class_default); 9491 %} 9492 9493 // RShiftI + AndI with negpow2-constant + LShiftI 9494 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9495 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9496 predicate(UseRotateAndMaskInstructionsPPC64); 9497 9498 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9499 size(4); 9500 ins_encode %{ 9501 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9502 long src2 = $src2$$constant; 9503 long src3 = $src3$$constant; 9504 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9505 if (maskbits >= 32) { 9506 __ li($dst$$Register, 0); // addi 9507 } else { 9508 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9509 } 9510 %} 9511 ins_pipe(pipe_class_default); 9512 %} 9513 9514 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9515 // no match-rule, false predicate 9516 effect(DEF dst, USE src1, USE src2); 9517 predicate(false); 9518 9519 format %{ "SLD $dst, $src1, $src2" %} 9520 size(4); 9521 ins_encode %{ 9522 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9523 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9524 %} 9525 ins_pipe(pipe_class_default); 9526 %} 9527 9528 // Register Shift Left 9529 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9530 match(Set dst (LShiftL src1 src2)); 9531 ins_cost(DEFAULT_COST*2); 9532 expand %{ 9533 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9534 iRegIdst tmpI; 9535 maskI_reg_imm(tmpI, src2, mask); 9536 lShiftL_regL_regI(dst, src1, tmpI); 9537 %} 9538 %} 9539 9540 // Register Shift Left Immediate 9541 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9542 match(Set dst (LShiftL src1 src2)); 9543 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9544 size(4); 9545 ins_encode %{ 9546 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9547 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9548 %} 9549 ins_pipe(pipe_class_default); 9550 %} 9551 9552 // If we shift more than 32 bits, we need not convert I2L. 9553 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9554 match(Set dst (LShiftL (ConvI2L src1) src2)); 9555 ins_cost(DEFAULT_COST); 9556 9557 size(4); 9558 format %{ "SLDI $dst, i2l($src1), $src2" %} 9559 ins_encode %{ 9560 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9561 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9562 %} 9563 ins_pipe(pipe_class_default); 9564 %} 9565 9566 // Shift a postivie int to the left. 9567 // Clrlsldi clears the upper 32 bits and shifts. 9568 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9569 match(Set dst (LShiftL (ConvI2L src1) src2)); 9570 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9571 9572 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9573 size(4); 9574 ins_encode %{ 9575 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9576 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9577 %} 9578 ins_pipe(pipe_class_default); 9579 %} 9580 9581 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9582 // no match-rule, false predicate 9583 effect(DEF dst, USE src1, USE src2); 9584 predicate(false); 9585 9586 format %{ "SRAW $dst, $src1, $src2" %} 9587 size(4); 9588 ins_encode %{ 9589 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9590 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9591 %} 9592 ins_pipe(pipe_class_default); 9593 %} 9594 9595 // Register Arithmetic Shift Right 9596 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9597 match(Set dst (RShiftI src1 src2)); 9598 ins_cost(DEFAULT_COST*2); 9599 expand %{ 9600 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9601 iRegIdst tmpI; 9602 maskI_reg_imm(tmpI, src2, mask); 9603 arShiftI_reg_reg(dst, src1, tmpI); 9604 %} 9605 %} 9606 9607 // Register Arithmetic Shift Right Immediate 9608 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9609 match(Set dst (RShiftI src1 src2)); 9610 9611 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9612 size(4); 9613 ins_encode %{ 9614 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9615 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9616 %} 9617 ins_pipe(pipe_class_default); 9618 %} 9619 9620 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9621 // no match-rule, false predicate 9622 effect(DEF dst, USE src1, USE src2); 9623 predicate(false); 9624 9625 format %{ "SRAD $dst, $src1, $src2" %} 9626 size(4); 9627 ins_encode %{ 9628 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9629 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9630 %} 9631 ins_pipe(pipe_class_default); 9632 %} 9633 9634 // Register Shift Right Arithmetic Long 9635 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9636 match(Set dst (RShiftL src1 src2)); 9637 ins_cost(DEFAULT_COST*2); 9638 9639 expand %{ 9640 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9641 iRegIdst tmpI; 9642 maskI_reg_imm(tmpI, src2, mask); 9643 arShiftL_regL_regI(dst, src1, tmpI); 9644 %} 9645 %} 9646 9647 // Register Shift Right Immediate 9648 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9649 match(Set dst (RShiftL src1 src2)); 9650 9651 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9652 size(4); 9653 ins_encode %{ 9654 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9655 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9656 %} 9657 ins_pipe(pipe_class_default); 9658 %} 9659 9660 // RShiftL + ConvL2I 9661 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9662 match(Set dst (ConvL2I (RShiftL src1 src2))); 9663 9664 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9665 size(4); 9666 ins_encode %{ 9667 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9668 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9669 %} 9670 ins_pipe(pipe_class_default); 9671 %} 9672 9673 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9674 // no match-rule, false predicate 9675 effect(DEF dst, USE src1, USE src2); 9676 predicate(false); 9677 9678 format %{ "SRW $dst, $src1, $src2" %} 9679 size(4); 9680 ins_encode %{ 9681 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9682 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9683 %} 9684 ins_pipe(pipe_class_default); 9685 %} 9686 9687 // Register Shift Right 9688 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9689 match(Set dst (URShiftI src1 src2)); 9690 ins_cost(DEFAULT_COST*2); 9691 9692 expand %{ 9693 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9694 iRegIdst tmpI; 9695 maskI_reg_imm(tmpI, src2, mask); 9696 urShiftI_reg_reg(dst, src1, tmpI); 9697 %} 9698 %} 9699 9700 // Register Shift Right Immediate 9701 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9702 match(Set dst (URShiftI src1 src2)); 9703 9704 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9705 size(4); 9706 ins_encode %{ 9707 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9708 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9709 %} 9710 ins_pipe(pipe_class_default); 9711 %} 9712 9713 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9714 // no match-rule, false predicate 9715 effect(DEF dst, USE src1, USE src2); 9716 predicate(false); 9717 9718 format %{ "SRD $dst, $src1, $src2" %} 9719 size(4); 9720 ins_encode %{ 9721 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9722 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9723 %} 9724 ins_pipe(pipe_class_default); 9725 %} 9726 9727 // Register Shift Right 9728 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9729 match(Set dst (URShiftL src1 src2)); 9730 ins_cost(DEFAULT_COST*2); 9731 9732 expand %{ 9733 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9734 iRegIdst tmpI; 9735 maskI_reg_imm(tmpI, src2, mask); 9736 urShiftL_regL_regI(dst, src1, tmpI); 9737 %} 9738 %} 9739 9740 // Register Shift Right Immediate 9741 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9742 match(Set dst (URShiftL src1 src2)); 9743 9744 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9745 size(4); 9746 ins_encode %{ 9747 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9748 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9749 %} 9750 ins_pipe(pipe_class_default); 9751 %} 9752 9753 // URShiftL + ConvL2I. 9754 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9755 match(Set dst (ConvL2I (URShiftL src1 src2))); 9756 9757 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9758 size(4); 9759 ins_encode %{ 9760 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9761 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9762 %} 9763 ins_pipe(pipe_class_default); 9764 %} 9765 9766 // Register Shift Right Immediate with a CastP2X 9767 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9768 match(Set dst (URShiftL (CastP2X src1) src2)); 9769 9770 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9771 size(4); 9772 ins_encode %{ 9773 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9774 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9775 %} 9776 ins_pipe(pipe_class_default); 9777 %} 9778 9779 // Bitfield Extract: URShiftI + AndI 9780 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9781 match(Set dst (AndI (URShiftI src1 src2) src3)); 9782 9783 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9784 size(4); 9785 ins_encode %{ 9786 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9787 int rshift = ($src2$$constant) & 0x1f; 9788 int length = log2_long(((jlong) $src3$$constant) + 1); 9789 if (rshift + length > 32) { 9790 // if necessary, adjust mask to omit rotated bits. 9791 length = 32 - rshift; 9792 } 9793 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9794 %} 9795 ins_pipe(pipe_class_default); 9796 %} 9797 9798 // Bitfield Extract: URShiftL + AndL 9799 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9800 match(Set dst (AndL (URShiftL src1 src2) src3)); 9801 9802 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9803 size(4); 9804 ins_encode %{ 9805 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9806 int rshift = ($src2$$constant) & 0x3f; 9807 int length = log2_long(((jlong) $src3$$constant) + 1); 9808 if (rshift + length > 64) { 9809 // if necessary, adjust mask to omit rotated bits. 9810 length = 64 - rshift; 9811 } 9812 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9813 %} 9814 ins_pipe(pipe_class_default); 9815 %} 9816 9817 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9818 match(Set dst (ConvL2I (ConvI2L src))); 9819 9820 format %{ "EXTSW $dst, $src \t// int->int" %} 9821 size(4); 9822 ins_encode %{ 9823 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9824 __ extsw($dst$$Register, $src$$Register); 9825 %} 9826 ins_pipe(pipe_class_default); 9827 %} 9828 9829 //----------Rotate Instructions------------------------------------------------ 9830 9831 // Rotate Left by 8-bit immediate 9832 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9833 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9834 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9835 9836 format %{ "ROTLWI $dst, $src, $lshift" %} 9837 size(4); 9838 ins_encode %{ 9839 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9840 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9841 %} 9842 ins_pipe(pipe_class_default); 9843 %} 9844 9845 // Rotate Right by 8-bit immediate 9846 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9847 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9848 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9849 9850 format %{ "ROTRWI $dst, $rshift" %} 9851 size(4); 9852 ins_encode %{ 9853 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9854 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9855 %} 9856 ins_pipe(pipe_class_default); 9857 %} 9858 9859 //----------Floating Point Arithmetic Instructions----------------------------- 9860 9861 // Add float single precision 9862 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9863 match(Set dst (AddF src1 src2)); 9864 9865 format %{ "FADDS $dst, $src1, $src2" %} 9866 size(4); 9867 ins_encode %{ 9868 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9869 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9870 %} 9871 ins_pipe(pipe_class_default); 9872 %} 9873 9874 // Add float double precision 9875 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9876 match(Set dst (AddD src1 src2)); 9877 9878 format %{ "FADD $dst, $src1, $src2" %} 9879 size(4); 9880 ins_encode %{ 9881 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9882 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9883 %} 9884 ins_pipe(pipe_class_default); 9885 %} 9886 9887 // Sub float single precision 9888 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9889 match(Set dst (SubF src1 src2)); 9890 9891 format %{ "FSUBS $dst, $src1, $src2" %} 9892 size(4); 9893 ins_encode %{ 9894 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9895 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9896 %} 9897 ins_pipe(pipe_class_default); 9898 %} 9899 9900 // Sub float double precision 9901 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9902 match(Set dst (SubD src1 src2)); 9903 format %{ "FSUB $dst, $src1, $src2" %} 9904 size(4); 9905 ins_encode %{ 9906 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9907 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9908 %} 9909 ins_pipe(pipe_class_default); 9910 %} 9911 9912 // Mul float single precision 9913 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9914 match(Set dst (MulF src1 src2)); 9915 format %{ "FMULS $dst, $src1, $src2" %} 9916 size(4); 9917 ins_encode %{ 9918 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9919 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9920 %} 9921 ins_pipe(pipe_class_default); 9922 %} 9923 9924 // Mul float double precision 9925 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9926 match(Set dst (MulD src1 src2)); 9927 format %{ "FMUL $dst, $src1, $src2" %} 9928 size(4); 9929 ins_encode %{ 9930 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9931 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9932 %} 9933 ins_pipe(pipe_class_default); 9934 %} 9935 9936 // Div float single precision 9937 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9938 match(Set dst (DivF src1 src2)); 9939 format %{ "FDIVS $dst, $src1, $src2" %} 9940 size(4); 9941 ins_encode %{ 9942 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9943 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9944 %} 9945 ins_pipe(pipe_class_default); 9946 %} 9947 9948 // Div float double precision 9949 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9950 match(Set dst (DivD src1 src2)); 9951 format %{ "FDIV $dst, $src1, $src2" %} 9952 size(4); 9953 ins_encode %{ 9954 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9955 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9956 %} 9957 ins_pipe(pipe_class_default); 9958 %} 9959 9960 // Absolute float single precision 9961 instruct absF_reg(regF dst, regF src) %{ 9962 match(Set dst (AbsF src)); 9963 format %{ "FABS $dst, $src \t// float" %} 9964 size(4); 9965 ins_encode %{ 9966 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9967 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9968 %} 9969 ins_pipe(pipe_class_default); 9970 %} 9971 9972 // Absolute float double precision 9973 instruct absD_reg(regD dst, regD src) %{ 9974 match(Set dst (AbsD src)); 9975 format %{ "FABS $dst, $src \t// double" %} 9976 size(4); 9977 ins_encode %{ 9978 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9979 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9980 %} 9981 ins_pipe(pipe_class_default); 9982 %} 9983 9984 instruct negF_reg(regF dst, regF src) %{ 9985 match(Set dst (NegF src)); 9986 format %{ "FNEG $dst, $src \t// float" %} 9987 size(4); 9988 ins_encode %{ 9989 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9990 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9991 %} 9992 ins_pipe(pipe_class_default); 9993 %} 9994 9995 instruct negD_reg(regD dst, regD src) %{ 9996 match(Set dst (NegD src)); 9997 format %{ "FNEG $dst, $src \t// double" %} 9998 size(4); 9999 ins_encode %{ 10000 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 10001 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 10002 %} 10003 ins_pipe(pipe_class_default); 10004 %} 10005 10006 // AbsF + NegF. 10007 instruct negF_absF_reg(regF dst, regF src) %{ 10008 match(Set dst (NegF (AbsF src))); 10009 format %{ "FNABS $dst, $src \t// float" %} 10010 size(4); 10011 ins_encode %{ 10012 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10013 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10014 %} 10015 ins_pipe(pipe_class_default); 10016 %} 10017 10018 // AbsD + NegD. 10019 instruct negD_absD_reg(regD dst, regD src) %{ 10020 match(Set dst (NegD (AbsD src))); 10021 format %{ "FNABS $dst, $src \t// double" %} 10022 size(4); 10023 ins_encode %{ 10024 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10025 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10026 %} 10027 ins_pipe(pipe_class_default); 10028 %} 10029 10030 // VM_Version::has_fsqrt() decides if this node will be used. 10031 // Sqrt float double precision 10032 instruct sqrtD_reg(regD dst, regD src) %{ 10033 match(Set dst (SqrtD src)); 10034 format %{ "FSQRT $dst, $src" %} 10035 size(4); 10036 ins_encode %{ 10037 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 10038 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 10039 %} 10040 ins_pipe(pipe_class_default); 10041 %} 10042 10043 // Single-precision sqrt. 10044 instruct sqrtF_reg(regF dst, regF src) %{ 10045 match(Set dst (SqrtF src)); 10046 predicate(VM_Version::has_fsqrts()); 10047 ins_cost(DEFAULT_COST); 10048 10049 format %{ "FSQRTS $dst, $src" %} 10050 size(4); 10051 ins_encode %{ 10052 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 10053 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 10054 %} 10055 ins_pipe(pipe_class_default); 10056 %} 10057 10058 instruct roundDouble_nop(regD dst) %{ 10059 match(Set dst (RoundDouble dst)); 10060 ins_cost(0); 10061 10062 format %{ " -- \t// RoundDouble not needed - empty" %} 10063 size(0); 10064 // PPC results are already "rounded" (i.e., normal-format IEEE). 10065 ins_encode( /*empty*/ ); 10066 ins_pipe(pipe_class_default); 10067 %} 10068 10069 instruct roundFloat_nop(regF dst) %{ 10070 match(Set dst (RoundFloat dst)); 10071 ins_cost(0); 10072 10073 format %{ " -- \t// RoundFloat not needed - empty" %} 10074 size(0); 10075 // PPC results are already "rounded" (i.e., normal-format IEEE). 10076 ins_encode( /*empty*/ ); 10077 ins_pipe(pipe_class_default); 10078 %} 10079 10080 10081 // Multiply-Accumulate 10082 // src1 * src2 + src3 10083 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10084 match(Set dst (FmaF src3 (Binary src1 src2))); 10085 10086 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10087 size(4); 10088 ins_encode %{ 10089 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10090 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10091 %} 10092 ins_pipe(pipe_class_default); 10093 %} 10094 10095 // src1 * src2 + src3 10096 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10097 match(Set dst (FmaD src3 (Binary src1 src2))); 10098 10099 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10100 size(4); 10101 ins_encode %{ 10102 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10103 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10104 %} 10105 ins_pipe(pipe_class_default); 10106 %} 10107 10108 // -src1 * src2 + src3 = -(src1*src2-src3) 10109 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10110 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10111 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10112 10113 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10114 size(4); 10115 ins_encode %{ 10116 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10117 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10118 %} 10119 ins_pipe(pipe_class_default); 10120 %} 10121 10122 // -src1 * src2 + src3 = -(src1*src2-src3) 10123 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10124 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10125 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10126 10127 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10128 size(4); 10129 ins_encode %{ 10130 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10131 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10132 %} 10133 ins_pipe(pipe_class_default); 10134 %} 10135 10136 // -src1 * src2 - src3 = -(src1*src2+src3) 10137 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10138 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10139 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10140 10141 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10142 size(4); 10143 ins_encode %{ 10144 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10145 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10146 %} 10147 ins_pipe(pipe_class_default); 10148 %} 10149 10150 // -src1 * src2 - src3 = -(src1*src2+src3) 10151 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10152 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10153 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10154 10155 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10156 size(4); 10157 ins_encode %{ 10158 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10159 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10160 %} 10161 ins_pipe(pipe_class_default); 10162 %} 10163 10164 // src1 * src2 - src3 10165 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10166 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10167 10168 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10169 size(4); 10170 ins_encode %{ 10171 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10172 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10173 %} 10174 ins_pipe(pipe_class_default); 10175 %} 10176 10177 // src1 * src2 - src3 10178 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10179 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10180 10181 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10182 size(4); 10183 ins_encode %{ 10184 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10185 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10186 %} 10187 ins_pipe(pipe_class_default); 10188 %} 10189 10190 10191 //----------Logical Instructions----------------------------------------------- 10192 10193 // And Instructions 10194 10195 // Register And 10196 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10197 match(Set dst (AndI src1 src2)); 10198 format %{ "AND $dst, $src1, $src2" %} 10199 size(4); 10200 ins_encode %{ 10201 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10202 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10203 %} 10204 ins_pipe(pipe_class_default); 10205 %} 10206 10207 // Left shifted Immediate And 10208 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10209 match(Set dst (AndI src1 src2)); 10210 effect(KILL cr0); 10211 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10212 size(4); 10213 ins_encode %{ 10214 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10215 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10216 %} 10217 ins_pipe(pipe_class_default); 10218 %} 10219 10220 // Immediate And 10221 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10222 match(Set dst (AndI src1 src2)); 10223 effect(KILL cr0); 10224 10225 format %{ "ANDI $dst, $src1, $src2" %} 10226 size(4); 10227 ins_encode %{ 10228 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10229 // FIXME: avoid andi_ ? 10230 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10231 %} 10232 ins_pipe(pipe_class_default); 10233 %} 10234 10235 // Immediate And where the immediate is a negative power of 2. 10236 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10237 match(Set dst (AndI src1 src2)); 10238 format %{ "ANDWI $dst, $src1, $src2" %} 10239 size(4); 10240 ins_encode %{ 10241 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10242 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10243 %} 10244 ins_pipe(pipe_class_default); 10245 %} 10246 10247 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10248 match(Set dst (AndI src1 src2)); 10249 format %{ "ANDWI $dst, $src1, $src2" %} 10250 size(4); 10251 ins_encode %{ 10252 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10253 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10254 %} 10255 ins_pipe(pipe_class_default); 10256 %} 10257 10258 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10259 match(Set dst (AndI src1 src2)); 10260 predicate(UseRotateAndMaskInstructionsPPC64); 10261 format %{ "ANDWI $dst, $src1, $src2" %} 10262 size(4); 10263 ins_encode %{ 10264 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10265 __ rlwinm($dst$$Register, $src1$$Register, 0, 10266 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10267 %} 10268 ins_pipe(pipe_class_default); 10269 %} 10270 10271 // Register And Long 10272 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10273 match(Set dst (AndL src1 src2)); 10274 ins_cost(DEFAULT_COST); 10275 10276 format %{ "AND $dst, $src1, $src2 \t// long" %} 10277 size(4); 10278 ins_encode %{ 10279 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10280 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10281 %} 10282 ins_pipe(pipe_class_default); 10283 %} 10284 10285 // Immediate And long 10286 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10287 match(Set dst (AndL src1 src2)); 10288 effect(KILL cr0); 10289 10290 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10291 size(4); 10292 ins_encode %{ 10293 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10294 // FIXME: avoid andi_ ? 10295 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10296 %} 10297 ins_pipe(pipe_class_default); 10298 %} 10299 10300 // Immediate And Long where the immediate is a negative power of 2. 10301 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10302 match(Set dst (AndL src1 src2)); 10303 format %{ "ANDDI $dst, $src1, $src2" %} 10304 size(4); 10305 ins_encode %{ 10306 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10307 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10308 %} 10309 ins_pipe(pipe_class_default); 10310 %} 10311 10312 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10313 match(Set dst (AndL src1 src2)); 10314 format %{ "ANDDI $dst, $src1, $src2" %} 10315 size(4); 10316 ins_encode %{ 10317 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10318 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10319 %} 10320 ins_pipe(pipe_class_default); 10321 %} 10322 10323 // AndL + ConvL2I. 10324 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10325 match(Set dst (ConvL2I (AndL src1 src2))); 10326 ins_cost(DEFAULT_COST); 10327 10328 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10329 size(4); 10330 ins_encode %{ 10331 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10332 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10333 %} 10334 ins_pipe(pipe_class_default); 10335 %} 10336 10337 // Or Instructions 10338 10339 // Register Or 10340 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10341 match(Set dst (OrI src1 src2)); 10342 format %{ "OR $dst, $src1, $src2" %} 10343 size(4); 10344 ins_encode %{ 10345 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10346 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10347 %} 10348 ins_pipe(pipe_class_default); 10349 %} 10350 10351 // Expand does not work with above instruct. (??) 10352 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10353 // no match-rule 10354 effect(DEF dst, USE src1, USE src2); 10355 format %{ "OR $dst, $src1, $src2" %} 10356 size(4); 10357 ins_encode %{ 10358 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10359 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10360 %} 10361 ins_pipe(pipe_class_default); 10362 %} 10363 10364 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10365 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10366 ins_cost(DEFAULT_COST*3); 10367 10368 expand %{ 10369 // FIXME: we should do this in the ideal world. 10370 iRegIdst tmp1; 10371 iRegIdst tmp2; 10372 orI_reg_reg(tmp1, src1, src2); 10373 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10374 orI_reg_reg(dst, tmp1, tmp2); 10375 %} 10376 %} 10377 10378 // Immediate Or 10379 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10380 match(Set dst (OrI src1 src2)); 10381 format %{ "ORI $dst, $src1, $src2" %} 10382 size(4); 10383 ins_encode %{ 10384 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10385 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10386 %} 10387 ins_pipe(pipe_class_default); 10388 %} 10389 10390 // Register Or Long 10391 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10392 match(Set dst (OrL src1 src2)); 10393 ins_cost(DEFAULT_COST); 10394 10395 size(4); 10396 format %{ "OR $dst, $src1, $src2 \t// long" %} 10397 ins_encode %{ 10398 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10399 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10400 %} 10401 ins_pipe(pipe_class_default); 10402 %} 10403 10404 // OrL + ConvL2I. 10405 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10406 match(Set dst (ConvL2I (OrL src1 src2))); 10407 ins_cost(DEFAULT_COST); 10408 10409 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10410 size(4); 10411 ins_encode %{ 10412 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10413 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10414 %} 10415 ins_pipe(pipe_class_default); 10416 %} 10417 10418 // Immediate Or long 10419 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10420 match(Set dst (OrL src1 con)); 10421 ins_cost(DEFAULT_COST); 10422 10423 format %{ "ORI $dst, $src1, $con \t// long" %} 10424 size(4); 10425 ins_encode %{ 10426 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10427 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10428 %} 10429 ins_pipe(pipe_class_default); 10430 %} 10431 10432 // Xor Instructions 10433 10434 // Register Xor 10435 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10436 match(Set dst (XorI src1 src2)); 10437 format %{ "XOR $dst, $src1, $src2" %} 10438 size(4); 10439 ins_encode %{ 10440 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10441 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10442 %} 10443 ins_pipe(pipe_class_default); 10444 %} 10445 10446 // Expand does not work with above instruct. (??) 10447 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10448 // no match-rule 10449 effect(DEF dst, USE src1, USE src2); 10450 format %{ "XOR $dst, $src1, $src2" %} 10451 size(4); 10452 ins_encode %{ 10453 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10454 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10455 %} 10456 ins_pipe(pipe_class_default); 10457 %} 10458 10459 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10460 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10461 ins_cost(DEFAULT_COST*3); 10462 10463 expand %{ 10464 // FIXME: we should do this in the ideal world. 10465 iRegIdst tmp1; 10466 iRegIdst tmp2; 10467 xorI_reg_reg(tmp1, src1, src2); 10468 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10469 xorI_reg_reg(dst, tmp1, tmp2); 10470 %} 10471 %} 10472 10473 // Immediate Xor 10474 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10475 match(Set dst (XorI src1 src2)); 10476 format %{ "XORI $dst, $src1, $src2" %} 10477 size(4); 10478 ins_encode %{ 10479 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10480 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10481 %} 10482 ins_pipe(pipe_class_default); 10483 %} 10484 10485 // Register Xor Long 10486 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10487 match(Set dst (XorL src1 src2)); 10488 ins_cost(DEFAULT_COST); 10489 10490 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10491 size(4); 10492 ins_encode %{ 10493 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10494 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10495 %} 10496 ins_pipe(pipe_class_default); 10497 %} 10498 10499 // XorL + ConvL2I. 10500 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10501 match(Set dst (ConvL2I (XorL src1 src2))); 10502 ins_cost(DEFAULT_COST); 10503 10504 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10505 size(4); 10506 ins_encode %{ 10507 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10508 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10509 %} 10510 ins_pipe(pipe_class_default); 10511 %} 10512 10513 // Immediate Xor Long 10514 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10515 match(Set dst (XorL src1 src2)); 10516 ins_cost(DEFAULT_COST); 10517 10518 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10519 size(4); 10520 ins_encode %{ 10521 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10522 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10523 %} 10524 ins_pipe(pipe_class_default); 10525 %} 10526 10527 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10528 match(Set dst (XorI src1 src2)); 10529 ins_cost(DEFAULT_COST); 10530 10531 format %{ "NOT $dst, $src1 ($src2)" %} 10532 size(4); 10533 ins_encode %{ 10534 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10535 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10536 %} 10537 ins_pipe(pipe_class_default); 10538 %} 10539 10540 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10541 match(Set dst (XorL src1 src2)); 10542 ins_cost(DEFAULT_COST); 10543 10544 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10545 size(4); 10546 ins_encode %{ 10547 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10548 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10549 %} 10550 ins_pipe(pipe_class_default); 10551 %} 10552 10553 // And-complement 10554 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10555 match(Set dst (AndI (XorI src1 src2) src3)); 10556 ins_cost(DEFAULT_COST); 10557 10558 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10559 size(4); 10560 ins_encode( enc_andc(dst, src3, src1) ); 10561 ins_pipe(pipe_class_default); 10562 %} 10563 10564 // And-complement 10565 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10566 // no match-rule, false predicate 10567 effect(DEF dst, USE src1, USE src2); 10568 predicate(false); 10569 10570 format %{ "ANDC $dst, $src1, $src2" %} 10571 size(4); 10572 ins_encode %{ 10573 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10574 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10575 %} 10576 ins_pipe(pipe_class_default); 10577 %} 10578 10579 //----------Moves between int/long and float/double---------------------------- 10580 // 10581 // The following rules move values from int/long registers/stack-locations 10582 // to float/double registers/stack-locations and vice versa, without doing any 10583 // conversions. These rules are used to implement the bit-conversion methods 10584 // of java.lang.Float etc., e.g. 10585 // int floatToIntBits(float value) 10586 // float intBitsToFloat(int bits) 10587 // 10588 // Notes on the implementation on ppc64: 10589 // For Power7 and earlier, the rules are limited to those which move between a 10590 // register and a stack-location, because we always have to go through memory 10591 // when moving between a float register and an integer register. 10592 // This restriction is removed in Power8 with the introduction of the mtfprd 10593 // and mffprd instructions. 10594 10595 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10596 match(Set dst (MoveL2D src)); 10597 predicate(VM_Version::has_mtfprd()); 10598 10599 format %{ "MTFPRD $dst, $src" %} 10600 size(4); 10601 ins_encode %{ 10602 __ mtfprd($dst$$FloatRegister, $src$$Register); 10603 %} 10604 ins_pipe(pipe_class_default); 10605 %} 10606 10607 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10608 // no match-rule, false predicate 10609 effect(DEF dst, USE src); 10610 predicate(false); 10611 10612 format %{ "MTFPRWA $dst, $src" %} 10613 size(4); 10614 ins_encode %{ 10615 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10616 %} 10617 ins_pipe(pipe_class_default); 10618 %} 10619 10620 //---------- Chain stack slots between similar types -------- 10621 10622 // These are needed so that the rules below can match. 10623 10624 // Load integer from stack slot 10625 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10626 match(Set dst src); 10627 ins_cost(MEMORY_REF_COST); 10628 10629 format %{ "LWZ $dst, $src" %} 10630 size(4); 10631 ins_encode( enc_lwz(dst, src) ); 10632 ins_pipe(pipe_class_memory); 10633 %} 10634 10635 // Store integer to stack slot 10636 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10637 match(Set dst src); 10638 ins_cost(MEMORY_REF_COST); 10639 10640 format %{ "STW $src, $dst \t// stk" %} 10641 size(4); 10642 ins_encode( enc_stw(src, dst) ); // rs=rt 10643 ins_pipe(pipe_class_memory); 10644 %} 10645 10646 // Load long from stack slot 10647 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10648 match(Set dst src); 10649 ins_cost(MEMORY_REF_COST); 10650 10651 format %{ "LD $dst, $src \t// long" %} 10652 size(4); 10653 ins_encode( enc_ld(dst, src) ); 10654 ins_pipe(pipe_class_memory); 10655 %} 10656 10657 // Store long to stack slot 10658 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10659 match(Set dst src); 10660 ins_cost(MEMORY_REF_COST); 10661 10662 format %{ "STD $src, $dst \t// long" %} 10663 size(4); 10664 ins_encode( enc_std(src, dst) ); // rs=rt 10665 ins_pipe(pipe_class_memory); 10666 %} 10667 10668 //----------Moves between int and float 10669 10670 // Move float value from float stack-location to integer register. 10671 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10672 match(Set dst (MoveF2I src)); 10673 ins_cost(MEMORY_REF_COST); 10674 10675 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10676 size(4); 10677 ins_encode( enc_lwz(dst, src) ); 10678 ins_pipe(pipe_class_memory); 10679 %} 10680 10681 // Move float value from float register to integer stack-location. 10682 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10683 match(Set dst (MoveF2I src)); 10684 ins_cost(MEMORY_REF_COST); 10685 10686 format %{ "STFS $src, $dst \t// MoveF2I" %} 10687 size(4); 10688 ins_encode( enc_stfs(src, dst) ); 10689 ins_pipe(pipe_class_memory); 10690 %} 10691 10692 // Move integer value from integer stack-location to float register. 10693 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10694 match(Set dst (MoveI2F src)); 10695 ins_cost(MEMORY_REF_COST); 10696 10697 format %{ "LFS $dst, $src \t// MoveI2F" %} 10698 size(4); 10699 ins_encode %{ 10700 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10701 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10702 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10703 %} 10704 ins_pipe(pipe_class_memory); 10705 %} 10706 10707 // Move integer value from integer register to float stack-location. 10708 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10709 match(Set dst (MoveI2F src)); 10710 ins_cost(MEMORY_REF_COST); 10711 10712 format %{ "STW $src, $dst \t// MoveI2F" %} 10713 size(4); 10714 ins_encode( enc_stw(src, dst) ); 10715 ins_pipe(pipe_class_memory); 10716 %} 10717 10718 //----------Moves between long and float 10719 10720 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10721 // no match-rule, false predicate 10722 effect(DEF dst, USE src); 10723 predicate(false); 10724 10725 format %{ "storeD $src, $dst \t// STACK" %} 10726 size(4); 10727 ins_encode( enc_stfd(src, dst) ); 10728 ins_pipe(pipe_class_default); 10729 %} 10730 10731 //----------Moves between long and double 10732 10733 // Move double value from double stack-location to long register. 10734 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10735 match(Set dst (MoveD2L src)); 10736 ins_cost(MEMORY_REF_COST); 10737 size(4); 10738 format %{ "LD $dst, $src \t// MoveD2L" %} 10739 ins_encode( enc_ld(dst, src) ); 10740 ins_pipe(pipe_class_memory); 10741 %} 10742 10743 // Move double value from double register to long stack-location. 10744 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10745 match(Set dst (MoveD2L src)); 10746 effect(DEF dst, USE src); 10747 ins_cost(MEMORY_REF_COST); 10748 10749 format %{ "STFD $src, $dst \t// MoveD2L" %} 10750 size(4); 10751 ins_encode( enc_stfd(src, dst) ); 10752 ins_pipe(pipe_class_memory); 10753 %} 10754 10755 // Move long value from long stack-location to double register. 10756 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10757 match(Set dst (MoveL2D src)); 10758 ins_cost(MEMORY_REF_COST); 10759 10760 format %{ "LFD $dst, $src \t// MoveL2D" %} 10761 size(4); 10762 ins_encode( enc_lfd(dst, src) ); 10763 ins_pipe(pipe_class_memory); 10764 %} 10765 10766 // Move long value from long register to double stack-location. 10767 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10768 match(Set dst (MoveL2D src)); 10769 ins_cost(MEMORY_REF_COST); 10770 10771 format %{ "STD $src, $dst \t// MoveL2D" %} 10772 size(4); 10773 ins_encode( enc_std(src, dst) ); 10774 ins_pipe(pipe_class_memory); 10775 %} 10776 10777 //----------Register Move Instructions----------------------------------------- 10778 10779 // Replicate for Superword 10780 10781 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10782 predicate(false); 10783 effect(DEF dst, USE src); 10784 10785 format %{ "MR $dst, $src \t// replicate " %} 10786 // variable size, 0 or 4. 10787 ins_encode %{ 10788 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10789 __ mr_if_needed($dst$$Register, $src$$Register); 10790 %} 10791 ins_pipe(pipe_class_default); 10792 %} 10793 10794 //----------Cast instructions (Java-level type cast)--------------------------- 10795 10796 // Cast Long to Pointer for unsafe natives. 10797 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10798 match(Set dst (CastX2P src)); 10799 10800 format %{ "MR $dst, $src \t// Long->Ptr" %} 10801 // variable size, 0 or 4. 10802 ins_encode %{ 10803 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10804 __ mr_if_needed($dst$$Register, $src$$Register); 10805 %} 10806 ins_pipe(pipe_class_default); 10807 %} 10808 10809 // Cast Pointer to Long for unsafe natives. 10810 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10811 match(Set dst (CastP2X src)); 10812 10813 format %{ "MR $dst, $src \t// Ptr->Long" %} 10814 // variable size, 0 or 4. 10815 ins_encode %{ 10816 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10817 __ mr_if_needed($dst$$Register, $src$$Register); 10818 %} 10819 ins_pipe(pipe_class_default); 10820 %} 10821 10822 instruct castPP(iRegPdst dst) %{ 10823 match(Set dst (CastPP dst)); 10824 format %{ " -- \t// castPP of $dst" %} 10825 size(0); 10826 ins_encode( /*empty*/ ); 10827 ins_pipe(pipe_class_default); 10828 %} 10829 10830 instruct castII(iRegIdst dst) %{ 10831 match(Set dst (CastII dst)); 10832 format %{ " -- \t// castII of $dst" %} 10833 size(0); 10834 ins_encode( /*empty*/ ); 10835 ins_pipe(pipe_class_default); 10836 %} 10837 10838 instruct checkCastPP(iRegPdst dst) %{ 10839 match(Set dst (CheckCastPP dst)); 10840 format %{ " -- \t// checkcastPP of $dst" %} 10841 size(0); 10842 ins_encode( /*empty*/ ); 10843 ins_pipe(pipe_class_default); 10844 %} 10845 10846 //----------Convert instructions----------------------------------------------- 10847 10848 // Convert to boolean. 10849 10850 // int_to_bool(src) : { 1 if src != 0 10851 // { 0 else 10852 // 10853 // strategy: 10854 // 1) Count leading zeros of 32 bit-value src, 10855 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10856 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10857 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10858 10859 // convI2Bool 10860 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10861 match(Set dst (Conv2B src)); 10862 predicate(UseCountLeadingZerosInstructionsPPC64); 10863 ins_cost(DEFAULT_COST); 10864 10865 expand %{ 10866 immI shiftAmount %{ 0x5 %} 10867 uimmI16 mask %{ 0x1 %} 10868 iRegIdst tmp1; 10869 iRegIdst tmp2; 10870 countLeadingZerosI(tmp1, src); 10871 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10872 xorI_reg_uimm16(dst, tmp2, mask); 10873 %} 10874 %} 10875 10876 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10877 match(Set dst (Conv2B src)); 10878 effect(TEMP crx); 10879 predicate(!UseCountLeadingZerosInstructionsPPC64); 10880 ins_cost(DEFAULT_COST); 10881 10882 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10883 "LI $dst, #0\n\t" 10884 "BEQ $crx, done\n\t" 10885 "LI $dst, #1\n" 10886 "done:" %} 10887 size(16); 10888 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10889 ins_pipe(pipe_class_compare); 10890 %} 10891 10892 // ConvI2B + XorI 10893 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10894 match(Set dst (XorI (Conv2B src) mask)); 10895 predicate(UseCountLeadingZerosInstructionsPPC64); 10896 ins_cost(DEFAULT_COST); 10897 10898 expand %{ 10899 immI shiftAmount %{ 0x5 %} 10900 iRegIdst tmp1; 10901 countLeadingZerosI(tmp1, src); 10902 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10903 %} 10904 %} 10905 10906 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10907 match(Set dst (XorI (Conv2B src) mask)); 10908 effect(TEMP crx); 10909 predicate(!UseCountLeadingZerosInstructionsPPC64); 10910 ins_cost(DEFAULT_COST); 10911 10912 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10913 "LI $dst, #1\n\t" 10914 "BEQ $crx, done\n\t" 10915 "LI $dst, #0\n" 10916 "done:" %} 10917 size(16); 10918 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10919 ins_pipe(pipe_class_compare); 10920 %} 10921 10922 // AndI 0b0..010..0 + ConvI2B 10923 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10924 match(Set dst (Conv2B (AndI src mask))); 10925 predicate(UseRotateAndMaskInstructionsPPC64); 10926 ins_cost(DEFAULT_COST); 10927 10928 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10929 size(4); 10930 ins_encode %{ 10931 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10932 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10933 %} 10934 ins_pipe(pipe_class_default); 10935 %} 10936 10937 // Convert pointer to boolean. 10938 // 10939 // ptr_to_bool(src) : { 1 if src != 0 10940 // { 0 else 10941 // 10942 // strategy: 10943 // 1) Count leading zeros of 64 bit-value src, 10944 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10945 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10946 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10947 10948 // ConvP2B 10949 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10950 match(Set dst (Conv2B src)); 10951 predicate(UseCountLeadingZerosInstructionsPPC64); 10952 ins_cost(DEFAULT_COST); 10953 10954 expand %{ 10955 immI shiftAmount %{ 0x6 %} 10956 uimmI16 mask %{ 0x1 %} 10957 iRegIdst tmp1; 10958 iRegIdst tmp2; 10959 countLeadingZerosP(tmp1, src); 10960 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10961 xorI_reg_uimm16(dst, tmp2, mask); 10962 %} 10963 %} 10964 10965 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10966 match(Set dst (Conv2B src)); 10967 effect(TEMP crx); 10968 predicate(!UseCountLeadingZerosInstructionsPPC64); 10969 ins_cost(DEFAULT_COST); 10970 10971 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10972 "LI $dst, #0\n\t" 10973 "BEQ $crx, done\n\t" 10974 "LI $dst, #1\n" 10975 "done:" %} 10976 size(16); 10977 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10978 ins_pipe(pipe_class_compare); 10979 %} 10980 10981 // ConvP2B + XorI 10982 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10983 match(Set dst (XorI (Conv2B src) mask)); 10984 predicate(UseCountLeadingZerosInstructionsPPC64); 10985 ins_cost(DEFAULT_COST); 10986 10987 expand %{ 10988 immI shiftAmount %{ 0x6 %} 10989 iRegIdst tmp1; 10990 countLeadingZerosP(tmp1, src); 10991 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10992 %} 10993 %} 10994 10995 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10996 match(Set dst (XorI (Conv2B src) mask)); 10997 effect(TEMP crx); 10998 predicate(!UseCountLeadingZerosInstructionsPPC64); 10999 ins_cost(DEFAULT_COST); 11000 11001 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 11002 "LI $dst, #1\n\t" 11003 "BEQ $crx, done\n\t" 11004 "LI $dst, #0\n" 11005 "done:" %} 11006 size(16); 11007 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 11008 ins_pipe(pipe_class_compare); 11009 %} 11010 11011 // if src1 < src2, return -1 else return 0 11012 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 11013 match(Set dst (CmpLTMask src1 src2)); 11014 ins_cost(DEFAULT_COST*4); 11015 11016 expand %{ 11017 iRegLdst src1s; 11018 iRegLdst src2s; 11019 iRegLdst diff; 11020 convI2L_reg(src1s, src1); // Ensure proper sign extension. 11021 convI2L_reg(src2s, src2); // Ensure proper sign extension. 11022 subL_reg_reg(diff, src1s, src2s); 11023 // Need to consider >=33 bit result, therefore we need signmaskL. 11024 signmask64I_regL(dst, diff); 11025 %} 11026 %} 11027 11028 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 11029 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 11030 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 11031 size(4); 11032 ins_encode %{ 11033 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 11034 __ srawi($dst$$Register, $src1$$Register, 0x1f); 11035 %} 11036 ins_pipe(pipe_class_default); 11037 %} 11038 11039 //----------Arithmetic Conversion Instructions--------------------------------- 11040 11041 // Convert to Byte -- nop 11042 // Convert to Short -- nop 11043 11044 // Convert to Int 11045 11046 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 11047 match(Set dst (RShiftI (LShiftI src amount) amount)); 11048 format %{ "EXTSB $dst, $src \t// byte->int" %} 11049 size(4); 11050 ins_encode %{ 11051 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 11052 __ extsb($dst$$Register, $src$$Register); 11053 %} 11054 ins_pipe(pipe_class_default); 11055 %} 11056 11057 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 11058 effect(DEF dst, USE src); 11059 11060 size(4); 11061 ins_encode %{ 11062 __ extsh($dst$$Register, $src$$Register); 11063 %} 11064 ins_pipe(pipe_class_default); 11065 %} 11066 11067 // LShiftI 16 + RShiftI 16 converts short to int. 11068 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 11069 match(Set dst (RShiftI (LShiftI src amount) amount)); 11070 format %{ "EXTSH $dst, $src \t// short->int" %} 11071 size(4); 11072 ins_encode %{ 11073 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 11074 __ extsh($dst$$Register, $src$$Register); 11075 %} 11076 ins_pipe(pipe_class_default); 11077 %} 11078 11079 // ConvL2I + ConvI2L: Sign extend int in long register. 11080 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11081 match(Set dst (ConvI2L (ConvL2I src))); 11082 11083 format %{ "EXTSW $dst, $src \t// long->long" %} 11084 size(4); 11085 ins_encode %{ 11086 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11087 __ extsw($dst$$Register, $src$$Register); 11088 %} 11089 ins_pipe(pipe_class_default); 11090 %} 11091 11092 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11093 match(Set dst (ConvL2I src)); 11094 format %{ "MR $dst, $src \t// long->int" %} 11095 // variable size, 0 or 4 11096 ins_encode %{ 11097 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11098 __ mr_if_needed($dst$$Register, $src$$Register); 11099 %} 11100 ins_pipe(pipe_class_default); 11101 %} 11102 11103 instruct convD2IRaw_regD(regD dst, regD src) %{ 11104 // no match-rule, false predicate 11105 effect(DEF dst, USE src); 11106 predicate(false); 11107 11108 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11109 size(4); 11110 ins_encode %{ 11111 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11112 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11113 %} 11114 ins_pipe(pipe_class_default); 11115 %} 11116 11117 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 11118 // no match-rule, false predicate 11119 effect(DEF dst, USE crx, USE src); 11120 predicate(false); 11121 11122 ins_variable_size_depending_on_alignment(true); 11123 11124 format %{ "cmovI $crx, $dst, $src" %} 11125 // Worst case is branch + move + stop, no stop without scheduler. 11126 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11127 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11128 ins_pipe(pipe_class_default); 11129 %} 11130 11131 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11132 // no match-rule, false predicate 11133 effect(DEF dst, USE crx, USE src); 11134 predicate(false); 11135 11136 ins_variable_size_depending_on_alignment(true); 11137 11138 format %{ "cmovI $crx, $dst, $src" %} 11139 // Worst case is branch + move + stop, no stop without scheduler. 11140 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11141 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11142 ins_pipe(pipe_class_default); 11143 %} 11144 11145 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11146 // no match-rule, false predicate 11147 effect(DEF dst, USE crx, USE mem); 11148 predicate(false); 11149 11150 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11151 postalloc_expand %{ 11152 // 11153 // replaces 11154 // 11155 // region dst crx mem 11156 // \ | | / 11157 // dst=cmovI_bso_stackSlotL_conLvalue0 11158 // 11159 // with 11160 // 11161 // region dst 11162 // \ / 11163 // dst=loadConI16(0) 11164 // | 11165 // ^ region dst crx mem 11166 // | \ | | / 11167 // dst=cmovI_bso_stackSlotL 11168 // 11169 11170 // Create new nodes. 11171 MachNode *m1 = new loadConI16Node(); 11172 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11173 11174 // inputs for new nodes 11175 m1->add_req(n_region); 11176 m2->add_req(n_region, n_crx, n_mem); 11177 11178 // precedences for new nodes 11179 m2->add_prec(m1); 11180 11181 // operands for new nodes 11182 m1->_opnds[0] = op_dst; 11183 m1->_opnds[1] = new immI16Oper(0); 11184 11185 m2->_opnds[0] = op_dst; 11186 m2->_opnds[1] = op_crx; 11187 m2->_opnds[2] = op_mem; 11188 11189 // registers for new nodes 11190 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11191 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11192 11193 // Insert new nodes. 11194 nodes->push(m1); 11195 nodes->push(m2); 11196 %} 11197 %} 11198 11199 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11200 // no match-rule, false predicate 11201 effect(DEF dst, USE crx, USE src); 11202 predicate(false); 11203 11204 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11205 postalloc_expand %{ 11206 // 11207 // replaces 11208 // 11209 // region dst crx src 11210 // \ | | / 11211 // dst=cmovI_bso_reg_conLvalue0 11212 // 11213 // with 11214 // 11215 // region dst 11216 // \ / 11217 // dst=loadConI16(0) 11218 // | 11219 // ^ region dst crx src 11220 // | \ | | / 11221 // dst=cmovI_bso_reg 11222 // 11223 11224 // Create new nodes. 11225 MachNode *m1 = new loadConI16Node(); 11226 MachNode *m2 = new cmovI_bso_regNode(); 11227 11228 // inputs for new nodes 11229 m1->add_req(n_region); 11230 m2->add_req(n_region, n_crx, n_src); 11231 11232 // precedences for new nodes 11233 m2->add_prec(m1); 11234 11235 // operands for new nodes 11236 m1->_opnds[0] = op_dst; 11237 m1->_opnds[1] = new immI16Oper(0); 11238 11239 m2->_opnds[0] = op_dst; 11240 m2->_opnds[1] = op_crx; 11241 m2->_opnds[2] = op_src; 11242 11243 // registers for new nodes 11244 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11245 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11246 11247 // Insert new nodes. 11248 nodes->push(m1); 11249 nodes->push(m2); 11250 %} 11251 %} 11252 11253 // Double to Int conversion, NaN is mapped to 0. 11254 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11255 match(Set dst (ConvD2I src)); 11256 predicate(!VM_Version::has_mtfprd()); 11257 ins_cost(DEFAULT_COST); 11258 11259 expand %{ 11260 regD tmpD; 11261 stackSlotL tmpS; 11262 flagsReg crx; 11263 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11264 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11265 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11266 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11267 %} 11268 %} 11269 11270 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11271 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11272 match(Set dst (ConvD2I src)); 11273 predicate(VM_Version::has_mtfprd()); 11274 ins_cost(DEFAULT_COST); 11275 11276 expand %{ 11277 regD tmpD; 11278 flagsReg crx; 11279 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11280 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11281 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11282 %} 11283 %} 11284 11285 instruct convF2IRaw_regF(regF dst, regF src) %{ 11286 // no match-rule, false predicate 11287 effect(DEF dst, USE src); 11288 predicate(false); 11289 11290 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11291 size(4); 11292 ins_encode %{ 11293 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11294 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11295 %} 11296 ins_pipe(pipe_class_default); 11297 %} 11298 11299 // Float to Int conversion, NaN is mapped to 0. 11300 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11301 match(Set dst (ConvF2I src)); 11302 predicate(!VM_Version::has_mtfprd()); 11303 ins_cost(DEFAULT_COST); 11304 11305 expand %{ 11306 regF tmpF; 11307 stackSlotL tmpS; 11308 flagsReg crx; 11309 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11310 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11311 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11312 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11313 %} 11314 %} 11315 11316 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11317 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11318 match(Set dst (ConvF2I src)); 11319 predicate(VM_Version::has_mtfprd()); 11320 ins_cost(DEFAULT_COST); 11321 11322 expand %{ 11323 regF tmpF; 11324 flagsReg crx; 11325 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11326 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11327 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11328 %} 11329 %} 11330 11331 // Convert to Long 11332 11333 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11334 match(Set dst (ConvI2L src)); 11335 format %{ "EXTSW $dst, $src \t// int->long" %} 11336 size(4); 11337 ins_encode %{ 11338 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11339 __ extsw($dst$$Register, $src$$Register); 11340 %} 11341 ins_pipe(pipe_class_default); 11342 %} 11343 11344 // Zero-extend: convert unsigned int to long (convUI2L). 11345 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11346 match(Set dst (AndL (ConvI2L src) mask)); 11347 ins_cost(DEFAULT_COST); 11348 11349 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11350 size(4); 11351 ins_encode %{ 11352 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11353 __ clrldi($dst$$Register, $src$$Register, 32); 11354 %} 11355 ins_pipe(pipe_class_default); 11356 %} 11357 11358 // Zero-extend: convert unsigned int to long in long register. 11359 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11360 match(Set dst (AndL src mask)); 11361 ins_cost(DEFAULT_COST); 11362 11363 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11364 size(4); 11365 ins_encode %{ 11366 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11367 __ clrldi($dst$$Register, $src$$Register, 32); 11368 %} 11369 ins_pipe(pipe_class_default); 11370 %} 11371 11372 instruct convF2LRaw_regF(regF dst, regF src) %{ 11373 // no match-rule, false predicate 11374 effect(DEF dst, USE src); 11375 predicate(false); 11376 11377 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11378 size(4); 11379 ins_encode %{ 11380 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11381 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11382 %} 11383 ins_pipe(pipe_class_default); 11384 %} 11385 11386 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 11387 // no match-rule, false predicate 11388 effect(DEF dst, USE crx, USE src); 11389 predicate(false); 11390 11391 ins_variable_size_depending_on_alignment(true); 11392 11393 format %{ "cmovL $crx, $dst, $src" %} 11394 // Worst case is branch + move + stop, no stop without scheduler. 11395 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11396 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11397 ins_pipe(pipe_class_default); 11398 %} 11399 11400 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11401 // no match-rule, false predicate 11402 effect(DEF dst, USE crx, USE src); 11403 predicate(false); 11404 11405 ins_variable_size_depending_on_alignment(true); 11406 11407 format %{ "cmovL $crx, $dst, $src" %} 11408 // Worst case is branch + move + stop, no stop without scheduler. 11409 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11410 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11411 ins_pipe(pipe_class_default); 11412 %} 11413 11414 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11415 // no match-rule, false predicate 11416 effect(DEF dst, USE crx, USE mem); 11417 predicate(false); 11418 11419 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11420 postalloc_expand %{ 11421 // 11422 // replaces 11423 // 11424 // region dst crx mem 11425 // \ | | / 11426 // dst=cmovL_bso_stackSlotL_conLvalue0 11427 // 11428 // with 11429 // 11430 // region dst 11431 // \ / 11432 // dst=loadConL16(0) 11433 // | 11434 // ^ region dst crx mem 11435 // | \ | | / 11436 // dst=cmovL_bso_stackSlotL 11437 // 11438 11439 // Create new nodes. 11440 MachNode *m1 = new loadConL16Node(); 11441 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11442 11443 // inputs for new nodes 11444 m1->add_req(n_region); 11445 m2->add_req(n_region, n_crx, n_mem); 11446 m2->add_prec(m1); 11447 11448 // operands for new nodes 11449 m1->_opnds[0] = op_dst; 11450 m1->_opnds[1] = new immL16Oper(0); 11451 m2->_opnds[0] = op_dst; 11452 m2->_opnds[1] = op_crx; 11453 m2->_opnds[2] = op_mem; 11454 11455 // registers for new nodes 11456 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11457 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11458 11459 // Insert new nodes. 11460 nodes->push(m1); 11461 nodes->push(m2); 11462 %} 11463 %} 11464 11465 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11466 // no match-rule, false predicate 11467 effect(DEF dst, USE crx, USE src); 11468 predicate(false); 11469 11470 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11471 postalloc_expand %{ 11472 // 11473 // replaces 11474 // 11475 // region dst crx src 11476 // \ | | / 11477 // dst=cmovL_bso_reg_conLvalue0 11478 // 11479 // with 11480 // 11481 // region dst 11482 // \ / 11483 // dst=loadConL16(0) 11484 // | 11485 // ^ region dst crx src 11486 // | \ | | / 11487 // dst=cmovL_bso_reg 11488 // 11489 11490 // Create new nodes. 11491 MachNode *m1 = new loadConL16Node(); 11492 MachNode *m2 = new cmovL_bso_regNode(); 11493 11494 // inputs for new nodes 11495 m1->add_req(n_region); 11496 m2->add_req(n_region, n_crx, n_src); 11497 m2->add_prec(m1); 11498 11499 // operands for new nodes 11500 m1->_opnds[0] = op_dst; 11501 m1->_opnds[1] = new immL16Oper(0); 11502 m2->_opnds[0] = op_dst; 11503 m2->_opnds[1] = op_crx; 11504 m2->_opnds[2] = op_src; 11505 11506 // registers for new nodes 11507 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11508 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11509 11510 // Insert new nodes. 11511 nodes->push(m1); 11512 nodes->push(m2); 11513 %} 11514 %} 11515 11516 // Float to Long conversion, NaN is mapped to 0. 11517 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11518 match(Set dst (ConvF2L src)); 11519 predicate(!VM_Version::has_mtfprd()); 11520 ins_cost(DEFAULT_COST); 11521 11522 expand %{ 11523 regF tmpF; 11524 stackSlotL tmpS; 11525 flagsReg crx; 11526 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11527 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11528 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11529 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11530 %} 11531 %} 11532 11533 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11534 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11535 match(Set dst (ConvF2L src)); 11536 predicate(VM_Version::has_mtfprd()); 11537 ins_cost(DEFAULT_COST); 11538 11539 expand %{ 11540 regF tmpF; 11541 flagsReg crx; 11542 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11543 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11544 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11545 %} 11546 %} 11547 11548 instruct convD2LRaw_regD(regD dst, regD src) %{ 11549 // no match-rule, false predicate 11550 effect(DEF dst, USE src); 11551 predicate(false); 11552 11553 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11554 size(4); 11555 ins_encode %{ 11556 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11557 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11558 %} 11559 ins_pipe(pipe_class_default); 11560 %} 11561 11562 // Double to Long conversion, NaN is mapped to 0. 11563 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11564 match(Set dst (ConvD2L src)); 11565 predicate(!VM_Version::has_mtfprd()); 11566 ins_cost(DEFAULT_COST); 11567 11568 expand %{ 11569 regD tmpD; 11570 stackSlotL tmpS; 11571 flagsReg crx; 11572 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11573 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11574 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11575 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11576 %} 11577 %} 11578 11579 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11580 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11581 match(Set dst (ConvD2L src)); 11582 predicate(VM_Version::has_mtfprd()); 11583 ins_cost(DEFAULT_COST); 11584 11585 expand %{ 11586 regD tmpD; 11587 flagsReg crx; 11588 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11589 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11590 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11591 %} 11592 %} 11593 11594 // Convert to Float 11595 11596 // Placed here as needed in expand. 11597 instruct convL2DRaw_regD(regD dst, regD src) %{ 11598 // no match-rule, false predicate 11599 effect(DEF dst, USE src); 11600 predicate(false); 11601 11602 format %{ "FCFID $dst, $src \t// convL2D" %} 11603 size(4); 11604 ins_encode %{ 11605 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11606 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11607 %} 11608 ins_pipe(pipe_class_default); 11609 %} 11610 11611 // Placed here as needed in expand. 11612 instruct convD2F_reg(regF dst, regD src) %{ 11613 match(Set dst (ConvD2F src)); 11614 format %{ "FRSP $dst, $src \t// convD2F" %} 11615 size(4); 11616 ins_encode %{ 11617 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11618 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11619 %} 11620 ins_pipe(pipe_class_default); 11621 %} 11622 11623 // Integer to Float conversion. 11624 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11625 match(Set dst (ConvI2F src)); 11626 predicate(!VM_Version::has_fcfids()); 11627 ins_cost(DEFAULT_COST); 11628 11629 expand %{ 11630 iRegLdst tmpL; 11631 stackSlotL tmpS; 11632 regD tmpD; 11633 regD tmpD2; 11634 convI2L_reg(tmpL, src); // Sign-extension int to long. 11635 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11636 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11637 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11638 convD2F_reg(dst, tmpD2); // Convert double to float. 11639 %} 11640 %} 11641 11642 instruct convL2FRaw_regF(regF dst, regD src) %{ 11643 // no match-rule, false predicate 11644 effect(DEF dst, USE src); 11645 predicate(false); 11646 11647 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11648 size(4); 11649 ins_encode %{ 11650 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11651 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11652 %} 11653 ins_pipe(pipe_class_default); 11654 %} 11655 11656 // Integer to Float conversion. Special version for Power7. 11657 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11658 match(Set dst (ConvI2F src)); 11659 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11660 ins_cost(DEFAULT_COST); 11661 11662 expand %{ 11663 iRegLdst tmpL; 11664 stackSlotL tmpS; 11665 regD tmpD; 11666 convI2L_reg(tmpL, src); // Sign-extension int to long. 11667 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11668 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11669 convL2FRaw_regF(dst, tmpD); // Convert to float. 11670 %} 11671 %} 11672 11673 // Integer to Float conversion. Special version for Power8. 11674 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11675 match(Set dst (ConvI2F src)); 11676 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11677 ins_cost(DEFAULT_COST); 11678 11679 expand %{ 11680 regD tmpD; 11681 moveI2D_reg(tmpD, src); 11682 convL2FRaw_regF(dst, tmpD); // Convert to float. 11683 %} 11684 %} 11685 11686 // L2F to avoid runtime call. 11687 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11688 match(Set dst (ConvL2F src)); 11689 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11690 ins_cost(DEFAULT_COST); 11691 11692 expand %{ 11693 stackSlotL tmpS; 11694 regD tmpD; 11695 regL_to_stkL(tmpS, src); // Store long to stack. 11696 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11697 convL2FRaw_regF(dst, tmpD); // Convert to float. 11698 %} 11699 %} 11700 11701 // L2F to avoid runtime call. Special version for Power8. 11702 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11703 match(Set dst (ConvL2F src)); 11704 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11705 ins_cost(DEFAULT_COST); 11706 11707 expand %{ 11708 regD tmpD; 11709 moveL2D_reg(tmpD, src); 11710 convL2FRaw_regF(dst, tmpD); // Convert to float. 11711 %} 11712 %} 11713 11714 // Moved up as used in expand. 11715 //instruct convD2F_reg(regF dst, regD src) %{%} 11716 11717 // Convert to Double 11718 11719 // Integer to Double conversion. 11720 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11721 match(Set dst (ConvI2D src)); 11722 predicate(!VM_Version::has_mtfprd()); 11723 ins_cost(DEFAULT_COST); 11724 11725 expand %{ 11726 iRegLdst tmpL; 11727 stackSlotL tmpS; 11728 regD tmpD; 11729 convI2L_reg(tmpL, src); // Sign-extension int to long. 11730 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11731 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11732 convL2DRaw_regD(dst, tmpD); // Convert to double. 11733 %} 11734 %} 11735 11736 // Integer to Double conversion. Special version for Power8. 11737 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11738 match(Set dst (ConvI2D src)); 11739 predicate(VM_Version::has_mtfprd()); 11740 ins_cost(DEFAULT_COST); 11741 11742 expand %{ 11743 regD tmpD; 11744 moveI2D_reg(tmpD, src); 11745 convL2DRaw_regD(dst, tmpD); // Convert to double. 11746 %} 11747 %} 11748 11749 // Long to Double conversion 11750 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11751 match(Set dst (ConvL2D src)); 11752 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11753 11754 expand %{ 11755 regD tmpD; 11756 moveL2D_stack_reg(tmpD, src); 11757 convL2DRaw_regD(dst, tmpD); 11758 %} 11759 %} 11760 11761 // Long to Double conversion. Special version for Power8. 11762 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11763 match(Set dst (ConvL2D src)); 11764 predicate(VM_Version::has_mtfprd()); 11765 ins_cost(DEFAULT_COST); 11766 11767 expand %{ 11768 regD tmpD; 11769 moveL2D_reg(tmpD, src); 11770 convL2DRaw_regD(dst, tmpD); // Convert to double. 11771 %} 11772 %} 11773 11774 instruct convF2D_reg(regD dst, regF src) %{ 11775 match(Set dst (ConvF2D src)); 11776 format %{ "FMR $dst, $src \t// float->double" %} 11777 // variable size, 0 or 4 11778 ins_encode %{ 11779 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11780 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11781 %} 11782 ins_pipe(pipe_class_default); 11783 %} 11784 11785 //----------Control Flow Instructions------------------------------------------ 11786 // Compare Instructions 11787 11788 // Compare Integers 11789 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11790 match(Set crx (CmpI src1 src2)); 11791 size(4); 11792 format %{ "CMPW $crx, $src1, $src2" %} 11793 ins_encode %{ 11794 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11795 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11796 %} 11797 ins_pipe(pipe_class_compare); 11798 %} 11799 11800 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11801 match(Set crx (CmpI src1 src2)); 11802 format %{ "CMPWI $crx, $src1, $src2" %} 11803 size(4); 11804 ins_encode %{ 11805 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11806 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11807 %} 11808 ins_pipe(pipe_class_compare); 11809 %} 11810 11811 // (src1 & src2) == 0? 11812 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11813 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11814 // r0 is killed 11815 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11816 size(4); 11817 ins_encode %{ 11818 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11819 __ andi_(R0, $src1$$Register, $src2$$constant); 11820 %} 11821 ins_pipe(pipe_class_compare); 11822 %} 11823 11824 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11825 match(Set crx (CmpL src1 src2)); 11826 format %{ "CMPD $crx, $src1, $src2" %} 11827 size(4); 11828 ins_encode %{ 11829 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11830 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11831 %} 11832 ins_pipe(pipe_class_compare); 11833 %} 11834 11835 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11836 match(Set crx (CmpL src1 src2)); 11837 format %{ "CMPDI $crx, $src1, $src2" %} 11838 size(4); 11839 ins_encode %{ 11840 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11841 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11842 %} 11843 ins_pipe(pipe_class_compare); 11844 %} 11845 11846 // Added CmpUL for LoopPredicate. 11847 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11848 match(Set crx (CmpUL src1 src2)); 11849 format %{ "CMPLD $crx, $src1, $src2" %} 11850 size(4); 11851 ins_encode %{ 11852 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11853 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11854 %} 11855 ins_pipe(pipe_class_compare); 11856 %} 11857 11858 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11859 match(Set crx (CmpUL src1 src2)); 11860 format %{ "CMPLDI $crx, $src1, $src2" %} 11861 size(4); 11862 ins_encode %{ 11863 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11864 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11865 %} 11866 ins_pipe(pipe_class_compare); 11867 %} 11868 11869 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11870 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11871 // r0 is killed 11872 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11873 size(4); 11874 ins_encode %{ 11875 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11876 __ and_(R0, $src1$$Register, $src2$$Register); 11877 %} 11878 ins_pipe(pipe_class_compare); 11879 %} 11880 11881 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11882 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11883 // r0 is killed 11884 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11885 size(4); 11886 ins_encode %{ 11887 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11888 __ andi_(R0, $src1$$Register, $src2$$constant); 11889 %} 11890 ins_pipe(pipe_class_compare); 11891 %} 11892 11893 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11894 // no match-rule, false predicate 11895 effect(DEF dst, USE crx); 11896 predicate(false); 11897 11898 ins_variable_size_depending_on_alignment(true); 11899 11900 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11901 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11902 size((false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16)); 11903 ins_encode %{ 11904 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11905 Label done; 11906 // li(Rdst, 0); // equal -> 0 11907 __ beq($crx$$CondRegister, done); 11908 __ li($dst$$Register, 1); // greater -> +1 11909 __ bgt($crx$$CondRegister, done); 11910 __ li($dst$$Register, -1); // unordered or less -> -1 11911 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11912 __ bind(done); 11913 %} 11914 ins_pipe(pipe_class_compare); 11915 %} 11916 11917 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11918 // no match-rule, false predicate 11919 effect(DEF dst, USE crx); 11920 predicate(false); 11921 11922 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11923 postalloc_expand %{ 11924 // 11925 // replaces 11926 // 11927 // region crx 11928 // \ | 11929 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11930 // 11931 // with 11932 // 11933 // region 11934 // \ 11935 // dst=loadConI16(0) 11936 // | 11937 // ^ region crx 11938 // | \ | 11939 // dst=cmovI_conIvalueMinus1_conIvalue1 11940 // 11941 11942 // Create new nodes. 11943 MachNode *m1 = new loadConI16Node(); 11944 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11945 11946 // inputs for new nodes 11947 m1->add_req(n_region); 11948 m2->add_req(n_region, n_crx); 11949 m2->add_prec(m1); 11950 11951 // operands for new nodes 11952 m1->_opnds[0] = op_dst; 11953 m1->_opnds[1] = new immI16Oper(0); 11954 m2->_opnds[0] = op_dst; 11955 m2->_opnds[1] = op_crx; 11956 11957 // registers for new nodes 11958 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11959 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11960 11961 // Insert new nodes. 11962 nodes->push(m1); 11963 nodes->push(m2); 11964 %} 11965 %} 11966 11967 // Manifest a CmpL3 result in an integer register. Very painful. 11968 // This is the test to avoid. 11969 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11970 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11971 match(Set dst (CmpL3 src1 src2)); 11972 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11973 11974 expand %{ 11975 flagsReg tmp1; 11976 cmpL_reg_reg(tmp1, src1, src2); 11977 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11978 %} 11979 %} 11980 11981 // Implicit range checks. 11982 // A range check in the ideal world has one of the following shapes: 11983 // - (If le (CmpU length index)), (IfTrue throw exception) 11984 // - (If lt (CmpU index length)), (IfFalse throw exception) 11985 // 11986 // Match range check 'If le (CmpU length index)'. 11987 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11988 match(If cmp (CmpU src_length index)); 11989 effect(USE labl); 11990 predicate(TrapBasedRangeChecks && 11991 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11992 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11993 (Matcher::branches_to_uncommon_trap(_leaf))); 11994 11995 ins_is_TrapBasedCheckNode(true); 11996 11997 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11998 size(4); 11999 ins_encode %{ 12000 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12001 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 12002 __ trap_range_check_le($src_length$$Register, $index$$constant); 12003 } else { 12004 // Both successors are uncommon traps, probability is 0. 12005 // Node got flipped during fixup flow. 12006 assert($cmp$$cmpcode == 0x9, "must be greater"); 12007 __ trap_range_check_g($src_length$$Register, $index$$constant); 12008 } 12009 %} 12010 ins_pipe(pipe_class_trap); 12011 %} 12012 12013 // Match range check 'If lt (CmpU index length)'. 12014 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 12015 match(If cmp (CmpU src_index src_length)); 12016 effect(USE labl); 12017 predicate(TrapBasedRangeChecks && 12018 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12019 _leaf->as_If()->_prob >= PROB_ALWAYS && 12020 (Matcher::branches_to_uncommon_trap(_leaf))); 12021 12022 ins_is_TrapBasedCheckNode(true); 12023 12024 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 12025 size(4); 12026 ins_encode %{ 12027 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 12028 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12029 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 12030 } else { 12031 // Both successors are uncommon traps, probability is 0. 12032 // Node got flipped during fixup flow. 12033 assert($cmp$$cmpcode == 0x8, "must be less"); 12034 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 12035 } 12036 %} 12037 ins_pipe(pipe_class_trap); 12038 %} 12039 12040 // Match range check 'If lt (CmpU index length)'. 12041 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 12042 match(If cmp (CmpU src_index length)); 12043 effect(USE labl); 12044 predicate(TrapBasedRangeChecks && 12045 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12046 _leaf->as_If()->_prob >= PROB_ALWAYS && 12047 (Matcher::branches_to_uncommon_trap(_leaf))); 12048 12049 ins_is_TrapBasedCheckNode(true); 12050 12051 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 12052 size(4); 12053 ins_encode %{ 12054 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12055 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12056 __ trap_range_check_ge($src_index$$Register, $length$$constant); 12057 } else { 12058 // Both successors are uncommon traps, probability is 0. 12059 // Node got flipped during fixup flow. 12060 assert($cmp$$cmpcode == 0x8, "must be less"); 12061 __ trap_range_check_l($src_index$$Register, $length$$constant); 12062 } 12063 %} 12064 ins_pipe(pipe_class_trap); 12065 %} 12066 12067 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 12068 match(Set crx (CmpU src1 src2)); 12069 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 12070 size(4); 12071 ins_encode %{ 12072 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12073 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12074 %} 12075 ins_pipe(pipe_class_compare); 12076 %} 12077 12078 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 12079 match(Set crx (CmpU src1 src2)); 12080 size(4); 12081 format %{ "CMPLWI $crx, $src1, $src2" %} 12082 ins_encode %{ 12083 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12084 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12085 %} 12086 ins_pipe(pipe_class_compare); 12087 %} 12088 12089 // Implicit zero checks (more implicit null checks). 12090 // No constant pool entries required. 12091 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12092 match(If cmp (CmpN value zero)); 12093 effect(USE labl); 12094 predicate(TrapBasedNullChecks && 12095 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12096 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12097 Matcher::branches_to_uncommon_trap(_leaf)); 12098 ins_cost(1); 12099 12100 ins_is_TrapBasedCheckNode(true); 12101 12102 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12103 size(4); 12104 ins_encode %{ 12105 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12106 if ($cmp$$cmpcode == 0xA) { 12107 __ trap_null_check($value$$Register); 12108 } else { 12109 // Both successors are uncommon traps, probability is 0. 12110 // Node got flipped during fixup flow. 12111 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12112 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12113 } 12114 %} 12115 ins_pipe(pipe_class_trap); 12116 %} 12117 12118 // Compare narrow oops. 12119 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12120 match(Set crx (CmpN src1 src2)); 12121 12122 size(4); 12123 ins_cost(2); 12124 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12125 ins_encode %{ 12126 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12127 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12128 %} 12129 ins_pipe(pipe_class_compare); 12130 %} 12131 12132 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12133 match(Set crx (CmpN src1 src2)); 12134 // Make this more expensive than zeroCheckN_iReg_imm0. 12135 ins_cost(2); 12136 12137 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12138 size(4); 12139 ins_encode %{ 12140 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12141 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12142 %} 12143 ins_pipe(pipe_class_compare); 12144 %} 12145 12146 // Implicit zero checks (more implicit null checks). 12147 // No constant pool entries required. 12148 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12149 match(If cmp (CmpP value zero)); 12150 effect(USE labl); 12151 predicate(TrapBasedNullChecks && 12152 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12153 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12154 Matcher::branches_to_uncommon_trap(_leaf)); 12155 ins_cost(1); // Should not be cheaper than zeroCheckN. 12156 12157 ins_is_TrapBasedCheckNode(true); 12158 12159 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12160 size(4); 12161 ins_encode %{ 12162 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12163 if ($cmp$$cmpcode == 0xA) { 12164 __ trap_null_check($value$$Register); 12165 } else { 12166 // Both successors are uncommon traps, probability is 0. 12167 // Node got flipped during fixup flow. 12168 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12169 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12170 } 12171 %} 12172 ins_pipe(pipe_class_trap); 12173 %} 12174 12175 // Compare Pointers 12176 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12177 match(Set crx (CmpP src1 src2)); 12178 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12179 size(4); 12180 ins_encode %{ 12181 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12182 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12183 %} 12184 ins_pipe(pipe_class_compare); 12185 %} 12186 12187 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12188 match(Set crx (CmpP src1 src2)); 12189 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12190 size(4); 12191 ins_encode %{ 12192 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12193 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12194 %} 12195 ins_pipe(pipe_class_compare); 12196 %} 12197 12198 // Used in postalloc expand. 12199 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12200 // This match rule prevents reordering of node before a safepoint. 12201 // This only makes sense if this instructions is used exclusively 12202 // for the expansion of EncodeP! 12203 match(Set crx (CmpP src1 src2)); 12204 predicate(false); 12205 12206 format %{ "CMPDI $crx, $src1, $src2" %} 12207 size(4); 12208 ins_encode %{ 12209 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12210 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12211 %} 12212 ins_pipe(pipe_class_compare); 12213 %} 12214 12215 //----------Float Compares---------------------------------------------------- 12216 12217 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12218 // Needs matchrule, see cmpDUnordered. 12219 match(Set crx (CmpF src1 src2)); 12220 // no match-rule, false predicate 12221 predicate(false); 12222 12223 format %{ "cmpFUrd $crx, $src1, $src2" %} 12224 size(4); 12225 ins_encode %{ 12226 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12227 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12228 %} 12229 ins_pipe(pipe_class_default); 12230 %} 12231 12232 instruct cmov_bns_less(flagsReg crx) %{ 12233 // no match-rule, false predicate 12234 effect(DEF crx); 12235 predicate(false); 12236 12237 ins_variable_size_depending_on_alignment(true); 12238 12239 format %{ "cmov $crx" %} 12240 // Worst case is branch + move + stop, no stop without scheduler. 12241 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12)); 12242 ins_encode %{ 12243 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12244 Label done; 12245 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12246 __ li(R0, 0); 12247 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12248 // TODO PPC port __ endgroup_if_needed(_size == 16); 12249 __ bind(done); 12250 %} 12251 ins_pipe(pipe_class_default); 12252 %} 12253 12254 // Compare floating, generate condition code. 12255 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12256 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12257 // 12258 // The following code sequence occurs a lot in mpegaudio: 12259 // 12260 // block BXX: 12261 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12262 // cmpFUrd CCR6, F11, F9 12263 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12264 // cmov CCR6 12265 // 8: instruct branchConSched: 12266 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12267 match(Set crx (CmpF src1 src2)); 12268 ins_cost(DEFAULT_COST+BRANCH_COST); 12269 12270 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12271 postalloc_expand %{ 12272 // 12273 // replaces 12274 // 12275 // region src1 src2 12276 // \ | | 12277 // crx=cmpF_reg_reg 12278 // 12279 // with 12280 // 12281 // region src1 src2 12282 // \ | | 12283 // crx=cmpFUnordered_reg_reg 12284 // | 12285 // ^ region 12286 // | \ 12287 // crx=cmov_bns_less 12288 // 12289 12290 // Create new nodes. 12291 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12292 MachNode *m2 = new cmov_bns_lessNode(); 12293 12294 // inputs for new nodes 12295 m1->add_req(n_region, n_src1, n_src2); 12296 m2->add_req(n_region); 12297 m2->add_prec(m1); 12298 12299 // operands for new nodes 12300 m1->_opnds[0] = op_crx; 12301 m1->_opnds[1] = op_src1; 12302 m1->_opnds[2] = op_src2; 12303 m2->_opnds[0] = op_crx; 12304 12305 // registers for new nodes 12306 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12307 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12308 12309 // Insert new nodes. 12310 nodes->push(m1); 12311 nodes->push(m2); 12312 %} 12313 %} 12314 12315 // Compare float, generate -1,0,1 12316 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12317 match(Set dst (CmpF3 src1 src2)); 12318 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12319 12320 expand %{ 12321 flagsReg tmp1; 12322 cmpFUnordered_reg_reg(tmp1, src1, src2); 12323 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12324 %} 12325 %} 12326 12327 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12328 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12329 // node right before the conditional move using it. 12330 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12331 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12332 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12333 // conditional move was supposed to be spilled. 12334 match(Set crx (CmpD src1 src2)); 12335 // False predicate, shall not be matched. 12336 predicate(false); 12337 12338 format %{ "cmpFUrd $crx, $src1, $src2" %} 12339 size(4); 12340 ins_encode %{ 12341 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12342 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12343 %} 12344 ins_pipe(pipe_class_default); 12345 %} 12346 12347 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12348 match(Set crx (CmpD src1 src2)); 12349 ins_cost(DEFAULT_COST+BRANCH_COST); 12350 12351 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12352 postalloc_expand %{ 12353 // 12354 // replaces 12355 // 12356 // region src1 src2 12357 // \ | | 12358 // crx=cmpD_reg_reg 12359 // 12360 // with 12361 // 12362 // region src1 src2 12363 // \ | | 12364 // crx=cmpDUnordered_reg_reg 12365 // | 12366 // ^ region 12367 // | \ 12368 // crx=cmov_bns_less 12369 // 12370 12371 // create new nodes 12372 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12373 MachNode *m2 = new cmov_bns_lessNode(); 12374 12375 // inputs for new nodes 12376 m1->add_req(n_region, n_src1, n_src2); 12377 m2->add_req(n_region); 12378 m2->add_prec(m1); 12379 12380 // operands for new nodes 12381 m1->_opnds[0] = op_crx; 12382 m1->_opnds[1] = op_src1; 12383 m1->_opnds[2] = op_src2; 12384 m2->_opnds[0] = op_crx; 12385 12386 // registers for new nodes 12387 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12388 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12389 12390 // Insert new nodes. 12391 nodes->push(m1); 12392 nodes->push(m2); 12393 %} 12394 %} 12395 12396 // Compare double, generate -1,0,1 12397 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12398 match(Set dst (CmpD3 src1 src2)); 12399 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12400 12401 expand %{ 12402 flagsReg tmp1; 12403 cmpDUnordered_reg_reg(tmp1, src1, src2); 12404 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12405 %} 12406 %} 12407 12408 // Compare char 12409 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12410 match(Set dst (Digit src1)); 12411 effect(TEMP src2, TEMP crx); 12412 ins_cost(3 * DEFAULT_COST); 12413 12414 format %{ "LI $src2, 0x3930\n\t" 12415 "CMPRB $crx, 0, $src1, $src2\n\t" 12416 "SETB $dst, $crx" %} 12417 size(12); 12418 ins_encode %{ 12419 // 0x30: 0, 0x39: 9 12420 __ li($src2$$Register, 0x3930); 12421 // compare src1 with ranges 0x30 to 0x39 12422 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12423 __ setb($dst$$Register, $crx$$CondRegister); 12424 %} 12425 ins_pipe(pipe_class_default); 12426 %} 12427 12428 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12429 match(Set dst (LowerCase src1)); 12430 effect(TEMP src2, TEMP crx); 12431 ins_cost(12 * DEFAULT_COST); 12432 12433 format %{ "LI $src2, 0x7A61\n\t" 12434 "CMPRB $crx, 0, $src1, $src2\n\t" 12435 "BGT $crx, done\n\t" 12436 "LIS $src2, (signed short)0xF6DF\n\t" 12437 "ORI $src2, $src2, 0xFFF8\n\t" 12438 "CMPRB $crx, 1, $src1, $src2\n\t" 12439 "BGT $crx, done\n\t" 12440 "LIS $src2, (signed short)0xAAB5\n\t" 12441 "ORI $src2, $src2, 0xBABA\n\t" 12442 "INSRDI $src2, $src2, 32, 0\n\t" 12443 "CMPEQB $crx, 1, $src1, $src2\n\t" 12444 "SETB $dst, $crx" %} 12445 12446 size(48); 12447 ins_encode %{ 12448 Label done; 12449 // 0x61: a, 0x7A: z 12450 __ li($src2$$Register, 0x7A61); 12451 // compare src1 with ranges 0x61 to 0x7A 12452 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12453 __ bgt($crx$$CondRegister, done); 12454 12455 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case 12456 __ lis($src2$$Register, (signed short)0xF6DF); 12457 __ ori($src2$$Register, $src2$$Register, 0xFFF8); 12458 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF 12459 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12460 __ bgt($crx$$CondRegister, done); 12461 12462 // 0xAA: feminine ordinal indicator 12463 // 0xB5: micro sign 12464 // 0xBA: masculine ordinal indicator 12465 __ lis($src2$$Register, (signed short)0xAAB5); 12466 __ ori($src2$$Register, $src2$$Register, 0xBABA); 12467 __ insrdi($src2$$Register, $src2$$Register, 32, 0); 12468 // compare src1 with 0xAA, 0xB5, and 0xBA 12469 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register); 12470 12471 __ bind(done); 12472 __ setb($dst$$Register, $crx$$CondRegister); 12473 %} 12474 ins_pipe(pipe_class_default); 12475 %} 12476 12477 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12478 match(Set dst (UpperCase src1)); 12479 effect(TEMP src2, TEMP crx); 12480 ins_cost(7 * DEFAULT_COST); 12481 12482 format %{ "LI $src2, 0x5A41\n\t" 12483 "CMPRB $crx, 0, $src1, $src2\n\t" 12484 "BGT $crx, done\n\t" 12485 "LIS $src2, (signed short)0xD6C0\n\t" 12486 "ORI $src2, $src2, 0xDED8\n\t" 12487 "CMPRB $crx, 1, $src1, $src2\n\t" 12488 "SETB $dst, $crx" %} 12489 12490 size(28); 12491 ins_encode %{ 12492 Label done; 12493 // 0x41: A, 0x5A: Z 12494 __ li($src2$$Register, 0x5A41); 12495 // compare src1 with a range 0x41 to 0x5A 12496 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12497 __ bgt($crx$$CondRegister, done); 12498 12499 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case 12500 __ lis($src2$$Register, (signed short)0xD6C0); 12501 __ ori($src2$$Register, $src2$$Register, 0xDED8); 12502 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE 12503 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12504 12505 __ bind(done); 12506 __ setb($dst$$Register, $crx$$CondRegister); 12507 %} 12508 ins_pipe(pipe_class_default); 12509 %} 12510 12511 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12512 match(Set dst (Whitespace src1)); 12513 effect(TEMP src2, TEMP crx); 12514 ins_cost(4 * DEFAULT_COST); 12515 12516 format %{ "LI $src2, 0x0D09\n\t" 12517 "ADDIS $src2, 0x201C\n\t" 12518 "CMPRB $crx, 1, $src1, $src2\n\t" 12519 "SETB $dst, $crx" %} 12520 size(16); 12521 ins_encode %{ 12522 // 0x09 to 0x0D, 0x1C to 0x20 12523 __ li($src2$$Register, 0x0D09); 12524 __ addis($src2$$Register, $src2$$Register, 0x0201C); 12525 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20 12526 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12527 __ setb($dst$$Register, $crx$$CondRegister); 12528 %} 12529 ins_pipe(pipe_class_default); 12530 %} 12531 12532 //----------Branches--------------------------------------------------------- 12533 // Jump 12534 12535 // Direct Branch. 12536 instruct branch(label labl) %{ 12537 match(Goto); 12538 effect(USE labl); 12539 ins_cost(BRANCH_COST); 12540 12541 format %{ "B $labl" %} 12542 size(4); 12543 ins_encode %{ 12544 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12545 Label d; // dummy 12546 __ bind(d); 12547 Label* p = $labl$$label; 12548 // `p' is `NULL' when this encoding class is used only to 12549 // determine the size of the encoded instruction. 12550 Label& l = (NULL == p)? d : *(p); 12551 __ b(l); 12552 %} 12553 ins_pipe(pipe_class_default); 12554 %} 12555 12556 // Conditional Near Branch 12557 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12558 // Same match rule as `branchConFar'. 12559 match(If cmp crx); 12560 effect(USE lbl); 12561 ins_cost(BRANCH_COST); 12562 12563 // If set to 1 this indicates that the current instruction is a 12564 // short variant of a long branch. This avoids using this 12565 // instruction in first-pass matching. It will then only be used in 12566 // the `Shorten_branches' pass. 12567 ins_short_branch(1); 12568 12569 format %{ "B$cmp $crx, $lbl" %} 12570 size(4); 12571 ins_encode( enc_bc(crx, cmp, lbl) ); 12572 ins_pipe(pipe_class_default); 12573 %} 12574 12575 // This is for cases when the ppc64 `bc' instruction does not 12576 // reach far enough. So we emit a far branch here, which is more 12577 // expensive. 12578 // 12579 // Conditional Far Branch 12580 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12581 // Same match rule as `branchCon'. 12582 match(If cmp crx); 12583 effect(USE crx, USE lbl); 12584 predicate(!false /* TODO: PPC port HB_Schedule*/); 12585 // Higher cost than `branchCon'. 12586 ins_cost(5*BRANCH_COST); 12587 12588 // This is not a short variant of a branch, but the long variant. 12589 ins_short_branch(0); 12590 12591 format %{ "B_FAR$cmp $crx, $lbl" %} 12592 size(8); 12593 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12594 ins_pipe(pipe_class_default); 12595 %} 12596 12597 // Conditional Branch used with Power6 scheduler (can be far or short). 12598 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12599 // Same match rule as `branchCon'. 12600 match(If cmp crx); 12601 effect(USE crx, USE lbl); 12602 predicate(false /* TODO: PPC port HB_Schedule*/); 12603 // Higher cost than `branchCon'. 12604 ins_cost(5*BRANCH_COST); 12605 12606 // Actually size doesn't depend on alignment but on shortening. 12607 ins_variable_size_depending_on_alignment(true); 12608 // long variant. 12609 ins_short_branch(0); 12610 12611 format %{ "B_FAR$cmp $crx, $lbl" %} 12612 size(8); // worst case 12613 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12614 ins_pipe(pipe_class_default); 12615 %} 12616 12617 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12618 match(CountedLoopEnd cmp crx); 12619 effect(USE labl); 12620 ins_cost(BRANCH_COST); 12621 12622 // short variant. 12623 ins_short_branch(1); 12624 12625 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12626 size(4); 12627 ins_encode( enc_bc(crx, cmp, labl) ); 12628 ins_pipe(pipe_class_default); 12629 %} 12630 12631 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12632 match(CountedLoopEnd cmp crx); 12633 effect(USE labl); 12634 predicate(!false /* TODO: PPC port HB_Schedule */); 12635 ins_cost(BRANCH_COST); 12636 12637 // Long variant. 12638 ins_short_branch(0); 12639 12640 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12641 size(8); 12642 ins_encode( enc_bc_far(crx, cmp, labl) ); 12643 ins_pipe(pipe_class_default); 12644 %} 12645 12646 // Conditional Branch used with Power6 scheduler (can be far or short). 12647 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12648 match(CountedLoopEnd cmp crx); 12649 effect(USE labl); 12650 predicate(false /* TODO: PPC port HB_Schedule */); 12651 // Higher cost than `branchCon'. 12652 ins_cost(5*BRANCH_COST); 12653 12654 // Actually size doesn't depend on alignment but on shortening. 12655 ins_variable_size_depending_on_alignment(true); 12656 // Long variant. 12657 ins_short_branch(0); 12658 12659 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12660 size(8); // worst case 12661 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12662 ins_pipe(pipe_class_default); 12663 %} 12664 12665 // ============================================================================ 12666 // Java runtime operations, intrinsics and other complex operations. 12667 12668 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12669 // array for an instance of the superklass. Set a hidden internal cache on a 12670 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12671 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12672 // 12673 // GL TODO: Improve this. 12674 // - result should not be a TEMP 12675 // - Add match rule as on sparc avoiding additional Cmp. 12676 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12677 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12678 match(Set result (PartialSubtypeCheck subklass superklass)); 12679 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12680 ins_cost(DEFAULT_COST*10); 12681 12682 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12683 ins_encode %{ 12684 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12685 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12686 $tmp_klass$$Register, NULL, $result$$Register); 12687 %} 12688 ins_pipe(pipe_class_default); 12689 %} 12690 12691 // inlined locking and unlocking 12692 12693 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12694 match(Set crx (FastLock oop box)); 12695 effect(TEMP tmp1, TEMP tmp2); 12696 predicate(!Compile::current()->use_rtm()); 12697 12698 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12699 ins_encode %{ 12700 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12701 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12702 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12703 UseBiasedLocking && !UseOptoBiasInlining); 12704 // If locking was successfull, crx should indicate 'EQ'. 12705 // The compiler generates a branch to the runtime call to 12706 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12707 %} 12708 ins_pipe(pipe_class_compare); 12709 %} 12710 12711 // Separate version for TM. Use bound register for box to enable USE_KILL. 12712 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12713 match(Set crx (FastLock oop box)); 12714 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12715 predicate(Compile::current()->use_rtm()); 12716 12717 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12718 ins_encode %{ 12719 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12720 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12721 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12722 /*Biased Locking*/ false, 12723 _rtm_counters, _stack_rtm_counters, 12724 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12725 /*TM*/ true, ra_->C->profile_rtm()); 12726 // If locking was successfull, crx should indicate 'EQ'. 12727 // The compiler generates a branch to the runtime call to 12728 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12729 %} 12730 ins_pipe(pipe_class_compare); 12731 %} 12732 12733 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12734 match(Set crx (FastUnlock oop box)); 12735 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12736 predicate(!Compile::current()->use_rtm()); 12737 12738 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12739 ins_encode %{ 12740 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12741 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12742 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12743 UseBiasedLocking && !UseOptoBiasInlining, 12744 false); 12745 // If unlocking was successfull, crx should indicate 'EQ'. 12746 // The compiler generates a branch to the runtime call to 12747 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12748 %} 12749 ins_pipe(pipe_class_compare); 12750 %} 12751 12752 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12753 match(Set crx (FastUnlock oop box)); 12754 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12755 predicate(Compile::current()->use_rtm()); 12756 12757 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12758 ins_encode %{ 12759 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12760 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12761 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12762 /*Biased Locking*/ false, /*TM*/ true); 12763 // If unlocking was successfull, crx should indicate 'EQ'. 12764 // The compiler generates a branch to the runtime call to 12765 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12766 %} 12767 ins_pipe(pipe_class_compare); 12768 %} 12769 12770 // Align address. 12771 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12772 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12773 12774 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12775 size(4); 12776 ins_encode %{ 12777 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12778 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12779 %} 12780 ins_pipe(pipe_class_default); 12781 %} 12782 12783 // Array size computation. 12784 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12785 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12786 12787 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12788 size(4); 12789 ins_encode %{ 12790 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12791 __ subf($dst$$Register, $start$$Register, $end$$Register); 12792 %} 12793 ins_pipe(pipe_class_default); 12794 %} 12795 12796 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12797 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12798 match(Set dummy (ClearArray cnt base)); 12799 effect(USE_KILL base, KILL ctr); 12800 ins_cost(2 * MEMORY_REF_COST); 12801 12802 format %{ "ClearArray $cnt, $base" %} 12803 ins_encode %{ 12804 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12805 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12806 %} 12807 ins_pipe(pipe_class_default); 12808 %} 12809 12810 // Clear-array with constant large array length. 12811 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12812 match(Set dummy (ClearArray cnt base)); 12813 effect(USE_KILL base, TEMP tmp, KILL ctr); 12814 ins_cost(3 * MEMORY_REF_COST); 12815 12816 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12817 ins_encode %{ 12818 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12819 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12820 %} 12821 ins_pipe(pipe_class_default); 12822 %} 12823 12824 // Clear-array with dynamic array length. 12825 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12826 match(Set dummy (ClearArray cnt base)); 12827 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12828 ins_cost(4 * MEMORY_REF_COST); 12829 12830 format %{ "ClearArray $cnt, $base" %} 12831 ins_encode %{ 12832 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12833 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12834 %} 12835 ins_pipe(pipe_class_default); 12836 %} 12837 12838 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12839 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12840 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12841 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12842 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12843 ins_cost(300); 12844 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12845 ins_encode %{ 12846 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12847 __ string_compare($str1$$Register, $str2$$Register, 12848 $cnt1$$Register, $cnt2$$Register, 12849 $tmp$$Register, 12850 $result$$Register, StrIntrinsicNode::LL); 12851 %} 12852 ins_pipe(pipe_class_default); 12853 %} 12854 12855 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12856 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12857 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12858 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12859 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12860 ins_cost(300); 12861 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12862 ins_encode %{ 12863 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12864 __ string_compare($str1$$Register, $str2$$Register, 12865 $cnt1$$Register, $cnt2$$Register, 12866 $tmp$$Register, 12867 $result$$Register, StrIntrinsicNode::UU); 12868 %} 12869 ins_pipe(pipe_class_default); 12870 %} 12871 12872 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12873 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12874 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12875 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12876 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12877 ins_cost(300); 12878 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12879 ins_encode %{ 12880 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12881 __ string_compare($str1$$Register, $str2$$Register, 12882 $cnt1$$Register, $cnt2$$Register, 12883 $tmp$$Register, 12884 $result$$Register, StrIntrinsicNode::LU); 12885 %} 12886 ins_pipe(pipe_class_default); 12887 %} 12888 12889 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12890 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12891 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12892 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12893 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12894 ins_cost(300); 12895 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12896 ins_encode %{ 12897 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12898 __ string_compare($str2$$Register, $str1$$Register, 12899 $cnt2$$Register, $cnt1$$Register, 12900 $tmp$$Register, 12901 $result$$Register, StrIntrinsicNode::UL); 12902 %} 12903 ins_pipe(pipe_class_default); 12904 %} 12905 12906 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12907 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12908 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12909 match(Set result (StrEquals (Binary str1 str2) cnt)); 12910 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12911 ins_cost(300); 12912 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12913 ins_encode %{ 12914 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12915 __ array_equals(false, $str1$$Register, $str2$$Register, 12916 $cnt$$Register, $tmp$$Register, 12917 $result$$Register, true /* byte */); 12918 %} 12919 ins_pipe(pipe_class_default); 12920 %} 12921 12922 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12923 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12924 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12925 match(Set result (StrEquals (Binary str1 str2) cnt)); 12926 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12927 ins_cost(300); 12928 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12929 ins_encode %{ 12930 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12931 __ array_equals(false, $str1$$Register, $str2$$Register, 12932 $cnt$$Register, $tmp$$Register, 12933 $result$$Register, false /* byte */); 12934 %} 12935 ins_pipe(pipe_class_default); 12936 %} 12937 12938 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12939 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12940 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12941 match(Set result (AryEq ary1 ary2)); 12942 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12943 ins_cost(300); 12944 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12945 ins_encode %{ 12946 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12947 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12948 $tmp1$$Register, $tmp2$$Register, 12949 $result$$Register, true /* byte */); 12950 %} 12951 ins_pipe(pipe_class_default); 12952 %} 12953 12954 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12955 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12956 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12957 match(Set result (AryEq ary1 ary2)); 12958 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12959 ins_cost(300); 12960 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12961 ins_encode %{ 12962 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12963 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12964 $tmp1$$Register, $tmp2$$Register, 12965 $result$$Register, false /* byte */); 12966 %} 12967 ins_pipe(pipe_class_default); 12968 %} 12969 12970 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12971 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12972 iRegIdst tmp1, iRegIdst tmp2, 12973 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12974 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12975 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12976 // Required for EA: check if it is still a type_array. 12977 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12978 ins_cost(150); 12979 12980 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12981 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12982 12983 ins_encode %{ 12984 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12985 immPOper *needleOper = (immPOper *)$needleImm; 12986 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12987 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12988 jchar chr; 12989 #ifdef VM_LITTLE_ENDIAN 12990 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12991 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12992 #else 12993 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12994 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12995 #endif 12996 __ string_indexof_char($result$$Register, 12997 $haystack$$Register, $haycnt$$Register, 12998 R0, chr, 12999 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13000 %} 13001 ins_pipe(pipe_class_compare); 13002 %} 13003 13004 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13005 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13006 iRegIdst tmp1, iRegIdst tmp2, 13007 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13008 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13009 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13010 // Required for EA: check if it is still a type_array. 13011 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13012 ins_cost(150); 13013 13014 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13015 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13016 13017 ins_encode %{ 13018 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13019 immPOper *needleOper = (immPOper *)$needleImm; 13020 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13021 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13022 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13023 __ string_indexof_char($result$$Register, 13024 $haystack$$Register, $haycnt$$Register, 13025 R0, chr, 13026 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13027 %} 13028 ins_pipe(pipe_class_compare); 13029 %} 13030 13031 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13032 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13033 iRegIdst tmp1, iRegIdst tmp2, 13034 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13035 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13036 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13037 // Required for EA: check if it is still a type_array. 13038 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13039 ins_cost(150); 13040 13041 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13042 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13043 13044 ins_encode %{ 13045 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13046 immPOper *needleOper = (immPOper *)$needleImm; 13047 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13048 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13049 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13050 __ string_indexof_char($result$$Register, 13051 $haystack$$Register, $haycnt$$Register, 13052 R0, chr, 13053 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13054 %} 13055 ins_pipe(pipe_class_compare); 13056 %} 13057 13058 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13059 rscratch2RegP needle, immI_1 needlecntImm, 13060 iRegIdst tmp1, iRegIdst tmp2, 13061 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13062 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13063 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13064 // Required for EA: check if it is still a type_array. 13065 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13066 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13067 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13068 ins_cost(180); 13069 13070 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13071 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13072 ins_encode %{ 13073 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13074 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13075 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13076 guarantee(needle_values, "sanity"); 13077 jchar chr; 13078 #ifdef VM_LITTLE_ENDIAN 13079 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 13080 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 13081 #else 13082 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 13083 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 13084 #endif 13085 __ string_indexof_char($result$$Register, 13086 $haystack$$Register, $haycnt$$Register, 13087 R0, chr, 13088 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13089 %} 13090 ins_pipe(pipe_class_compare); 13091 %} 13092 13093 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13094 rscratch2RegP needle, immI_1 needlecntImm, 13095 iRegIdst tmp1, iRegIdst tmp2, 13096 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13097 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13098 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13099 // Required for EA: check if it is still a type_array. 13100 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13101 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13102 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13103 ins_cost(180); 13104 13105 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13106 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13107 ins_encode %{ 13108 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13109 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13110 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13111 guarantee(needle_values, "sanity"); 13112 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13113 __ string_indexof_char($result$$Register, 13114 $haystack$$Register, $haycnt$$Register, 13115 R0, chr, 13116 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13117 %} 13118 ins_pipe(pipe_class_compare); 13119 %} 13120 13121 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13122 rscratch2RegP needle, immI_1 needlecntImm, 13123 iRegIdst tmp1, iRegIdst tmp2, 13124 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13125 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13126 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13127 // Required for EA: check if it is still a type_array. 13128 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13129 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13130 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13131 ins_cost(180); 13132 13133 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13134 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13135 ins_encode %{ 13136 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13137 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13138 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13139 guarantee(needle_values, "sanity"); 13140 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13141 __ string_indexof_char($result$$Register, 13142 $haystack$$Register, $haycnt$$Register, 13143 R0, chr, 13144 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13145 %} 13146 ins_pipe(pipe_class_compare); 13147 %} 13148 13149 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13150 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 13151 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13152 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 13153 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13154 ins_cost(180); 13155 13156 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 13157 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13158 ins_encode %{ 13159 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13160 __ string_indexof_char($result$$Register, 13161 $haystack$$Register, $haycnt$$Register, 13162 $ch$$Register, 0 /* this is not used if the character is already in a register */, 13163 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13164 %} 13165 ins_pipe(pipe_class_compare); 13166 %} 13167 13168 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13169 iRegPsrc needle, uimmI15 needlecntImm, 13170 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13171 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13172 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13173 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13174 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13175 // Required for EA: check if it is still a type_array. 13176 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13177 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13178 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13179 ins_cost(250); 13180 13181 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13182 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13183 ins_encode %{ 13184 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13185 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13186 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13187 13188 __ string_indexof($result$$Register, 13189 $haystack$$Register, $haycnt$$Register, 13190 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13191 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13192 %} 13193 ins_pipe(pipe_class_compare); 13194 %} 13195 13196 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13197 iRegPsrc needle, uimmI15 needlecntImm, 13198 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13199 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13200 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13201 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13202 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13203 // Required for EA: check if it is still a type_array. 13204 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13205 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13206 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13207 ins_cost(250); 13208 13209 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13210 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13211 ins_encode %{ 13212 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13213 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13214 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13215 13216 __ string_indexof($result$$Register, 13217 $haystack$$Register, $haycnt$$Register, 13218 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13219 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13220 %} 13221 ins_pipe(pipe_class_compare); 13222 %} 13223 13224 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13225 iRegPsrc needle, uimmI15 needlecntImm, 13226 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13227 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13228 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13229 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13230 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13231 // Required for EA: check if it is still a type_array. 13232 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13233 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13234 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13235 ins_cost(250); 13236 13237 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13238 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13239 ins_encode %{ 13240 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13241 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13242 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13243 13244 __ string_indexof($result$$Register, 13245 $haystack$$Register, $haycnt$$Register, 13246 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13247 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13248 %} 13249 ins_pipe(pipe_class_compare); 13250 %} 13251 13252 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13253 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13254 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13255 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13256 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13257 TEMP_DEF result, 13258 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13259 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13260 ins_cost(300); 13261 13262 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13263 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13264 ins_encode %{ 13265 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13266 __ string_indexof($result$$Register, 13267 $haystack$$Register, $haycnt$$Register, 13268 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13269 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13270 %} 13271 ins_pipe(pipe_class_compare); 13272 %} 13273 13274 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13275 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13276 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13277 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13278 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13279 TEMP_DEF result, 13280 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13281 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13282 ins_cost(300); 13283 13284 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13285 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13286 ins_encode %{ 13287 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13288 __ string_indexof($result$$Register, 13289 $haystack$$Register, $haycnt$$Register, 13290 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13291 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13292 %} 13293 ins_pipe(pipe_class_compare); 13294 %} 13295 13296 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13297 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13298 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13299 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13300 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13301 TEMP_DEF result, 13302 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13303 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13304 ins_cost(300); 13305 13306 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13307 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13308 ins_encode %{ 13309 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13310 __ string_indexof($result$$Register, 13311 $haystack$$Register, $haycnt$$Register, 13312 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13313 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13314 %} 13315 ins_pipe(pipe_class_compare); 13316 %} 13317 13318 // char[] to byte[] compression 13319 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13320 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13321 match(Set result (StrCompressedCopy src (Binary dst len))); 13322 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13323 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13324 ins_cost(300); 13325 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13326 ins_encode %{ 13327 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13328 Label Lskip, Ldone; 13329 __ li($result$$Register, 0); 13330 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13331 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13332 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13333 __ beq(CCR0, Lskip); 13334 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13335 __ bind(Lskip); 13336 __ mr($result$$Register, $len$$Register); 13337 __ bind(Ldone); 13338 %} 13339 ins_pipe(pipe_class_default); 13340 %} 13341 13342 // byte[] to char[] inflation 13343 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13344 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13345 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13346 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13347 ins_cost(300); 13348 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13349 ins_encode %{ 13350 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13351 Label Ldone; 13352 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13353 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13354 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13355 __ beq(CCR0, Ldone); 13356 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13357 __ bind(Ldone); 13358 %} 13359 ins_pipe(pipe_class_default); 13360 %} 13361 13362 // StringCoding.java intrinsics 13363 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13364 regCTR ctr, flagsRegCR0 cr0) 13365 %{ 13366 match(Set result (HasNegatives ary1 len)); 13367 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13368 ins_cost(300); 13369 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13370 ins_encode %{ 13371 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13372 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13373 $tmp1$$Register, $tmp2$$Register); 13374 %} 13375 ins_pipe(pipe_class_default); 13376 %} 13377 13378 // encode char[] to byte[] in ISO_8859_1 13379 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13380 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13381 match(Set result (EncodeISOArray src (Binary dst len))); 13382 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13383 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13384 ins_cost(300); 13385 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13386 ins_encode %{ 13387 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13388 Label Lslow, Lfailure1, Lfailure2, Ldone; 13389 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13390 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13391 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13392 __ beq(CCR0, Ldone); 13393 __ bind(Lslow); 13394 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13395 __ li($result$$Register, 0); 13396 __ b(Ldone); 13397 13398 __ bind(Lfailure1); 13399 __ mr($result$$Register, $len$$Register); 13400 __ mfctr($tmp1$$Register); 13401 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13402 __ beq(CCR0, Ldone); 13403 __ b(Lslow); 13404 13405 __ bind(Lfailure2); 13406 __ mfctr($result$$Register); // Remaining characters. 13407 13408 __ bind(Ldone); 13409 __ subf($result$$Register, $result$$Register, $len$$Register); 13410 %} 13411 ins_pipe(pipe_class_default); 13412 %} 13413 13414 13415 //---------- Min/Max Instructions --------------------------------------------- 13416 13417 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13418 match(Set dst (MinI src1 src2)); 13419 ins_cost(DEFAULT_COST*6); 13420 13421 expand %{ 13422 iRegLdst src1s; 13423 iRegLdst src2s; 13424 iRegLdst diff; 13425 iRegLdst sm; 13426 iRegLdst doz; // difference or zero 13427 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13428 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13429 subL_reg_reg(diff, src2s, src1s); 13430 // Need to consider >=33 bit result, therefore we need signmaskL. 13431 signmask64L_regL(sm, diff); 13432 andL_reg_reg(doz, diff, sm); // <=0 13433 addI_regL_regL(dst, doz, src1s); 13434 %} 13435 %} 13436 13437 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13438 match(Set dst (MinI src1 src2)); 13439 effect(KILL cr0); 13440 predicate(VM_Version::has_isel()); 13441 ins_cost(DEFAULT_COST*2); 13442 13443 ins_encode %{ 13444 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13445 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13446 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13447 %} 13448 ins_pipe(pipe_class_default); 13449 %} 13450 13451 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13452 match(Set dst (MaxI src1 src2)); 13453 ins_cost(DEFAULT_COST*6); 13454 13455 expand %{ 13456 iRegLdst src1s; 13457 iRegLdst src2s; 13458 iRegLdst diff; 13459 iRegLdst sm; 13460 iRegLdst doz; // difference or zero 13461 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13462 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13463 subL_reg_reg(diff, src2s, src1s); 13464 // Need to consider >=33 bit result, therefore we need signmaskL. 13465 signmask64L_regL(sm, diff); 13466 andcL_reg_reg(doz, diff, sm); // >=0 13467 addI_regL_regL(dst, doz, src1s); 13468 %} 13469 %} 13470 13471 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13472 match(Set dst (MaxI src1 src2)); 13473 effect(KILL cr0); 13474 predicate(VM_Version::has_isel()); 13475 ins_cost(DEFAULT_COST*2); 13476 13477 ins_encode %{ 13478 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13479 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13480 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13481 %} 13482 ins_pipe(pipe_class_default); 13483 %} 13484 13485 //---------- Population Count Instructions ------------------------------------ 13486 13487 // Popcnt for Power7. 13488 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13489 match(Set dst (PopCountI src)); 13490 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13491 ins_cost(DEFAULT_COST); 13492 13493 format %{ "POPCNTW $dst, $src" %} 13494 size(4); 13495 ins_encode %{ 13496 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13497 __ popcntw($dst$$Register, $src$$Register); 13498 %} 13499 ins_pipe(pipe_class_default); 13500 %} 13501 13502 // Popcnt for Power7. 13503 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13504 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13505 match(Set dst (PopCountL src)); 13506 ins_cost(DEFAULT_COST); 13507 13508 format %{ "POPCNTD $dst, $src" %} 13509 size(4); 13510 ins_encode %{ 13511 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13512 __ popcntd($dst$$Register, $src$$Register); 13513 %} 13514 ins_pipe(pipe_class_default); 13515 %} 13516 13517 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13518 match(Set dst (CountLeadingZerosI src)); 13519 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13520 ins_cost(DEFAULT_COST); 13521 13522 format %{ "CNTLZW $dst, $src" %} 13523 size(4); 13524 ins_encode %{ 13525 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13526 __ cntlzw($dst$$Register, $src$$Register); 13527 %} 13528 ins_pipe(pipe_class_default); 13529 %} 13530 13531 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13532 match(Set dst (CountLeadingZerosL src)); 13533 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13534 ins_cost(DEFAULT_COST); 13535 13536 format %{ "CNTLZD $dst, $src" %} 13537 size(4); 13538 ins_encode %{ 13539 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13540 __ cntlzd($dst$$Register, $src$$Register); 13541 %} 13542 ins_pipe(pipe_class_default); 13543 %} 13544 13545 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13546 // no match-rule, false predicate 13547 effect(DEF dst, USE src); 13548 predicate(false); 13549 13550 format %{ "CNTLZD $dst, $src" %} 13551 size(4); 13552 ins_encode %{ 13553 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13554 __ cntlzd($dst$$Register, $src$$Register); 13555 %} 13556 ins_pipe(pipe_class_default); 13557 %} 13558 13559 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13560 match(Set dst (CountTrailingZerosI src)); 13561 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13562 ins_cost(DEFAULT_COST); 13563 13564 expand %{ 13565 immI16 imm1 %{ (int)-1 %} 13566 immI16 imm2 %{ (int)32 %} 13567 immI_minus1 m1 %{ -1 %} 13568 iRegIdst tmpI1; 13569 iRegIdst tmpI2; 13570 iRegIdst tmpI3; 13571 addI_reg_imm16(tmpI1, src, imm1); 13572 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13573 countLeadingZerosI(tmpI3, tmpI2); 13574 subI_imm16_reg(dst, imm2, tmpI3); 13575 %} 13576 %} 13577 13578 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{ 13579 match(Set dst (CountTrailingZerosI src)); 13580 predicate(UseCountTrailingZerosInstructionsPPC64); 13581 ins_cost(DEFAULT_COST); 13582 13583 format %{ "CNTTZW $dst, $src" %} 13584 size(4); 13585 ins_encode %{ 13586 __ cnttzw($dst$$Register, $src$$Register); 13587 %} 13588 ins_pipe(pipe_class_default); 13589 %} 13590 13591 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13592 match(Set dst (CountTrailingZerosL src)); 13593 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13594 ins_cost(DEFAULT_COST); 13595 13596 expand %{ 13597 immL16 imm1 %{ (long)-1 %} 13598 immI16 imm2 %{ (int)64 %} 13599 iRegLdst tmpL1; 13600 iRegLdst tmpL2; 13601 iRegIdst tmpL3; 13602 addL_reg_imm16(tmpL1, src, imm1); 13603 andcL_reg_reg(tmpL2, tmpL1, src); 13604 countLeadingZerosL(tmpL3, tmpL2); 13605 subI_imm16_reg(dst, imm2, tmpL3); 13606 %} 13607 %} 13608 13609 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{ 13610 match(Set dst (CountTrailingZerosL src)); 13611 predicate(UseCountTrailingZerosInstructionsPPC64); 13612 ins_cost(DEFAULT_COST); 13613 13614 format %{ "CNTTZD $dst, $src" %} 13615 size(4); 13616 ins_encode %{ 13617 __ cnttzd($dst$$Register, $src$$Register); 13618 %} 13619 ins_pipe(pipe_class_default); 13620 %} 13621 13622 // Expand nodes for byte_reverse_int. 13623 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13624 effect(DEF dst, USE src, USE pos, USE shift); 13625 predicate(false); 13626 13627 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13628 size(4); 13629 ins_encode %{ 13630 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13631 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13632 %} 13633 ins_pipe(pipe_class_default); 13634 %} 13635 13636 // As insrwi_a, but with USE_DEF. 13637 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13638 effect(USE_DEF dst, USE src, USE pos, USE shift); 13639 predicate(false); 13640 13641 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13642 size(4); 13643 ins_encode %{ 13644 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13645 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13646 %} 13647 ins_pipe(pipe_class_default); 13648 %} 13649 13650 // Just slightly faster than java implementation. 13651 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13652 match(Set dst (ReverseBytesI src)); 13653 ins_cost(7*DEFAULT_COST); 13654 13655 expand %{ 13656 immI16 imm24 %{ (int) 24 %} 13657 immI16 imm16 %{ (int) 16 %} 13658 immI16 imm8 %{ (int) 8 %} 13659 immI16 imm4 %{ (int) 4 %} 13660 immI16 imm0 %{ (int) 0 %} 13661 iRegLdst tmpI1; 13662 iRegLdst tmpI2; 13663 iRegLdst tmpI3; 13664 13665 urShiftI_reg_imm(tmpI1, src, imm24); 13666 insrwi_a(dst, tmpI1, imm24, imm8); 13667 urShiftI_reg_imm(tmpI2, src, imm16); 13668 insrwi(dst, tmpI2, imm8, imm16); 13669 urShiftI_reg_imm(tmpI3, src, imm8); 13670 insrwi(dst, tmpI3, imm8, imm8); 13671 insrwi(dst, src, imm0, imm8); 13672 %} 13673 %} 13674 13675 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13676 match(Set dst (ReverseBytesL src)); 13677 ins_cost(15*DEFAULT_COST); 13678 13679 expand %{ 13680 immI16 imm56 %{ (int) 56 %} 13681 immI16 imm48 %{ (int) 48 %} 13682 immI16 imm40 %{ (int) 40 %} 13683 immI16 imm32 %{ (int) 32 %} 13684 immI16 imm24 %{ (int) 24 %} 13685 immI16 imm16 %{ (int) 16 %} 13686 immI16 imm8 %{ (int) 8 %} 13687 immI16 imm0 %{ (int) 0 %} 13688 iRegLdst tmpL1; 13689 iRegLdst tmpL2; 13690 iRegLdst tmpL3; 13691 iRegLdst tmpL4; 13692 iRegLdst tmpL5; 13693 iRegLdst tmpL6; 13694 13695 // src : |a|b|c|d|e|f|g|h| 13696 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13697 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13698 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13699 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13700 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13701 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13702 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13703 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13704 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13705 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13706 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13707 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13708 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13709 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13710 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13711 %} 13712 %} 13713 13714 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13715 match(Set dst (ReverseBytesUS src)); 13716 ins_cost(2*DEFAULT_COST); 13717 13718 expand %{ 13719 immI16 imm16 %{ (int) 16 %} 13720 immI16 imm8 %{ (int) 8 %} 13721 13722 urShiftI_reg_imm(dst, src, imm8); 13723 insrwi(dst, src, imm16, imm8); 13724 %} 13725 %} 13726 13727 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13728 match(Set dst (ReverseBytesS src)); 13729 ins_cost(3*DEFAULT_COST); 13730 13731 expand %{ 13732 immI16 imm16 %{ (int) 16 %} 13733 immI16 imm8 %{ (int) 8 %} 13734 iRegLdst tmpI1; 13735 13736 urShiftI_reg_imm(tmpI1, src, imm8); 13737 insrwi(tmpI1, src, imm16, imm8); 13738 extsh(dst, tmpI1); 13739 %} 13740 %} 13741 13742 // Load Integer reversed byte order 13743 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13744 match(Set dst (ReverseBytesI (LoadI mem))); 13745 ins_cost(MEMORY_REF_COST); 13746 13747 size(4); 13748 ins_encode %{ 13749 __ lwbrx($dst$$Register, $mem$$Register); 13750 %} 13751 ins_pipe(pipe_class_default); 13752 %} 13753 13754 // Load Long - aligned and reversed 13755 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13756 match(Set dst (ReverseBytesL (LoadL mem))); 13757 predicate(VM_Version::has_ldbrx()); 13758 ins_cost(MEMORY_REF_COST); 13759 13760 size(4); 13761 ins_encode %{ 13762 __ ldbrx($dst$$Register, $mem$$Register); 13763 %} 13764 ins_pipe(pipe_class_default); 13765 %} 13766 13767 // Load unsigned short / char reversed byte order 13768 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13769 match(Set dst (ReverseBytesUS (LoadUS mem))); 13770 ins_cost(MEMORY_REF_COST); 13771 13772 size(4); 13773 ins_encode %{ 13774 __ lhbrx($dst$$Register, $mem$$Register); 13775 %} 13776 ins_pipe(pipe_class_default); 13777 %} 13778 13779 // Load short reversed byte order 13780 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13781 match(Set dst (ReverseBytesS (LoadS mem))); 13782 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13783 13784 size(8); 13785 ins_encode %{ 13786 __ lhbrx($dst$$Register, $mem$$Register); 13787 __ extsh($dst$$Register, $dst$$Register); 13788 %} 13789 ins_pipe(pipe_class_default); 13790 %} 13791 13792 // Store Integer reversed byte order 13793 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13794 match(Set mem (StoreI mem (ReverseBytesI src))); 13795 ins_cost(MEMORY_REF_COST); 13796 13797 size(4); 13798 ins_encode %{ 13799 __ stwbrx($src$$Register, $mem$$Register); 13800 %} 13801 ins_pipe(pipe_class_default); 13802 %} 13803 13804 // Store Long reversed byte order 13805 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13806 match(Set mem (StoreL mem (ReverseBytesL src))); 13807 predicate(VM_Version::has_stdbrx()); 13808 ins_cost(MEMORY_REF_COST); 13809 13810 size(4); 13811 ins_encode %{ 13812 __ stdbrx($src$$Register, $mem$$Register); 13813 %} 13814 ins_pipe(pipe_class_default); 13815 %} 13816 13817 // Store unsigned short / char reversed byte order 13818 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13819 match(Set mem (StoreC mem (ReverseBytesUS src))); 13820 ins_cost(MEMORY_REF_COST); 13821 13822 size(4); 13823 ins_encode %{ 13824 __ sthbrx($src$$Register, $mem$$Register); 13825 %} 13826 ins_pipe(pipe_class_default); 13827 %} 13828 13829 // Store short reversed byte order 13830 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13831 match(Set mem (StoreC mem (ReverseBytesS src))); 13832 ins_cost(MEMORY_REF_COST); 13833 13834 size(4); 13835 ins_encode %{ 13836 __ sthbrx($src$$Register, $mem$$Register); 13837 %} 13838 ins_pipe(pipe_class_default); 13839 %} 13840 13841 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13842 effect(DEF temp1, USE src); 13843 13844 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %} 13845 size(4); 13846 ins_encode %{ 13847 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13848 %} 13849 ins_pipe(pipe_class_default); 13850 %} 13851 13852 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13853 effect(DEF dst, USE src, USE imm1); 13854 13855 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %} 13856 size(4); 13857 ins_encode %{ 13858 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13859 %} 13860 ins_pipe(pipe_class_default); 13861 %} 13862 13863 instruct xscvdpspn_regF(vecX dst, regF src) %{ 13864 effect(DEF dst, USE src); 13865 13866 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %} 13867 size(4); 13868 ins_encode %{ 13869 __ xscvdpspn($dst$$VectorSRegister, $src$$FloatRegister->to_vsr()); 13870 %} 13871 ins_pipe(pipe_class_default); 13872 %} 13873 13874 //---------- Replicate Vector Instructions ------------------------------------ 13875 13876 // Insrdi does replicate if src == dst. 13877 instruct repl32(iRegLdst dst) %{ 13878 predicate(false); 13879 effect(USE_DEF dst); 13880 13881 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13882 size(4); 13883 ins_encode %{ 13884 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13885 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13886 %} 13887 ins_pipe(pipe_class_default); 13888 %} 13889 13890 // Insrdi does replicate if src == dst. 13891 instruct repl48(iRegLdst dst) %{ 13892 predicate(false); 13893 effect(USE_DEF dst); 13894 13895 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13896 size(4); 13897 ins_encode %{ 13898 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13899 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13900 %} 13901 ins_pipe(pipe_class_default); 13902 %} 13903 13904 // Insrdi does replicate if src == dst. 13905 instruct repl56(iRegLdst dst) %{ 13906 predicate(false); 13907 effect(USE_DEF dst); 13908 13909 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13910 size(4); 13911 ins_encode %{ 13912 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13913 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 13914 %} 13915 ins_pipe(pipe_class_default); 13916 %} 13917 13918 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13919 match(Set dst (ReplicateB src)); 13920 predicate(n->as_Vector()->length() == 8); 13921 expand %{ 13922 moveReg(dst, src); 13923 repl56(dst); 13924 repl48(dst); 13925 repl32(dst); 13926 %} 13927 %} 13928 13929 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 13930 match(Set dst (ReplicateB zero)); 13931 predicate(n->as_Vector()->length() == 8); 13932 format %{ "LI $dst, #0 \t// replicate8B" %} 13933 size(4); 13934 ins_encode %{ 13935 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13936 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13937 %} 13938 ins_pipe(pipe_class_default); 13939 %} 13940 13941 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13942 match(Set dst (ReplicateB src)); 13943 predicate(n->as_Vector()->length() == 8); 13944 format %{ "LI $dst, #-1 \t// replicate8B" %} 13945 size(4); 13946 ins_encode %{ 13947 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13948 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13949 %} 13950 ins_pipe(pipe_class_default); 13951 %} 13952 13953 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 13954 match(Set dst (ReplicateB src)); 13955 predicate(n->as_Vector()->length() == 16); 13956 13957 expand %{ 13958 iRegLdst tmpL; 13959 vecX tmpV; 13960 immI8 imm1 %{ (int) 1 %} 13961 moveReg(tmpL, src); 13962 repl56(tmpL); 13963 repl48(tmpL); 13964 mtvsrwz(tmpV, tmpL); 13965 xxspltw(dst, tmpV, imm1); 13966 %} 13967 %} 13968 13969 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 13970 match(Set dst (ReplicateB zero)); 13971 predicate(n->as_Vector()->length() == 16); 13972 13973 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 13974 size(4); 13975 ins_encode %{ 13976 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13977 %} 13978 ins_pipe(pipe_class_default); 13979 %} 13980 13981 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 13982 match(Set dst (ReplicateB src)); 13983 predicate(n->as_Vector()->length() == 16); 13984 13985 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13986 size(4); 13987 ins_encode %{ 13988 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13989 %} 13990 ins_pipe(pipe_class_default); 13991 %} 13992 13993 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13994 match(Set dst (ReplicateS src)); 13995 predicate(n->as_Vector()->length() == 4); 13996 expand %{ 13997 moveReg(dst, src); 13998 repl48(dst); 13999 repl32(dst); 14000 %} 14001 %} 14002 14003 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 14004 match(Set dst (ReplicateS zero)); 14005 predicate(n->as_Vector()->length() == 4); 14006 format %{ "LI $dst, #0 \t// replicate4C" %} 14007 size(4); 14008 ins_encode %{ 14009 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14010 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14011 %} 14012 ins_pipe(pipe_class_default); 14013 %} 14014 14015 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14016 match(Set dst (ReplicateS src)); 14017 predicate(n->as_Vector()->length() == 4); 14018 format %{ "LI $dst, -1 \t// replicate4C" %} 14019 size(4); 14020 ins_encode %{ 14021 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14022 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14023 %} 14024 ins_pipe(pipe_class_default); 14025 %} 14026 14027 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 14028 match(Set dst (ReplicateS src)); 14029 predicate(n->as_Vector()->length() == 8); 14030 14031 expand %{ 14032 iRegLdst tmpL; 14033 vecX tmpV; 14034 immI8 zero %{ (int) 0 %} 14035 moveReg(tmpL, src); 14036 repl48(tmpL); 14037 repl32(tmpL); 14038 mtvsrd(tmpV, tmpL); 14039 xxpermdi(dst, tmpV, tmpV, zero); 14040 %} 14041 %} 14042 14043 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 14044 match(Set dst (ReplicateS zero)); 14045 predicate(n->as_Vector()->length() == 8); 14046 14047 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 14048 size(4); 14049 ins_encode %{ 14050 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14051 %} 14052 ins_pipe(pipe_class_default); 14053 %} 14054 14055 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 14056 match(Set dst (ReplicateS src)); 14057 predicate(n->as_Vector()->length() == 8); 14058 14059 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14060 size(4); 14061 ins_encode %{ 14062 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14063 %} 14064 ins_pipe(pipe_class_default); 14065 %} 14066 14067 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14068 match(Set dst (ReplicateI src)); 14069 predicate(n->as_Vector()->length() == 2); 14070 ins_cost(2 * DEFAULT_COST); 14071 expand %{ 14072 moveReg(dst, src); 14073 repl32(dst); 14074 %} 14075 %} 14076 14077 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 14078 match(Set dst (ReplicateI zero)); 14079 predicate(n->as_Vector()->length() == 2); 14080 format %{ "LI $dst, #0 \t// replicate4C" %} 14081 size(4); 14082 ins_encode %{ 14083 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14084 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14085 %} 14086 ins_pipe(pipe_class_default); 14087 %} 14088 14089 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14090 match(Set dst (ReplicateI src)); 14091 predicate(n->as_Vector()->length() == 2); 14092 format %{ "LI $dst, -1 \t// replicate4C" %} 14093 size(4); 14094 ins_encode %{ 14095 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14096 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14097 %} 14098 ins_pipe(pipe_class_default); 14099 %} 14100 14101 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 14102 match(Set dst (ReplicateI src)); 14103 predicate(n->as_Vector()->length() == 4); 14104 ins_cost(2 * DEFAULT_COST); 14105 14106 expand %{ 14107 iRegLdst tmpL; 14108 vecX tmpV; 14109 immI8 zero %{ (int) 0 %} 14110 moveReg(tmpL, src); 14111 repl32(tmpL); 14112 mtvsrd(tmpV, tmpL); 14113 xxpermdi(dst, tmpV, tmpV, zero); 14114 %} 14115 %} 14116 14117 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 14118 match(Set dst (ReplicateI zero)); 14119 predicate(n->as_Vector()->length() == 4); 14120 14121 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 14122 size(4); 14123 ins_encode %{ 14124 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14125 %} 14126 ins_pipe(pipe_class_default); 14127 %} 14128 14129 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 14130 match(Set dst (ReplicateI src)); 14131 predicate(n->as_Vector()->length() == 4); 14132 14133 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 14134 size(4); 14135 ins_encode %{ 14136 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14137 %} 14138 ins_pipe(pipe_class_default); 14139 %} 14140 14141 // Move float to int register via stack, replicate. 14142 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 14143 match(Set dst (ReplicateF src)); 14144 predicate(n->as_Vector()->length() == 2); 14145 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14146 expand %{ 14147 stackSlotL tmpS; 14148 iRegIdst tmpI; 14149 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14150 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14151 moveReg(dst, tmpI); // Move int to long reg. 14152 repl32(dst); // Replicate bitpattern. 14153 %} 14154 %} 14155 14156 // Replicate scalar constant to packed float values in Double register 14157 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 14158 match(Set dst (ReplicateF src)); 14159 predicate(n->as_Vector()->length() == 2); 14160 ins_cost(5 * DEFAULT_COST); 14161 14162 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 14163 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 14164 %} 14165 14166 // Replicate scalar zero constant to packed float values in Double register 14167 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 14168 match(Set dst (ReplicateF zero)); 14169 predicate(n->as_Vector()->length() == 2); 14170 14171 format %{ "LI $dst, #0 \t// replicate2F" %} 14172 ins_encode %{ 14173 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14174 __ li($dst$$Register, 0x0); 14175 %} 14176 ins_pipe(pipe_class_default); 14177 %} 14178 14179 14180 //----------Vector Arithmetic Instructions-------------------------------------- 14181 14182 // Vector Addition Instructions 14183 14184 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{ 14185 match(Set dst (AddVB src1 src2)); 14186 predicate(n->as_Vector()->length() == 16); 14187 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %} 14188 size(4); 14189 ins_encode %{ 14190 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14191 %} 14192 ins_pipe(pipe_class_default); 14193 %} 14194 14195 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{ 14196 match(Set dst (AddVS src1 src2)); 14197 predicate(n->as_Vector()->length() == 8); 14198 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %} 14199 size(4); 14200 ins_encode %{ 14201 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14202 %} 14203 ins_pipe(pipe_class_default); 14204 %} 14205 14206 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{ 14207 match(Set dst (AddVI src1 src2)); 14208 predicate(n->as_Vector()->length() == 4); 14209 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %} 14210 size(4); 14211 ins_encode %{ 14212 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14213 %} 14214 ins_pipe(pipe_class_default); 14215 %} 14216 14217 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{ 14218 match(Set dst (AddVF src1 src2)); 14219 predicate(n->as_Vector()->length() == 4); 14220 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %} 14221 size(4); 14222 ins_encode %{ 14223 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14224 %} 14225 ins_pipe(pipe_class_default); 14226 %} 14227 14228 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{ 14229 match(Set dst (AddVL src1 src2)); 14230 predicate(n->as_Vector()->length() == 2); 14231 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %} 14232 size(4); 14233 ins_encode %{ 14234 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14235 %} 14236 ins_pipe(pipe_class_default); 14237 %} 14238 14239 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{ 14240 match(Set dst (AddVD src1 src2)); 14241 predicate(n->as_Vector()->length() == 2); 14242 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %} 14243 size(4); 14244 ins_encode %{ 14245 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14246 %} 14247 ins_pipe(pipe_class_default); 14248 %} 14249 14250 // Vector Subtraction Instructions 14251 14252 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{ 14253 match(Set dst (SubVB src1 src2)); 14254 predicate(n->as_Vector()->length() == 16); 14255 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %} 14256 size(4); 14257 ins_encode %{ 14258 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14259 %} 14260 ins_pipe(pipe_class_default); 14261 %} 14262 14263 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{ 14264 match(Set dst (SubVS src1 src2)); 14265 predicate(n->as_Vector()->length() == 8); 14266 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %} 14267 size(4); 14268 ins_encode %{ 14269 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14270 %} 14271 ins_pipe(pipe_class_default); 14272 %} 14273 14274 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{ 14275 match(Set dst (SubVI src1 src2)); 14276 predicate(n->as_Vector()->length() == 4); 14277 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %} 14278 size(4); 14279 ins_encode %{ 14280 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14281 %} 14282 ins_pipe(pipe_class_default); 14283 %} 14284 14285 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{ 14286 match(Set dst (SubVF src1 src2)); 14287 predicate(n->as_Vector()->length() == 4); 14288 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %} 14289 size(4); 14290 ins_encode %{ 14291 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14292 %} 14293 ins_pipe(pipe_class_default); 14294 %} 14295 14296 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{ 14297 match(Set dst (SubVL src1 src2)); 14298 predicate(n->as_Vector()->length() == 2); 14299 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %} 14300 size(4); 14301 ins_encode %{ 14302 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14303 %} 14304 ins_pipe(pipe_class_default); 14305 %} 14306 14307 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{ 14308 match(Set dst (SubVD src1 src2)); 14309 predicate(n->as_Vector()->length() == 2); 14310 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %} 14311 size(4); 14312 ins_encode %{ 14313 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14314 %} 14315 ins_pipe(pipe_class_default); 14316 %} 14317 14318 // Vector Multiplication Instructions 14319 14320 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 14321 match(Set dst (MulVS src1 src2)); 14322 predicate(n->as_Vector()->length() == 8); 14323 effect(TEMP tmp); 14324 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %} 14325 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %} 14326 size(8); 14327 ins_encode %{ 14328 __ vspltish($tmp$$VectorSRegister->to_vr(), 0); 14329 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr()); 14330 %} 14331 ins_pipe(pipe_class_default); 14332 %} 14333 14334 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{ 14335 match(Set dst (MulVI src1 src2)); 14336 predicate(n->as_Vector()->length() == 4); 14337 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %} 14338 size(4); 14339 ins_encode %{ 14340 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14341 %} 14342 ins_pipe(pipe_class_default); 14343 %} 14344 14345 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{ 14346 match(Set dst (MulVF src1 src2)); 14347 predicate(n->as_Vector()->length() == 4); 14348 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %} 14349 size(4); 14350 ins_encode %{ 14351 __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14352 %} 14353 ins_pipe(pipe_class_default); 14354 %} 14355 14356 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{ 14357 match(Set dst (MulVD src1 src2)); 14358 predicate(n->as_Vector()->length() == 2); 14359 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %} 14360 size(4); 14361 ins_encode %{ 14362 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14363 %} 14364 ins_pipe(pipe_class_default); 14365 %} 14366 14367 // Vector Division Instructions 14368 14369 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{ 14370 match(Set dst (DivVF src1 src2)); 14371 predicate(n->as_Vector()->length() == 4); 14372 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %} 14373 size(4); 14374 ins_encode %{ 14375 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14376 %} 14377 ins_pipe(pipe_class_default); 14378 %} 14379 14380 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ 14381 match(Set dst (DivVD src1 src2)); 14382 predicate(n->as_Vector()->length() == 2); 14383 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %} 14384 size(4); 14385 ins_encode %{ 14386 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14387 %} 14388 ins_pipe(pipe_class_default); 14389 %} 14390 14391 // Vector Absolute Instructions 14392 14393 instruct vabs4F_reg(vecX dst, vecX src) %{ 14394 match(Set dst (AbsVF src)); 14395 predicate(n->as_Vector()->length() == 4); 14396 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %} 14397 size(4); 14398 ins_encode %{ 14399 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister); 14400 %} 14401 ins_pipe(pipe_class_default); 14402 %} 14403 14404 instruct vabs2D_reg(vecX dst, vecX src) %{ 14405 match(Set dst (AbsVD src)); 14406 predicate(n->as_Vector()->length() == 2); 14407 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %} 14408 size(4); 14409 ins_encode %{ 14410 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister); 14411 %} 14412 ins_pipe(pipe_class_default); 14413 %} 14414 14415 // Vector Negate Instructions 14416 14417 instruct vneg4F_reg(vecX dst, vecX src) %{ 14418 match(Set dst (NegVF src)); 14419 predicate(n->as_Vector()->length() == 4); 14420 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %} 14421 size(4); 14422 ins_encode %{ 14423 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister); 14424 %} 14425 ins_pipe(pipe_class_default); 14426 %} 14427 14428 instruct vneg2D_reg(vecX dst, vecX src) %{ 14429 match(Set dst (NegVD src)); 14430 predicate(n->as_Vector()->length() == 2); 14431 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %} 14432 size(4); 14433 ins_encode %{ 14434 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister); 14435 %} 14436 ins_pipe(pipe_class_default); 14437 %} 14438 14439 // Vector Square Root Instructions 14440 14441 instruct vsqrt4F_reg(vecX dst, vecX src) %{ 14442 match(Set dst (SqrtVF src)); 14443 predicate(n->as_Vector()->length() == 4); 14444 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %} 14445 size(4); 14446 ins_encode %{ 14447 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister); 14448 %} 14449 ins_pipe(pipe_class_default); 14450 %} 14451 14452 instruct vsqrt2D_reg(vecX dst, vecX src) %{ 14453 match(Set dst (SqrtVD src)); 14454 predicate(n->as_Vector()->length() == 2); 14455 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %} 14456 size(4); 14457 ins_encode %{ 14458 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister); 14459 %} 14460 ins_pipe(pipe_class_default); 14461 %} 14462 14463 // Vector Population Count Instructions 14464 14465 instruct vpopcnt4I_reg(vecX dst, vecX src) %{ 14466 match(Set dst (PopCountVI src)); 14467 predicate(n->as_Vector()->length() == 4); 14468 format %{ "VPOPCNTW $dst,$src\t// pop count packed4I" %} 14469 size(4); 14470 ins_encode %{ 14471 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14472 %} 14473 ins_pipe(pipe_class_default); 14474 %} 14475 14476 14477 //----------Overflow Math Instructions----------------------------------------- 14478 14479 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 14480 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14481 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14482 14483 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14484 match(Set cr0 (OverflowAddL op1 op2)); 14485 14486 format %{ "add_ $op1, $op2\t# overflow check long" %} 14487 ins_encode %{ 14488 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14489 __ li(R0, 0); 14490 __ mtxer(R0); // clear XER.SO 14491 __ addo_(R0, $op1$$Register, $op2$$Register); 14492 %} 14493 ins_pipe(pipe_class_default); 14494 %} 14495 14496 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14497 match(Set cr0 (OverflowSubL op1 op2)); 14498 14499 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14500 ins_encode %{ 14501 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14502 __ li(R0, 0); 14503 __ mtxer(R0); // clear XER.SO 14504 __ subfo_(R0, $op2$$Register, $op1$$Register); 14505 %} 14506 ins_pipe(pipe_class_default); 14507 %} 14508 14509 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14510 match(Set cr0 (OverflowSubL zero op2)); 14511 14512 format %{ "nego_ R0, $op2\t# overflow check long" %} 14513 ins_encode %{ 14514 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14515 __ li(R0, 0); 14516 __ mtxer(R0); // clear XER.SO 14517 __ nego_(R0, $op2$$Register); 14518 %} 14519 ins_pipe(pipe_class_default); 14520 %} 14521 14522 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14523 match(Set cr0 (OverflowMulL op1 op2)); 14524 14525 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14526 ins_encode %{ 14527 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14528 __ li(R0, 0); 14529 __ mtxer(R0); // clear XER.SO 14530 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14531 %} 14532 ins_pipe(pipe_class_default); 14533 %} 14534 14535 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14536 match(Set dst (ReplicateF src)); 14537 predicate(n->as_Vector()->length() == 4); 14538 ins_cost(DEFAULT_COST); 14539 expand %{ 14540 vecX tmpV; 14541 immI8 zero %{ (int) 0 %} 14542 14543 xscvdpspn_regF(tmpV, src); 14544 xxspltw(dst, tmpV, zero); 14545 %} 14546 %} 14547 14548 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14549 match(Set dst (ReplicateF src)); 14550 predicate(n->as_Vector()->length() == 4); 14551 effect(TEMP tmp); 14552 ins_cost(10 * DEFAULT_COST); 14553 14554 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14555 %} 14556 14557 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14558 match(Set dst (ReplicateF zero)); 14559 predicate(n->as_Vector()->length() == 4); 14560 14561 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14562 ins_encode %{ 14563 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14564 %} 14565 ins_pipe(pipe_class_default); 14566 %} 14567 14568 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14569 match(Set dst (ReplicateD src)); 14570 predicate(n->as_Vector()->length() == 2); 14571 14572 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %} 14573 size(4); 14574 ins_encode %{ 14575 __ xxpermdi($dst$$VectorSRegister, $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0); 14576 %} 14577 ins_pipe(pipe_class_default); 14578 %} 14579 14580 instruct repl2D_immI0(vecX dst, immI_0 zero) %{ 14581 match(Set dst (ReplicateD zero)); 14582 predicate(n->as_Vector()->length() == 2); 14583 14584 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14585 size(4); 14586 ins_encode %{ 14587 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14588 %} 14589 ins_pipe(pipe_class_default); 14590 %} 14591 14592 instruct repl2D_immIminus1(vecX dst, immI_minus1 src) %{ 14593 match(Set dst (ReplicateD src)); 14594 predicate(n->as_Vector()->length() == 2); 14595 14596 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14597 size(4); 14598 ins_encode %{ 14599 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14600 %} 14601 ins_pipe(pipe_class_default); 14602 %} 14603 14604 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14605 predicate(false); 14606 effect(DEF dst, USE src); 14607 14608 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %} 14609 size(4); 14610 ins_encode %{ 14611 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14612 %} 14613 ins_pipe(pipe_class_default); 14614 %} 14615 14616 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14617 effect(DEF dst, USE src, USE zero); 14618 14619 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %} 14620 size(4); 14621 ins_encode %{ 14622 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14623 %} 14624 ins_pipe(pipe_class_default); 14625 %} 14626 14627 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14628 effect(DEF dst, USE src1, USE src2, USE zero); 14629 14630 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %} 14631 size(4); 14632 ins_encode %{ 14633 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14634 %} 14635 ins_pipe(pipe_class_default); 14636 %} 14637 14638 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14639 match(Set dst (ReplicateL src)); 14640 predicate(n->as_Vector()->length() == 2); 14641 expand %{ 14642 vecX tmpV; 14643 immI8 zero %{ (int) 0 %} 14644 mtvsrd(tmpV, src); 14645 xxpermdi(dst, tmpV, tmpV, zero); 14646 %} 14647 %} 14648 14649 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14650 match(Set dst (ReplicateL zero)); 14651 predicate(n->as_Vector()->length() == 2); 14652 14653 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14654 size(4); 14655 ins_encode %{ 14656 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14657 %} 14658 ins_pipe(pipe_class_default); 14659 %} 14660 14661 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14662 match(Set dst (ReplicateL src)); 14663 predicate(n->as_Vector()->length() == 2); 14664 14665 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14666 size(4); 14667 ins_encode %{ 14668 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14669 %} 14670 ins_pipe(pipe_class_default); 14671 %} 14672 14673 // ============================================================================ 14674 // Safepoint Instruction 14675 14676 instruct safePoint_poll(iRegPdst poll) %{ 14677 match(SafePoint poll); 14678 14679 // It caused problems to add the effect that r0 is killed, but this 14680 // effect no longer needs to be mentioned, since r0 is not contained 14681 // in a reg_class. 14682 14683 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14684 size(4); 14685 ins_encode( enc_poll(0x0, poll) ); 14686 ins_pipe(pipe_class_default); 14687 %} 14688 14689 // ============================================================================ 14690 // Call Instructions 14691 14692 // Call Java Static Instruction 14693 14694 // Schedulable version of call static node. 14695 instruct CallStaticJavaDirect(method meth) %{ 14696 match(CallStaticJava); 14697 effect(USE meth); 14698 ins_cost(CALL_COST); 14699 14700 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14701 14702 format %{ "CALL,static $meth \t// ==> " %} 14703 size(4); 14704 ins_encode( enc_java_static_call(meth) ); 14705 ins_pipe(pipe_class_call); 14706 %} 14707 14708 // Call Java Dynamic Instruction 14709 14710 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14711 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14712 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14713 // The call destination must still be placed in the constant pool. 14714 instruct CallDynamicJavaDirectSched(method meth) %{ 14715 match(CallDynamicJava); // To get all the data fields we need ... 14716 effect(USE meth); 14717 predicate(false); // ... but never match. 14718 14719 ins_field_load_ic_hi_node(loadConL_hiNode*); 14720 ins_field_load_ic_node(loadConLNode*); 14721 ins_num_consts(1 /* 1 patchable constant: call destination */); 14722 14723 format %{ "BL \t// dynamic $meth ==> " %} 14724 size(4); 14725 ins_encode( enc_java_dynamic_call_sched(meth) ); 14726 ins_pipe(pipe_class_call); 14727 %} 14728 14729 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14730 // We use postalloc expanded calls if we use inline caches 14731 // and do not update method data. 14732 // 14733 // This instruction has two constants: inline cache (IC) and call destination. 14734 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14735 // one constant. 14736 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14737 match(CallDynamicJava); 14738 effect(USE meth); 14739 predicate(UseInlineCaches); 14740 ins_cost(CALL_COST); 14741 14742 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14743 14744 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14745 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14746 %} 14747 14748 // Compound version of call dynamic java 14749 // We use postalloc expanded calls if we use inline caches 14750 // and do not update method data. 14751 instruct CallDynamicJavaDirect(method meth) %{ 14752 match(CallDynamicJava); 14753 effect(USE meth); 14754 predicate(!UseInlineCaches); 14755 ins_cost(CALL_COST); 14756 14757 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14758 ins_num_consts(4); 14759 14760 format %{ "CALL,dynamic $meth \t// ==> " %} 14761 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14762 ins_pipe(pipe_class_call); 14763 %} 14764 14765 // Call Runtime Instruction 14766 14767 instruct CallRuntimeDirect(method meth) %{ 14768 match(CallRuntime); 14769 effect(USE meth); 14770 ins_cost(CALL_COST); 14771 14772 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14773 // env for callee, C-toc. 14774 ins_num_consts(3); 14775 14776 format %{ "CALL,runtime" %} 14777 ins_encode( enc_java_to_runtime_call(meth) ); 14778 ins_pipe(pipe_class_call); 14779 %} 14780 14781 // Call Leaf 14782 14783 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14784 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14785 effect(DEF dst, USE src); 14786 14787 ins_num_consts(1); 14788 14789 format %{ "MTCTR $src" %} 14790 size(4); 14791 ins_encode( enc_leaf_call_mtctr(src) ); 14792 ins_pipe(pipe_class_default); 14793 %} 14794 14795 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 14796 instruct CallLeafDirect(method meth) %{ 14797 match(CallLeaf); // To get the data all the data fields we need ... 14798 effect(USE meth); 14799 predicate(false); // but never match. 14800 14801 format %{ "BCTRL \t// leaf call $meth ==> " %} 14802 size(4); 14803 ins_encode %{ 14804 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 14805 __ bctrl(); 14806 %} 14807 ins_pipe(pipe_class_call); 14808 %} 14809 14810 // postalloc expand of CallLeafDirect. 14811 // Load adress to call from TOC, then bl to it. 14812 instruct CallLeafDirect_Ex(method meth) %{ 14813 match(CallLeaf); 14814 effect(USE meth); 14815 ins_cost(CALL_COST); 14816 14817 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14818 // env for callee, C-toc. 14819 ins_num_consts(3); 14820 14821 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14822 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14823 %} 14824 14825 // Call runtime without safepoint - same as CallLeaf. 14826 // postalloc expand of CallLeafNoFPDirect. 14827 // Load adress to call from TOC, then bl to it. 14828 instruct CallLeafNoFPDirect_Ex(method meth) %{ 14829 match(CallLeafNoFP); 14830 effect(USE meth); 14831 ins_cost(CALL_COST); 14832 14833 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14834 // env for callee, C-toc. 14835 ins_num_consts(3); 14836 14837 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14838 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14839 %} 14840 14841 // Tail Call; Jump from runtime stub to Java code. 14842 // Also known as an 'interprocedural jump'. 14843 // Target of jump will eventually return to caller. 14844 // TailJump below removes the return address. 14845 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 14846 match(TailCall jump_target method_oop); 14847 ins_cost(CALL_COST); 14848 14849 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 14850 "BCTR \t// tail call" %} 14851 size(8); 14852 ins_encode %{ 14853 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14854 __ mtctr($jump_target$$Register); 14855 __ bctr(); 14856 %} 14857 ins_pipe(pipe_class_call); 14858 %} 14859 14860 // Return Instruction 14861 instruct Ret() %{ 14862 match(Return); 14863 format %{ "BLR \t// branch to link register" %} 14864 size(4); 14865 ins_encode %{ 14866 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 14867 // LR is restored in MachEpilogNode. Just do the RET here. 14868 __ blr(); 14869 %} 14870 ins_pipe(pipe_class_default); 14871 %} 14872 14873 // Tail Jump; remove the return address; jump to target. 14874 // TailCall above leaves the return address around. 14875 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14876 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14877 // "restore" before this instruction (in Epilogue), we need to materialize it 14878 // in %i0. 14879 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14880 match(TailJump jump_target ex_oop); 14881 ins_cost(CALL_COST); 14882 14883 format %{ "LD R4_ARG2 = LR\n\t" 14884 "MTCTR $jump_target\n\t" 14885 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14886 size(12); 14887 ins_encode %{ 14888 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14889 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 14890 __ mtctr($jump_target$$Register); 14891 __ bctr(); 14892 %} 14893 ins_pipe(pipe_class_call); 14894 %} 14895 14896 // Create exception oop: created by stack-crawling runtime code. 14897 // Created exception is now available to this handler, and is setup 14898 // just prior to jumping to this handler. No code emitted. 14899 instruct CreateException(rarg1RegP ex_oop) %{ 14900 match(Set ex_oop (CreateEx)); 14901 ins_cost(0); 14902 14903 format %{ " -- \t// exception oop; no code emitted" %} 14904 size(0); 14905 ins_encode( /*empty*/ ); 14906 ins_pipe(pipe_class_default); 14907 %} 14908 14909 // Rethrow exception: The exception oop will come in the first 14910 // argument position. Then JUMP (not call) to the rethrow stub code. 14911 instruct RethrowException() %{ 14912 match(Rethrow); 14913 ins_cost(CALL_COST); 14914 14915 format %{ "Jmp rethrow_stub" %} 14916 ins_encode %{ 14917 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14918 cbuf.set_insts_mark(); 14919 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 14920 %} 14921 ins_pipe(pipe_class_call); 14922 %} 14923 14924 // Die now. 14925 instruct ShouldNotReachHere() %{ 14926 match(Halt); 14927 ins_cost(CALL_COST); 14928 14929 format %{ "ShouldNotReachHere" %} 14930 size(4); 14931 ins_encode %{ 14932 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 14933 __ trap_should_not_reach_here(); 14934 %} 14935 ins_pipe(pipe_class_default); 14936 %} 14937 14938 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 14939 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 14940 // Get a DEF on threadRegP, no costs, no encoding, use 14941 // 'ins_should_rematerialize(true)' to avoid spilling. 14942 instruct tlsLoadP(threadRegP dst) %{ 14943 match(Set dst (ThreadLocal)); 14944 ins_cost(0); 14945 14946 ins_should_rematerialize(true); 14947 14948 format %{ " -- \t// $dst=Thread::current(), empty" %} 14949 size(0); 14950 ins_encode( /*empty*/ ); 14951 ins_pipe(pipe_class_empty); 14952 %} 14953 14954 //---Some PPC specific nodes--------------------------------------------------- 14955 14956 // Stop a group. 14957 instruct endGroup() %{ 14958 ins_cost(0); 14959 14960 ins_is_nop(true); 14961 14962 format %{ "End Bundle (ori r1, r1, 0)" %} 14963 size(4); 14964 ins_encode %{ 14965 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 14966 __ endgroup(); 14967 %} 14968 ins_pipe(pipe_class_default); 14969 %} 14970 14971 // Nop instructions 14972 14973 instruct fxNop() %{ 14974 ins_cost(0); 14975 14976 ins_is_nop(true); 14977 14978 format %{ "fxNop" %} 14979 size(4); 14980 ins_encode %{ 14981 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14982 __ nop(); 14983 %} 14984 ins_pipe(pipe_class_default); 14985 %} 14986 14987 instruct fpNop0() %{ 14988 ins_cost(0); 14989 14990 ins_is_nop(true); 14991 14992 format %{ "fpNop0" %} 14993 size(4); 14994 ins_encode %{ 14995 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14996 __ fpnop0(); 14997 %} 14998 ins_pipe(pipe_class_default); 14999 %} 15000 15001 instruct fpNop1() %{ 15002 ins_cost(0); 15003 15004 ins_is_nop(true); 15005 15006 format %{ "fpNop1" %} 15007 size(4); 15008 ins_encode %{ 15009 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15010 __ fpnop1(); 15011 %} 15012 ins_pipe(pipe_class_default); 15013 %} 15014 15015 instruct brNop0() %{ 15016 ins_cost(0); 15017 size(4); 15018 format %{ "brNop0" %} 15019 ins_encode %{ 15020 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15021 __ brnop0(); 15022 %} 15023 ins_is_nop(true); 15024 ins_pipe(pipe_class_default); 15025 %} 15026 15027 instruct brNop1() %{ 15028 ins_cost(0); 15029 15030 ins_is_nop(true); 15031 15032 format %{ "brNop1" %} 15033 size(4); 15034 ins_encode %{ 15035 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15036 __ brnop1(); 15037 %} 15038 ins_pipe(pipe_class_default); 15039 %} 15040 15041 instruct brNop2() %{ 15042 ins_cost(0); 15043 15044 ins_is_nop(true); 15045 15046 format %{ "brNop2" %} 15047 size(4); 15048 ins_encode %{ 15049 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15050 __ brnop2(); 15051 %} 15052 ins_pipe(pipe_class_default); 15053 %} 15054 15055 //----------PEEPHOLE RULES----------------------------------------------------- 15056 // These must follow all instruction definitions as they use the names 15057 // defined in the instructions definitions. 15058 // 15059 // peepmatch ( root_instr_name [preceeding_instruction]* ); 15060 // 15061 // peepconstraint %{ 15062 // (instruction_number.operand_name relational_op instruction_number.operand_name 15063 // [, ...] ); 15064 // // instruction numbers are zero-based using left to right order in peepmatch 15065 // 15066 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 15067 // // provide an instruction_number.operand_name for each operand that appears 15068 // // in the replacement instruction's match rule 15069 // 15070 // ---------VM FLAGS--------------------------------------------------------- 15071 // 15072 // All peephole optimizations can be turned off using -XX:-OptoPeephole 15073 // 15074 // Each peephole rule is given an identifying number starting with zero and 15075 // increasing by one in the order seen by the parser. An individual peephole 15076 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 15077 // on the command-line. 15078 // 15079 // ---------CURRENT LIMITATIONS---------------------------------------------- 15080 // 15081 // Only match adjacent instructions in same basic block 15082 // Only equality constraints 15083 // Only constraints between operands, not (0.dest_reg == EAX_enc) 15084 // Only one replacement instruction 15085 // 15086 // ---------EXAMPLE---------------------------------------------------------- 15087 // 15088 // // pertinent parts of existing instructions in architecture description 15089 // instruct movI(eRegI dst, eRegI src) %{ 15090 // match(Set dst (CopyI src)); 15091 // %} 15092 // 15093 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 15094 // match(Set dst (AddI dst src)); 15095 // effect(KILL cr); 15096 // %} 15097 // 15098 // // Change (inc mov) to lea 15099 // peephole %{ 15100 // // increment preceeded by register-register move 15101 // peepmatch ( incI_eReg movI ); 15102 // // require that the destination register of the increment 15103 // // match the destination register of the move 15104 // peepconstraint ( 0.dst == 1.dst ); 15105 // // construct a replacement instruction that sets 15106 // // the destination to ( move's source register + one ) 15107 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15108 // %} 15109 // 15110 // Implementation no longer uses movX instructions since 15111 // machine-independent system no longer uses CopyX nodes. 15112 // 15113 // peephole %{ 15114 // peepmatch ( incI_eReg movI ); 15115 // peepconstraint ( 0.dst == 1.dst ); 15116 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15117 // %} 15118 // 15119 // peephole %{ 15120 // peepmatch ( decI_eReg movI ); 15121 // peepconstraint ( 0.dst == 1.dst ); 15122 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15123 // %} 15124 // 15125 // peephole %{ 15126 // peepmatch ( addI_eReg_imm movI ); 15127 // peepconstraint ( 0.dst == 1.dst ); 15128 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15129 // %} 15130 // 15131 // peephole %{ 15132 // peepmatch ( addP_eReg_imm movP ); 15133 // peepconstraint ( 0.dst == 1.dst ); 15134 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 15135 // %} 15136 15137 // // Change load of spilled value to only a spill 15138 // instruct storeI(memory mem, eRegI src) %{ 15139 // match(Set mem (StoreI mem src)); 15140 // %} 15141 // 15142 // instruct loadI(eRegI dst, memory mem) %{ 15143 // match(Set dst (LoadI mem)); 15144 // %} 15145 // 15146 peephole %{ 15147 peepmatch ( loadI storeI ); 15148 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15149 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 15150 %} 15151 15152 peephole %{ 15153 peepmatch ( loadL storeL ); 15154 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15155 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 15156 %} 15157 15158 peephole %{ 15159 peepmatch ( loadP storeP ); 15160 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 15161 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 15162 %} 15163 15164 //----------SMARTSPILL RULES--------------------------------------------------- 15165 // These must follow all instruction definitions as they use the names 15166 // defined in the instructions definitions.