1 // 2 // Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2017 SAP SE. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // 27 // PPC64 Architecture Description File 28 // 29 30 //----------REGISTER DEFINITION BLOCK------------------------------------------ 31 // This information is used by the matcher and the register allocator to 32 // describe individual registers and classes of registers within the target 33 // architecture. 34 register %{ 35 //----------Architecture Description Register Definitions---------------------- 36 // General Registers 37 // "reg_def" name (register save type, C convention save type, 38 // ideal register type, encoding); 39 // 40 // Register Save Types: 41 // 42 // NS = No-Save: The register allocator assumes that these registers 43 // can be used without saving upon entry to the method, & 44 // that they do not need to be saved at call sites. 45 // 46 // SOC = Save-On-Call: The register allocator assumes that these registers 47 // can be used without saving upon entry to the method, 48 // but that they must be saved at call sites. 49 // These are called "volatiles" on ppc. 50 // 51 // SOE = Save-On-Entry: The register allocator assumes that these registers 52 // must be saved before using them upon entry to the 53 // method, but they do not need to be saved at call 54 // sites. 55 // These are called "nonvolatiles" on ppc. 56 // 57 // AS = Always-Save: The register allocator assumes that these registers 58 // must be saved before using them upon entry to the 59 // method, & that they must be saved at call sites. 60 // 61 // Ideal Register Type is used to determine how to save & restore a 62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 64 // 65 // The encoding number is the actual bit-pattern placed into the opcodes. 66 // 67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI 68 // Supplement Version 1.7 as of 2003-10-29. 69 // 70 // For each 64-bit register we must define two registers: the register 71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half', 72 // e.g. R3_H, which is needed by the allocator, but is not used 73 // for stores, loads, etc. 74 75 // ---------------------------- 76 // Integer/Long Registers 77 // ---------------------------- 78 79 // PPC64 has 32 64-bit integer registers. 80 81 // types: v = volatile, nv = non-volatile, s = system 82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs 83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() ); 84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP 85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() ); 86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC 87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() ); 88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret 89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() ); 90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2 91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() ); 92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3 93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() ); 94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4 95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() ); 96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5 97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() ); 98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6 99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() ); 100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7 101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() ); 102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8 103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next()); 104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch 105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next()); 106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch 107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next()); 108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id 109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next()); 110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv 111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next()); 112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv 113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next()); 114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv 115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next()); 116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv 117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next()); 118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv 119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next()); 120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv 121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next()); 122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv 123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next()); 124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv 125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next()); 126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv 127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next()); 128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv 129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next()); 130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv 131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next()); 132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv 133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next()); 134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv 135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next()); 136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv 137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next()); 138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv 139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next()); 140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv 141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next()); 142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv 143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next()); 144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv 145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next()); 146 147 148 // ---------------------------- 149 // Float/Double Registers 150 // ---------------------------- 151 152 // Double Registers 153 // The rules of ADL require that double registers be defined in pairs. 154 // Each pair must be two 32-bit values, but not necessarily a pair of 155 // single float registers. In each pair, ADLC-assigned register numbers 156 // must be adjacent, with the lower number even. Finally, when the 157 // CPU stores such a register pair to memory, the word associated with 158 // the lower ADLC-assigned number must be stored to the lower address. 159 160 // PPC64 has 32 64-bit floating-point registers. Each can store a single 161 // or double precision floating-point value. 162 163 // types: v = volatile, nv = non-volatile, s = system 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch 165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret 167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2 169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3 171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4 173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5 175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6 177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7 179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8 181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9 183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10 185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next()); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11 187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next()); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12 189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next()); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13 191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next()); 192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv 193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next()); 194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv 195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next()); 196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv 197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next()); 198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv 199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next()); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv 201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next()); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv 203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next()); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv 205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next()); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv 207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next()); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv 209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next()); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv 211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next()); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv 213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next()); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv 215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next()); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv 217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next()); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv 219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next()); 220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv 221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next()); 222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv 223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next()); 224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv 225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next()); 226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv 227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next()); 228 229 // ---------------------------- 230 // Special Registers 231 // ---------------------------- 232 233 // Condition Codes Flag Registers 234 235 // PPC64 has 8 condition code "registers" which are all contained 236 // in the CR register. 237 238 // types: v = volatile, nv = non-volatile, s = system 239 reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v 240 reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v 241 reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv 242 reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv 243 reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv 244 reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v 245 reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v 246 reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg()); // v 247 248 // Special registers of PPC64 249 250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v 251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v 252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v 253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v 254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v 255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v 256 257 // ---------------------------- 258 // Vector-Scalar Registers 259 // ---------------------------- 260 reg_def VSR0 ( SOC, SOC, Op_VecX, 0, NULL); 261 reg_def VSR1 ( SOC, SOC, Op_VecX, 1, NULL); 262 reg_def VSR2 ( SOC, SOC, Op_VecX, 2, NULL); 263 reg_def VSR3 ( SOC, SOC, Op_VecX, 3, NULL); 264 reg_def VSR4 ( SOC, SOC, Op_VecX, 4, NULL); 265 reg_def VSR5 ( SOC, SOC, Op_VecX, 5, NULL); 266 reg_def VSR6 ( SOC, SOC, Op_VecX, 6, NULL); 267 reg_def VSR7 ( SOC, SOC, Op_VecX, 7, NULL); 268 reg_def VSR8 ( SOC, SOC, Op_VecX, 8, NULL); 269 reg_def VSR9 ( SOC, SOC, Op_VecX, 9, NULL); 270 reg_def VSR10 ( SOC, SOC, Op_VecX, 10, NULL); 271 reg_def VSR11 ( SOC, SOC, Op_VecX, 11, NULL); 272 reg_def VSR12 ( SOC, SOC, Op_VecX, 12, NULL); 273 reg_def VSR13 ( SOC, SOC, Op_VecX, 13, NULL); 274 reg_def VSR14 ( SOC, SOC, Op_VecX, 14, NULL); 275 reg_def VSR15 ( SOC, SOC, Op_VecX, 15, NULL); 276 reg_def VSR16 ( SOC, SOC, Op_VecX, 16, NULL); 277 reg_def VSR17 ( SOC, SOC, Op_VecX, 17, NULL); 278 reg_def VSR18 ( SOC, SOC, Op_VecX, 18, NULL); 279 reg_def VSR19 ( SOC, SOC, Op_VecX, 19, NULL); 280 reg_def VSR20 ( SOC, SOC, Op_VecX, 20, NULL); 281 reg_def VSR21 ( SOC, SOC, Op_VecX, 21, NULL); 282 reg_def VSR22 ( SOC, SOC, Op_VecX, 22, NULL); 283 reg_def VSR23 ( SOC, SOC, Op_VecX, 23, NULL); 284 reg_def VSR24 ( SOC, SOC, Op_VecX, 24, NULL); 285 reg_def VSR25 ( SOC, SOC, Op_VecX, 25, NULL); 286 reg_def VSR26 ( SOC, SOC, Op_VecX, 26, NULL); 287 reg_def VSR27 ( SOC, SOC, Op_VecX, 27, NULL); 288 reg_def VSR28 ( SOC, SOC, Op_VecX, 28, NULL); 289 reg_def VSR29 ( SOC, SOC, Op_VecX, 29, NULL); 290 reg_def VSR30 ( SOC, SOC, Op_VecX, 30, NULL); 291 reg_def VSR31 ( SOC, SOC, Op_VecX, 31, NULL); 292 reg_def VSR32 ( SOC, SOC, Op_VecX, 32, NULL); 293 reg_def VSR33 ( SOC, SOC, Op_VecX, 33, NULL); 294 reg_def VSR34 ( SOC, SOC, Op_VecX, 34, NULL); 295 reg_def VSR35 ( SOC, SOC, Op_VecX, 35, NULL); 296 reg_def VSR36 ( SOC, SOC, Op_VecX, 36, NULL); 297 reg_def VSR37 ( SOC, SOC, Op_VecX, 37, NULL); 298 reg_def VSR38 ( SOC, SOC, Op_VecX, 38, NULL); 299 reg_def VSR39 ( SOC, SOC, Op_VecX, 39, NULL); 300 reg_def VSR40 ( SOC, SOC, Op_VecX, 40, NULL); 301 reg_def VSR41 ( SOC, SOC, Op_VecX, 41, NULL); 302 reg_def VSR42 ( SOC, SOC, Op_VecX, 42, NULL); 303 reg_def VSR43 ( SOC, SOC, Op_VecX, 43, NULL); 304 reg_def VSR44 ( SOC, SOC, Op_VecX, 44, NULL); 305 reg_def VSR45 ( SOC, SOC, Op_VecX, 45, NULL); 306 reg_def VSR46 ( SOC, SOC, Op_VecX, 46, NULL); 307 reg_def VSR47 ( SOC, SOC, Op_VecX, 47, NULL); 308 reg_def VSR48 ( SOC, SOC, Op_VecX, 48, NULL); 309 reg_def VSR49 ( SOC, SOC, Op_VecX, 49, NULL); 310 reg_def VSR50 ( SOC, SOC, Op_VecX, 50, NULL); 311 reg_def VSR51 ( SOC, SOC, Op_VecX, 51, NULL); 312 reg_def VSR52 ( SOC, SOC, Op_VecX, 52, NULL); 313 reg_def VSR53 ( SOC, SOC, Op_VecX, 53, NULL); 314 reg_def VSR54 ( SOC, SOC, Op_VecX, 54, NULL); 315 reg_def VSR55 ( SOC, SOC, Op_VecX, 55, NULL); 316 reg_def VSR56 ( SOC, SOC, Op_VecX, 56, NULL); 317 reg_def VSR57 ( SOC, SOC, Op_VecX, 57, NULL); 318 reg_def VSR58 ( SOC, SOC, Op_VecX, 58, NULL); 319 reg_def VSR59 ( SOC, SOC, Op_VecX, 59, NULL); 320 reg_def VSR60 ( SOC, SOC, Op_VecX, 60, NULL); 321 reg_def VSR61 ( SOC, SOC, Op_VecX, 61, NULL); 322 reg_def VSR62 ( SOC, SOC, Op_VecX, 62, NULL); 323 reg_def VSR63 ( SOC, SOC, Op_VecX, 63, NULL); 324 325 // ---------------------------- 326 // Specify priority of register selection within phases of register 327 // allocation. Highest priority is first. A useful heuristic is to 328 // give registers a low priority when they are required by machine 329 // instructions, like EAX and EDX on I486, and choose no-save registers 330 // before save-on-call, & save-on-call before save-on-entry. Registers 331 // which participate in fixed calling sequences should come last. 332 // Registers which are used as pairs must fall on an even boundary. 333 334 // It's worth about 1% on SPEC geomean to get this right. 335 336 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 337 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 338 // R3_num. Therefore, R3_num may not be (and in reality is not) 339 // the same as R3->encoding()! Furthermore, we cannot make any 340 // assumptions on ordering, e.g. R3_num may be less than R2_num. 341 // Additionally, the function 342 // static enum RC rc_class(OptoReg::Name reg ) 343 // maps a given <register>_num value to its chunk type (except for flags) 344 // and its current implementation relies on chunk0 and chunk1 having a 345 // size of 64 each. 346 347 // If you change this allocation class, please have a look at the 348 // default values for the parameters RoundRobinIntegerRegIntervalStart 349 // and RoundRobinFloatRegIntervalStart 350 351 alloc_class chunk0 ( 352 // Chunk0 contains *all* 64 integer registers halves. 353 354 // "non-volatile" registers 355 R14, R14_H, 356 R15, R15_H, 357 R17, R17_H, 358 R18, R18_H, 359 R19, R19_H, 360 R20, R20_H, 361 R21, R21_H, 362 R22, R22_H, 363 R23, R23_H, 364 R24, R24_H, 365 R25, R25_H, 366 R26, R26_H, 367 R27, R27_H, 368 R28, R28_H, 369 R29, R29_H, 370 R30, R30_H, 371 R31, R31_H, 372 373 // scratch/special registers 374 R11, R11_H, 375 R12, R12_H, 376 377 // argument registers 378 R10, R10_H, 379 R9, R9_H, 380 R8, R8_H, 381 R7, R7_H, 382 R6, R6_H, 383 R5, R5_H, 384 R4, R4_H, 385 R3, R3_H, 386 387 // special registers, not available for allocation 388 R16, R16_H, // R16_thread 389 R13, R13_H, // system thread id 390 R2, R2_H, // may be used for TOC 391 R1, R1_H, // SP 392 R0, R0_H // R0 (scratch) 393 ); 394 395 // If you change this allocation class, please have a look at the 396 // default values for the parameters RoundRobinIntegerRegIntervalStart 397 // and RoundRobinFloatRegIntervalStart 398 399 alloc_class chunk1 ( 400 // Chunk1 contains *all* 64 floating-point registers halves. 401 402 // scratch register 403 F0, F0_H, 404 405 // argument registers 406 F13, F13_H, 407 F12, F12_H, 408 F11, F11_H, 409 F10, F10_H, 410 F9, F9_H, 411 F8, F8_H, 412 F7, F7_H, 413 F6, F6_H, 414 F5, F5_H, 415 F4, F4_H, 416 F3, F3_H, 417 F2, F2_H, 418 F1, F1_H, 419 420 // non-volatile registers 421 F14, F14_H, 422 F15, F15_H, 423 F16, F16_H, 424 F17, F17_H, 425 F18, F18_H, 426 F19, F19_H, 427 F20, F20_H, 428 F21, F21_H, 429 F22, F22_H, 430 F23, F23_H, 431 F24, F24_H, 432 F25, F25_H, 433 F26, F26_H, 434 F27, F27_H, 435 F28, F28_H, 436 F29, F29_H, 437 F30, F30_H, 438 F31, F31_H 439 ); 440 441 alloc_class chunk2 ( 442 // Chunk2 contains *all* 8 condition code registers. 443 444 CCR0, 445 CCR1, 446 CCR2, 447 CCR3, 448 CCR4, 449 CCR5, 450 CCR6, 451 CCR7 452 ); 453 454 alloc_class chunk3 ( 455 VSR0, 456 VSR1, 457 VSR2, 458 VSR3, 459 VSR4, 460 VSR5, 461 VSR6, 462 VSR7, 463 VSR8, 464 VSR9, 465 VSR10, 466 VSR11, 467 VSR12, 468 VSR13, 469 VSR14, 470 VSR15, 471 VSR16, 472 VSR17, 473 VSR18, 474 VSR19, 475 VSR20, 476 VSR21, 477 VSR22, 478 VSR23, 479 VSR24, 480 VSR25, 481 VSR26, 482 VSR27, 483 VSR28, 484 VSR29, 485 VSR30, 486 VSR31, 487 VSR32, 488 VSR33, 489 VSR34, 490 VSR35, 491 VSR36, 492 VSR37, 493 VSR38, 494 VSR39, 495 VSR40, 496 VSR41, 497 VSR42, 498 VSR43, 499 VSR44, 500 VSR45, 501 VSR46, 502 VSR47, 503 VSR48, 504 VSR49, 505 VSR50, 506 VSR51, 507 VSR52, 508 VSR53, 509 VSR54, 510 VSR55, 511 VSR56, 512 VSR57, 513 VSR58, 514 VSR59, 515 VSR60, 516 VSR61, 517 VSR62, 518 VSR63 519 ); 520 521 alloc_class chunk4 ( 522 // special registers 523 // These registers are not allocated, but used for nodes generated by postalloc expand. 524 SR_XER, 525 SR_LR, 526 SR_CTR, 527 SR_VRSAVE, 528 SR_SPEFSCR, 529 SR_PPR 530 ); 531 532 //-------Architecture Description Register Classes----------------------- 533 534 // Several register classes are automatically defined based upon 535 // information in this architecture description. 536 537 // 1) reg_class inline_cache_reg ( as defined in frame section ) 538 // 2) reg_class compiler_method_oop_reg ( as defined in frame section ) 539 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 540 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 541 // 542 543 // ---------------------------- 544 // 32 Bit Register Classes 545 // ---------------------------- 546 547 // We specify registers twice, once as read/write, and once read-only. 548 // We use the read-only registers for source operands. With this, we 549 // can include preset read only registers in this class, as a hard-coded 550 // '0'-register. (We used to simulate this on ppc.) 551 552 // 32 bit registers that can be read and written i.e. these registers 553 // can be dest (or src) of normal instructions. 554 reg_class bits32_reg_rw( 555 /*R0*/ // R0 556 /*R1*/ // SP 557 R2, // TOC 558 R3, 559 R4, 560 R5, 561 R6, 562 R7, 563 R8, 564 R9, 565 R10, 566 R11, 567 R12, 568 /*R13*/ // system thread id 569 R14, 570 R15, 571 /*R16*/ // R16_thread 572 R17, 573 R18, 574 R19, 575 R20, 576 R21, 577 R22, 578 R23, 579 R24, 580 R25, 581 R26, 582 R27, 583 R28, 584 /*R29,*/ // global TOC 585 R30, 586 R31 587 ); 588 589 // 32 bit registers that can only be read i.e. these registers can 590 // only be src of all instructions. 591 reg_class bits32_reg_ro( 592 /*R0*/ // R0 593 /*R1*/ // SP 594 R2 // TOC 595 R3, 596 R4, 597 R5, 598 R6, 599 R7, 600 R8, 601 R9, 602 R10, 603 R11, 604 R12, 605 /*R13*/ // system thread id 606 R14, 607 R15, 608 /*R16*/ // R16_thread 609 R17, 610 R18, 611 R19, 612 R20, 613 R21, 614 R22, 615 R23, 616 R24, 617 R25, 618 R26, 619 R27, 620 R28, 621 /*R29,*/ 622 R30, 623 R31 624 ); 625 626 reg_class rscratch1_bits32_reg(R11); 627 reg_class rscratch2_bits32_reg(R12); 628 reg_class rarg1_bits32_reg(R3); 629 reg_class rarg2_bits32_reg(R4); 630 reg_class rarg3_bits32_reg(R5); 631 reg_class rarg4_bits32_reg(R6); 632 633 // ---------------------------- 634 // 64 Bit Register Classes 635 // ---------------------------- 636 // 64-bit build means 64-bit pointers means hi/lo pairs 637 638 reg_class rscratch1_bits64_reg(R11_H, R11); 639 reg_class rscratch2_bits64_reg(R12_H, R12); 640 reg_class rarg1_bits64_reg(R3_H, R3); 641 reg_class rarg2_bits64_reg(R4_H, R4); 642 reg_class rarg3_bits64_reg(R5_H, R5); 643 reg_class rarg4_bits64_reg(R6_H, R6); 644 // Thread register, 'written' by tlsLoadP, see there. 645 reg_class thread_bits64_reg(R16_H, R16); 646 647 reg_class r19_bits64_reg(R19_H, R19); 648 649 // 64 bit registers that can be read and written i.e. these registers 650 // can be dest (or src) of normal instructions. 651 reg_class bits64_reg_rw( 652 /*R0_H, R0*/ // R0 653 /*R1_H, R1*/ // SP 654 R2_H, R2, // TOC 655 R3_H, R3, 656 R4_H, R4, 657 R5_H, R5, 658 R6_H, R6, 659 R7_H, R7, 660 R8_H, R8, 661 R9_H, R9, 662 R10_H, R10, 663 R11_H, R11, 664 R12_H, R12, 665 /*R13_H, R13*/ // system thread id 666 R14_H, R14, 667 R15_H, R15, 668 /*R16_H, R16*/ // R16_thread 669 R17_H, R17, 670 R18_H, R18, 671 R19_H, R19, 672 R20_H, R20, 673 R21_H, R21, 674 R22_H, R22, 675 R23_H, R23, 676 R24_H, R24, 677 R25_H, R25, 678 R26_H, R26, 679 R27_H, R27, 680 R28_H, R28, 681 /*R29_H, R29,*/ 682 R30_H, R30, 683 R31_H, R31 684 ); 685 686 // 64 bit registers used excluding r2, r11 and r12 687 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses 688 // r2, r11 and r12 internally. 689 reg_class bits64_reg_leaf_call( 690 /*R0_H, R0*/ // R0 691 /*R1_H, R1*/ // SP 692 /*R2_H, R2*/ // TOC 693 R3_H, R3, 694 R4_H, R4, 695 R5_H, R5, 696 R6_H, R6, 697 R7_H, R7, 698 R8_H, R8, 699 R9_H, R9, 700 R10_H, R10, 701 /*R11_H, R11*/ 702 /*R12_H, R12*/ 703 /*R13_H, R13*/ // system thread id 704 R14_H, R14, 705 R15_H, R15, 706 /*R16_H, R16*/ // R16_thread 707 R17_H, R17, 708 R18_H, R18, 709 R19_H, R19, 710 R20_H, R20, 711 R21_H, R21, 712 R22_H, R22, 713 R23_H, R23, 714 R24_H, R24, 715 R25_H, R25, 716 R26_H, R26, 717 R27_H, R27, 718 R28_H, R28, 719 /*R29_H, R29,*/ 720 R30_H, R30, 721 R31_H, R31 722 ); 723 724 // Used to hold the TOC to avoid collisions with expanded DynamicCall 725 // which uses r19 as inline cache internally and expanded LeafCall which uses 726 // r2, r11 and r12 internally. 727 reg_class bits64_constant_table_base( 728 /*R0_H, R0*/ // R0 729 /*R1_H, R1*/ // SP 730 /*R2_H, R2*/ // TOC 731 R3_H, R3, 732 R4_H, R4, 733 R5_H, R5, 734 R6_H, R6, 735 R7_H, R7, 736 R8_H, R8, 737 R9_H, R9, 738 R10_H, R10, 739 /*R11_H, R11*/ 740 /*R12_H, R12*/ 741 /*R13_H, R13*/ // system thread id 742 R14_H, R14, 743 R15_H, R15, 744 /*R16_H, R16*/ // R16_thread 745 R17_H, R17, 746 R18_H, R18, 747 /*R19_H, R19*/ 748 R20_H, R20, 749 R21_H, R21, 750 R22_H, R22, 751 R23_H, R23, 752 R24_H, R24, 753 R25_H, R25, 754 R26_H, R26, 755 R27_H, R27, 756 R28_H, R28, 757 /*R29_H, R29,*/ 758 R30_H, R30, 759 R31_H, R31 760 ); 761 762 // 64 bit registers that can only be read i.e. these registers can 763 // only be src of all instructions. 764 reg_class bits64_reg_ro( 765 /*R0_H, R0*/ // R0 766 R1_H, R1, 767 R2_H, R2, // TOC 768 R3_H, R3, 769 R4_H, R4, 770 R5_H, R5, 771 R6_H, R6, 772 R7_H, R7, 773 R8_H, R8, 774 R9_H, R9, 775 R10_H, R10, 776 R11_H, R11, 777 R12_H, R12, 778 /*R13_H, R13*/ // system thread id 779 R14_H, R14, 780 R15_H, R15, 781 R16_H, R16, // R16_thread 782 R17_H, R17, 783 R18_H, R18, 784 R19_H, R19, 785 R20_H, R20, 786 R21_H, R21, 787 R22_H, R22, 788 R23_H, R23, 789 R24_H, R24, 790 R25_H, R25, 791 R26_H, R26, 792 R27_H, R27, 793 R28_H, R28, 794 /*R29_H, R29,*/ // TODO: let allocator handle TOC!! 795 R30_H, R30, 796 R31_H, R31 797 ); 798 799 800 // ---------------------------- 801 // Special Class for Condition Code Flags Register 802 803 reg_class int_flags( 804 /*CCR0*/ // scratch 805 /*CCR1*/ // scratch 806 /*CCR2*/ // nv! 807 /*CCR3*/ // nv! 808 /*CCR4*/ // nv! 809 CCR5, 810 CCR6, 811 CCR7 812 ); 813 814 reg_class int_flags_ro( 815 CCR0, 816 CCR1, 817 CCR2, 818 CCR3, 819 CCR4, 820 CCR5, 821 CCR6, 822 CCR7 823 ); 824 825 reg_class int_flags_CR0(CCR0); 826 reg_class int_flags_CR1(CCR1); 827 reg_class int_flags_CR6(CCR6); 828 reg_class ctr_reg(SR_CTR); 829 830 // ---------------------------- 831 // Float Register Classes 832 // ---------------------------- 833 834 reg_class flt_reg( 835 F0, 836 F1, 837 F2, 838 F3, 839 F4, 840 F5, 841 F6, 842 F7, 843 F8, 844 F9, 845 F10, 846 F11, 847 F12, 848 F13, 849 F14, // nv! 850 F15, // nv! 851 F16, // nv! 852 F17, // nv! 853 F18, // nv! 854 F19, // nv! 855 F20, // nv! 856 F21, // nv! 857 F22, // nv! 858 F23, // nv! 859 F24, // nv! 860 F25, // nv! 861 F26, // nv! 862 F27, // nv! 863 F28, // nv! 864 F29, // nv! 865 F30, // nv! 866 F31 // nv! 867 ); 868 869 // Double precision float registers have virtual `high halves' that 870 // are needed by the allocator. 871 reg_class dbl_reg( 872 F0, F0_H, 873 F1, F1_H, 874 F2, F2_H, 875 F3, F3_H, 876 F4, F4_H, 877 F5, F5_H, 878 F6, F6_H, 879 F7, F7_H, 880 F8, F8_H, 881 F9, F9_H, 882 F10, F10_H, 883 F11, F11_H, 884 F12, F12_H, 885 F13, F13_H, 886 F14, F14_H, // nv! 887 F15, F15_H, // nv! 888 F16, F16_H, // nv! 889 F17, F17_H, // nv! 890 F18, F18_H, // nv! 891 F19, F19_H, // nv! 892 F20, F20_H, // nv! 893 F21, F21_H, // nv! 894 F22, F22_H, // nv! 895 F23, F23_H, // nv! 896 F24, F24_H, // nv! 897 F25, F25_H, // nv! 898 F26, F26_H, // nv! 899 F27, F27_H, // nv! 900 F28, F28_H, // nv! 901 F29, F29_H, // nv! 902 F30, F30_H, // nv! 903 F31, F31_H // nv! 904 ); 905 906 // ---------------------------- 907 // Vector-Scalar Register Class 908 // ---------------------------- 909 910 reg_class vs_reg( 911 VSR32, 912 VSR33, 913 VSR34, 914 VSR35, 915 VSR36, 916 VSR37, 917 VSR38, 918 VSR39, 919 VSR40, 920 VSR41, 921 VSR42, 922 VSR43, 923 VSR44, 924 VSR45, 925 VSR46, 926 VSR47, 927 VSR48, 928 VSR49, 929 VSR50, 930 VSR51 931 // VSR52, // nv! 932 // VSR53, // nv! 933 // VSR54, // nv! 934 // VSR55, // nv! 935 // VSR56, // nv! 936 // VSR57, // nv! 937 // VSR58, // nv! 938 // VSR59, // nv! 939 // VSR60, // nv! 940 // VSR61, // nv! 941 // VSR62, // nv! 942 // VSR63 // nv! 943 ); 944 945 %} 946 947 //----------DEFINITION BLOCK--------------------------------------------------- 948 // Define name --> value mappings to inform the ADLC of an integer valued name 949 // Current support includes integer values in the range [0, 0x7FFFFFFF] 950 // Format: 951 // int_def <name> ( <int_value>, <expression>); 952 // Generated Code in ad_<arch>.hpp 953 // #define <name> (<expression>) 954 // // value == <int_value> 955 // Generated code in ad_<arch>.cpp adlc_verification() 956 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 957 // 958 definitions %{ 959 // The default cost (of an ALU instruction). 960 int_def DEFAULT_COST_LOW ( 30, 30); 961 int_def DEFAULT_COST ( 100, 100); 962 int_def HUGE_COST (1000000, 1000000); 963 964 // Memory refs 965 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 966 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 967 968 // Branches are even more expensive. 969 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 970 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 971 %} 972 973 974 //----------SOURCE BLOCK------------------------------------------------------- 975 // This is a block of C++ code which provides values, functions, and 976 // definitions necessary in the rest of the architecture description. 977 source_hpp %{ 978 // Header information of the source block. 979 // Method declarations/definitions which are used outside 980 // the ad-scope can conveniently be defined here. 981 // 982 // To keep related declarations/definitions/uses close together, 983 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 984 985 // Returns true if Node n is followed by a MemBar node that 986 // will do an acquire. If so, this node must not do the acquire 987 // operation. 988 bool followed_by_acquire(const Node *n); 989 %} 990 991 source %{ 992 993 // Should the Matcher clone shifts on addressing modes, expecting them 994 // to be subsumed into complex addressing expressions or compute them 995 // into registers? 996 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 997 return clone_base_plus_offset_address(m, mstack, address_visited); 998 } 999 1000 void Compile::reshape_address(AddPNode* addp) { 1001 } 1002 1003 // Optimize load-acquire. 1004 // 1005 // Check if acquire is unnecessary due to following operation that does 1006 // acquire anyways. 1007 // Walk the pattern: 1008 // 1009 // n: Load.acq 1010 // | 1011 // MemBarAcquire 1012 // | | 1013 // Proj(ctrl) Proj(mem) 1014 // | | 1015 // MemBarRelease/Volatile 1016 // 1017 bool followed_by_acquire(const Node *load) { 1018 assert(load->is_Load(), "So far implemented only for loads."); 1019 1020 // Find MemBarAcquire. 1021 const Node *mba = NULL; 1022 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 1023 const Node *out = load->fast_out(i); 1024 if (out->Opcode() == Op_MemBarAcquire) { 1025 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 1026 mba = out; 1027 break; 1028 } 1029 } 1030 if (!mba) return false; 1031 1032 // Find following MemBar node. 1033 // 1034 // The following node must be reachable by control AND memory 1035 // edge to assure no other operations are in between the two nodes. 1036 // 1037 // So first get the Proj node, mem_proj, to use it to iterate forward. 1038 Node *mem_proj = NULL; 1039 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 1040 mem_proj = mba->fast_out(i); // Throw out-of-bounds if proj not found 1041 assert(mem_proj->is_Proj(), "only projections here"); 1042 ProjNode *proj = mem_proj->as_Proj(); 1043 if (proj->_con == TypeFunc::Memory && 1044 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 1045 break; 1046 } 1047 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 1048 1049 // Search MemBar behind Proj. If there are other memory operations 1050 // behind the Proj we lost. 1051 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 1052 Node *x = mem_proj->fast_out(j); 1053 // Proj might have an edge to a store or load node which precedes the membar. 1054 if (x->is_Mem()) return false; 1055 1056 // On PPC64 release and volatile are implemented by an instruction 1057 // that also has acquire semantics. I.e. there is no need for an 1058 // acquire before these. 1059 int xop = x->Opcode(); 1060 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 1061 // Make sure we're not missing Call/Phi/MergeMem by checking 1062 // control edges. The control edge must directly lead back 1063 // to the MemBarAcquire 1064 Node *ctrl_proj = x->in(0); 1065 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 1066 return true; 1067 } 1068 } 1069 } 1070 1071 return false; 1072 } 1073 1074 #define __ _masm. 1075 1076 // Tertiary op of a LoadP or StoreP encoding. 1077 #define REGP_OP true 1078 1079 // **************************************************************************** 1080 1081 // REQUIRED FUNCTIONALITY 1082 1083 // !!!!! Special hack to get all type of calls to specify the byte offset 1084 // from the start of the call to the point where the return address 1085 // will point. 1086 1087 // PPC port: Removed use of lazy constant construct. 1088 1089 int MachCallStaticJavaNode::ret_addr_offset() { 1090 // It's only a single branch-and-link instruction. 1091 return 4; 1092 } 1093 1094 int MachCallDynamicJavaNode::ret_addr_offset() { 1095 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 1096 // postalloc expanded calls if we use inline caches and do not update method data. 1097 if (UseInlineCaches) 1098 return 4; 1099 1100 int vtable_index = this->_vtable_index; 1101 if (vtable_index < 0) { 1102 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 1103 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 1104 return 12; 1105 } else { 1106 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 1107 return 24; 1108 } 1109 } 1110 1111 int MachCallRuntimeNode::ret_addr_offset() { 1112 #if defined(ABI_ELFv2) 1113 return 28; 1114 #else 1115 return 40; 1116 #endif 1117 } 1118 1119 //============================================================================= 1120 1121 // condition code conversions 1122 1123 static int cc_to_boint(int cc) { 1124 return Assembler::bcondCRbiIs0 | (cc & 8); 1125 } 1126 1127 static int cc_to_inverse_boint(int cc) { 1128 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 1129 } 1130 1131 static int cc_to_biint(int cc, int flags_reg) { 1132 return (flags_reg << 2) | (cc & 3); 1133 } 1134 1135 //============================================================================= 1136 1137 // Compute padding required for nodes which need alignment. The padding 1138 // is the number of bytes (not instructions) which will be inserted before 1139 // the instruction. The padding must match the size of a NOP instruction. 1140 1141 // Currently not used on this platform. 1142 1143 //============================================================================= 1144 1145 // Indicate if the safepoint node needs the polling page as an input. 1146 bool SafePointNode::needs_polling_address_input() { 1147 // The address is loaded from thread by a seperate node. 1148 return true; 1149 } 1150 1151 //============================================================================= 1152 1153 // Emit an interrupt that is caught by the debugger (for debugging compiler). 1154 void emit_break(CodeBuffer &cbuf) { 1155 MacroAssembler _masm(&cbuf); 1156 __ illtrap(); 1157 } 1158 1159 #ifndef PRODUCT 1160 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1161 st->print("BREAKPOINT"); 1162 } 1163 #endif 1164 1165 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1166 emit_break(cbuf); 1167 } 1168 1169 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1170 return MachNode::size(ra_); 1171 } 1172 1173 //============================================================================= 1174 1175 void emit_nop(CodeBuffer &cbuf) { 1176 MacroAssembler _masm(&cbuf); 1177 __ nop(); 1178 } 1179 1180 static inline void emit_long(CodeBuffer &cbuf, int value) { 1181 *((int*)(cbuf.insts_end())) = value; 1182 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1183 } 1184 1185 //============================================================================= 1186 1187 %} // interrupt source 1188 1189 source_hpp %{ // Header information of the source block. 1190 1191 //-------------------------------------------------------------- 1192 //---< Used for optimization in Compile::Shorten_branches >--- 1193 //-------------------------------------------------------------- 1194 1195 class CallStubImpl { 1196 1197 public: 1198 1199 // Emit call stub, compiled java to interpreter. 1200 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1201 1202 // Size of call trampoline stub. 1203 // This doesn't need to be accurate to the byte, but it 1204 // must be larger than or equal to the real size of the stub. 1205 static uint size_call_trampoline() { 1206 return MacroAssembler::trampoline_stub_size; 1207 } 1208 1209 // number of relocations needed by a call trampoline stub 1210 static uint reloc_call_trampoline() { 1211 return 5; 1212 } 1213 1214 }; 1215 1216 %} // end source_hpp 1217 1218 source %{ 1219 1220 // Emit a trampoline stub for a call to a target which is too far away. 1221 // 1222 // code sequences: 1223 // 1224 // call-site: 1225 // branch-and-link to <destination> or <trampoline stub> 1226 // 1227 // Related trampoline stub for this call-site in the stub section: 1228 // load the call target from the constant pool 1229 // branch via CTR (LR/link still points to the call-site above) 1230 1231 void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1232 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1233 if (stub == NULL) { 1234 ciEnv::current()->record_out_of_memory_failure(); 1235 } 1236 } 1237 1238 //============================================================================= 1239 1240 // Emit an inline branch-and-link call and a related trampoline stub. 1241 // 1242 // code sequences: 1243 // 1244 // call-site: 1245 // branch-and-link to <destination> or <trampoline stub> 1246 // 1247 // Related trampoline stub for this call-site in the stub section: 1248 // load the call target from the constant pool 1249 // branch via CTR (LR/link still points to the call-site above) 1250 // 1251 1252 typedef struct { 1253 int insts_call_instruction_offset; 1254 int ret_addr_offset; 1255 } EmitCallOffsets; 1256 1257 // Emit a branch-and-link instruction that branches to a trampoline. 1258 // - Remember the offset of the branch-and-link instruction. 1259 // - Add a relocation at the branch-and-link instruction. 1260 // - Emit a branch-and-link. 1261 // - Remember the return pc offset. 1262 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1263 EmitCallOffsets offsets = { -1, -1 }; 1264 const int start_offset = __ offset(); 1265 offsets.insts_call_instruction_offset = __ offset(); 1266 1267 // No entry point given, use the current pc. 1268 if (entry_point == NULL) entry_point = __ pc(); 1269 1270 // Put the entry point as a constant into the constant pool. 1271 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1272 if (entry_point_toc_addr == NULL) { 1273 ciEnv::current()->record_out_of_memory_failure(); 1274 return offsets; 1275 } 1276 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1277 1278 // Emit the trampoline stub which will be related to the branch-and-link below. 1279 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1280 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1281 __ relocate(rtype); 1282 1283 // Note: At this point we do not have the address of the trampoline 1284 // stub, and the entry point might be too far away for bl, so __ pc() 1285 // serves as dummy and the bl will be patched later. 1286 __ bl((address) __ pc()); 1287 1288 offsets.ret_addr_offset = __ offset() - start_offset; 1289 1290 return offsets; 1291 } 1292 1293 //============================================================================= 1294 1295 // Factory for creating loadConL* nodes for large/small constant pool. 1296 1297 static inline jlong replicate_immF(float con) { 1298 // Replicate float con 2 times and pack into vector. 1299 int val = *((int*)&con); 1300 jlong lval = val; 1301 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1302 return lval; 1303 } 1304 1305 //============================================================================= 1306 1307 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1308 int Compile::ConstantTable::calculate_table_base_offset() const { 1309 return 0; // absolute addressing, no offset 1310 } 1311 1312 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1313 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1314 iRegPdstOper *op_dst = new iRegPdstOper(); 1315 MachNode *m1 = new loadToc_hiNode(); 1316 MachNode *m2 = new loadToc_loNode(); 1317 1318 m1->add_req(NULL); 1319 m2->add_req(NULL, m1); 1320 m1->_opnds[0] = op_dst; 1321 m2->_opnds[0] = op_dst; 1322 m2->_opnds[1] = op_dst; 1323 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1324 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1325 nodes->push(m1); 1326 nodes->push(m2); 1327 } 1328 1329 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1330 // Is postalloc expanded. 1331 ShouldNotReachHere(); 1332 } 1333 1334 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1335 return 0; 1336 } 1337 1338 #ifndef PRODUCT 1339 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1340 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1341 } 1342 #endif 1343 1344 //============================================================================= 1345 1346 #ifndef PRODUCT 1347 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1348 Compile* C = ra_->C; 1349 const long framesize = C->frame_slots() << LogBytesPerInt; 1350 1351 st->print("PROLOG\n\t"); 1352 if (C->need_stack_bang(framesize)) { 1353 st->print("stack_overflow_check\n\t"); 1354 } 1355 1356 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1357 st->print("save return pc\n\t"); 1358 st->print("push frame %ld\n\t", -framesize); 1359 } 1360 } 1361 #endif 1362 1363 // Macro used instead of the common __ to emulate the pipes of PPC. 1364 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1365 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1366 // still no scheduling of this code is possible, the micro scheduler is aware of the 1367 // code and can update its internal data. The following mechanism is used to achieve this: 1368 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1369 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1370 #if 0 // TODO: PPC port 1371 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1372 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1373 _masm. 1374 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1375 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1376 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1377 C->hb_scheduling()->_pdScheduling->advance_offset 1378 #else 1379 #define ___(op) if (UsePower6SchedulerPPC64) \ 1380 Unimplemented(); \ 1381 _masm. 1382 #define ___stop if (UsePower6SchedulerPPC64) \ 1383 Unimplemented() 1384 #define ___advance if (UsePower6SchedulerPPC64) \ 1385 Unimplemented() 1386 #endif 1387 1388 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1389 Compile* C = ra_->C; 1390 MacroAssembler _masm(&cbuf); 1391 1392 const long framesize = C->frame_size_in_bytes(); 1393 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1394 1395 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1396 1397 const Register return_pc = R20; // Must match return_addr() in frame section. 1398 const Register callers_sp = R21; 1399 const Register push_frame_temp = R22; 1400 const Register toc_temp = R23; 1401 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1402 1403 if (method_is_frameless) { 1404 // Add nop at beginning of all frameless methods to prevent any 1405 // oop instructions from getting overwritten by make_not_entrant 1406 // (patching attempt would fail). 1407 ___(nop) nop(); 1408 } else { 1409 // Get return pc. 1410 ___(mflr) mflr(return_pc); 1411 } 1412 1413 // Calls to C2R adapters often do not accept exceptional returns. 1414 // We require that their callers must bang for them. But be 1415 // careful, because some VM calls (such as call site linkage) can 1416 // use several kilobytes of stack. But the stack safety zone should 1417 // account for that. See bugs 4446381, 4468289, 4497237. 1418 1419 int bangsize = C->bang_size_in_bytes(); 1420 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1421 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1422 // Unfortunately we cannot use the function provided in 1423 // assembler.cpp as we have to emulate the pipes. So I had to 1424 // insert the code of generate_stack_overflow_check(), see 1425 // assembler.cpp for some illuminative comments. 1426 const int page_size = os::vm_page_size(); 1427 int bang_end = JavaThread::stack_shadow_zone_size(); 1428 1429 // This is how far the previous frame's stack banging extended. 1430 const int bang_end_safe = bang_end; 1431 1432 if (bangsize > page_size) { 1433 bang_end += bangsize; 1434 } 1435 1436 int bang_offset = bang_end_safe; 1437 1438 while (bang_offset <= bang_end) { 1439 // Need at least one stack bang at end of shadow zone. 1440 1441 // Again I had to copy code, this time from assembler_ppc.cpp, 1442 // bang_stack_with_offset - see there for comments. 1443 1444 // Stack grows down, caller passes positive offset. 1445 assert(bang_offset > 0, "must bang with positive offset"); 1446 1447 long stdoffset = -bang_offset; 1448 1449 if (Assembler::is_simm(stdoffset, 16)) { 1450 // Signed 16 bit offset, a simple std is ok. 1451 if (UseLoadInstructionsForStackBangingPPC64) { 1452 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1453 } else { 1454 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1455 } 1456 } else if (Assembler::is_simm(stdoffset, 31)) { 1457 // Use largeoffset calculations for addis & ld/std. 1458 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1459 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1460 1461 Register tmp = R11; 1462 ___(addis) addis(tmp, R1_SP, hi); 1463 if (UseLoadInstructionsForStackBangingPPC64) { 1464 ___(ld) ld(R0, lo, tmp); 1465 } else { 1466 ___(std) std(R0, lo, tmp); 1467 } 1468 } else { 1469 ShouldNotReachHere(); 1470 } 1471 1472 bang_offset += page_size; 1473 } 1474 // R11 trashed 1475 } // C->need_stack_bang(framesize) && UseStackBanging 1476 1477 unsigned int bytes = (unsigned int)framesize; 1478 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1479 ciMethod *currMethod = C->method(); 1480 1481 // Optimized version for most common case. 1482 if (UsePower6SchedulerPPC64 && 1483 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1484 !(false /* ConstantsALot TODO: PPC port*/)) { 1485 ___(or) mr(callers_sp, R1_SP); 1486 ___(std) std(return_pc, _abi(lr), R1_SP); 1487 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1488 return; 1489 } 1490 1491 if (!method_is_frameless) { 1492 // Get callers sp. 1493 ___(or) mr(callers_sp, R1_SP); 1494 1495 // Push method's frame, modifies SP. 1496 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1497 // The ABI is already accounted for in 'framesize' via the 1498 // 'out_preserve' area. 1499 Register tmp = push_frame_temp; 1500 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1501 if (Assembler::is_simm(-offset, 16)) { 1502 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1503 } else { 1504 long x = -offset; 1505 // Had to insert load_const(tmp, -offset). 1506 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1507 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1508 ___(rldicr) sldi(tmp, tmp, 32); 1509 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1510 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1511 1512 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1513 } 1514 } 1515 #if 0 // TODO: PPC port 1516 // For testing large constant pools, emit a lot of constants to constant pool. 1517 // "Randomize" const_size. 1518 if (ConstantsALot) { 1519 const int num_consts = const_size(); 1520 for (int i = 0; i < num_consts; i++) { 1521 __ long_constant(0xB0B5B00BBABE); 1522 } 1523 } 1524 #endif 1525 if (!method_is_frameless) { 1526 // Save return pc. 1527 ___(std) std(return_pc, _abi(lr), callers_sp); 1528 } 1529 1530 C->set_frame_complete(cbuf.insts_size()); 1531 } 1532 #undef ___ 1533 #undef ___stop 1534 #undef ___advance 1535 1536 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1537 // Variable size. determine dynamically. 1538 return MachNode::size(ra_); 1539 } 1540 1541 int MachPrologNode::reloc() const { 1542 // Return number of relocatable values contained in this instruction. 1543 return 1; // 1 reloc entry for load_const(toc). 1544 } 1545 1546 //============================================================================= 1547 1548 #ifndef PRODUCT 1549 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1550 Compile* C = ra_->C; 1551 1552 st->print("EPILOG\n\t"); 1553 st->print("restore return pc\n\t"); 1554 st->print("pop frame\n\t"); 1555 1556 if (do_polling() && C->is_method_compilation()) { 1557 st->print("touch polling page\n\t"); 1558 } 1559 } 1560 #endif 1561 1562 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1563 Compile* C = ra_->C; 1564 MacroAssembler _masm(&cbuf); 1565 1566 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1567 assert(framesize >= 0, "negative frame-size?"); 1568 1569 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1570 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1571 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1572 const Register polling_page = R12; 1573 1574 if (!method_is_frameless) { 1575 // Restore return pc relative to callers' sp. 1576 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1577 } 1578 1579 if (method_needs_polling) { 1580 if (SafepointMechanism::uses_thread_local_poll()) { 1581 __ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread); 1582 } else { 1583 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); 1584 } 1585 } 1586 1587 if (!method_is_frameless) { 1588 // Move return pc to LR. 1589 __ mtlr(return_pc); 1590 // Pop frame (fixed frame-size). 1591 __ addi(R1_SP, R1_SP, (int)framesize); 1592 } 1593 1594 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1595 __ reserved_stack_check(return_pc); 1596 } 1597 1598 if (method_needs_polling) { 1599 // We need to mark the code position where the load from the safepoint 1600 // polling page was emitted as relocInfo::poll_return_type here. 1601 __ relocate(relocInfo::poll_return_type); 1602 __ load_from_polling_page(polling_page); 1603 } 1604 } 1605 1606 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1607 // Variable size. Determine dynamically. 1608 return MachNode::size(ra_); 1609 } 1610 1611 int MachEpilogNode::reloc() const { 1612 // Return number of relocatable values contained in this instruction. 1613 return 1; // 1 for load_from_polling_page. 1614 } 1615 1616 const Pipeline * MachEpilogNode::pipeline() const { 1617 return MachNode::pipeline_class(); 1618 } 1619 1620 // This method seems to be obsolete. It is declared in machnode.hpp 1621 // and defined in all *.ad files, but it is never called. Should we 1622 // get rid of it? 1623 int MachEpilogNode::safepoint_offset() const { 1624 assert(do_polling(), "no return for this epilog node"); 1625 return 0; 1626 } 1627 1628 #if 0 // TODO: PPC port 1629 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1630 MacroAssembler _masm(&cbuf); 1631 if (LoadPollAddressFromThread) { 1632 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1633 } else { 1634 _masm.nop(); 1635 } 1636 } 1637 1638 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1639 if (LoadPollAddressFromThread) { 1640 return 4; 1641 } else { 1642 return 4; 1643 } 1644 } 1645 1646 #ifndef PRODUCT 1647 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1648 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1649 } 1650 #endif 1651 1652 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1653 return RSCRATCH1_BITS64_REG_mask(); 1654 } 1655 #endif // PPC port 1656 1657 // ============================================================================= 1658 1659 // Figure out which register class each belongs in: rc_int, rc_float or 1660 // rc_stack. 1661 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1662 1663 static enum RC rc_class(OptoReg::Name reg) { 1664 // Return the register class for the given register. The given register 1665 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1666 // enumeration in adGlobals_ppc.hpp. 1667 1668 if (reg == OptoReg::Bad) return rc_bad; 1669 1670 // We have 64 integer register halves, starting at index 0. 1671 if (reg < 64) return rc_int; 1672 1673 // We have 64 floating-point register halves, starting at index 64. 1674 if (reg < 64+64) return rc_float; 1675 1676 // Between float regs & stack are the flags regs. 1677 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1678 1679 return rc_stack; 1680 } 1681 1682 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1683 bool do_print, Compile* C, outputStream *st) { 1684 1685 assert(opcode == Assembler::LD_OPCODE || 1686 opcode == Assembler::STD_OPCODE || 1687 opcode == Assembler::LWZ_OPCODE || 1688 opcode == Assembler::STW_OPCODE || 1689 opcode == Assembler::LFD_OPCODE || 1690 opcode == Assembler::STFD_OPCODE || 1691 opcode == Assembler::LFS_OPCODE || 1692 opcode == Assembler::STFS_OPCODE, 1693 "opcode not supported"); 1694 1695 if (cbuf) { 1696 int d = 1697 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1698 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1699 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1700 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1701 } 1702 #ifndef PRODUCT 1703 else if (do_print) { 1704 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1705 op_str, 1706 Matcher::regName[reg], 1707 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1708 } 1709 #endif 1710 return 4; // size 1711 } 1712 1713 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1714 Compile* C = ra_->C; 1715 1716 // Get registers to move. 1717 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1718 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1719 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1720 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1721 1722 enum RC src_hi_rc = rc_class(src_hi); 1723 enum RC src_lo_rc = rc_class(src_lo); 1724 enum RC dst_hi_rc = rc_class(dst_hi); 1725 enum RC dst_lo_rc = rc_class(dst_lo); 1726 1727 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1728 if (src_hi != OptoReg::Bad) 1729 assert((src_lo&1)==0 && src_lo+1==src_hi && 1730 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1731 "expected aligned-adjacent pairs"); 1732 // Generate spill code! 1733 int size = 0; 1734 1735 if (src_lo == dst_lo && src_hi == dst_hi) 1736 return size; // Self copy, no move. 1737 1738 // -------------------------------------- 1739 // Memory->Memory Spill. Use R0 to hold the value. 1740 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1741 int src_offset = ra_->reg2offset(src_lo); 1742 int dst_offset = ra_->reg2offset(dst_lo); 1743 if (src_hi != OptoReg::Bad) { 1744 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1745 "expected same type of move for high parts"); 1746 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1747 if (!cbuf && !do_size) st->print("\n\t"); 1748 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1749 } else { 1750 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1751 if (!cbuf && !do_size) st->print("\n\t"); 1752 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1753 } 1754 return size; 1755 } 1756 1757 // -------------------------------------- 1758 // Check for float->int copy; requires a trip through memory. 1759 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1760 Unimplemented(); 1761 } 1762 1763 // -------------------------------------- 1764 // Check for integer reg-reg copy. 1765 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1766 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1767 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1768 size = (Rsrc != Rdst) ? 4 : 0; 1769 1770 if (cbuf) { 1771 MacroAssembler _masm(cbuf); 1772 if (size) { 1773 __ mr(Rdst, Rsrc); 1774 } 1775 } 1776 #ifndef PRODUCT 1777 else if (!do_size) { 1778 if (size) { 1779 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1780 } else { 1781 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1782 } 1783 } 1784 #endif 1785 return size; 1786 } 1787 1788 // Check for integer store. 1789 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1790 int dst_offset = ra_->reg2offset(dst_lo); 1791 if (src_hi != OptoReg::Bad) { 1792 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1793 "expected same type of move for high parts"); 1794 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1795 } else { 1796 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1797 } 1798 return size; 1799 } 1800 1801 // Check for integer load. 1802 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1803 int src_offset = ra_->reg2offset(src_lo); 1804 if (src_hi != OptoReg::Bad) { 1805 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1806 "expected same type of move for high parts"); 1807 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1808 } else { 1809 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1810 } 1811 return size; 1812 } 1813 1814 // Check for float reg-reg copy. 1815 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1816 if (cbuf) { 1817 MacroAssembler _masm(cbuf); 1818 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1819 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1820 __ fmr(Rdst, Rsrc); 1821 } 1822 #ifndef PRODUCT 1823 else if (!do_size) { 1824 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1825 } 1826 #endif 1827 return 4; 1828 } 1829 1830 // Check for float store. 1831 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1832 int dst_offset = ra_->reg2offset(dst_lo); 1833 if (src_hi != OptoReg::Bad) { 1834 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1835 "expected same type of move for high parts"); 1836 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1837 } else { 1838 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1839 } 1840 return size; 1841 } 1842 1843 // Check for float load. 1844 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1845 int src_offset = ra_->reg2offset(src_lo); 1846 if (src_hi != OptoReg::Bad) { 1847 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1848 "expected same type of move for high parts"); 1849 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1850 } else { 1851 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1852 } 1853 return size; 1854 } 1855 1856 // -------------------------------------------------------------------- 1857 // Check for hi bits still needing moving. Only happens for misaligned 1858 // arguments to native calls. 1859 if (src_hi == dst_hi) 1860 return size; // Self copy; no move. 1861 1862 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1863 ShouldNotReachHere(); // Unimplemented 1864 return 0; 1865 } 1866 1867 #ifndef PRODUCT 1868 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1869 if (!ra_) 1870 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1871 else 1872 implementation(NULL, ra_, false, st); 1873 } 1874 #endif 1875 1876 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1877 implementation(&cbuf, ra_, false, NULL); 1878 } 1879 1880 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1881 return implementation(NULL, ra_, true, NULL); 1882 } 1883 1884 #if 0 // TODO: PPC port 1885 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1886 #ifndef PRODUCT 1887 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1888 #endif 1889 assert(ra_->node_regs_max_index() != 0, ""); 1890 1891 // Get registers to move. 1892 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1893 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1894 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1895 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1896 1897 enum RC src_lo_rc = rc_class(src_lo); 1898 enum RC dst_lo_rc = rc_class(dst_lo); 1899 1900 if (src_lo == dst_lo && src_hi == dst_hi) 1901 return ppc64Opcode_none; // Self copy, no move. 1902 1903 // -------------------------------------- 1904 // Memory->Memory Spill. Use R0 to hold the value. 1905 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1906 return ppc64Opcode_compound; 1907 } 1908 1909 // -------------------------------------- 1910 // Check for float->int copy; requires a trip through memory. 1911 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1912 Unimplemented(); 1913 } 1914 1915 // -------------------------------------- 1916 // Check for integer reg-reg copy. 1917 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1918 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1919 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1920 if (Rsrc == Rdst) { 1921 return ppc64Opcode_none; 1922 } else { 1923 return ppc64Opcode_or; 1924 } 1925 } 1926 1927 // Check for integer store. 1928 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1929 if (src_hi != OptoReg::Bad) { 1930 return ppc64Opcode_std; 1931 } else { 1932 return ppc64Opcode_stw; 1933 } 1934 } 1935 1936 // Check for integer load. 1937 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1938 if (src_hi != OptoReg::Bad) { 1939 return ppc64Opcode_ld; 1940 } else { 1941 return ppc64Opcode_lwz; 1942 } 1943 } 1944 1945 // Check for float reg-reg copy. 1946 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1947 return ppc64Opcode_fmr; 1948 } 1949 1950 // Check for float store. 1951 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1952 if (src_hi != OptoReg::Bad) { 1953 return ppc64Opcode_stfd; 1954 } else { 1955 return ppc64Opcode_stfs; 1956 } 1957 } 1958 1959 // Check for float load. 1960 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1961 if (src_hi != OptoReg::Bad) { 1962 return ppc64Opcode_lfd; 1963 } else { 1964 return ppc64Opcode_lfs; 1965 } 1966 } 1967 1968 // -------------------------------------------------------------------- 1969 // Check for hi bits still needing moving. Only happens for misaligned 1970 // arguments to native calls. 1971 if (src_hi == dst_hi) { 1972 return ppc64Opcode_none; // Self copy; no move. 1973 } 1974 1975 ShouldNotReachHere(); 1976 return ppc64Opcode_undefined; 1977 } 1978 #endif // PPC port 1979 1980 #ifndef PRODUCT 1981 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1982 st->print("NOP \t// %d nops to pad for loops.", _count); 1983 } 1984 #endif 1985 1986 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 1987 MacroAssembler _masm(&cbuf); 1988 // _count contains the number of nops needed for padding. 1989 for (int i = 0; i < _count; i++) { 1990 __ nop(); 1991 } 1992 } 1993 1994 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 1995 return _count * 4; 1996 } 1997 1998 #ifndef PRODUCT 1999 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2000 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2001 char reg_str[128]; 2002 ra_->dump_register(this, reg_str); 2003 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 2004 } 2005 #endif 2006 2007 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2008 MacroAssembler _masm(&cbuf); 2009 2010 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2011 int reg = ra_->get_encode(this); 2012 2013 if (Assembler::is_simm(offset, 16)) { 2014 __ addi(as_Register(reg), R1, offset); 2015 } else { 2016 ShouldNotReachHere(); 2017 } 2018 } 2019 2020 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2021 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2022 return 4; 2023 } 2024 2025 #ifndef PRODUCT 2026 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2027 st->print_cr("---- MachUEPNode ----"); 2028 st->print_cr("..."); 2029 } 2030 #endif 2031 2032 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2033 // This is the unverified entry point. 2034 MacroAssembler _masm(&cbuf); 2035 2036 // Inline_cache contains a klass. 2037 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 2038 Register receiver_klass = R12_scratch2; // tmp 2039 2040 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 2041 assert(R11_scratch1 == R11, "need prologue scratch register"); 2042 2043 // Check for NULL argument if we don't have implicit null checks. 2044 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 2045 if (TrapBasedNullChecks) { 2046 __ trap_null_check(R3_ARG1); 2047 } else { 2048 Label valid; 2049 __ cmpdi(CCR0, R3_ARG1, 0); 2050 __ bne_predict_taken(CCR0, valid); 2051 // We have a null argument, branch to ic_miss_stub. 2052 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2053 relocInfo::runtime_call_type); 2054 __ bind(valid); 2055 } 2056 } 2057 // Assume argument is not NULL, load klass from receiver. 2058 __ load_klass(receiver_klass, R3_ARG1); 2059 2060 if (TrapBasedICMissChecks) { 2061 __ trap_ic_miss_check(receiver_klass, ic_klass); 2062 } else { 2063 Label valid; 2064 __ cmpd(CCR0, receiver_klass, ic_klass); 2065 __ beq_predict_taken(CCR0, valid); 2066 // We have an unexpected klass, branch to ic_miss_stub. 2067 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2068 relocInfo::runtime_call_type); 2069 __ bind(valid); 2070 } 2071 2072 // Argument is valid and klass is as expected, continue. 2073 } 2074 2075 #if 0 // TODO: PPC port 2076 // Optimize UEP code on z (save a load_const() call in main path). 2077 int MachUEPNode::ep_offset() { 2078 return 0; 2079 } 2080 #endif 2081 2082 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2083 // Variable size. Determine dynamically. 2084 return MachNode::size(ra_); 2085 } 2086 2087 //============================================================================= 2088 2089 %} // interrupt source 2090 2091 source_hpp %{ // Header information of the source block. 2092 2093 class HandlerImpl { 2094 2095 public: 2096 2097 static int emit_exception_handler(CodeBuffer &cbuf); 2098 static int emit_deopt_handler(CodeBuffer& cbuf); 2099 2100 static uint size_exception_handler() { 2101 // The exception_handler is a b64_patchable. 2102 return MacroAssembler::b64_patchable_size; 2103 } 2104 2105 static uint size_deopt_handler() { 2106 // The deopt_handler is a bl64_patchable. 2107 return MacroAssembler::bl64_patchable_size; 2108 } 2109 2110 }; 2111 2112 %} // end source_hpp 2113 2114 source %{ 2115 2116 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2117 MacroAssembler _masm(&cbuf); 2118 2119 address base = __ start_a_stub(size_exception_handler()); 2120 if (base == NULL) return 0; // CodeBuffer::expand failed 2121 2122 int offset = __ offset(); 2123 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2124 relocInfo::runtime_call_type); 2125 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2126 __ end_a_stub(); 2127 2128 return offset; 2129 } 2130 2131 // The deopt_handler is like the exception handler, but it calls to 2132 // the deoptimization blob instead of jumping to the exception blob. 2133 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2134 MacroAssembler _masm(&cbuf); 2135 2136 address base = __ start_a_stub(size_deopt_handler()); 2137 if (base == NULL) return 0; // CodeBuffer::expand failed 2138 2139 int offset = __ offset(); 2140 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2141 relocInfo::runtime_call_type); 2142 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2143 __ end_a_stub(); 2144 2145 return offset; 2146 } 2147 2148 //============================================================================= 2149 2150 // Use a frame slots bias for frameless methods if accessing the stack. 2151 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2152 if (as_Register(reg_enc) == R1_SP) { 2153 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2154 } 2155 return 0; 2156 } 2157 2158 const bool Matcher::match_rule_supported(int opcode) { 2159 if (!has_match_rule(opcode)) 2160 return false; 2161 2162 switch (opcode) { 2163 case Op_SqrtD: 2164 return VM_Version::has_fsqrt(); 2165 case Op_CountLeadingZerosI: 2166 case Op_CountLeadingZerosL: 2167 case Op_CountTrailingZerosI: 2168 case Op_CountTrailingZerosL: 2169 if (!UseCountLeadingZerosInstructionsPPC64) 2170 return false; 2171 break; 2172 2173 case Op_PopCountI: 2174 case Op_PopCountL: 2175 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2176 2177 case Op_StrComp: 2178 return SpecialStringCompareTo; 2179 case Op_StrEquals: 2180 return SpecialStringEquals; 2181 case Op_StrIndexOf: 2182 return SpecialStringIndexOf; 2183 case Op_StrIndexOfChar: 2184 return SpecialStringIndexOf; 2185 } 2186 2187 return true; // Per default match rules are supported. 2188 } 2189 2190 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2191 2192 // TODO 2193 // identify extra cases that we might want to provide match rules for 2194 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2195 bool ret_value = match_rule_supported(opcode); 2196 // Add rules here. 2197 2198 return ret_value; // Per default match rules are supported. 2199 } 2200 2201 const bool Matcher::has_predicated_vectors(void) { 2202 return false; 2203 } 2204 2205 const int Matcher::float_pressure(int default_pressure_threshold) { 2206 return default_pressure_threshold; 2207 } 2208 2209 int Matcher::regnum_to_fpu_offset(int regnum) { 2210 // No user for this method? 2211 Unimplemented(); 2212 return 999; 2213 } 2214 2215 const bool Matcher::convL2FSupported(void) { 2216 // fcfids can do the conversion (>= Power7). 2217 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2218 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2219 } 2220 2221 // Vector width in bytes. 2222 const int Matcher::vector_width_in_bytes(BasicType bt) { 2223 if (SuperwordUseVSX) { 2224 assert(MaxVectorSize == 16, ""); 2225 return 16; 2226 } else { 2227 assert(MaxVectorSize == 8, ""); 2228 return 8; 2229 } 2230 } 2231 2232 // Vector ideal reg. 2233 const uint Matcher::vector_ideal_reg(int size) { 2234 if (SuperwordUseVSX) { 2235 assert(MaxVectorSize == 16 && size == 16, ""); 2236 return Op_VecX; 2237 } else { 2238 assert(MaxVectorSize == 8 && size == 8, ""); 2239 return Op_RegL; 2240 } 2241 } 2242 2243 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2244 fatal("vector shift is not supported"); 2245 return Node::NotAMachineReg; 2246 } 2247 2248 // Limits on vector size (number of elements) loaded into vector. 2249 const int Matcher::max_vector_size(const BasicType bt) { 2250 assert(is_java_primitive(bt), "only primitive type vectors"); 2251 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2252 } 2253 2254 const int Matcher::min_vector_size(const BasicType bt) { 2255 return max_vector_size(bt); // Same as max. 2256 } 2257 2258 // PPC doesn't support misaligned vectors store/load. 2259 const bool Matcher::misaligned_vectors_ok() { 2260 return !AlignVector; // can be changed by flag 2261 } 2262 2263 // PPC AES support not yet implemented 2264 const bool Matcher::pass_original_key_for_aes() { 2265 return false; 2266 } 2267 2268 // RETURNS: whether this branch offset is short enough that a short 2269 // branch can be used. 2270 // 2271 // If the platform does not provide any short branch variants, then 2272 // this method should return `false' for offset 0. 2273 // 2274 // `Compile::Fill_buffer' will decide on basis of this information 2275 // whether to do the pass `Compile::Shorten_branches' at all. 2276 // 2277 // And `Compile::Shorten_branches' will decide on basis of this 2278 // information whether to replace particular branch sites by short 2279 // ones. 2280 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2281 // Is the offset within the range of a ppc64 pc relative branch? 2282 bool b; 2283 2284 const int safety_zone = 3 * BytesPerInstWord; 2285 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2286 29 - 16 + 1 + 2); 2287 return b; 2288 } 2289 2290 const bool Matcher::isSimpleConstant64(jlong value) { 2291 // Probably always true, even if a temp register is required. 2292 return true; 2293 } 2294 /* TODO: PPC port 2295 // Make a new machine dependent decode node (with its operands). 2296 MachTypeNode *Matcher::make_decode_node() { 2297 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2298 "This method is only implemented for unscaled cOops mode so far"); 2299 MachTypeNode *decode = new decodeN_unscaledNode(); 2300 decode->set_opnd_array(0, new iRegPdstOper()); 2301 decode->set_opnd_array(1, new iRegNsrcOper()); 2302 return decode; 2303 } 2304 */ 2305 2306 // false => size gets scaled to BytesPerLong, ok. 2307 const bool Matcher::init_array_count_is_in_bytes = false; 2308 2309 // Use conditional move (CMOVL) on Power7. 2310 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2311 2312 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2313 // fsel doesn't accept a condition register as input, so this would be slightly different. 2314 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2315 2316 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2317 const bool Matcher::require_postalloc_expand = true; 2318 2319 // Do we need to mask the count passed to shift instructions or does 2320 // the cpu only look at the lower 5/6 bits anyway? 2321 // PowerPC requires masked shift counts. 2322 const bool Matcher::need_masked_shift_count = true; 2323 2324 // This affects two different things: 2325 // - how Decode nodes are matched 2326 // - how ImplicitNullCheck opportunities are recognized 2327 // If true, the matcher will try to remove all Decodes and match them 2328 // (as operands) into nodes. NullChecks are not prepared to deal with 2329 // Decodes by final_graph_reshaping(). 2330 // If false, final_graph_reshaping() forces the decode behind the Cmp 2331 // for a NullCheck. The matcher matches the Decode node into a register. 2332 // Implicit_null_check optimization moves the Decode along with the 2333 // memory operation back up before the NullCheck. 2334 bool Matcher::narrow_oop_use_complex_address() { 2335 // TODO: PPC port if (MatchDecodeNodes) return true; 2336 return false; 2337 } 2338 2339 bool Matcher::narrow_klass_use_complex_address() { 2340 NOT_LP64(ShouldNotCallThis()); 2341 assert(UseCompressedClassPointers, "only for compressed klass code"); 2342 // TODO: PPC port if (MatchDecodeNodes) return true; 2343 return false; 2344 } 2345 2346 bool Matcher::const_oop_prefer_decode() { 2347 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2348 return Universe::narrow_oop_base() == NULL; 2349 } 2350 2351 bool Matcher::const_klass_prefer_decode() { 2352 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2353 return Universe::narrow_klass_base() == NULL; 2354 } 2355 2356 // Is it better to copy float constants, or load them directly from memory? 2357 // Intel can load a float constant from a direct address, requiring no 2358 // extra registers. Most RISCs will have to materialize an address into a 2359 // register first, so they would do better to copy the constant from stack. 2360 const bool Matcher::rematerialize_float_constants = false; 2361 2362 // If CPU can load and store mis-aligned doubles directly then no fixup is 2363 // needed. Else we split the double into 2 integer pieces and move it 2364 // piece-by-piece. Only happens when passing doubles into C code as the 2365 // Java calling convention forces doubles to be aligned. 2366 const bool Matcher::misaligned_doubles_ok = true; 2367 2368 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2369 Unimplemented(); 2370 } 2371 2372 // Advertise here if the CPU requires explicit rounding operations 2373 // to implement the UseStrictFP mode. 2374 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2375 2376 // Do floats take an entire double register or just half? 2377 // 2378 // A float occupies a ppc64 double register. For the allocator, a 2379 // ppc64 double register appears as a pair of float registers. 2380 bool Matcher::float_in_double() { return true; } 2381 2382 // Do ints take an entire long register or just half? 2383 // The relevant question is how the int is callee-saved: 2384 // the whole long is written but de-opt'ing will have to extract 2385 // the relevant 32 bits. 2386 const bool Matcher::int_in_long = true; 2387 2388 // Constants for c2c and c calling conventions. 2389 2390 const MachRegisterNumbers iarg_reg[8] = { 2391 R3_num, R4_num, R5_num, R6_num, 2392 R7_num, R8_num, R9_num, R10_num 2393 }; 2394 2395 const MachRegisterNumbers farg_reg[13] = { 2396 F1_num, F2_num, F3_num, F4_num, 2397 F5_num, F6_num, F7_num, F8_num, 2398 F9_num, F10_num, F11_num, F12_num, 2399 F13_num 2400 }; 2401 2402 const MachRegisterNumbers vsarg_reg[64] = { 2403 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2404 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2405 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2406 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2407 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2408 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2409 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2410 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2411 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2412 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2413 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2414 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2415 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2416 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2417 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2418 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2419 }; 2420 2421 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2422 2423 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2424 2425 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2426 2427 // Return whether or not this register is ever used as an argument. This 2428 // function is used on startup to build the trampoline stubs in generateOptoStub. 2429 // Registers not mentioned will be killed by the VM call in the trampoline, and 2430 // arguments in those registers not be available to the callee. 2431 bool Matcher::can_be_java_arg(int reg) { 2432 // We return true for all registers contained in iarg_reg[] and 2433 // farg_reg[] and their virtual halves. 2434 // We must include the virtual halves in order to get STDs and LDs 2435 // instead of STWs and LWs in the trampoline stubs. 2436 2437 if ( reg == R3_num || reg == R3_H_num 2438 || reg == R4_num || reg == R4_H_num 2439 || reg == R5_num || reg == R5_H_num 2440 || reg == R6_num || reg == R6_H_num 2441 || reg == R7_num || reg == R7_H_num 2442 || reg == R8_num || reg == R8_H_num 2443 || reg == R9_num || reg == R9_H_num 2444 || reg == R10_num || reg == R10_H_num) 2445 return true; 2446 2447 if ( reg == F1_num || reg == F1_H_num 2448 || reg == F2_num || reg == F2_H_num 2449 || reg == F3_num || reg == F3_H_num 2450 || reg == F4_num || reg == F4_H_num 2451 || reg == F5_num || reg == F5_H_num 2452 || reg == F6_num || reg == F6_H_num 2453 || reg == F7_num || reg == F7_H_num 2454 || reg == F8_num || reg == F8_H_num 2455 || reg == F9_num || reg == F9_H_num 2456 || reg == F10_num || reg == F10_H_num 2457 || reg == F11_num || reg == F11_H_num 2458 || reg == F12_num || reg == F12_H_num 2459 || reg == F13_num || reg == F13_H_num) 2460 return true; 2461 2462 return false; 2463 } 2464 2465 bool Matcher::is_spillable_arg(int reg) { 2466 return can_be_java_arg(reg); 2467 } 2468 2469 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2470 return false; 2471 } 2472 2473 // Register for DIVI projection of divmodI. 2474 RegMask Matcher::divI_proj_mask() { 2475 ShouldNotReachHere(); 2476 return RegMask(); 2477 } 2478 2479 // Register for MODI projection of divmodI. 2480 RegMask Matcher::modI_proj_mask() { 2481 ShouldNotReachHere(); 2482 return RegMask(); 2483 } 2484 2485 // Register for DIVL projection of divmodL. 2486 RegMask Matcher::divL_proj_mask() { 2487 ShouldNotReachHere(); 2488 return RegMask(); 2489 } 2490 2491 // Register for MODL projection of divmodL. 2492 RegMask Matcher::modL_proj_mask() { 2493 ShouldNotReachHere(); 2494 return RegMask(); 2495 } 2496 2497 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2498 return RegMask(); 2499 } 2500 2501 const bool Matcher::convi2l_type_required = true; 2502 2503 %} 2504 2505 //----------ENCODING BLOCK----------------------------------------------------- 2506 // This block specifies the encoding classes used by the compiler to output 2507 // byte streams. Encoding classes are parameterized macros used by 2508 // Machine Instruction Nodes in order to generate the bit encoding of the 2509 // instruction. Operands specify their base encoding interface with the 2510 // interface keyword. There are currently supported four interfaces, 2511 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2512 // operand to generate a function which returns its register number when 2513 // queried. CONST_INTER causes an operand to generate a function which 2514 // returns the value of the constant when queried. MEMORY_INTER causes an 2515 // operand to generate four functions which return the Base Register, the 2516 // Index Register, the Scale Value, and the Offset Value of the operand when 2517 // queried. COND_INTER causes an operand to generate six functions which 2518 // return the encoding code (ie - encoding bits for the instruction) 2519 // associated with each basic boolean condition for a conditional instruction. 2520 // 2521 // Instructions specify two basic values for encoding. Again, a function 2522 // is available to check if the constant displacement is an oop. They use the 2523 // ins_encode keyword to specify their encoding classes (which must be 2524 // a sequence of enc_class names, and their parameters, specified in 2525 // the encoding block), and they use the 2526 // opcode keyword to specify, in order, their primary, secondary, and 2527 // tertiary opcode. Only the opcode sections which a particular instruction 2528 // needs for encoding need to be specified. 2529 encode %{ 2530 enc_class enc_unimplemented %{ 2531 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2532 MacroAssembler _masm(&cbuf); 2533 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2534 %} 2535 2536 enc_class enc_untested %{ 2537 #ifdef ASSERT 2538 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2539 MacroAssembler _masm(&cbuf); 2540 __ untested("Untested mach node encoding in AD file."); 2541 #else 2542 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2543 #endif 2544 %} 2545 2546 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2547 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2548 MacroAssembler _masm(&cbuf); 2549 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2550 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2551 %} 2552 2553 // Load acquire. 2554 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2555 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2556 MacroAssembler _masm(&cbuf); 2557 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2558 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2559 __ twi_0($dst$$Register); 2560 __ isync(); 2561 %} 2562 2563 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2564 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2565 2566 MacroAssembler _masm(&cbuf); 2567 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2568 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2569 %} 2570 2571 // Load acquire. 2572 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2573 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2574 2575 MacroAssembler _masm(&cbuf); 2576 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2577 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2578 __ twi_0($dst$$Register); 2579 __ isync(); 2580 %} 2581 2582 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2583 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2584 2585 MacroAssembler _masm(&cbuf); 2586 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2587 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2588 %} 2589 2590 // Load acquire. 2591 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2592 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2593 2594 MacroAssembler _masm(&cbuf); 2595 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2596 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2597 __ twi_0($dst$$Register); 2598 __ isync(); 2599 %} 2600 2601 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2602 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2603 MacroAssembler _masm(&cbuf); 2604 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2605 // Operand 'ds' requires 4-alignment. 2606 assert((Idisp & 0x3) == 0, "unaligned offset"); 2607 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2608 %} 2609 2610 // Load acquire. 2611 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2612 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2613 MacroAssembler _masm(&cbuf); 2614 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2615 // Operand 'ds' requires 4-alignment. 2616 assert((Idisp & 0x3) == 0, "unaligned offset"); 2617 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2618 __ twi_0($dst$$Register); 2619 __ isync(); 2620 %} 2621 2622 enc_class enc_lfd(RegF dst, memory mem) %{ 2623 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2624 MacroAssembler _masm(&cbuf); 2625 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2626 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2627 %} 2628 2629 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2630 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2631 2632 MacroAssembler _masm(&cbuf); 2633 int toc_offset = 0; 2634 2635 address const_toc_addr; 2636 // Create a non-oop constant, no relocation needed. 2637 // If it is an IC, it has a virtual_call_Relocation. 2638 const_toc_addr = __ long_constant((jlong)$src$$constant); 2639 if (const_toc_addr == NULL) { 2640 ciEnv::current()->record_out_of_memory_failure(); 2641 return; 2642 } 2643 2644 // Get the constant's TOC offset. 2645 toc_offset = __ offset_to_method_toc(const_toc_addr); 2646 2647 // Keep the current instruction offset in mind. 2648 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2649 2650 __ ld($dst$$Register, toc_offset, $toc$$Register); 2651 %} 2652 2653 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2654 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2655 2656 MacroAssembler _masm(&cbuf); 2657 2658 if (!ra_->C->in_scratch_emit_size()) { 2659 address const_toc_addr; 2660 // Create a non-oop constant, no relocation needed. 2661 // If it is an IC, it has a virtual_call_Relocation. 2662 const_toc_addr = __ long_constant((jlong)$src$$constant); 2663 if (const_toc_addr == NULL) { 2664 ciEnv::current()->record_out_of_memory_failure(); 2665 return; 2666 } 2667 2668 // Get the constant's TOC offset. 2669 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2670 // Store the toc offset of the constant. 2671 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2672 2673 // Also keep the current instruction offset in mind. 2674 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2675 } 2676 2677 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2678 %} 2679 2680 %} // encode 2681 2682 source %{ 2683 2684 typedef struct { 2685 loadConL_hiNode *_large_hi; 2686 loadConL_loNode *_large_lo; 2687 loadConLNode *_small; 2688 MachNode *_last; 2689 } loadConLNodesTuple; 2690 2691 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2692 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2693 loadConLNodesTuple nodes; 2694 2695 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2696 if (large_constant_pool) { 2697 // Create new nodes. 2698 loadConL_hiNode *m1 = new loadConL_hiNode(); 2699 loadConL_loNode *m2 = new loadConL_loNode(); 2700 2701 // inputs for new nodes 2702 m1->add_req(NULL, toc); 2703 m2->add_req(NULL, m1); 2704 2705 // operands for new nodes 2706 m1->_opnds[0] = new iRegLdstOper(); // dst 2707 m1->_opnds[1] = immSrc; // src 2708 m1->_opnds[2] = new iRegPdstOper(); // toc 2709 m2->_opnds[0] = new iRegLdstOper(); // dst 2710 m2->_opnds[1] = immSrc; // src 2711 m2->_opnds[2] = new iRegLdstOper(); // base 2712 2713 // Initialize ins_attrib TOC fields. 2714 m1->_const_toc_offset = -1; 2715 m2->_const_toc_offset_hi_node = m1; 2716 2717 // Initialize ins_attrib instruction offset. 2718 m1->_cbuf_insts_offset = -1; 2719 2720 // register allocation for new nodes 2721 ra_->set_pair(m1->_idx, reg_second, reg_first); 2722 ra_->set_pair(m2->_idx, reg_second, reg_first); 2723 2724 // Create result. 2725 nodes._large_hi = m1; 2726 nodes._large_lo = m2; 2727 nodes._small = NULL; 2728 nodes._last = nodes._large_lo; 2729 assert(m2->bottom_type()->isa_long(), "must be long"); 2730 } else { 2731 loadConLNode *m2 = new loadConLNode(); 2732 2733 // inputs for new nodes 2734 m2->add_req(NULL, toc); 2735 2736 // operands for new nodes 2737 m2->_opnds[0] = new iRegLdstOper(); // dst 2738 m2->_opnds[1] = immSrc; // src 2739 m2->_opnds[2] = new iRegPdstOper(); // toc 2740 2741 // Initialize ins_attrib instruction offset. 2742 m2->_cbuf_insts_offset = -1; 2743 2744 // register allocation for new nodes 2745 ra_->set_pair(m2->_idx, reg_second, reg_first); 2746 2747 // Create result. 2748 nodes._large_hi = NULL; 2749 nodes._large_lo = NULL; 2750 nodes._small = m2; 2751 nodes._last = nodes._small; 2752 assert(m2->bottom_type()->isa_long(), "must be long"); 2753 } 2754 2755 return nodes; 2756 } 2757 2758 typedef struct { 2759 loadConL_hiNode *_large_hi; 2760 loadConL_loNode *_large_lo; 2761 mtvsrdNode *_moved; 2762 xxspltdNode *_replicated; 2763 loadConLNode *_small; 2764 MachNode *_last; 2765 } loadConLReplicatedNodesTuple; 2766 2767 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2768 vecXOper *dst, immI_0Oper *zero, 2769 OptoReg::Name reg_second, OptoReg::Name reg_first, 2770 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2771 loadConLReplicatedNodesTuple nodes; 2772 2773 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2774 if (large_constant_pool) { 2775 // Create new nodes. 2776 loadConL_hiNode *m1 = new loadConL_hiNode(); 2777 loadConL_loNode *m2 = new loadConL_loNode(); 2778 mtvsrdNode *m3 = new mtvsrdNode(); 2779 xxspltdNode *m4 = new xxspltdNode(); 2780 2781 // inputs for new nodes 2782 m1->add_req(NULL, toc); 2783 m2->add_req(NULL, m1); 2784 m3->add_req(NULL, m2); 2785 m4->add_req(NULL, m3); 2786 2787 // operands for new nodes 2788 m1->_opnds[0] = new iRegLdstOper(); // dst 2789 m1->_opnds[1] = immSrc; // src 2790 m1->_opnds[2] = new iRegPdstOper(); // toc 2791 2792 m2->_opnds[0] = new iRegLdstOper(); // dst 2793 m2->_opnds[1] = immSrc; // src 2794 m2->_opnds[2] = new iRegLdstOper(); // base 2795 2796 m3->_opnds[0] = new vecXOper(); // dst 2797 m3->_opnds[1] = new iRegLdstOper(); // src 2798 2799 m4->_opnds[0] = new vecXOper(); // dst 2800 m4->_opnds[1] = new vecXOper(); // src 2801 m4->_opnds[2] = zero; 2802 2803 // Initialize ins_attrib TOC fields. 2804 m1->_const_toc_offset = -1; 2805 m2->_const_toc_offset_hi_node = m1; 2806 2807 // Initialize ins_attrib instruction offset. 2808 m1->_cbuf_insts_offset = -1; 2809 2810 // register allocation for new nodes 2811 ra_->set_pair(m1->_idx, reg_second, reg_first); 2812 ra_->set_pair(m2->_idx, reg_second, reg_first); 2813 ra_->set1(m3->_idx, reg_second); 2814 ra_->set2(m3->_idx, reg_vec_first); 2815 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2816 2817 // Create result. 2818 nodes._large_hi = m1; 2819 nodes._large_lo = m2; 2820 nodes._moved = m3; 2821 nodes._replicated = m4; 2822 nodes._small = NULL; 2823 nodes._last = nodes._replicated; 2824 assert(m2->bottom_type()->isa_long(), "must be long"); 2825 } else { 2826 loadConLNode *m2 = new loadConLNode(); 2827 mtvsrdNode *m3 = new mtvsrdNode(); 2828 xxspltdNode *m4 = new xxspltdNode(); 2829 2830 // inputs for new nodes 2831 m2->add_req(NULL, toc); 2832 2833 // operands for new nodes 2834 m2->_opnds[0] = new iRegLdstOper(); // dst 2835 m2->_opnds[1] = immSrc; // src 2836 m2->_opnds[2] = new iRegPdstOper(); // toc 2837 2838 m3->_opnds[0] = new vecXOper(); // dst 2839 m3->_opnds[1] = new iRegLdstOper(); // src 2840 2841 m4->_opnds[0] = new vecXOper(); // dst 2842 m4->_opnds[1] = new vecXOper(); // src 2843 m4->_opnds[2] = zero; 2844 2845 // Initialize ins_attrib instruction offset. 2846 m2->_cbuf_insts_offset = -1; 2847 ra_->set1(m3->_idx, reg_second); 2848 ra_->set2(m3->_idx, reg_vec_first); 2849 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2850 2851 // register allocation for new nodes 2852 ra_->set_pair(m2->_idx, reg_second, reg_first); 2853 2854 // Create result. 2855 nodes._large_hi = NULL; 2856 nodes._large_lo = NULL; 2857 nodes._small = m2; 2858 nodes._moved = m3; 2859 nodes._replicated = m4; 2860 nodes._last = nodes._replicated; 2861 assert(m2->bottom_type()->isa_long(), "must be long"); 2862 } 2863 2864 return nodes; 2865 } 2866 2867 %} // source 2868 2869 encode %{ 2870 // Postalloc expand emitter for loading a long constant from the method's TOC. 2871 // Enc_class needed as consttanttablebase is not supported by postalloc 2872 // expand. 2873 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2874 // Create new nodes. 2875 loadConLNodesTuple loadConLNodes = 2876 loadConLNodesTuple_create(ra_, n_toc, op_src, 2877 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2878 2879 // Push new nodes. 2880 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2881 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2882 2883 // some asserts 2884 assert(nodes->length() >= 1, "must have created at least 1 node"); 2885 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2886 %} 2887 2888 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2889 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2890 2891 MacroAssembler _masm(&cbuf); 2892 int toc_offset = 0; 2893 2894 intptr_t val = $src$$constant; 2895 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2896 address const_toc_addr; 2897 if (constant_reloc == relocInfo::oop_type) { 2898 // Create an oop constant and a corresponding relocation. 2899 AddressLiteral a = __ allocate_oop_address((jobject)val); 2900 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2901 __ relocate(a.rspec()); 2902 } else if (constant_reloc == relocInfo::metadata_type) { 2903 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2904 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2905 __ relocate(a.rspec()); 2906 } else { 2907 // Create a non-oop constant, no relocation needed. 2908 const_toc_addr = __ long_constant((jlong)$src$$constant); 2909 } 2910 2911 if (const_toc_addr == NULL) { 2912 ciEnv::current()->record_out_of_memory_failure(); 2913 return; 2914 } 2915 // Get the constant's TOC offset. 2916 toc_offset = __ offset_to_method_toc(const_toc_addr); 2917 2918 __ ld($dst$$Register, toc_offset, $toc$$Register); 2919 %} 2920 2921 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2922 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2923 2924 MacroAssembler _masm(&cbuf); 2925 if (!ra_->C->in_scratch_emit_size()) { 2926 intptr_t val = $src$$constant; 2927 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2928 address const_toc_addr; 2929 if (constant_reloc == relocInfo::oop_type) { 2930 // Create an oop constant and a corresponding relocation. 2931 AddressLiteral a = __ allocate_oop_address((jobject)val); 2932 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2933 __ relocate(a.rspec()); 2934 } else if (constant_reloc == relocInfo::metadata_type) { 2935 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2936 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2937 __ relocate(a.rspec()); 2938 } else { // non-oop pointers, e.g. card mark base, heap top 2939 // Create a non-oop constant, no relocation needed. 2940 const_toc_addr = __ long_constant((jlong)$src$$constant); 2941 } 2942 2943 if (const_toc_addr == NULL) { 2944 ciEnv::current()->record_out_of_memory_failure(); 2945 return; 2946 } 2947 // Get the constant's TOC offset. 2948 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2949 // Store the toc offset of the constant. 2950 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 2951 } 2952 2953 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2954 %} 2955 2956 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 2957 // Enc_class needed as consttanttablebase is not supported by postalloc 2958 // expand. 2959 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 2960 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2961 if (large_constant_pool) { 2962 // Create new nodes. 2963 loadConP_hiNode *m1 = new loadConP_hiNode(); 2964 loadConP_loNode *m2 = new loadConP_loNode(); 2965 2966 // inputs for new nodes 2967 m1->add_req(NULL, n_toc); 2968 m2->add_req(NULL, m1); 2969 2970 // operands for new nodes 2971 m1->_opnds[0] = new iRegPdstOper(); // dst 2972 m1->_opnds[1] = op_src; // src 2973 m1->_opnds[2] = new iRegPdstOper(); // toc 2974 m2->_opnds[0] = new iRegPdstOper(); // dst 2975 m2->_opnds[1] = op_src; // src 2976 m2->_opnds[2] = new iRegLdstOper(); // base 2977 2978 // Initialize ins_attrib TOC fields. 2979 m1->_const_toc_offset = -1; 2980 m2->_const_toc_offset_hi_node = m1; 2981 2982 // Register allocation for new nodes. 2983 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2984 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2985 2986 nodes->push(m1); 2987 nodes->push(m2); 2988 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2989 } else { 2990 loadConPNode *m2 = new loadConPNode(); 2991 2992 // inputs for new nodes 2993 m2->add_req(NULL, n_toc); 2994 2995 // operands for new nodes 2996 m2->_opnds[0] = new iRegPdstOper(); // dst 2997 m2->_opnds[1] = op_src; // src 2998 m2->_opnds[2] = new iRegPdstOper(); // toc 2999 3000 // Register allocation for new nodes. 3001 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3002 3003 nodes->push(m2); 3004 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3005 } 3006 %} 3007 3008 // Enc_class needed as consttanttablebase is not supported by postalloc 3009 // expand. 3010 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3011 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3012 3013 MachNode *m2; 3014 if (large_constant_pool) { 3015 m2 = new loadConFCompNode(); 3016 } else { 3017 m2 = new loadConFNode(); 3018 } 3019 // inputs for new nodes 3020 m2->add_req(NULL, n_toc); 3021 3022 // operands for new nodes 3023 m2->_opnds[0] = op_dst; 3024 m2->_opnds[1] = op_src; 3025 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3026 3027 // register allocation for new nodes 3028 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3029 nodes->push(m2); 3030 %} 3031 3032 // Enc_class needed as consttanttablebase is not supported by postalloc 3033 // expand. 3034 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3035 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3036 3037 MachNode *m2; 3038 if (large_constant_pool) { 3039 m2 = new loadConDCompNode(); 3040 } else { 3041 m2 = new loadConDNode(); 3042 } 3043 // inputs for new nodes 3044 m2->add_req(NULL, n_toc); 3045 3046 // operands for new nodes 3047 m2->_opnds[0] = op_dst; 3048 m2->_opnds[1] = op_src; 3049 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3050 3051 // register allocation for new nodes 3052 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3053 nodes->push(m2); 3054 %} 3055 3056 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3057 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3058 MacroAssembler _masm(&cbuf); 3059 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3060 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3061 %} 3062 3063 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3064 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3065 MacroAssembler _masm(&cbuf); 3066 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3067 // Operand 'ds' requires 4-alignment. 3068 assert((Idisp & 0x3) == 0, "unaligned offset"); 3069 __ std($src$$Register, Idisp, $mem$$base$$Register); 3070 %} 3071 3072 enc_class enc_stfs(RegF src, memory mem) %{ 3073 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3074 MacroAssembler _masm(&cbuf); 3075 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3076 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3077 %} 3078 3079 enc_class enc_stfd(RegF src, memory mem) %{ 3080 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3081 MacroAssembler _masm(&cbuf); 3082 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3083 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3084 %} 3085 3086 // Use release_store for card-marking to ensure that previous 3087 // oop-stores are visible before the card-mark change. 3088 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3089 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3090 // FIXME: Implement this as a cmove and use a fixed condition code 3091 // register which is written on every transition to compiled code, 3092 // e.g. in call-stub and when returning from runtime stubs. 3093 // 3094 // Proposed code sequence for the cmove implementation: 3095 // 3096 // Label skip_release; 3097 // __ beq(CCRfixed, skip_release); 3098 // __ release(); 3099 // __ bind(skip_release); 3100 // __ stb(card mark); 3101 3102 MacroAssembler _masm(&cbuf); 3103 Label skip_storestore; 3104 3105 #if 0 // TODO: PPC port 3106 // Check CMSCollectorCardTableModRefBSExt::_requires_release and do the 3107 // StoreStore barrier conditionally. 3108 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3109 __ cmpwi($crx$$CondRegister, R0, 0); 3110 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3111 #endif 3112 __ li(R0, 0); 3113 __ membar(Assembler::StoreStore); 3114 #if 0 // TODO: PPC port 3115 __ bind(skip_storestore); 3116 #endif 3117 3118 // Do the store. 3119 if ($mem$$index == 0) { 3120 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3121 } else { 3122 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3123 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3124 } 3125 %} 3126 3127 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3128 3129 if (VM_Version::has_isel()) { 3130 // use isel instruction with Power 7 3131 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3132 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3133 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3134 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3135 3136 n_compare->add_req(n_region, n_src); 3137 n_compare->_opnds[0] = op_crx; 3138 n_compare->_opnds[1] = op_src; 3139 n_compare->_opnds[2] = new immL16Oper(0); 3140 3141 n_sub_base->add_req(n_region, n_src); 3142 n_sub_base->_opnds[0] = op_dst; 3143 n_sub_base->_opnds[1] = op_src; 3144 n_sub_base->_bottom_type = _bottom_type; 3145 3146 n_shift->add_req(n_region, n_sub_base); 3147 n_shift->_opnds[0] = op_dst; 3148 n_shift->_opnds[1] = op_dst; 3149 n_shift->_bottom_type = _bottom_type; 3150 3151 n_cond_set->add_req(n_region, n_compare, n_shift); 3152 n_cond_set->_opnds[0] = op_dst; 3153 n_cond_set->_opnds[1] = op_crx; 3154 n_cond_set->_opnds[2] = op_dst; 3155 n_cond_set->_bottom_type = _bottom_type; 3156 3157 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3158 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3159 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3160 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3161 3162 nodes->push(n_compare); 3163 nodes->push(n_sub_base); 3164 nodes->push(n_shift); 3165 nodes->push(n_cond_set); 3166 3167 } else { 3168 // before Power 7 3169 moveRegNode *n_move = new moveRegNode(); 3170 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3171 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3172 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3173 3174 n_move->add_req(n_region, n_src); 3175 n_move->_opnds[0] = op_dst; 3176 n_move->_opnds[1] = op_src; 3177 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3178 3179 n_compare->add_req(n_region, n_src); 3180 n_compare->add_prec(n_move); 3181 3182 n_compare->_opnds[0] = op_crx; 3183 n_compare->_opnds[1] = op_src; 3184 n_compare->_opnds[2] = new immL16Oper(0); 3185 3186 n_sub_base->add_req(n_region, n_compare, n_src); 3187 n_sub_base->_opnds[0] = op_dst; 3188 n_sub_base->_opnds[1] = op_crx; 3189 n_sub_base->_opnds[2] = op_src; 3190 n_sub_base->_bottom_type = _bottom_type; 3191 3192 n_shift->add_req(n_region, n_sub_base); 3193 n_shift->_opnds[0] = op_dst; 3194 n_shift->_opnds[1] = op_dst; 3195 n_shift->_bottom_type = _bottom_type; 3196 3197 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3198 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3199 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3200 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3201 3202 nodes->push(n_move); 3203 nodes->push(n_compare); 3204 nodes->push(n_sub_base); 3205 nodes->push(n_shift); 3206 } 3207 3208 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3209 %} 3210 3211 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3212 3213 encodeP_subNode *n1 = new encodeP_subNode(); 3214 n1->add_req(n_region, n_src); 3215 n1->_opnds[0] = op_dst; 3216 n1->_opnds[1] = op_src; 3217 n1->_bottom_type = _bottom_type; 3218 3219 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3220 n2->add_req(n_region, n1); 3221 n2->_opnds[0] = op_dst; 3222 n2->_opnds[1] = op_dst; 3223 n2->_bottom_type = _bottom_type; 3224 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3225 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3226 3227 nodes->push(n1); 3228 nodes->push(n2); 3229 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3230 %} 3231 3232 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3233 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3234 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3235 3236 n_compare->add_req(n_region, n_src); 3237 n_compare->_opnds[0] = op_crx; 3238 n_compare->_opnds[1] = op_src; 3239 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3240 3241 n_shift->add_req(n_region, n_src); 3242 n_shift->_opnds[0] = op_dst; 3243 n_shift->_opnds[1] = op_src; 3244 n_shift->_bottom_type = _bottom_type; 3245 3246 if (VM_Version::has_isel()) { 3247 // use isel instruction with Power 7 3248 3249 decodeN_addNode *n_add_base = new decodeN_addNode(); 3250 n_add_base->add_req(n_region, n_shift); 3251 n_add_base->_opnds[0] = op_dst; 3252 n_add_base->_opnds[1] = op_dst; 3253 n_add_base->_bottom_type = _bottom_type; 3254 3255 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3256 n_cond_set->add_req(n_region, n_compare, n_add_base); 3257 n_cond_set->_opnds[0] = op_dst; 3258 n_cond_set->_opnds[1] = op_crx; 3259 n_cond_set->_opnds[2] = op_dst; 3260 n_cond_set->_bottom_type = _bottom_type; 3261 3262 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3263 ra_->set_oop(n_cond_set, true); 3264 3265 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3266 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3267 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3268 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3269 3270 nodes->push(n_compare); 3271 nodes->push(n_shift); 3272 nodes->push(n_add_base); 3273 nodes->push(n_cond_set); 3274 3275 } else { 3276 // before Power 7 3277 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3278 3279 n_add_base->add_req(n_region, n_compare, n_shift); 3280 n_add_base->_opnds[0] = op_dst; 3281 n_add_base->_opnds[1] = op_crx; 3282 n_add_base->_opnds[2] = op_dst; 3283 n_add_base->_bottom_type = _bottom_type; 3284 3285 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3286 ra_->set_oop(n_add_base, true); 3287 3288 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3289 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3290 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3291 3292 nodes->push(n_compare); 3293 nodes->push(n_shift); 3294 nodes->push(n_add_base); 3295 } 3296 %} 3297 3298 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3299 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3300 n1->add_req(n_region, n_src); 3301 n1->_opnds[0] = op_dst; 3302 n1->_opnds[1] = op_src; 3303 n1->_bottom_type = _bottom_type; 3304 3305 decodeN_addNode *n2 = new decodeN_addNode(); 3306 n2->add_req(n_region, n1); 3307 n2->_opnds[0] = op_dst; 3308 n2->_opnds[1] = op_dst; 3309 n2->_bottom_type = _bottom_type; 3310 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3311 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3312 3313 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3314 ra_->set_oop(n2, true); 3315 3316 nodes->push(n1); 3317 nodes->push(n2); 3318 %} 3319 3320 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3321 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3322 3323 MacroAssembler _masm(&cbuf); 3324 int cc = $cmp$$cmpcode; 3325 int flags_reg = $crx$$reg; 3326 Label done; 3327 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3328 // Branch if not (cmp crx). 3329 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3330 __ mr($dst$$Register, $src$$Register); 3331 // TODO PPC port __ endgroup_if_needed(_size == 12); 3332 __ bind(done); 3333 %} 3334 3335 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3336 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3337 3338 MacroAssembler _masm(&cbuf); 3339 Label done; 3340 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3341 // Branch if not (cmp crx). 3342 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3343 __ li($dst$$Register, $src$$constant); 3344 // TODO PPC port __ endgroup_if_needed(_size == 12); 3345 __ bind(done); 3346 %} 3347 3348 // This enc_class is needed so that scheduler gets proper 3349 // input mapping for latency computation. 3350 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3351 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3352 MacroAssembler _masm(&cbuf); 3353 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3354 %} 3355 3356 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3357 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3358 3359 MacroAssembler _masm(&cbuf); 3360 3361 Label done; 3362 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3363 __ li($dst$$Register, $zero$$constant); 3364 __ beq($crx$$CondRegister, done); 3365 __ li($dst$$Register, $notzero$$constant); 3366 __ bind(done); 3367 %} 3368 3369 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3370 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3371 3372 MacroAssembler _masm(&cbuf); 3373 3374 Label done; 3375 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3376 __ li($dst$$Register, $zero$$constant); 3377 __ beq($crx$$CondRegister, done); 3378 __ li($dst$$Register, $notzero$$constant); 3379 __ bind(done); 3380 %} 3381 3382 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3383 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3384 3385 MacroAssembler _masm(&cbuf); 3386 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3387 Label done; 3388 __ bso($crx$$CondRegister, done); 3389 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3390 // TODO PPC port __ endgroup_if_needed(_size == 12); 3391 __ bind(done); 3392 %} 3393 3394 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3395 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3396 3397 MacroAssembler _masm(&cbuf); 3398 Label done; 3399 __ bso($crx$$CondRegister, done); 3400 __ mffprd($dst$$Register, $src$$FloatRegister); 3401 // TODO PPC port __ endgroup_if_needed(_size == 12); 3402 __ bind(done); 3403 %} 3404 3405 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3406 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3407 3408 MacroAssembler _masm(&cbuf); 3409 Label d; // dummy 3410 __ bind(d); 3411 Label* p = ($lbl$$label); 3412 // `p' is `NULL' when this encoding class is used only to 3413 // determine the size of the encoded instruction. 3414 Label& l = (NULL == p)? d : *(p); 3415 int cc = $cmp$$cmpcode; 3416 int flags_reg = $crx$$reg; 3417 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3418 int bhint = Assembler::bhintNoHint; 3419 3420 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3421 if (_prob <= PROB_NEVER) { 3422 bhint = Assembler::bhintIsNotTaken; 3423 } else if (_prob >= PROB_ALWAYS) { 3424 bhint = Assembler::bhintIsTaken; 3425 } 3426 } 3427 3428 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3429 cc_to_biint(cc, flags_reg), 3430 l); 3431 %} 3432 3433 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3434 // The scheduler doesn't know about branch shortening, so we set the opcode 3435 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3436 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3437 3438 MacroAssembler _masm(&cbuf); 3439 Label d; // dummy 3440 __ bind(d); 3441 Label* p = ($lbl$$label); 3442 // `p' is `NULL' when this encoding class is used only to 3443 // determine the size of the encoded instruction. 3444 Label& l = (NULL == p)? d : *(p); 3445 int cc = $cmp$$cmpcode; 3446 int flags_reg = $crx$$reg; 3447 int bhint = Assembler::bhintNoHint; 3448 3449 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3450 if (_prob <= PROB_NEVER) { 3451 bhint = Assembler::bhintIsNotTaken; 3452 } else if (_prob >= PROB_ALWAYS) { 3453 bhint = Assembler::bhintIsTaken; 3454 } 3455 } 3456 3457 // Tell the conditional far branch to optimize itself when being relocated. 3458 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3459 cc_to_biint(cc, flags_reg), 3460 l, 3461 MacroAssembler::bc_far_optimize_on_relocate); 3462 %} 3463 3464 // Branch used with Power6 scheduling (can be shortened without changing the node). 3465 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3466 // The scheduler doesn't know about branch shortening, so we set the opcode 3467 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3468 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3469 3470 MacroAssembler _masm(&cbuf); 3471 Label d; // dummy 3472 __ bind(d); 3473 Label* p = ($lbl$$label); 3474 // `p' is `NULL' when this encoding class is used only to 3475 // determine the size of the encoded instruction. 3476 Label& l = (NULL == p)? d : *(p); 3477 int cc = $cmp$$cmpcode; 3478 int flags_reg = $crx$$reg; 3479 int bhint = Assembler::bhintNoHint; 3480 3481 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3482 if (_prob <= PROB_NEVER) { 3483 bhint = Assembler::bhintIsNotTaken; 3484 } else if (_prob >= PROB_ALWAYS) { 3485 bhint = Assembler::bhintIsTaken; 3486 } 3487 } 3488 3489 #if 0 // TODO: PPC port 3490 if (_size == 8) { 3491 // Tell the conditional far branch to optimize itself when being relocated. 3492 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3493 cc_to_biint(cc, flags_reg), 3494 l, 3495 MacroAssembler::bc_far_optimize_on_relocate); 3496 } else { 3497 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3498 cc_to_biint(cc, flags_reg), 3499 l); 3500 } 3501 #endif 3502 Unimplemented(); 3503 %} 3504 3505 // Postalloc expand emitter for loading a replicatef float constant from 3506 // the method's TOC. 3507 // Enc_class needed as consttanttablebase is not supported by postalloc 3508 // expand. 3509 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3510 // Create new nodes. 3511 3512 // Make an operand with the bit pattern to load as float. 3513 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3514 3515 loadConLNodesTuple loadConLNodes = 3516 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3517 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3518 3519 // Push new nodes. 3520 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3521 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3522 3523 assert(nodes->length() >= 1, "must have created at least 1 node"); 3524 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3525 %} 3526 3527 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc) %{ 3528 // Create new nodes. 3529 3530 // Make an operand with the bit pattern to load as float. 3531 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3532 immI_0Oper *op_zero = new immI_0Oper(0); 3533 3534 loadConLReplicatedNodesTuple loadConLNodes = 3535 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3536 OptoReg::Name(R20_H_num), OptoReg::Name(R20_num), 3537 OptoReg::Name(VSR11_num), OptoReg::Name(VSR10_num)); 3538 3539 // Push new nodes. 3540 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3541 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3542 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3543 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3544 3545 assert(nodes->length() >= 1, "must have created at least 1 node"); 3546 %} 3547 3548 // This enc_class is needed so that scheduler gets proper 3549 // input mapping for latency computation. 3550 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3551 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3552 // Fake operand dst needed for PPC scheduler. 3553 assert($dst$$constant == 0x0, "dst must be 0x0"); 3554 3555 MacroAssembler _masm(&cbuf); 3556 // Mark the code position where the load from the safepoint 3557 // polling page was emitted as relocInfo::poll_type. 3558 __ relocate(relocInfo::poll_type); 3559 __ load_from_polling_page($poll$$Register); 3560 %} 3561 3562 // A Java static call or a runtime call. 3563 // 3564 // Branch-and-link relative to a trampoline. 3565 // The trampoline loads the target address and does a long branch to there. 3566 // In case we call java, the trampoline branches to a interpreter_stub 3567 // which loads the inline cache and the real call target from the constant pool. 3568 // 3569 // This basically looks like this: 3570 // 3571 // >>>> consts -+ -+ 3572 // | |- offset1 3573 // [call target1] | <-+ 3574 // [IC cache] |- offset2 3575 // [call target2] <--+ 3576 // 3577 // <<<< consts 3578 // >>>> insts 3579 // 3580 // bl offset16 -+ -+ ??? // How many bits available? 3581 // | | 3582 // <<<< insts | | 3583 // >>>> stubs | | 3584 // | |- trampoline_stub_Reloc 3585 // trampoline stub: | <-+ 3586 // r2 = toc | 3587 // r2 = [r2 + offset1] | // Load call target1 from const section 3588 // mtctr r2 | 3589 // bctr |- static_stub_Reloc 3590 // comp_to_interp_stub: <---+ 3591 // r1 = toc 3592 // ICreg = [r1 + IC_offset] // Load IC from const section 3593 // r1 = [r1 + offset2] // Load call target2 from const section 3594 // mtctr r1 3595 // bctr 3596 // 3597 // <<<< stubs 3598 // 3599 // The call instruction in the code either 3600 // - Branches directly to a compiled method if the offset is encodable in instruction. 3601 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3602 // - Branches to the compiled_to_interp stub if the target is interpreted. 3603 // 3604 // Further there are three relocations from the loads to the constants in 3605 // the constant section. 3606 // 3607 // Usage of r1 and r2 in the stubs allows to distinguish them. 3608 enc_class enc_java_static_call(method meth) %{ 3609 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3610 3611 MacroAssembler _masm(&cbuf); 3612 address entry_point = (address)$meth$$method; 3613 3614 if (!_method) { 3615 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3616 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3617 } else { 3618 // Remember the offset not the address. 3619 const int start_offset = __ offset(); 3620 3621 // The trampoline stub. 3622 // No entry point given, use the current pc. 3623 // Make sure branch fits into 3624 if (entry_point == 0) entry_point = __ pc(); 3625 3626 // Put the entry point as a constant into the constant pool. 3627 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3628 if (entry_point_toc_addr == NULL) { 3629 ciEnv::current()->record_out_of_memory_failure(); 3630 return; 3631 } 3632 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3633 3634 // Emit the trampoline stub which will be related to the branch-and-link below. 3635 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3636 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3637 int method_index = resolved_method_index(cbuf); 3638 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3639 : static_call_Relocation::spec(method_index)); 3640 3641 // The real call. 3642 // Note: At this point we do not have the address of the trampoline 3643 // stub, and the entry point might be too far away for bl, so __ pc() 3644 // serves as dummy and the bl will be patched later. 3645 cbuf.set_insts_mark(); 3646 __ bl(__ pc()); // Emits a relocation. 3647 3648 // The stub for call to interpreter. 3649 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3650 if (stub == NULL) { 3651 ciEnv::current()->record_failure("CodeCache is full"); 3652 return; 3653 } 3654 } 3655 %} 3656 3657 // Second node of expanded dynamic call - the call. 3658 enc_class enc_java_dynamic_call_sched(method meth) %{ 3659 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3660 3661 MacroAssembler _masm(&cbuf); 3662 3663 if (!ra_->C->in_scratch_emit_size()) { 3664 // Create a call trampoline stub for the given method. 3665 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3666 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3667 if (entry_point_const == NULL) { 3668 ciEnv::current()->record_out_of_memory_failure(); 3669 return; 3670 } 3671 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3672 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3673 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3674 3675 // Build relocation at call site with ic position as data. 3676 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3677 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3678 "must have one, but can't have both"); 3679 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3680 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3681 "must contain instruction offset"); 3682 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3683 ? _load_ic_hi_node->_cbuf_insts_offset 3684 : _load_ic_node->_cbuf_insts_offset; 3685 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3686 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3687 "should be load from TOC"); 3688 int method_index = resolved_method_index(cbuf); 3689 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3690 } 3691 3692 // At this point I do not have the address of the trampoline stub, 3693 // and the entry point might be too far away for bl. Pc() serves 3694 // as dummy and bl will be patched later. 3695 __ bl((address) __ pc()); 3696 %} 3697 3698 // postalloc expand emitter for virtual calls. 3699 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3700 3701 // Create the nodes for loading the IC from the TOC. 3702 loadConLNodesTuple loadConLNodes_IC = 3703 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3704 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3705 3706 // Create the call node. 3707 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3708 call->_method_handle_invoke = _method_handle_invoke; 3709 call->_vtable_index = _vtable_index; 3710 call->_method = _method; 3711 call->_bci = _bci; 3712 call->_optimized_virtual = _optimized_virtual; 3713 call->_tf = _tf; 3714 call->_entry_point = _entry_point; 3715 call->_cnt = _cnt; 3716 call->_argsize = _argsize; 3717 call->_oop_map = _oop_map; 3718 call->_jvms = _jvms; 3719 call->_jvmadj = _jvmadj; 3720 call->_in_rms = _in_rms; 3721 call->_nesting = _nesting; 3722 call->_override_symbolic_info = _override_symbolic_info; 3723 3724 // New call needs all inputs of old call. 3725 // Req... 3726 for (uint i = 0; i < req(); ++i) { 3727 // The expanded node does not need toc any more. 3728 // Add the inline cache constant here instead. This expresses the 3729 // register of the inline cache must be live at the call. 3730 // Else we would have to adapt JVMState by -1. 3731 if (i == mach_constant_base_node_input()) { 3732 call->add_req(loadConLNodes_IC._last); 3733 } else { 3734 call->add_req(in(i)); 3735 } 3736 } 3737 // ...as well as prec 3738 for (uint i = req(); i < len(); ++i) { 3739 call->add_prec(in(i)); 3740 } 3741 3742 // Remember nodes loading the inline cache into r19. 3743 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3744 call->_load_ic_node = loadConLNodes_IC._small; 3745 3746 // Operands for new nodes. 3747 call->_opnds[0] = _opnds[0]; 3748 call->_opnds[1] = _opnds[1]; 3749 3750 // Only the inline cache is associated with a register. 3751 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3752 3753 // Push new nodes. 3754 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3755 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3756 nodes->push(call); 3757 %} 3758 3759 // Compound version of call dynamic 3760 // Toc is only passed so that it can be used in ins_encode statement. 3761 // In the code we have to use $constanttablebase. 3762 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3763 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3764 MacroAssembler _masm(&cbuf); 3765 int start_offset = __ offset(); 3766 3767 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3768 #if 0 3769 int vtable_index = this->_vtable_index; 3770 if (_vtable_index < 0) { 3771 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3772 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3773 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3774 3775 // Virtual call relocation will point to ic load. 3776 address virtual_call_meta_addr = __ pc(); 3777 // Load a clear inline cache. 3778 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3779 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3780 if (!success) { 3781 ciEnv::current()->record_out_of_memory_failure(); 3782 return; 3783 } 3784 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3785 // to determine who we intended to call. 3786 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3787 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3788 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3789 "Fix constant in ret_addr_offset()"); 3790 } else { 3791 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3792 // Go thru the vtable. Get receiver klass. Receiver already 3793 // checked for non-null. If we'll go thru a C2I adapter, the 3794 // interpreter expects method in R19_method. 3795 3796 __ load_klass(R11_scratch1, R3); 3797 3798 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3799 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3800 __ li(R19_method, v_off); 3801 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3802 // NOTE: for vtable dispatches, the vtable entry will never be 3803 // null. However it may very well end up in handle_wrong_method 3804 // if the method is abstract for the particular class. 3805 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3806 // Call target. Either compiled code or C2I adapter. 3807 __ mtctr(R11_scratch1); 3808 __ bctrl(); 3809 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3810 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3811 } 3812 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3813 "Fix constant in ret_addr_offset()"); 3814 } 3815 #endif 3816 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3817 %} 3818 3819 // a runtime call 3820 enc_class enc_java_to_runtime_call (method meth) %{ 3821 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3822 3823 MacroAssembler _masm(&cbuf); 3824 const address start_pc = __ pc(); 3825 3826 #if defined(ABI_ELFv2) 3827 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3828 __ call_c(entry, relocInfo::runtime_call_type); 3829 #else 3830 // The function we're going to call. 3831 FunctionDescriptor fdtemp; 3832 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3833 3834 Register Rtoc = R12_scratch2; 3835 // Calculate the method's TOC. 3836 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3837 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3838 // pool entries; call_c_using_toc will optimize the call. 3839 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3840 if (!success) { 3841 ciEnv::current()->record_out_of_memory_failure(); 3842 return; 3843 } 3844 #endif 3845 3846 // Check the ret_addr_offset. 3847 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3848 "Fix constant in ret_addr_offset()"); 3849 %} 3850 3851 // Move to ctr for leaf call. 3852 // This enc_class is needed so that scheduler gets proper 3853 // input mapping for latency computation. 3854 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3855 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3856 MacroAssembler _masm(&cbuf); 3857 __ mtctr($src$$Register); 3858 %} 3859 3860 // Postalloc expand emitter for runtime leaf calls. 3861 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3862 loadConLNodesTuple loadConLNodes_Entry; 3863 #if defined(ABI_ELFv2) 3864 jlong entry_address = (jlong) this->entry_point(); 3865 assert(entry_address, "need address here"); 3866 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3867 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3868 #else 3869 // Get the struct that describes the function we are about to call. 3870 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3871 assert(fd, "need fd here"); 3872 jlong entry_address = (jlong) fd->entry(); 3873 // new nodes 3874 loadConLNodesTuple loadConLNodes_Env; 3875 loadConLNodesTuple loadConLNodes_Toc; 3876 3877 // Create nodes and operands for loading the entry point. 3878 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3879 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3880 3881 3882 // Create nodes and operands for loading the env pointer. 3883 if (fd->env() != NULL) { 3884 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3885 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3886 } else { 3887 loadConLNodes_Env._large_hi = NULL; 3888 loadConLNodes_Env._large_lo = NULL; 3889 loadConLNodes_Env._small = NULL; 3890 loadConLNodes_Env._last = new loadConL16Node(); 3891 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3892 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3893 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3894 } 3895 3896 // Create nodes and operands for loading the Toc point. 3897 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3898 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3899 #endif // ABI_ELFv2 3900 // mtctr node 3901 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3902 3903 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3904 mtctr->add_req(0, loadConLNodes_Entry._last); 3905 3906 mtctr->_opnds[0] = new iRegLdstOper(); 3907 mtctr->_opnds[1] = new iRegLdstOper(); 3908 3909 // call node 3910 MachCallLeafNode *call = new CallLeafDirectNode(); 3911 3912 call->_opnds[0] = _opnds[0]; 3913 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3914 3915 // Make the new call node look like the old one. 3916 call->_name = _name; 3917 call->_tf = _tf; 3918 call->_entry_point = _entry_point; 3919 call->_cnt = _cnt; 3920 call->_argsize = _argsize; 3921 call->_oop_map = _oop_map; 3922 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3923 call->_jvms = NULL; 3924 call->_jvmadj = _jvmadj; 3925 call->_in_rms = _in_rms; 3926 call->_nesting = _nesting; 3927 3928 3929 // New call needs all inputs of old call. 3930 // Req... 3931 for (uint i = 0; i < req(); ++i) { 3932 if (i != mach_constant_base_node_input()) { 3933 call->add_req(in(i)); 3934 } 3935 } 3936 3937 // These must be reqired edges, as the registers are live up to 3938 // the call. Else the constants are handled as kills. 3939 call->add_req(mtctr); 3940 #if !defined(ABI_ELFv2) 3941 call->add_req(loadConLNodes_Env._last); 3942 call->add_req(loadConLNodes_Toc._last); 3943 #endif 3944 3945 // ...as well as prec 3946 for (uint i = req(); i < len(); ++i) { 3947 call->add_prec(in(i)); 3948 } 3949 3950 // registers 3951 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 3952 3953 // Insert the new nodes. 3954 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 3955 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 3956 #if !defined(ABI_ELFv2) 3957 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 3958 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 3959 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 3960 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 3961 #endif 3962 nodes->push(mtctr); 3963 nodes->push(call); 3964 %} 3965 %} 3966 3967 //----------FRAME-------------------------------------------------------------- 3968 // Definition of frame structure and management information. 3969 3970 frame %{ 3971 // What direction does stack grow in (assumed to be same for native & Java). 3972 stack_direction(TOWARDS_LOW); 3973 3974 // These two registers define part of the calling convention between 3975 // compiled code and the interpreter. 3976 3977 // Inline Cache Register or method for I2C. 3978 inline_cache_reg(R19); // R19_method 3979 3980 // Method Oop Register when calling interpreter. 3981 interpreter_method_oop_reg(R19); // R19_method 3982 3983 // Optional: name the operand used by cisc-spilling to access 3984 // [stack_pointer + offset]. 3985 cisc_spilling_operand_name(indOffset); 3986 3987 // Number of stack slots consumed by a Monitor enter. 3988 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 3989 3990 // Compiled code's Frame Pointer. 3991 frame_pointer(R1); // R1_SP 3992 3993 // Interpreter stores its frame pointer in a register which is 3994 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 3995 // interpreted java to compiled java. 3996 // 3997 // R14_state holds pointer to caller's cInterpreter. 3998 interpreter_frame_pointer(R14); // R14_state 3999 4000 stack_alignment(frame::alignment_in_bytes); 4001 4002 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4003 4004 // Number of outgoing stack slots killed above the 4005 // out_preserve_stack_slots for calls to C. Supports the var-args 4006 // backing area for register parms. 4007 // 4008 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4009 4010 // The after-PROLOG location of the return address. Location of 4011 // return address specifies a type (REG or STACK) and a number 4012 // representing the register number (i.e. - use a register name) or 4013 // stack slot. 4014 // 4015 // A: Link register is stored in stack slot ... 4016 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4017 // J: Therefore, we make sure that the link register is also in R11_scratch1 4018 // at the end of the prolog. 4019 // B: We use R20, now. 4020 //return_addr(REG R20); 4021 4022 // G: After reading the comments made by all the luminaries on their 4023 // failure to tell the compiler where the return address really is, 4024 // I hardly dare to try myself. However, I'm convinced it's in slot 4025 // 4 what apparently works and saves us some spills. 4026 return_addr(STACK 4); 4027 4028 // This is the body of the function 4029 // 4030 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4031 // uint length, // length of array 4032 // bool is_outgoing) 4033 // 4034 // The `sig' array is to be updated. sig[j] represents the location 4035 // of the j-th argument, either a register or a stack slot. 4036 4037 // Comment taken from i486.ad: 4038 // Body of function which returns an integer array locating 4039 // arguments either in registers or in stack slots. Passed an array 4040 // of ideal registers called "sig" and a "length" count. Stack-slot 4041 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4042 // arguments for a CALLEE. Incoming stack arguments are 4043 // automatically biased by the preserve_stack_slots field above. 4044 calling_convention %{ 4045 // No difference between ingoing/outgoing. Just pass false. 4046 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4047 %} 4048 4049 // Comment taken from i486.ad: 4050 // Body of function which returns an integer array locating 4051 // arguments either in registers or in stack slots. Passed an array 4052 // of ideal registers called "sig" and a "length" count. Stack-slot 4053 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4054 // arguments for a CALLEE. Incoming stack arguments are 4055 // automatically biased by the preserve_stack_slots field above. 4056 c_calling_convention %{ 4057 // This is obviously always outgoing. 4058 // C argument in register AND stack slot. 4059 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4060 %} 4061 4062 // Location of native (C/C++) and interpreter return values. This 4063 // is specified to be the same as Java. In the 32-bit VM, long 4064 // values are actually returned from native calls in O0:O1 and 4065 // returned to the interpreter in I0:I1. The copying to and from 4066 // the register pairs is done by the appropriate call and epilog 4067 // opcodes. This simplifies the register allocator. 4068 c_return_value %{ 4069 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4070 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4071 "only return normal values"); 4072 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4073 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4074 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4075 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4076 %} 4077 4078 // Location of compiled Java return values. Same as C 4079 return_value %{ 4080 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4081 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4082 "only return normal values"); 4083 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4084 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4085 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4086 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4087 %} 4088 %} 4089 4090 4091 //----------ATTRIBUTES--------------------------------------------------------- 4092 4093 //----------Operand Attributes------------------------------------------------- 4094 op_attrib op_cost(1); // Required cost attribute. 4095 4096 //----------Instruction Attributes--------------------------------------------- 4097 4098 // Cost attribute. required. 4099 ins_attrib ins_cost(DEFAULT_COST); 4100 4101 // Is this instruction a non-matching short branch variant of some 4102 // long branch? Not required. 4103 ins_attrib ins_short_branch(0); 4104 4105 ins_attrib ins_is_TrapBasedCheckNode(true); 4106 4107 // Number of constants. 4108 // This instruction uses the given number of constants 4109 // (optional attribute). 4110 // This is needed to determine in time whether the constant pool will 4111 // exceed 4000 entries. Before postalloc_expand the overall number of constants 4112 // is determined. It's also used to compute the constant pool size 4113 // in Output(). 4114 ins_attrib ins_num_consts(0); 4115 4116 // Required alignment attribute (must be a power of 2) specifies the 4117 // alignment that some part of the instruction (not necessarily the 4118 // start) requires. If > 1, a compute_padding() function must be 4119 // provided for the instruction. 4120 ins_attrib ins_alignment(1); 4121 4122 // Enforce/prohibit rematerializations. 4123 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4124 // then rematerialization of that instruction is prohibited and the 4125 // instruction's value will be spilled if necessary. 4126 // Causes that MachNode::rematerialize() returns false. 4127 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 4128 // then rematerialization should be enforced and a copy of the instruction 4129 // should be inserted if possible; rematerialization is not guaranteed. 4130 // Note: this may result in rematerializations in front of every use. 4131 // Causes that MachNode::rematerialize() can return true. 4132 // (optional attribute) 4133 ins_attrib ins_cannot_rematerialize(false); 4134 ins_attrib ins_should_rematerialize(false); 4135 4136 // Instruction has variable size depending on alignment. 4137 ins_attrib ins_variable_size_depending_on_alignment(false); 4138 4139 // Instruction is a nop. 4140 ins_attrib ins_is_nop(false); 4141 4142 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4143 ins_attrib ins_use_mach_if_fast_lock_node(false); 4144 4145 // Field for the toc offset of a constant. 4146 // 4147 // This is needed if the toc offset is not encodable as an immediate in 4148 // the PPC load instruction. If so, the upper (hi) bits of the offset are 4149 // added to the toc, and from this a load with immediate is performed. 4150 // With postalloc expand, we get two nodes that require the same offset 4151 // but which don't know about each other. The offset is only known 4152 // when the constant is added to the constant pool during emitting. 4153 // It is generated in the 'hi'-node adding the upper bits, and saved 4154 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 4155 // the offset from there when it gets encoded. 4156 ins_attrib ins_field_const_toc_offset(0); 4157 ins_attrib ins_field_const_toc_offset_hi_node(0); 4158 4159 // A field that can hold the instructions offset in the code buffer. 4160 // Set in the nodes emitter. 4161 ins_attrib ins_field_cbuf_insts_offset(-1); 4162 4163 // Fields for referencing a call's load-IC-node. 4164 // If the toc offset can not be encoded as an immediate in a load, we 4165 // use two nodes. 4166 ins_attrib ins_field_load_ic_hi_node(0); 4167 ins_attrib ins_field_load_ic_node(0); 4168 4169 //----------OPERANDS----------------------------------------------------------- 4170 // Operand definitions must precede instruction definitions for correct 4171 // parsing in the ADLC because operands constitute user defined types 4172 // which are used in instruction definitions. 4173 // 4174 // Formats are generated automatically for constants and base registers. 4175 4176 operand vecX() %{ 4177 constraint(ALLOC_IN_RC(vs_reg)); 4178 match(VecX); 4179 4180 format %{ %} 4181 interface(REG_INTER); 4182 %} 4183 4184 //----------Simple Operands---------------------------------------------------- 4185 // Immediate Operands 4186 4187 // Integer Immediate: 32-bit 4188 operand immI() %{ 4189 match(ConI); 4190 op_cost(40); 4191 format %{ %} 4192 interface(CONST_INTER); 4193 %} 4194 4195 operand immI8() %{ 4196 predicate(Assembler::is_simm(n->get_int(), 8)); 4197 op_cost(0); 4198 match(ConI); 4199 format %{ %} 4200 interface(CONST_INTER); 4201 %} 4202 4203 // Integer Immediate: 16-bit 4204 operand immI16() %{ 4205 predicate(Assembler::is_simm(n->get_int(), 16)); 4206 op_cost(0); 4207 match(ConI); 4208 format %{ %} 4209 interface(CONST_INTER); 4210 %} 4211 4212 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4213 operand immIhi16() %{ 4214 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4215 match(ConI); 4216 op_cost(0); 4217 format %{ %} 4218 interface(CONST_INTER); 4219 %} 4220 4221 operand immInegpow2() %{ 4222 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 4223 match(ConI); 4224 op_cost(0); 4225 format %{ %} 4226 interface(CONST_INTER); 4227 %} 4228 4229 operand immIpow2minus1() %{ 4230 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 4231 match(ConI); 4232 op_cost(0); 4233 format %{ %} 4234 interface(CONST_INTER); 4235 %} 4236 4237 operand immIpowerOf2() %{ 4238 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 4239 match(ConI); 4240 op_cost(0); 4241 format %{ %} 4242 interface(CONST_INTER); 4243 %} 4244 4245 // Unsigned Integer Immediate: the values 0-31 4246 operand uimmI5() %{ 4247 predicate(Assembler::is_uimm(n->get_int(), 5)); 4248 match(ConI); 4249 op_cost(0); 4250 format %{ %} 4251 interface(CONST_INTER); 4252 %} 4253 4254 // Unsigned Integer Immediate: 6-bit 4255 operand uimmI6() %{ 4256 predicate(Assembler::is_uimm(n->get_int(), 6)); 4257 match(ConI); 4258 op_cost(0); 4259 format %{ %} 4260 interface(CONST_INTER); 4261 %} 4262 4263 // Unsigned Integer Immediate: 6-bit int, greater than 32 4264 operand uimmI6_ge32() %{ 4265 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4266 match(ConI); 4267 op_cost(0); 4268 format %{ %} 4269 interface(CONST_INTER); 4270 %} 4271 4272 // Unsigned Integer Immediate: 15-bit 4273 operand uimmI15() %{ 4274 predicate(Assembler::is_uimm(n->get_int(), 15)); 4275 match(ConI); 4276 op_cost(0); 4277 format %{ %} 4278 interface(CONST_INTER); 4279 %} 4280 4281 // Unsigned Integer Immediate: 16-bit 4282 operand uimmI16() %{ 4283 predicate(Assembler::is_uimm(n->get_int(), 16)); 4284 match(ConI); 4285 op_cost(0); 4286 format %{ %} 4287 interface(CONST_INTER); 4288 %} 4289 4290 // constant 'int 0'. 4291 operand immI_0() %{ 4292 predicate(n->get_int() == 0); 4293 match(ConI); 4294 op_cost(0); 4295 format %{ %} 4296 interface(CONST_INTER); 4297 %} 4298 4299 // constant 'int 1'. 4300 operand immI_1() %{ 4301 predicate(n->get_int() == 1); 4302 match(ConI); 4303 op_cost(0); 4304 format %{ %} 4305 interface(CONST_INTER); 4306 %} 4307 4308 // constant 'int -1'. 4309 operand immI_minus1() %{ 4310 predicate(n->get_int() == -1); 4311 match(ConI); 4312 op_cost(0); 4313 format %{ %} 4314 interface(CONST_INTER); 4315 %} 4316 4317 // int value 16. 4318 operand immI_16() %{ 4319 predicate(n->get_int() == 16); 4320 match(ConI); 4321 op_cost(0); 4322 format %{ %} 4323 interface(CONST_INTER); 4324 %} 4325 4326 // int value 24. 4327 operand immI_24() %{ 4328 predicate(n->get_int() == 24); 4329 match(ConI); 4330 op_cost(0); 4331 format %{ %} 4332 interface(CONST_INTER); 4333 %} 4334 4335 // Compressed oops constants 4336 // Pointer Immediate 4337 operand immN() %{ 4338 match(ConN); 4339 4340 op_cost(10); 4341 format %{ %} 4342 interface(CONST_INTER); 4343 %} 4344 4345 // NULL Pointer Immediate 4346 operand immN_0() %{ 4347 predicate(n->get_narrowcon() == 0); 4348 match(ConN); 4349 4350 op_cost(0); 4351 format %{ %} 4352 interface(CONST_INTER); 4353 %} 4354 4355 // Compressed klass constants 4356 operand immNKlass() %{ 4357 match(ConNKlass); 4358 4359 op_cost(0); 4360 format %{ %} 4361 interface(CONST_INTER); 4362 %} 4363 4364 // This operand can be used to avoid matching of an instruct 4365 // with chain rule. 4366 operand immNKlass_NM() %{ 4367 match(ConNKlass); 4368 predicate(false); 4369 op_cost(0); 4370 format %{ %} 4371 interface(CONST_INTER); 4372 %} 4373 4374 // Pointer Immediate: 64-bit 4375 operand immP() %{ 4376 match(ConP); 4377 op_cost(0); 4378 format %{ %} 4379 interface(CONST_INTER); 4380 %} 4381 4382 // Operand to avoid match of loadConP. 4383 // This operand can be used to avoid matching of an instruct 4384 // with chain rule. 4385 operand immP_NM() %{ 4386 match(ConP); 4387 predicate(false); 4388 op_cost(0); 4389 format %{ %} 4390 interface(CONST_INTER); 4391 %} 4392 4393 // costant 'pointer 0'. 4394 operand immP_0() %{ 4395 predicate(n->get_ptr() == 0); 4396 match(ConP); 4397 op_cost(0); 4398 format %{ %} 4399 interface(CONST_INTER); 4400 %} 4401 4402 // pointer 0x0 or 0x1 4403 operand immP_0or1() %{ 4404 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4405 match(ConP); 4406 op_cost(0); 4407 format %{ %} 4408 interface(CONST_INTER); 4409 %} 4410 4411 operand immL() %{ 4412 match(ConL); 4413 op_cost(40); 4414 format %{ %} 4415 interface(CONST_INTER); 4416 %} 4417 4418 operand immLmax30() %{ 4419 predicate((n->get_long() <= 30)); 4420 match(ConL); 4421 op_cost(0); 4422 format %{ %} 4423 interface(CONST_INTER); 4424 %} 4425 4426 // Long Immediate: 16-bit 4427 operand immL16() %{ 4428 predicate(Assembler::is_simm(n->get_long(), 16)); 4429 match(ConL); 4430 op_cost(0); 4431 format %{ %} 4432 interface(CONST_INTER); 4433 %} 4434 4435 // Long Immediate: 16-bit, 4-aligned 4436 operand immL16Alg4() %{ 4437 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4438 match(ConL); 4439 op_cost(0); 4440 format %{ %} 4441 interface(CONST_INTER); 4442 %} 4443 4444 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4445 operand immL32hi16() %{ 4446 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4447 match(ConL); 4448 op_cost(0); 4449 format %{ %} 4450 interface(CONST_INTER); 4451 %} 4452 4453 // Long Immediate: 32-bit 4454 operand immL32() %{ 4455 predicate(Assembler::is_simm(n->get_long(), 32)); 4456 match(ConL); 4457 op_cost(0); 4458 format %{ %} 4459 interface(CONST_INTER); 4460 %} 4461 4462 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4463 operand immLhighest16() %{ 4464 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4465 match(ConL); 4466 op_cost(0); 4467 format %{ %} 4468 interface(CONST_INTER); 4469 %} 4470 4471 operand immLnegpow2() %{ 4472 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4473 match(ConL); 4474 op_cost(0); 4475 format %{ %} 4476 interface(CONST_INTER); 4477 %} 4478 4479 operand immLpow2minus1() %{ 4480 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4481 (n->get_long() != (jlong)0xffffffffffffffffL)); 4482 match(ConL); 4483 op_cost(0); 4484 format %{ %} 4485 interface(CONST_INTER); 4486 %} 4487 4488 // constant 'long 0'. 4489 operand immL_0() %{ 4490 predicate(n->get_long() == 0L); 4491 match(ConL); 4492 op_cost(0); 4493 format %{ %} 4494 interface(CONST_INTER); 4495 %} 4496 4497 // constat ' long -1'. 4498 operand immL_minus1() %{ 4499 predicate(n->get_long() == -1L); 4500 match(ConL); 4501 op_cost(0); 4502 format %{ %} 4503 interface(CONST_INTER); 4504 %} 4505 4506 // Long Immediate: low 32-bit mask 4507 operand immL_32bits() %{ 4508 predicate(n->get_long() == 0xFFFFFFFFL); 4509 match(ConL); 4510 op_cost(0); 4511 format %{ %} 4512 interface(CONST_INTER); 4513 %} 4514 4515 // Unsigned Long Immediate: 16-bit 4516 operand uimmL16() %{ 4517 predicate(Assembler::is_uimm(n->get_long(), 16)); 4518 match(ConL); 4519 op_cost(0); 4520 format %{ %} 4521 interface(CONST_INTER); 4522 %} 4523 4524 // Float Immediate 4525 operand immF() %{ 4526 match(ConF); 4527 op_cost(40); 4528 format %{ %} 4529 interface(CONST_INTER); 4530 %} 4531 4532 // Float Immediate: +0.0f. 4533 operand immF_0() %{ 4534 predicate(jint_cast(n->getf()) == 0); 4535 match(ConF); 4536 4537 op_cost(0); 4538 format %{ %} 4539 interface(CONST_INTER); 4540 %} 4541 4542 // Double Immediate 4543 operand immD() %{ 4544 match(ConD); 4545 op_cost(40); 4546 format %{ %} 4547 interface(CONST_INTER); 4548 %} 4549 4550 // Integer Register Operands 4551 // Integer Destination Register 4552 // See definition of reg_class bits32_reg_rw. 4553 operand iRegIdst() %{ 4554 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4555 match(RegI); 4556 match(rscratch1RegI); 4557 match(rscratch2RegI); 4558 match(rarg1RegI); 4559 match(rarg2RegI); 4560 match(rarg3RegI); 4561 match(rarg4RegI); 4562 format %{ %} 4563 interface(REG_INTER); 4564 %} 4565 4566 // Integer Source Register 4567 // See definition of reg_class bits32_reg_ro. 4568 operand iRegIsrc() %{ 4569 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4570 match(RegI); 4571 match(rscratch1RegI); 4572 match(rscratch2RegI); 4573 match(rarg1RegI); 4574 match(rarg2RegI); 4575 match(rarg3RegI); 4576 match(rarg4RegI); 4577 format %{ %} 4578 interface(REG_INTER); 4579 %} 4580 4581 operand rscratch1RegI() %{ 4582 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4583 match(iRegIdst); 4584 format %{ %} 4585 interface(REG_INTER); 4586 %} 4587 4588 operand rscratch2RegI() %{ 4589 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4590 match(iRegIdst); 4591 format %{ %} 4592 interface(REG_INTER); 4593 %} 4594 4595 operand rarg1RegI() %{ 4596 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4597 match(iRegIdst); 4598 format %{ %} 4599 interface(REG_INTER); 4600 %} 4601 4602 operand rarg2RegI() %{ 4603 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4604 match(iRegIdst); 4605 format %{ %} 4606 interface(REG_INTER); 4607 %} 4608 4609 operand rarg3RegI() %{ 4610 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4611 match(iRegIdst); 4612 format %{ %} 4613 interface(REG_INTER); 4614 %} 4615 4616 operand rarg4RegI() %{ 4617 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4618 match(iRegIdst); 4619 format %{ %} 4620 interface(REG_INTER); 4621 %} 4622 4623 operand rarg1RegL() %{ 4624 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4625 match(iRegLdst); 4626 format %{ %} 4627 interface(REG_INTER); 4628 %} 4629 4630 operand rarg2RegL() %{ 4631 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4632 match(iRegLdst); 4633 format %{ %} 4634 interface(REG_INTER); 4635 %} 4636 4637 operand rarg3RegL() %{ 4638 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4639 match(iRegLdst); 4640 format %{ %} 4641 interface(REG_INTER); 4642 %} 4643 4644 operand rarg4RegL() %{ 4645 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4646 match(iRegLdst); 4647 format %{ %} 4648 interface(REG_INTER); 4649 %} 4650 4651 // Pointer Destination Register 4652 // See definition of reg_class bits64_reg_rw. 4653 operand iRegPdst() %{ 4654 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4655 match(RegP); 4656 match(rscratch1RegP); 4657 match(rscratch2RegP); 4658 match(rarg1RegP); 4659 match(rarg2RegP); 4660 match(rarg3RegP); 4661 match(rarg4RegP); 4662 format %{ %} 4663 interface(REG_INTER); 4664 %} 4665 4666 // Pointer Destination Register 4667 // Operand not using r11 and r12 (killed in epilog). 4668 operand iRegPdstNoScratch() %{ 4669 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4670 match(RegP); 4671 match(rarg1RegP); 4672 match(rarg2RegP); 4673 match(rarg3RegP); 4674 match(rarg4RegP); 4675 format %{ %} 4676 interface(REG_INTER); 4677 %} 4678 4679 // Pointer Source Register 4680 // See definition of reg_class bits64_reg_ro. 4681 operand iRegPsrc() %{ 4682 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4683 match(RegP); 4684 match(iRegPdst); 4685 match(rscratch1RegP); 4686 match(rscratch2RegP); 4687 match(rarg1RegP); 4688 match(rarg2RegP); 4689 match(rarg3RegP); 4690 match(rarg4RegP); 4691 match(threadRegP); 4692 format %{ %} 4693 interface(REG_INTER); 4694 %} 4695 4696 // Thread operand. 4697 operand threadRegP() %{ 4698 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4699 match(iRegPdst); 4700 format %{ "R16" %} 4701 interface(REG_INTER); 4702 %} 4703 4704 operand rscratch1RegP() %{ 4705 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4706 match(iRegPdst); 4707 format %{ "R11" %} 4708 interface(REG_INTER); 4709 %} 4710 4711 operand rscratch2RegP() %{ 4712 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4713 match(iRegPdst); 4714 format %{ %} 4715 interface(REG_INTER); 4716 %} 4717 4718 operand rarg1RegP() %{ 4719 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4720 match(iRegPdst); 4721 format %{ %} 4722 interface(REG_INTER); 4723 %} 4724 4725 operand rarg2RegP() %{ 4726 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4727 match(iRegPdst); 4728 format %{ %} 4729 interface(REG_INTER); 4730 %} 4731 4732 operand rarg3RegP() %{ 4733 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4734 match(iRegPdst); 4735 format %{ %} 4736 interface(REG_INTER); 4737 %} 4738 4739 operand rarg4RegP() %{ 4740 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4741 match(iRegPdst); 4742 format %{ %} 4743 interface(REG_INTER); 4744 %} 4745 4746 operand iRegNsrc() %{ 4747 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4748 match(RegN); 4749 match(iRegNdst); 4750 4751 format %{ %} 4752 interface(REG_INTER); 4753 %} 4754 4755 operand iRegNdst() %{ 4756 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4757 match(RegN); 4758 4759 format %{ %} 4760 interface(REG_INTER); 4761 %} 4762 4763 // Long Destination Register 4764 // See definition of reg_class bits64_reg_rw. 4765 operand iRegLdst() %{ 4766 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4767 match(RegL); 4768 match(rscratch1RegL); 4769 match(rscratch2RegL); 4770 format %{ %} 4771 interface(REG_INTER); 4772 %} 4773 4774 // Long Source Register 4775 // See definition of reg_class bits64_reg_ro. 4776 operand iRegLsrc() %{ 4777 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4778 match(RegL); 4779 match(iRegLdst); 4780 match(rscratch1RegL); 4781 match(rscratch2RegL); 4782 format %{ %} 4783 interface(REG_INTER); 4784 %} 4785 4786 // Special operand for ConvL2I. 4787 operand iRegL2Isrc(iRegLsrc reg) %{ 4788 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4789 match(ConvL2I reg); 4790 format %{ "ConvL2I($reg)" %} 4791 interface(REG_INTER) 4792 %} 4793 4794 operand rscratch1RegL() %{ 4795 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4796 match(RegL); 4797 format %{ %} 4798 interface(REG_INTER); 4799 %} 4800 4801 operand rscratch2RegL() %{ 4802 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4803 match(RegL); 4804 format %{ %} 4805 interface(REG_INTER); 4806 %} 4807 4808 // Condition Code Flag Registers 4809 operand flagsReg() %{ 4810 constraint(ALLOC_IN_RC(int_flags)); 4811 match(RegFlags); 4812 format %{ %} 4813 interface(REG_INTER); 4814 %} 4815 4816 operand flagsRegSrc() %{ 4817 constraint(ALLOC_IN_RC(int_flags_ro)); 4818 match(RegFlags); 4819 match(flagsReg); 4820 match(flagsRegCR0); 4821 format %{ %} 4822 interface(REG_INTER); 4823 %} 4824 4825 // Condition Code Flag Register CR0 4826 operand flagsRegCR0() %{ 4827 constraint(ALLOC_IN_RC(int_flags_CR0)); 4828 match(RegFlags); 4829 format %{ "CR0" %} 4830 interface(REG_INTER); 4831 %} 4832 4833 operand flagsRegCR1() %{ 4834 constraint(ALLOC_IN_RC(int_flags_CR1)); 4835 match(RegFlags); 4836 format %{ "CR1" %} 4837 interface(REG_INTER); 4838 %} 4839 4840 operand flagsRegCR6() %{ 4841 constraint(ALLOC_IN_RC(int_flags_CR6)); 4842 match(RegFlags); 4843 format %{ "CR6" %} 4844 interface(REG_INTER); 4845 %} 4846 4847 operand regCTR() %{ 4848 constraint(ALLOC_IN_RC(ctr_reg)); 4849 // RegFlags should work. Introducing a RegSpecial type would cause a 4850 // lot of changes. 4851 match(RegFlags); 4852 format %{"SR_CTR" %} 4853 interface(REG_INTER); 4854 %} 4855 4856 operand regD() %{ 4857 constraint(ALLOC_IN_RC(dbl_reg)); 4858 match(RegD); 4859 format %{ %} 4860 interface(REG_INTER); 4861 %} 4862 4863 operand regF() %{ 4864 constraint(ALLOC_IN_RC(flt_reg)); 4865 match(RegF); 4866 format %{ %} 4867 interface(REG_INTER); 4868 %} 4869 4870 // Special Registers 4871 4872 // Method Register 4873 operand inline_cache_regP(iRegPdst reg) %{ 4874 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4875 match(reg); 4876 format %{ %} 4877 interface(REG_INTER); 4878 %} 4879 4880 operand compiler_method_oop_regP(iRegPdst reg) %{ 4881 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4882 match(reg); 4883 format %{ %} 4884 interface(REG_INTER); 4885 %} 4886 4887 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4888 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4889 match(reg); 4890 format %{ %} 4891 interface(REG_INTER); 4892 %} 4893 4894 // Operands to remove register moves in unscaled mode. 4895 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4896 operand iRegP2N(iRegPsrc reg) %{ 4897 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4898 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4899 match(EncodeP reg); 4900 format %{ "$reg" %} 4901 interface(REG_INTER) 4902 %} 4903 4904 operand iRegN2P(iRegNsrc reg) %{ 4905 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4906 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4907 match(DecodeN reg); 4908 format %{ "$reg" %} 4909 interface(REG_INTER) 4910 %} 4911 4912 operand iRegN2P_klass(iRegNsrc reg) %{ 4913 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4914 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4915 match(DecodeNKlass reg); 4916 format %{ "$reg" %} 4917 interface(REG_INTER) 4918 %} 4919 4920 //----------Complex Operands--------------------------------------------------- 4921 // Indirect Memory Reference 4922 operand indirect(iRegPsrc reg) %{ 4923 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4924 match(reg); 4925 op_cost(100); 4926 format %{ "[$reg]" %} 4927 interface(MEMORY_INTER) %{ 4928 base($reg); 4929 index(0x0); 4930 scale(0x0); 4931 disp(0x0); 4932 %} 4933 %} 4934 4935 // Indirect with Offset 4936 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 4937 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4938 match(AddP reg offset); 4939 op_cost(100); 4940 format %{ "[$reg + $offset]" %} 4941 interface(MEMORY_INTER) %{ 4942 base($reg); 4943 index(0x0); 4944 scale(0x0); 4945 disp($offset); 4946 %} 4947 %} 4948 4949 // Indirect with 4-aligned Offset 4950 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 4951 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4952 match(AddP reg offset); 4953 op_cost(100); 4954 format %{ "[$reg + $offset]" %} 4955 interface(MEMORY_INTER) %{ 4956 base($reg); 4957 index(0x0); 4958 scale(0x0); 4959 disp($offset); 4960 %} 4961 %} 4962 4963 //----------Complex Operands for Compressed OOPs------------------------------- 4964 // Compressed OOPs with narrow_oop_shift == 0. 4965 4966 // Indirect Memory Reference, compressed OOP 4967 operand indirectNarrow(iRegNsrc reg) %{ 4968 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4969 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4970 match(DecodeN reg); 4971 op_cost(100); 4972 format %{ "[$reg]" %} 4973 interface(MEMORY_INTER) %{ 4974 base($reg); 4975 index(0x0); 4976 scale(0x0); 4977 disp(0x0); 4978 %} 4979 %} 4980 4981 operand indirectNarrow_klass(iRegNsrc reg) %{ 4982 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4983 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4984 match(DecodeNKlass reg); 4985 op_cost(100); 4986 format %{ "[$reg]" %} 4987 interface(MEMORY_INTER) %{ 4988 base($reg); 4989 index(0x0); 4990 scale(0x0); 4991 disp(0x0); 4992 %} 4993 %} 4994 4995 // Indirect with Offset, compressed OOP 4996 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 4997 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4998 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4999 match(AddP (DecodeN reg) offset); 5000 op_cost(100); 5001 format %{ "[$reg + $offset]" %} 5002 interface(MEMORY_INTER) %{ 5003 base($reg); 5004 index(0x0); 5005 scale(0x0); 5006 disp($offset); 5007 %} 5008 %} 5009 5010 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5011 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5012 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5013 match(AddP (DecodeNKlass reg) offset); 5014 op_cost(100); 5015 format %{ "[$reg + $offset]" %} 5016 interface(MEMORY_INTER) %{ 5017 base($reg); 5018 index(0x0); 5019 scale(0x0); 5020 disp($offset); 5021 %} 5022 %} 5023 5024 // Indirect with 4-aligned Offset, compressed OOP 5025 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 5026 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5027 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5028 match(AddP (DecodeN reg) offset); 5029 op_cost(100); 5030 format %{ "[$reg + $offset]" %} 5031 interface(MEMORY_INTER) %{ 5032 base($reg); 5033 index(0x0); 5034 scale(0x0); 5035 disp($offset); 5036 %} 5037 %} 5038 5039 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5040 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5041 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5042 match(AddP (DecodeNKlass reg) offset); 5043 op_cost(100); 5044 format %{ "[$reg + $offset]" %} 5045 interface(MEMORY_INTER) %{ 5046 base($reg); 5047 index(0x0); 5048 scale(0x0); 5049 disp($offset); 5050 %} 5051 %} 5052 5053 //----------Special Memory Operands-------------------------------------------- 5054 // Stack Slot Operand 5055 // 5056 // This operand is used for loading and storing temporary values on 5057 // the stack where a match requires a value to flow through memory. 5058 operand stackSlotI(sRegI reg) %{ 5059 constraint(ALLOC_IN_RC(stack_slots)); 5060 op_cost(100); 5061 //match(RegI); 5062 format %{ "[sp+$reg]" %} 5063 interface(MEMORY_INTER) %{ 5064 base(0x1); // R1_SP 5065 index(0x0); 5066 scale(0x0); 5067 disp($reg); // Stack Offset 5068 %} 5069 %} 5070 5071 operand stackSlotL(sRegL reg) %{ 5072 constraint(ALLOC_IN_RC(stack_slots)); 5073 op_cost(100); 5074 //match(RegL); 5075 format %{ "[sp+$reg]" %} 5076 interface(MEMORY_INTER) %{ 5077 base(0x1); // R1_SP 5078 index(0x0); 5079 scale(0x0); 5080 disp($reg); // Stack Offset 5081 %} 5082 %} 5083 5084 operand stackSlotP(sRegP reg) %{ 5085 constraint(ALLOC_IN_RC(stack_slots)); 5086 op_cost(100); 5087 //match(RegP); 5088 format %{ "[sp+$reg]" %} 5089 interface(MEMORY_INTER) %{ 5090 base(0x1); // R1_SP 5091 index(0x0); 5092 scale(0x0); 5093 disp($reg); // Stack Offset 5094 %} 5095 %} 5096 5097 operand stackSlotF(sRegF reg) %{ 5098 constraint(ALLOC_IN_RC(stack_slots)); 5099 op_cost(100); 5100 //match(RegF); 5101 format %{ "[sp+$reg]" %} 5102 interface(MEMORY_INTER) %{ 5103 base(0x1); // R1_SP 5104 index(0x0); 5105 scale(0x0); 5106 disp($reg); // Stack Offset 5107 %} 5108 %} 5109 5110 operand stackSlotD(sRegD reg) %{ 5111 constraint(ALLOC_IN_RC(stack_slots)); 5112 op_cost(100); 5113 //match(RegD); 5114 format %{ "[sp+$reg]" %} 5115 interface(MEMORY_INTER) %{ 5116 base(0x1); // R1_SP 5117 index(0x0); 5118 scale(0x0); 5119 disp($reg); // Stack Offset 5120 %} 5121 %} 5122 5123 // Operands for expressing Control Flow 5124 // NOTE: Label is a predefined operand which should not be redefined in 5125 // the AD file. It is generically handled within the ADLC. 5126 5127 //----------Conditional Branch Operands---------------------------------------- 5128 // Comparison Op 5129 // 5130 // This is the operation of the comparison, and is limited to the 5131 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5132 // (!=). 5133 // 5134 // Other attributes of the comparison, such as unsignedness, are specified 5135 // by the comparison instruction that sets a condition code flags register. 5136 // That result is represented by a flags operand whose subtype is appropriate 5137 // to the unsignedness (etc.) of the comparison. 5138 // 5139 // Later, the instruction which matches both the Comparison Op (a Bool) and 5140 // the flags (produced by the Cmp) specifies the coding of the comparison op 5141 // by matching a specific subtype of Bool operand below. 5142 5143 // When used for floating point comparisons: unordered same as less. 5144 operand cmpOp() %{ 5145 match(Bool); 5146 format %{ "" %} 5147 interface(COND_INTER) %{ 5148 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5149 // BO & BI 5150 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5151 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5152 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5153 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5154 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5155 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5156 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5157 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5158 %} 5159 %} 5160 5161 //----------OPERAND CLASSES---------------------------------------------------- 5162 // Operand Classes are groups of operands that are used to simplify 5163 // instruction definitions by not requiring the AD writer to specify 5164 // seperate instructions for every form of operand when the 5165 // instruction accepts multiple operand types with the same basic 5166 // encoding and format. The classic case of this is memory operands. 5167 // Indirect is not included since its use is limited to Compare & Swap. 5168 5169 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5170 // Memory operand where offsets are 4-aligned. Required for ld, std. 5171 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5172 opclass indirectMemory(indirect, indirectNarrow); 5173 5174 // Special opclass for I and ConvL2I. 5175 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5176 5177 // Operand classes to match encode and decode. iRegN_P2N is only used 5178 // for storeN. I have never seen an encode node elsewhere. 5179 opclass iRegN_P2N(iRegNsrc, iRegP2N); 5180 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5181 5182 //----------PIPELINE----------------------------------------------------------- 5183 5184 pipeline %{ 5185 5186 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5187 // J. Res. & Dev., No. 1, Jan. 2002. 5188 5189 //----------ATTRIBUTES--------------------------------------------------------- 5190 attributes %{ 5191 5192 // Power4 instructions are of fixed length. 5193 fixed_size_instructions; 5194 5195 // TODO: if `bundle' means number of instructions fetched 5196 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5197 // max instructions issued per cycle, this is 5. 5198 max_instructions_per_bundle = 8; 5199 5200 // A Power4 instruction is 4 bytes long. 5201 instruction_unit_size = 4; 5202 5203 // The Power4 processor fetches 64 bytes... 5204 instruction_fetch_unit_size = 64; 5205 5206 // ...in one line 5207 instruction_fetch_units = 1 5208 5209 // Unused, list one so that array generated by adlc is not empty. 5210 // Aix compiler chokes if _nop_count = 0. 5211 nops(fxNop); 5212 %} 5213 5214 //----------RESOURCES---------------------------------------------------------- 5215 // Resources are the functional units available to the machine 5216 resources( 5217 PPC_BR, // branch unit 5218 PPC_CR, // condition unit 5219 PPC_FX1, // integer arithmetic unit 1 5220 PPC_FX2, // integer arithmetic unit 2 5221 PPC_LDST1, // load/store unit 1 5222 PPC_LDST2, // load/store unit 2 5223 PPC_FP1, // float arithmetic unit 1 5224 PPC_FP2, // float arithmetic unit 2 5225 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5226 PPC_FX = PPC_FX1 | PPC_FX2, 5227 PPC_FP = PPC_FP1 | PPC_FP2 5228 ); 5229 5230 //----------PIPELINE DESCRIPTION----------------------------------------------- 5231 // Pipeline Description specifies the stages in the machine's pipeline 5232 pipe_desc( 5233 // Power4 longest pipeline path 5234 PPC_IF, // instruction fetch 5235 PPC_IC, 5236 //PPC_BP, // branch prediction 5237 PPC_D0, // decode 5238 PPC_D1, // decode 5239 PPC_D2, // decode 5240 PPC_D3, // decode 5241 PPC_Xfer1, 5242 PPC_GD, // group definition 5243 PPC_MP, // map 5244 PPC_ISS, // issue 5245 PPC_RF, // resource fetch 5246 PPC_EX1, // execute (all units) 5247 PPC_EX2, // execute (FP, LDST) 5248 PPC_EX3, // execute (FP, LDST) 5249 PPC_EX4, // execute (FP) 5250 PPC_EX5, // execute (FP) 5251 PPC_EX6, // execute (FP) 5252 PPC_WB, // write back 5253 PPC_Xfer2, 5254 PPC_CP 5255 ); 5256 5257 //----------PIPELINE CLASSES--------------------------------------------------- 5258 // Pipeline Classes describe the stages in which input and output are 5259 // referenced by the hardware pipeline. 5260 5261 // Simple pipeline classes. 5262 5263 // Default pipeline class. 5264 pipe_class pipe_class_default() %{ 5265 single_instruction; 5266 fixed_latency(2); 5267 %} 5268 5269 // Pipeline class for empty instructions. 5270 pipe_class pipe_class_empty() %{ 5271 single_instruction; 5272 fixed_latency(0); 5273 %} 5274 5275 // Pipeline class for compares. 5276 pipe_class pipe_class_compare() %{ 5277 single_instruction; 5278 fixed_latency(16); 5279 %} 5280 5281 // Pipeline class for traps. 5282 pipe_class pipe_class_trap() %{ 5283 single_instruction; 5284 fixed_latency(100); 5285 %} 5286 5287 // Pipeline class for memory operations. 5288 pipe_class pipe_class_memory() %{ 5289 single_instruction; 5290 fixed_latency(16); 5291 %} 5292 5293 // Pipeline class for call. 5294 pipe_class pipe_class_call() %{ 5295 single_instruction; 5296 fixed_latency(100); 5297 %} 5298 5299 // Define the class for the Nop node. 5300 define %{ 5301 MachNop = pipe_class_default; 5302 %} 5303 5304 %} 5305 5306 //----------INSTRUCTIONS------------------------------------------------------- 5307 5308 // Naming of instructions: 5309 // opA_operB / opA_operB_operC: 5310 // Operation 'op' with one or two source operands 'oper'. Result 5311 // type is A, source operand types are B and C. 5312 // Iff A == B == C, B and C are left out. 5313 // 5314 // The instructions are ordered according to the following scheme: 5315 // - loads 5316 // - load constants 5317 // - prefetch 5318 // - store 5319 // - encode/decode 5320 // - membar 5321 // - conditional moves 5322 // - compare & swap 5323 // - arithmetic and logic operations 5324 // * int: Add, Sub, Mul, Div, Mod 5325 // * int: lShift, arShift, urShift, rot 5326 // * float: Add, Sub, Mul, Div 5327 // * and, or, xor ... 5328 // - register moves: float <-> int, reg <-> stack, repl 5329 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5330 // - conv (low level type cast requiring bit changes (sign extend etc) 5331 // - compares, range & zero checks. 5332 // - branches 5333 // - complex operations, intrinsics, min, max, replicate 5334 // - lock 5335 // - Calls 5336 // 5337 // If there are similar instructions with different types they are sorted: 5338 // int before float 5339 // small before big 5340 // signed before unsigned 5341 // e.g., loadS before loadUS before loadI before loadF. 5342 5343 5344 //----------Load/Store Instructions-------------------------------------------- 5345 5346 //----------Load Instructions-------------------------------------------------- 5347 5348 // Converts byte to int. 5349 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5350 // reuses the 'amount' operand, but adlc expects that operand specification 5351 // and operands in match rule are equivalent. 5352 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5353 effect(DEF dst, USE src); 5354 format %{ "EXTSB $dst, $src \t// byte->int" %} 5355 size(4); 5356 ins_encode %{ 5357 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5358 __ extsb($dst$$Register, $src$$Register); 5359 %} 5360 ins_pipe(pipe_class_default); 5361 %} 5362 5363 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5364 // match-rule, false predicate 5365 match(Set dst (LoadB mem)); 5366 predicate(false); 5367 5368 format %{ "LBZ $dst, $mem" %} 5369 size(4); 5370 ins_encode( enc_lbz(dst, mem) ); 5371 ins_pipe(pipe_class_memory); 5372 %} 5373 5374 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5375 // match-rule, false predicate 5376 match(Set dst (LoadB mem)); 5377 predicate(false); 5378 5379 format %{ "LBZ $dst, $mem\n\t" 5380 "TWI $dst\n\t" 5381 "ISYNC" %} 5382 size(12); 5383 ins_encode( enc_lbz_ac(dst, mem) ); 5384 ins_pipe(pipe_class_memory); 5385 %} 5386 5387 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5388 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5389 match(Set dst (LoadB mem)); 5390 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5391 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5392 expand %{ 5393 iRegIdst tmp; 5394 loadUB_indirect(tmp, mem); 5395 convB2I_reg_2(dst, tmp); 5396 %} 5397 %} 5398 5399 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5400 match(Set dst (LoadB mem)); 5401 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5402 expand %{ 5403 iRegIdst tmp; 5404 loadUB_indirect_ac(tmp, mem); 5405 convB2I_reg_2(dst, tmp); 5406 %} 5407 %} 5408 5409 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5410 // match-rule, false predicate 5411 match(Set dst (LoadB mem)); 5412 predicate(false); 5413 5414 format %{ "LBZ $dst, $mem" %} 5415 size(4); 5416 ins_encode( enc_lbz(dst, mem) ); 5417 ins_pipe(pipe_class_memory); 5418 %} 5419 5420 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5421 // match-rule, false predicate 5422 match(Set dst (LoadB mem)); 5423 predicate(false); 5424 5425 format %{ "LBZ $dst, $mem\n\t" 5426 "TWI $dst\n\t" 5427 "ISYNC" %} 5428 size(12); 5429 ins_encode( enc_lbz_ac(dst, mem) ); 5430 ins_pipe(pipe_class_memory); 5431 %} 5432 5433 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5434 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5435 match(Set dst (LoadB mem)); 5436 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5437 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5438 5439 expand %{ 5440 iRegIdst tmp; 5441 loadUB_indOffset16(tmp, mem); 5442 convB2I_reg_2(dst, tmp); 5443 %} 5444 %} 5445 5446 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5447 match(Set dst (LoadB mem)); 5448 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5449 5450 expand %{ 5451 iRegIdst tmp; 5452 loadUB_indOffset16_ac(tmp, mem); 5453 convB2I_reg_2(dst, tmp); 5454 %} 5455 %} 5456 5457 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5458 instruct loadUB(iRegIdst dst, memory mem) %{ 5459 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5460 match(Set dst (LoadUB mem)); 5461 ins_cost(MEMORY_REF_COST); 5462 5463 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5464 size(4); 5465 ins_encode( enc_lbz(dst, mem) ); 5466 ins_pipe(pipe_class_memory); 5467 %} 5468 5469 // Load Unsigned Byte (8bit UNsigned) acquire. 5470 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5471 match(Set dst (LoadUB mem)); 5472 ins_cost(3*MEMORY_REF_COST); 5473 5474 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5475 "TWI $dst\n\t" 5476 "ISYNC" %} 5477 size(12); 5478 ins_encode( enc_lbz_ac(dst, mem) ); 5479 ins_pipe(pipe_class_memory); 5480 %} 5481 5482 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5483 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5484 match(Set dst (ConvI2L (LoadUB mem))); 5485 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5486 ins_cost(MEMORY_REF_COST); 5487 5488 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5489 size(4); 5490 ins_encode( enc_lbz(dst, mem) ); 5491 ins_pipe(pipe_class_memory); 5492 %} 5493 5494 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5495 match(Set dst (ConvI2L (LoadUB mem))); 5496 ins_cost(3*MEMORY_REF_COST); 5497 5498 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5499 "TWI $dst\n\t" 5500 "ISYNC" %} 5501 size(12); 5502 ins_encode( enc_lbz_ac(dst, mem) ); 5503 ins_pipe(pipe_class_memory); 5504 %} 5505 5506 // Load Short (16bit signed) 5507 instruct loadS(iRegIdst dst, memory mem) %{ 5508 match(Set dst (LoadS mem)); 5509 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5510 ins_cost(MEMORY_REF_COST); 5511 5512 format %{ "LHA $dst, $mem" %} 5513 size(4); 5514 ins_encode %{ 5515 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5516 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5517 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5518 %} 5519 ins_pipe(pipe_class_memory); 5520 %} 5521 5522 // Load Short (16bit signed) acquire. 5523 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5524 match(Set dst (LoadS mem)); 5525 ins_cost(3*MEMORY_REF_COST); 5526 5527 format %{ "LHA $dst, $mem\t acquire\n\t" 5528 "TWI $dst\n\t" 5529 "ISYNC" %} 5530 size(12); 5531 ins_encode %{ 5532 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5533 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5534 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5535 __ twi_0($dst$$Register); 5536 __ isync(); 5537 %} 5538 ins_pipe(pipe_class_memory); 5539 %} 5540 5541 // Load Char (16bit unsigned) 5542 instruct loadUS(iRegIdst dst, memory mem) %{ 5543 match(Set dst (LoadUS mem)); 5544 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5545 ins_cost(MEMORY_REF_COST); 5546 5547 format %{ "LHZ $dst, $mem" %} 5548 size(4); 5549 ins_encode( enc_lhz(dst, mem) ); 5550 ins_pipe(pipe_class_memory); 5551 %} 5552 5553 // Load Char (16bit unsigned) acquire. 5554 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5555 match(Set dst (LoadUS mem)); 5556 ins_cost(3*MEMORY_REF_COST); 5557 5558 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5559 "TWI $dst\n\t" 5560 "ISYNC" %} 5561 size(12); 5562 ins_encode( enc_lhz_ac(dst, mem) ); 5563 ins_pipe(pipe_class_memory); 5564 %} 5565 5566 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5567 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5568 match(Set dst (ConvI2L (LoadUS mem))); 5569 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5570 ins_cost(MEMORY_REF_COST); 5571 5572 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5573 size(4); 5574 ins_encode( enc_lhz(dst, mem) ); 5575 ins_pipe(pipe_class_memory); 5576 %} 5577 5578 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5579 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5580 match(Set dst (ConvI2L (LoadUS mem))); 5581 ins_cost(3*MEMORY_REF_COST); 5582 5583 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5584 "TWI $dst\n\t" 5585 "ISYNC" %} 5586 size(12); 5587 ins_encode( enc_lhz_ac(dst, mem) ); 5588 ins_pipe(pipe_class_memory); 5589 %} 5590 5591 // Load Integer. 5592 instruct loadI(iRegIdst dst, memory mem) %{ 5593 match(Set dst (LoadI mem)); 5594 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5595 ins_cost(MEMORY_REF_COST); 5596 5597 format %{ "LWZ $dst, $mem" %} 5598 size(4); 5599 ins_encode( enc_lwz(dst, mem) ); 5600 ins_pipe(pipe_class_memory); 5601 %} 5602 5603 // Load Integer acquire. 5604 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5605 match(Set dst (LoadI mem)); 5606 ins_cost(3*MEMORY_REF_COST); 5607 5608 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5609 "TWI $dst\n\t" 5610 "ISYNC" %} 5611 size(12); 5612 ins_encode( enc_lwz_ac(dst, mem) ); 5613 ins_pipe(pipe_class_memory); 5614 %} 5615 5616 // Match loading integer and casting it to unsigned int in 5617 // long register. 5618 // LoadI + ConvI2L + AndL 0xffffffff. 5619 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5620 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5621 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5622 ins_cost(MEMORY_REF_COST); 5623 5624 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5625 size(4); 5626 ins_encode( enc_lwz(dst, mem) ); 5627 ins_pipe(pipe_class_memory); 5628 %} 5629 5630 // Match loading integer and casting it to long. 5631 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5632 match(Set dst (ConvI2L (LoadI mem))); 5633 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5634 ins_cost(MEMORY_REF_COST); 5635 5636 format %{ "LWA $dst, $mem \t// loadI2L" %} 5637 size(4); 5638 ins_encode %{ 5639 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5640 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5641 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5642 %} 5643 ins_pipe(pipe_class_memory); 5644 %} 5645 5646 // Match loading integer and casting it to long - acquire. 5647 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5648 match(Set dst (ConvI2L (LoadI mem))); 5649 ins_cost(3*MEMORY_REF_COST); 5650 5651 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5652 "TWI $dst\n\t" 5653 "ISYNC" %} 5654 size(12); 5655 ins_encode %{ 5656 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5657 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5658 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5659 __ twi_0($dst$$Register); 5660 __ isync(); 5661 %} 5662 ins_pipe(pipe_class_memory); 5663 %} 5664 5665 // Load Long - aligned 5666 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5667 match(Set dst (LoadL mem)); 5668 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5669 ins_cost(MEMORY_REF_COST); 5670 5671 format %{ "LD $dst, $mem \t// long" %} 5672 size(4); 5673 ins_encode( enc_ld(dst, mem) ); 5674 ins_pipe(pipe_class_memory); 5675 %} 5676 5677 // Load Long - aligned acquire. 5678 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5679 match(Set dst (LoadL mem)); 5680 ins_cost(3*MEMORY_REF_COST); 5681 5682 format %{ "LD $dst, $mem \t// long acquire\n\t" 5683 "TWI $dst\n\t" 5684 "ISYNC" %} 5685 size(12); 5686 ins_encode( enc_ld_ac(dst, mem) ); 5687 ins_pipe(pipe_class_memory); 5688 %} 5689 5690 // Load Long - UNaligned 5691 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5692 match(Set dst (LoadL_unaligned mem)); 5693 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5694 ins_cost(MEMORY_REF_COST); 5695 5696 format %{ "LD $dst, $mem \t// unaligned long" %} 5697 size(4); 5698 ins_encode( enc_ld(dst, mem) ); 5699 ins_pipe(pipe_class_memory); 5700 %} 5701 5702 // Load nodes for superwords 5703 5704 // Load Aligned Packed Byte 5705 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5706 predicate(n->as_LoadVector()->memory_size() == 8); 5707 match(Set dst (LoadVector mem)); 5708 ins_cost(MEMORY_REF_COST); 5709 5710 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5711 size(4); 5712 ins_encode( enc_ld(dst, mem) ); 5713 ins_pipe(pipe_class_memory); 5714 %} 5715 5716 // Load Aligned Packed Byte 5717 instruct loadV16(vecX dst, indirect mem) %{ 5718 predicate(n->as_LoadVector()->memory_size() == 16); 5719 match(Set dst (LoadVector mem)); 5720 ins_cost(MEMORY_REF_COST); 5721 5722 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5723 size(4); 5724 ins_encode %{ 5725 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5726 %} 5727 ins_pipe(pipe_class_default); 5728 %} 5729 5730 // Load Range, range = array length (=jint) 5731 instruct loadRange(iRegIdst dst, memory mem) %{ 5732 match(Set dst (LoadRange mem)); 5733 ins_cost(MEMORY_REF_COST); 5734 5735 format %{ "LWZ $dst, $mem \t// range" %} 5736 size(4); 5737 ins_encode( enc_lwz(dst, mem) ); 5738 ins_pipe(pipe_class_memory); 5739 %} 5740 5741 // Load Compressed Pointer 5742 instruct loadN(iRegNdst dst, memory mem) %{ 5743 match(Set dst (LoadN mem)); 5744 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5745 ins_cost(MEMORY_REF_COST); 5746 5747 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5748 size(4); 5749 ins_encode( enc_lwz(dst, mem) ); 5750 ins_pipe(pipe_class_memory); 5751 %} 5752 5753 // Load Compressed Pointer acquire. 5754 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5755 match(Set dst (LoadN mem)); 5756 ins_cost(3*MEMORY_REF_COST); 5757 5758 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5759 "TWI $dst\n\t" 5760 "ISYNC" %} 5761 size(12); 5762 ins_encode( enc_lwz_ac(dst, mem) ); 5763 ins_pipe(pipe_class_memory); 5764 %} 5765 5766 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5767 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5768 match(Set dst (DecodeN (LoadN mem))); 5769 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5770 ins_cost(MEMORY_REF_COST); 5771 5772 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5773 size(4); 5774 ins_encode( enc_lwz(dst, mem) ); 5775 ins_pipe(pipe_class_memory); 5776 %} 5777 5778 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5779 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5780 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5781 _kids[0]->_leaf->as_Load()->is_unordered()); 5782 ins_cost(MEMORY_REF_COST); 5783 5784 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5785 size(4); 5786 ins_encode( enc_lwz(dst, mem) ); 5787 ins_pipe(pipe_class_memory); 5788 %} 5789 5790 // Load Pointer 5791 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5792 match(Set dst (LoadP mem)); 5793 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5794 ins_cost(MEMORY_REF_COST); 5795 5796 format %{ "LD $dst, $mem \t// ptr" %} 5797 size(4); 5798 ins_encode( enc_ld(dst, mem) ); 5799 ins_pipe(pipe_class_memory); 5800 %} 5801 5802 // Load Pointer acquire. 5803 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5804 match(Set dst (LoadP mem)); 5805 ins_cost(3*MEMORY_REF_COST); 5806 5807 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5808 "TWI $dst\n\t" 5809 "ISYNC" %} 5810 size(12); 5811 ins_encode( enc_ld_ac(dst, mem) ); 5812 ins_pipe(pipe_class_memory); 5813 %} 5814 5815 // LoadP + CastP2L 5816 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5817 match(Set dst (CastP2X (LoadP mem))); 5818 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5819 ins_cost(MEMORY_REF_COST); 5820 5821 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5822 size(4); 5823 ins_encode( enc_ld(dst, mem) ); 5824 ins_pipe(pipe_class_memory); 5825 %} 5826 5827 // Load compressed klass pointer. 5828 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5829 match(Set dst (LoadNKlass mem)); 5830 ins_cost(MEMORY_REF_COST); 5831 5832 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5833 size(4); 5834 ins_encode( enc_lwz(dst, mem) ); 5835 ins_pipe(pipe_class_memory); 5836 %} 5837 5838 // Load Klass Pointer 5839 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5840 match(Set dst (LoadKlass mem)); 5841 ins_cost(MEMORY_REF_COST); 5842 5843 format %{ "LD $dst, $mem \t// klass ptr" %} 5844 size(4); 5845 ins_encode( enc_ld(dst, mem) ); 5846 ins_pipe(pipe_class_memory); 5847 %} 5848 5849 // Load Float 5850 instruct loadF(regF dst, memory mem) %{ 5851 match(Set dst (LoadF mem)); 5852 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5853 ins_cost(MEMORY_REF_COST); 5854 5855 format %{ "LFS $dst, $mem" %} 5856 size(4); 5857 ins_encode %{ 5858 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5859 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5860 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5861 %} 5862 ins_pipe(pipe_class_memory); 5863 %} 5864 5865 // Load Float acquire. 5866 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5867 match(Set dst (LoadF mem)); 5868 effect(TEMP cr0); 5869 ins_cost(3*MEMORY_REF_COST); 5870 5871 format %{ "LFS $dst, $mem \t// acquire\n\t" 5872 "FCMPU cr0, $dst, $dst\n\t" 5873 "BNE cr0, next\n" 5874 "next:\n\t" 5875 "ISYNC" %} 5876 size(16); 5877 ins_encode %{ 5878 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5879 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5880 Label next; 5881 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5882 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5883 __ bne(CCR0, next); 5884 __ bind(next); 5885 __ isync(); 5886 %} 5887 ins_pipe(pipe_class_memory); 5888 %} 5889 5890 // Load Double - aligned 5891 instruct loadD(regD dst, memory mem) %{ 5892 match(Set dst (LoadD mem)); 5893 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5894 ins_cost(MEMORY_REF_COST); 5895 5896 format %{ "LFD $dst, $mem" %} 5897 size(4); 5898 ins_encode( enc_lfd(dst, mem) ); 5899 ins_pipe(pipe_class_memory); 5900 %} 5901 5902 // Load Double - aligned acquire. 5903 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5904 match(Set dst (LoadD mem)); 5905 effect(TEMP cr0); 5906 ins_cost(3*MEMORY_REF_COST); 5907 5908 format %{ "LFD $dst, $mem \t// acquire\n\t" 5909 "FCMPU cr0, $dst, $dst\n\t" 5910 "BNE cr0, next\n" 5911 "next:\n\t" 5912 "ISYNC" %} 5913 size(16); 5914 ins_encode %{ 5915 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5916 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5917 Label next; 5918 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5919 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5920 __ bne(CCR0, next); 5921 __ bind(next); 5922 __ isync(); 5923 %} 5924 ins_pipe(pipe_class_memory); 5925 %} 5926 5927 // Load Double - UNaligned 5928 instruct loadD_unaligned(regD dst, memory mem) %{ 5929 match(Set dst (LoadD_unaligned mem)); 5930 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5931 ins_cost(MEMORY_REF_COST); 5932 5933 format %{ "LFD $dst, $mem" %} 5934 size(4); 5935 ins_encode( enc_lfd(dst, mem) ); 5936 ins_pipe(pipe_class_memory); 5937 %} 5938 5939 //----------Constants-------------------------------------------------------- 5940 5941 // Load MachConstantTableBase: add hi offset to global toc. 5942 // TODO: Handle hidden register r29 in bundler! 5943 instruct loadToc_hi(iRegLdst dst) %{ 5944 effect(DEF dst); 5945 ins_cost(DEFAULT_COST); 5946 5947 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 5948 size(4); 5949 ins_encode %{ 5950 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5951 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 5952 %} 5953 ins_pipe(pipe_class_default); 5954 %} 5955 5956 // Load MachConstantTableBase: add lo offset to global toc. 5957 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 5958 effect(DEF dst, USE src); 5959 ins_cost(DEFAULT_COST); 5960 5961 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 5962 size(4); 5963 ins_encode %{ 5964 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5965 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 5966 %} 5967 ins_pipe(pipe_class_default); 5968 %} 5969 5970 // Load 16-bit integer constant 0xssss???? 5971 instruct loadConI16(iRegIdst dst, immI16 src) %{ 5972 match(Set dst src); 5973 5974 format %{ "LI $dst, $src" %} 5975 size(4); 5976 ins_encode %{ 5977 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5978 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 5979 %} 5980 ins_pipe(pipe_class_default); 5981 %} 5982 5983 // Load integer constant 0x????0000 5984 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 5985 match(Set dst src); 5986 ins_cost(DEFAULT_COST); 5987 5988 format %{ "LIS $dst, $src.hi" %} 5989 size(4); 5990 ins_encode %{ 5991 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5992 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 5993 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5994 %} 5995 ins_pipe(pipe_class_default); 5996 %} 5997 5998 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 5999 // and sign extended), this adds the low 16 bits. 6000 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6001 // no match-rule, false predicate 6002 effect(DEF dst, USE src1, USE src2); 6003 predicate(false); 6004 6005 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6006 size(4); 6007 ins_encode %{ 6008 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6009 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6010 %} 6011 ins_pipe(pipe_class_default); 6012 %} 6013 6014 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6015 match(Set dst src); 6016 ins_cost(DEFAULT_COST*2); 6017 6018 expand %{ 6019 // Would like to use $src$$constant. 6020 immI16 srcLo %{ _opnds[1]->constant() %} 6021 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6022 immIhi16 srcHi %{ _opnds[1]->constant() %} 6023 iRegIdst tmpI; 6024 loadConIhi16(tmpI, srcHi); 6025 loadConI32_lo16(dst, tmpI, srcLo); 6026 %} 6027 %} 6028 6029 // No constant pool entries required. 6030 instruct loadConL16(iRegLdst dst, immL16 src) %{ 6031 match(Set dst src); 6032 6033 format %{ "LI $dst, $src \t// long" %} 6034 size(4); 6035 ins_encode %{ 6036 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6037 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6038 %} 6039 ins_pipe(pipe_class_default); 6040 %} 6041 6042 // Load long constant 0xssssssss????0000 6043 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6044 match(Set dst src); 6045 ins_cost(DEFAULT_COST); 6046 6047 format %{ "LIS $dst, $src.hi \t// long" %} 6048 size(4); 6049 ins_encode %{ 6050 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6051 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6052 %} 6053 ins_pipe(pipe_class_default); 6054 %} 6055 6056 // To load a 32 bit constant: merge lower 16 bits into already loaded 6057 // high 16 bits. 6058 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6059 // no match-rule, false predicate 6060 effect(DEF dst, USE src1, USE src2); 6061 predicate(false); 6062 6063 format %{ "ORI $dst, $src1, $src2.lo" %} 6064 size(4); 6065 ins_encode %{ 6066 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6067 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6068 %} 6069 ins_pipe(pipe_class_default); 6070 %} 6071 6072 // Load 32-bit long constant 6073 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6074 match(Set dst src); 6075 ins_cost(DEFAULT_COST*2); 6076 6077 expand %{ 6078 // Would like to use $src$$constant. 6079 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6080 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6081 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6082 iRegLdst tmpL; 6083 loadConL32hi16(tmpL, srcHi); 6084 loadConL32_lo16(dst, tmpL, srcLo); 6085 %} 6086 %} 6087 6088 // Load long constant 0x????000000000000. 6089 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6090 match(Set dst src); 6091 ins_cost(DEFAULT_COST); 6092 6093 expand %{ 6094 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6095 immI shift32 %{ 32 %} 6096 iRegLdst tmpL; 6097 loadConL32hi16(tmpL, srcHi); 6098 lshiftL_regL_immI(dst, tmpL, shift32); 6099 %} 6100 %} 6101 6102 // Expand node for constant pool load: small offset. 6103 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6104 effect(DEF dst, USE src, USE toc); 6105 ins_cost(MEMORY_REF_COST); 6106 6107 ins_num_consts(1); 6108 // Needed so that CallDynamicJavaDirect can compute the address of this 6109 // instruction for relocation. 6110 ins_field_cbuf_insts_offset(int); 6111 6112 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6113 size(4); 6114 ins_encode( enc_load_long_constL(dst, src, toc) ); 6115 ins_pipe(pipe_class_memory); 6116 %} 6117 6118 // Expand node for constant pool load: large offset. 6119 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6120 effect(DEF dst, USE src, USE toc); 6121 predicate(false); 6122 6123 ins_num_consts(1); 6124 ins_field_const_toc_offset(int); 6125 // Needed so that CallDynamicJavaDirect can compute the address of this 6126 // instruction for relocation. 6127 ins_field_cbuf_insts_offset(int); 6128 6129 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6130 size(4); 6131 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6132 ins_pipe(pipe_class_default); 6133 %} 6134 6135 // Expand node for constant pool load: large offset. 6136 // No constant pool entries required. 6137 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6138 effect(DEF dst, USE src, USE base); 6139 predicate(false); 6140 6141 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6142 6143 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6144 size(4); 6145 ins_encode %{ 6146 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6147 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6148 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6149 %} 6150 ins_pipe(pipe_class_memory); 6151 %} 6152 6153 // Load long constant from constant table. Expand in case of 6154 // offset > 16 bit is needed. 6155 // Adlc adds toc node MachConstantTableBase. 6156 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6157 match(Set dst src); 6158 ins_cost(MEMORY_REF_COST); 6159 6160 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6161 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6162 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6163 %} 6164 6165 // Load NULL as compressed oop. 6166 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6167 match(Set dst src); 6168 ins_cost(DEFAULT_COST); 6169 6170 format %{ "LI $dst, $src \t// compressed ptr" %} 6171 size(4); 6172 ins_encode %{ 6173 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6174 __ li($dst$$Register, 0); 6175 %} 6176 ins_pipe(pipe_class_default); 6177 %} 6178 6179 // Load hi part of compressed oop constant. 6180 instruct loadConN_hi(iRegNdst dst, immN src) %{ 6181 effect(DEF dst, USE src); 6182 ins_cost(DEFAULT_COST); 6183 6184 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6185 size(4); 6186 ins_encode %{ 6187 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6188 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6189 %} 6190 ins_pipe(pipe_class_default); 6191 %} 6192 6193 // Add lo part of compressed oop constant to already loaded hi part. 6194 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6195 effect(DEF dst, USE src1, USE src2); 6196 ins_cost(DEFAULT_COST); 6197 6198 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6199 size(4); 6200 ins_encode %{ 6201 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6202 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6203 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6204 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6205 __ relocate(rspec, 1); 6206 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6207 %} 6208 ins_pipe(pipe_class_default); 6209 %} 6210 6211 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6212 effect(DEF dst, USE src, USE shift, USE mask_begin); 6213 6214 size(4); 6215 ins_encode %{ 6216 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6217 %} 6218 ins_pipe(pipe_class_default); 6219 %} 6220 6221 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6222 // leaving the upper 32 bits with sign-extension bits. 6223 // This clears these bits: dst = src & 0xFFFFFFFF. 6224 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6225 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6226 effect(DEF dst, USE src); 6227 predicate(false); 6228 6229 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6230 size(4); 6231 ins_encode %{ 6232 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6233 __ clrldi($dst$$Register, $src$$Register, 0x20); 6234 %} 6235 ins_pipe(pipe_class_default); 6236 %} 6237 6238 // Optimize DecodeN for disjoint base. 6239 // Load base of compressed oops into a register 6240 instruct loadBase(iRegLdst dst) %{ 6241 effect(DEF dst); 6242 6243 format %{ "LoadConst $dst, heapbase" %} 6244 ins_encode %{ 6245 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6246 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 6247 %} 6248 ins_pipe(pipe_class_default); 6249 %} 6250 6251 // Loading ConN must be postalloc expanded so that edges between 6252 // the nodes are safe. They may not interfere with a safepoint. 6253 // GL TODO: This needs three instructions: better put this into the constant pool. 6254 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6255 match(Set dst src); 6256 ins_cost(DEFAULT_COST*2); 6257 6258 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6259 postalloc_expand %{ 6260 MachNode *m1 = new loadConN_hiNode(); 6261 MachNode *m2 = new loadConN_loNode(); 6262 MachNode *m3 = new clearMs32bNode(); 6263 m1->add_req(NULL); 6264 m2->add_req(NULL, m1); 6265 m3->add_req(NULL, m2); 6266 m1->_opnds[0] = op_dst; 6267 m1->_opnds[1] = op_src; 6268 m2->_opnds[0] = op_dst; 6269 m2->_opnds[1] = op_dst; 6270 m2->_opnds[2] = op_src; 6271 m3->_opnds[0] = op_dst; 6272 m3->_opnds[1] = op_dst; 6273 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6274 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6275 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6276 nodes->push(m1); 6277 nodes->push(m2); 6278 nodes->push(m3); 6279 %} 6280 %} 6281 6282 // We have seen a safepoint between the hi and lo parts, and this node was handled 6283 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6284 // not a narrow oop. 6285 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6286 match(Set dst src); 6287 effect(DEF dst, USE src); 6288 ins_cost(DEFAULT_COST); 6289 6290 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6291 size(4); 6292 ins_encode %{ 6293 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6294 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 6295 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6296 %} 6297 ins_pipe(pipe_class_default); 6298 %} 6299 6300 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6301 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6302 match(Set dst src1); 6303 effect(TEMP src2); 6304 ins_cost(DEFAULT_COST); 6305 6306 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6307 size(4); 6308 ins_encode %{ 6309 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6310 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6311 %} 6312 ins_pipe(pipe_class_default); 6313 %} 6314 6315 // This needs a match rule so that build_oop_map knows this is 6316 // not a narrow oop. 6317 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6318 match(Set dst src1); 6319 effect(TEMP src2); 6320 ins_cost(DEFAULT_COST); 6321 6322 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6323 size(4); 6324 ins_encode %{ 6325 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6326 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 6327 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6328 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6329 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6330 6331 __ relocate(rspec, 1); 6332 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6333 %} 6334 ins_pipe(pipe_class_default); 6335 %} 6336 6337 // Loading ConNKlass must be postalloc expanded so that edges between 6338 // the nodes are safe. They may not interfere with a safepoint. 6339 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6340 match(Set dst src); 6341 ins_cost(DEFAULT_COST*2); 6342 6343 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6344 postalloc_expand %{ 6345 // Load high bits into register. Sign extended. 6346 MachNode *m1 = new loadConNKlass_hiNode(); 6347 m1->add_req(NULL); 6348 m1->_opnds[0] = op_dst; 6349 m1->_opnds[1] = op_src; 6350 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6351 nodes->push(m1); 6352 6353 MachNode *m2 = m1; 6354 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 6355 // Value might be 1-extended. Mask out these bits. 6356 m2 = new loadConNKlass_maskNode(); 6357 m2->add_req(NULL, m1); 6358 m2->_opnds[0] = op_dst; 6359 m2->_opnds[1] = op_src; 6360 m2->_opnds[2] = op_dst; 6361 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6362 nodes->push(m2); 6363 } 6364 6365 MachNode *m3 = new loadConNKlass_loNode(); 6366 m3->add_req(NULL, m2); 6367 m3->_opnds[0] = op_dst; 6368 m3->_opnds[1] = op_src; 6369 m3->_opnds[2] = op_dst; 6370 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6371 nodes->push(m3); 6372 %} 6373 %} 6374 6375 // 0x1 is used in object initialization (initial object header). 6376 // No constant pool entries required. 6377 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6378 match(Set dst src); 6379 6380 format %{ "LI $dst, $src \t// ptr" %} 6381 size(4); 6382 ins_encode %{ 6383 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6384 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6385 %} 6386 ins_pipe(pipe_class_default); 6387 %} 6388 6389 // Expand node for constant pool load: small offset. 6390 // The match rule is needed to generate the correct bottom_type(), 6391 // however this node should never match. The use of predicate is not 6392 // possible since ADLC forbids predicates for chain rules. The higher 6393 // costs do not prevent matching in this case. For that reason the 6394 // operand immP_NM with predicate(false) is used. 6395 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6396 match(Set dst src); 6397 effect(TEMP toc); 6398 6399 ins_num_consts(1); 6400 6401 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6402 size(4); 6403 ins_encode( enc_load_long_constP(dst, src, toc) ); 6404 ins_pipe(pipe_class_memory); 6405 %} 6406 6407 // Expand node for constant pool load: large offset. 6408 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6409 effect(DEF dst, USE src, USE toc); 6410 predicate(false); 6411 6412 ins_num_consts(1); 6413 ins_field_const_toc_offset(int); 6414 6415 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6416 size(4); 6417 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6418 ins_pipe(pipe_class_default); 6419 %} 6420 6421 // Expand node for constant pool load: large offset. 6422 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6423 match(Set dst src); 6424 effect(TEMP base); 6425 6426 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6427 6428 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6429 size(4); 6430 ins_encode %{ 6431 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6432 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6433 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6434 %} 6435 ins_pipe(pipe_class_memory); 6436 %} 6437 6438 // Load pointer constant from constant table. Expand in case an 6439 // offset > 16 bit is needed. 6440 // Adlc adds toc node MachConstantTableBase. 6441 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6442 match(Set dst src); 6443 ins_cost(MEMORY_REF_COST); 6444 6445 // This rule does not use "expand" because then 6446 // the result type is not known to be an Oop. An ADLC 6447 // enhancement will be needed to make that work - not worth it! 6448 6449 // If this instruction rematerializes, it prolongs the live range 6450 // of the toc node, causing illegal graphs. 6451 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6452 ins_cannot_rematerialize(true); 6453 6454 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6455 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6456 %} 6457 6458 // Expand node for constant pool load: small offset. 6459 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6460 effect(DEF dst, USE src, USE toc); 6461 ins_cost(MEMORY_REF_COST); 6462 6463 ins_num_consts(1); 6464 6465 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6466 size(4); 6467 ins_encode %{ 6468 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6469 address float_address = __ float_constant($src$$constant); 6470 if (float_address == NULL) { 6471 ciEnv::current()->record_out_of_memory_failure(); 6472 return; 6473 } 6474 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6475 %} 6476 ins_pipe(pipe_class_memory); 6477 %} 6478 6479 // Expand node for constant pool load: large offset. 6480 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6481 effect(DEF dst, USE src, USE toc); 6482 ins_cost(MEMORY_REF_COST); 6483 6484 ins_num_consts(1); 6485 6486 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6487 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6488 "ADDIS $toc, $toc, -offset_hi"%} 6489 size(12); 6490 ins_encode %{ 6491 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6492 FloatRegister Rdst = $dst$$FloatRegister; 6493 Register Rtoc = $toc$$Register; 6494 address float_address = __ float_constant($src$$constant); 6495 if (float_address == NULL) { 6496 ciEnv::current()->record_out_of_memory_failure(); 6497 return; 6498 } 6499 int offset = __ offset_to_method_toc(float_address); 6500 int hi = (offset + (1<<15))>>16; 6501 int lo = offset - hi * (1<<16); 6502 6503 __ addis(Rtoc, Rtoc, hi); 6504 __ lfs(Rdst, lo, Rtoc); 6505 __ addis(Rtoc, Rtoc, -hi); 6506 %} 6507 ins_pipe(pipe_class_memory); 6508 %} 6509 6510 // Adlc adds toc node MachConstantTableBase. 6511 instruct loadConF_Ex(regF dst, immF src) %{ 6512 match(Set dst src); 6513 ins_cost(MEMORY_REF_COST); 6514 6515 // See loadConP. 6516 ins_cannot_rematerialize(true); 6517 6518 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6519 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6520 %} 6521 6522 // Expand node for constant pool load: small offset. 6523 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6524 effect(DEF dst, USE src, USE toc); 6525 ins_cost(MEMORY_REF_COST); 6526 6527 ins_num_consts(1); 6528 6529 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6530 size(4); 6531 ins_encode %{ 6532 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6533 address float_address = __ double_constant($src$$constant); 6534 if (float_address == NULL) { 6535 ciEnv::current()->record_out_of_memory_failure(); 6536 return; 6537 } 6538 int offset = __ offset_to_method_toc(float_address); 6539 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6540 %} 6541 ins_pipe(pipe_class_memory); 6542 %} 6543 6544 // Expand node for constant pool load: large offset. 6545 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6546 effect(DEF dst, USE src, USE toc); 6547 ins_cost(MEMORY_REF_COST); 6548 6549 ins_num_consts(1); 6550 6551 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6552 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6553 "ADDIS $toc, $toc, -offset_hi" %} 6554 size(12); 6555 ins_encode %{ 6556 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6557 FloatRegister Rdst = $dst$$FloatRegister; 6558 Register Rtoc = $toc$$Register; 6559 address float_address = __ double_constant($src$$constant); 6560 if (float_address == NULL) { 6561 ciEnv::current()->record_out_of_memory_failure(); 6562 return; 6563 } 6564 int offset = __ offset_to_method_toc(float_address); 6565 int hi = (offset + (1<<15))>>16; 6566 int lo = offset - hi * (1<<16); 6567 6568 __ addis(Rtoc, Rtoc, hi); 6569 __ lfd(Rdst, lo, Rtoc); 6570 __ addis(Rtoc, Rtoc, -hi); 6571 %} 6572 ins_pipe(pipe_class_memory); 6573 %} 6574 6575 // Adlc adds toc node MachConstantTableBase. 6576 instruct loadConD_Ex(regD dst, immD src) %{ 6577 match(Set dst src); 6578 ins_cost(MEMORY_REF_COST); 6579 6580 // See loadConP. 6581 ins_cannot_rematerialize(true); 6582 6583 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6584 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6585 %} 6586 6587 // Prefetch instructions. 6588 // Must be safe to execute with invalid address (cannot fault). 6589 6590 // Special prefetch versions which use the dcbz instruction. 6591 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6592 match(PrefetchAllocation (AddP mem src)); 6593 predicate(AllocatePrefetchStyle == 3); 6594 ins_cost(MEMORY_REF_COST); 6595 6596 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6597 size(4); 6598 ins_encode %{ 6599 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6600 __ dcbz($src$$Register, $mem$$base$$Register); 6601 %} 6602 ins_pipe(pipe_class_memory); 6603 %} 6604 6605 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6606 match(PrefetchAllocation mem); 6607 predicate(AllocatePrefetchStyle == 3); 6608 ins_cost(MEMORY_REF_COST); 6609 6610 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6611 size(4); 6612 ins_encode %{ 6613 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6614 __ dcbz($mem$$base$$Register); 6615 %} 6616 ins_pipe(pipe_class_memory); 6617 %} 6618 6619 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6620 match(PrefetchAllocation (AddP mem src)); 6621 predicate(AllocatePrefetchStyle != 3); 6622 ins_cost(MEMORY_REF_COST); 6623 6624 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6625 size(4); 6626 ins_encode %{ 6627 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6628 __ dcbtst($src$$Register, $mem$$base$$Register); 6629 %} 6630 ins_pipe(pipe_class_memory); 6631 %} 6632 6633 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6634 match(PrefetchAllocation mem); 6635 predicate(AllocatePrefetchStyle != 3); 6636 ins_cost(MEMORY_REF_COST); 6637 6638 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6639 size(4); 6640 ins_encode %{ 6641 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6642 __ dcbtst($mem$$base$$Register); 6643 %} 6644 ins_pipe(pipe_class_memory); 6645 %} 6646 6647 //----------Store Instructions------------------------------------------------- 6648 6649 // Store Byte 6650 instruct storeB(memory mem, iRegIsrc src) %{ 6651 match(Set mem (StoreB mem src)); 6652 ins_cost(MEMORY_REF_COST); 6653 6654 format %{ "STB $src, $mem \t// byte" %} 6655 size(4); 6656 ins_encode %{ 6657 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6658 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6659 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6660 %} 6661 ins_pipe(pipe_class_memory); 6662 %} 6663 6664 // Store Char/Short 6665 instruct storeC(memory mem, iRegIsrc src) %{ 6666 match(Set mem (StoreC mem src)); 6667 ins_cost(MEMORY_REF_COST); 6668 6669 format %{ "STH $src, $mem \t// short" %} 6670 size(4); 6671 ins_encode %{ 6672 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6673 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6674 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6675 %} 6676 ins_pipe(pipe_class_memory); 6677 %} 6678 6679 // Store Integer 6680 instruct storeI(memory mem, iRegIsrc src) %{ 6681 match(Set mem (StoreI mem src)); 6682 ins_cost(MEMORY_REF_COST); 6683 6684 format %{ "STW $src, $mem" %} 6685 size(4); 6686 ins_encode( enc_stw(src, mem) ); 6687 ins_pipe(pipe_class_memory); 6688 %} 6689 6690 // ConvL2I + StoreI. 6691 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6692 match(Set mem (StoreI mem (ConvL2I src))); 6693 ins_cost(MEMORY_REF_COST); 6694 6695 format %{ "STW l2i($src), $mem" %} 6696 size(4); 6697 ins_encode( enc_stw(src, mem) ); 6698 ins_pipe(pipe_class_memory); 6699 %} 6700 6701 // Store Long 6702 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6703 match(Set mem (StoreL mem src)); 6704 ins_cost(MEMORY_REF_COST); 6705 6706 format %{ "STD $src, $mem \t// long" %} 6707 size(4); 6708 ins_encode( enc_std(src, mem) ); 6709 ins_pipe(pipe_class_memory); 6710 %} 6711 6712 // Store super word nodes. 6713 6714 // Store Aligned Packed Byte long register to memory 6715 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6716 predicate(n->as_StoreVector()->memory_size() == 8); 6717 match(Set mem (StoreVector mem src)); 6718 ins_cost(MEMORY_REF_COST); 6719 6720 format %{ "STD $mem, $src \t// packed8B" %} 6721 size(4); 6722 ins_encode( enc_std(src, mem) ); 6723 ins_pipe(pipe_class_memory); 6724 %} 6725 6726 // Store Packed Byte long register to memory 6727 instruct storeV16(indirect mem, vecX src) %{ 6728 predicate(n->as_StoreVector()->memory_size() == 16); 6729 match(Set mem (StoreVector mem src)); 6730 ins_cost(MEMORY_REF_COST); 6731 6732 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6733 size(4); 6734 ins_encode %{ 6735 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6736 %} 6737 ins_pipe(pipe_class_default); 6738 %} 6739 6740 // Store Compressed Oop 6741 instruct storeN(memory dst, iRegN_P2N src) %{ 6742 match(Set dst (StoreN dst src)); 6743 ins_cost(MEMORY_REF_COST); 6744 6745 format %{ "STW $src, $dst \t// compressed oop" %} 6746 size(4); 6747 ins_encode( enc_stw(src, dst) ); 6748 ins_pipe(pipe_class_memory); 6749 %} 6750 6751 // Store Compressed KLass 6752 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6753 match(Set dst (StoreNKlass dst src)); 6754 ins_cost(MEMORY_REF_COST); 6755 6756 format %{ "STW $src, $dst \t// compressed klass" %} 6757 size(4); 6758 ins_encode( enc_stw(src, dst) ); 6759 ins_pipe(pipe_class_memory); 6760 %} 6761 6762 // Store Pointer 6763 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6764 match(Set dst (StoreP dst src)); 6765 ins_cost(MEMORY_REF_COST); 6766 6767 format %{ "STD $src, $dst \t// ptr" %} 6768 size(4); 6769 ins_encode( enc_std(src, dst) ); 6770 ins_pipe(pipe_class_memory); 6771 %} 6772 6773 // Store Float 6774 instruct storeF(memory mem, regF src) %{ 6775 match(Set mem (StoreF mem src)); 6776 ins_cost(MEMORY_REF_COST); 6777 6778 format %{ "STFS $src, $mem" %} 6779 size(4); 6780 ins_encode( enc_stfs(src, mem) ); 6781 ins_pipe(pipe_class_memory); 6782 %} 6783 6784 // Store Double 6785 instruct storeD(memory mem, regD src) %{ 6786 match(Set mem (StoreD mem src)); 6787 ins_cost(MEMORY_REF_COST); 6788 6789 format %{ "STFD $src, $mem" %} 6790 size(4); 6791 ins_encode( enc_stfd(src, mem) ); 6792 ins_pipe(pipe_class_memory); 6793 %} 6794 6795 //----------Store Instructions With Zeros-------------------------------------- 6796 6797 // Card-mark for CMS garbage collection. 6798 // This cardmark does an optimization so that it must not always 6799 // do a releasing store. For this, it gets the address of 6800 // CMSCollectorCardTableModRefBSExt::_requires_release as input. 6801 // (Using releaseFieldAddr in the match rule is a hack.) 6802 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6803 match(Set mem (StoreCM mem releaseFieldAddr)); 6804 effect(TEMP crx); 6805 predicate(false); 6806 ins_cost(MEMORY_REF_COST); 6807 6808 // See loadConP. 6809 ins_cannot_rematerialize(true); 6810 6811 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6812 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6813 ins_pipe(pipe_class_memory); 6814 %} 6815 6816 // Card-mark for CMS garbage collection. 6817 // This cardmark does an optimization so that it must not always 6818 // do a releasing store. For this, it needs the constant address of 6819 // CMSCollectorCardTableModRefBSExt::_requires_release. 6820 // This constant address is split off here by expand so we can use 6821 // adlc / matcher functionality to load it from the constant section. 6822 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6823 match(Set mem (StoreCM mem zero)); 6824 predicate(UseConcMarkSweepGC); 6825 6826 expand %{ 6827 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableModRefBSExt::requires_release_address() */ %} 6828 iRegLdst releaseFieldAddress; 6829 flagsReg crx; 6830 loadConL_Ex(releaseFieldAddress, baseImm); 6831 storeCM_CMS(mem, releaseFieldAddress, crx); 6832 %} 6833 %} 6834 6835 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6836 match(Set mem (StoreCM mem zero)); 6837 predicate(UseG1GC); 6838 ins_cost(MEMORY_REF_COST); 6839 6840 ins_cannot_rematerialize(true); 6841 6842 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6843 size(8); 6844 ins_encode %{ 6845 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6846 __ li(R0, 0); 6847 //__ release(); // G1: oops are allowed to get visible after dirty marking 6848 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6849 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6850 %} 6851 ins_pipe(pipe_class_memory); 6852 %} 6853 6854 // Convert oop pointer into compressed form. 6855 6856 // Nodes for postalloc expand. 6857 6858 // Shift node for expand. 6859 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6860 // The match rule is needed to make it a 'MachTypeNode'! 6861 match(Set dst (EncodeP src)); 6862 predicate(false); 6863 6864 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6865 size(4); 6866 ins_encode %{ 6867 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6868 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6869 %} 6870 ins_pipe(pipe_class_default); 6871 %} 6872 6873 // Add node for expand. 6874 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6875 // The match rule is needed to make it a 'MachTypeNode'! 6876 match(Set dst (EncodeP src)); 6877 predicate(false); 6878 6879 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6880 ins_encode %{ 6881 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6882 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6883 %} 6884 ins_pipe(pipe_class_default); 6885 %} 6886 6887 // Conditional sub base. 6888 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6889 // The match rule is needed to make it a 'MachTypeNode'! 6890 match(Set dst (EncodeP (Binary crx src1))); 6891 predicate(false); 6892 6893 format %{ "BEQ $crx, done\n\t" 6894 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6895 "done:" %} 6896 ins_encode %{ 6897 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6898 Label done; 6899 __ beq($crx$$CondRegister, done); 6900 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6901 __ bind(done); 6902 %} 6903 ins_pipe(pipe_class_default); 6904 %} 6905 6906 // Power 7 can use isel instruction 6907 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6908 // The match rule is needed to make it a 'MachTypeNode'! 6909 match(Set dst (EncodeP (Binary crx src1))); 6910 predicate(false); 6911 6912 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6913 size(4); 6914 ins_encode %{ 6915 // This is a Power7 instruction for which no machine description exists. 6916 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6917 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6918 %} 6919 ins_pipe(pipe_class_default); 6920 %} 6921 6922 // Disjoint narrow oop base. 6923 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6924 match(Set dst (EncodeP src)); 6925 predicate(Universe::narrow_oop_base_disjoint()); 6926 6927 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6928 size(4); 6929 ins_encode %{ 6930 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6931 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 6932 %} 6933 ins_pipe(pipe_class_default); 6934 %} 6935 6936 // shift != 0, base != 0 6937 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6938 match(Set dst (EncodeP src)); 6939 effect(TEMP crx); 6940 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6941 Universe::narrow_oop_shift() != 0 && 6942 Universe::narrow_oop_base_overlaps()); 6943 6944 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 6945 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 6946 %} 6947 6948 // shift != 0, base != 0 6949 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 6950 match(Set dst (EncodeP src)); 6951 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 6952 Universe::narrow_oop_shift() != 0 && 6953 Universe::narrow_oop_base_overlaps()); 6954 6955 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 6956 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 6957 %} 6958 6959 // shift != 0, base == 0 6960 // TODO: This is the same as encodeP_shift. Merge! 6961 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 6962 match(Set dst (EncodeP src)); 6963 predicate(Universe::narrow_oop_shift() != 0 && 6964 Universe::narrow_oop_base() ==0); 6965 6966 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 6967 size(4); 6968 ins_encode %{ 6969 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6970 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6971 %} 6972 ins_pipe(pipe_class_default); 6973 %} 6974 6975 // Compressed OOPs with narrow_oop_shift == 0. 6976 // shift == 0, base == 0 6977 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 6978 match(Set dst (EncodeP src)); 6979 predicate(Universe::narrow_oop_shift() == 0); 6980 6981 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 6982 // variable size, 0 or 4. 6983 ins_encode %{ 6984 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6985 __ mr_if_needed($dst$$Register, $src$$Register); 6986 %} 6987 ins_pipe(pipe_class_default); 6988 %} 6989 6990 // Decode nodes. 6991 6992 // Shift node for expand. 6993 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 6994 // The match rule is needed to make it a 'MachTypeNode'! 6995 match(Set dst (DecodeN src)); 6996 predicate(false); 6997 6998 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 6999 size(4); 7000 ins_encode %{ 7001 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7002 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7003 %} 7004 ins_pipe(pipe_class_default); 7005 %} 7006 7007 // Add node for expand. 7008 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7009 // The match rule is needed to make it a 'MachTypeNode'! 7010 match(Set dst (DecodeN src)); 7011 predicate(false); 7012 7013 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7014 ins_encode %{ 7015 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7016 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7017 %} 7018 ins_pipe(pipe_class_default); 7019 %} 7020 7021 // conditianal add base for expand 7022 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7023 // The match rule is needed to make it a 'MachTypeNode'! 7024 // NOTICE that the rule is nonsense - we just have to make sure that: 7025 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7026 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7027 match(Set dst (DecodeN (Binary crx src))); 7028 predicate(false); 7029 7030 format %{ "BEQ $crx, done\n\t" 7031 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7032 "done:" %} 7033 ins_encode %{ 7034 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7035 Label done; 7036 __ beq($crx$$CondRegister, done); 7037 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7038 __ bind(done); 7039 %} 7040 ins_pipe(pipe_class_default); 7041 %} 7042 7043 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7044 // The match rule is needed to make it a 'MachTypeNode'! 7045 // NOTICE that the rule is nonsense - we just have to make sure that: 7046 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7047 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7048 match(Set dst (DecodeN (Binary crx src1))); 7049 predicate(false); 7050 7051 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7052 size(4); 7053 ins_encode %{ 7054 // This is a Power7 instruction for which no machine description exists. 7055 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7056 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7057 %} 7058 ins_pipe(pipe_class_default); 7059 %} 7060 7061 // shift != 0, base != 0 7062 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7063 match(Set dst (DecodeN src)); 7064 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7065 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7066 Universe::narrow_oop_shift() != 0 && 7067 Universe::narrow_oop_base() != 0); 7068 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7069 effect(TEMP crx); 7070 7071 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7072 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7073 %} 7074 7075 // shift != 0, base == 0 7076 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7077 match(Set dst (DecodeN src)); 7078 predicate(Universe::narrow_oop_shift() != 0 && 7079 Universe::narrow_oop_base() == 0); 7080 7081 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7082 size(4); 7083 ins_encode %{ 7084 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7085 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7086 %} 7087 ins_pipe(pipe_class_default); 7088 %} 7089 7090 // Optimize DecodeN for disjoint base. 7091 // Shift narrow oop and or it into register that already contains the heap base. 7092 // Base == dst must hold, and is assured by construction in postaloc_expand. 7093 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7094 match(Set dst (DecodeN src)); 7095 effect(TEMP base); 7096 predicate(false); 7097 7098 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7099 size(4); 7100 ins_encode %{ 7101 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7102 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 7103 %} 7104 ins_pipe(pipe_class_default); 7105 %} 7106 7107 // Optimize DecodeN for disjoint base. 7108 // This node requires only one cycle on the critical path. 7109 // We must postalloc_expand as we can not express use_def effects where 7110 // the used register is L and the def'ed register P. 7111 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7112 match(Set dst (DecodeN src)); 7113 effect(TEMP_DEF dst); 7114 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7115 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7116 Universe::narrow_oop_base_disjoint()); 7117 ins_cost(DEFAULT_COST); 7118 7119 format %{ "MOV $dst, heapbase \t\n" 7120 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7121 postalloc_expand %{ 7122 loadBaseNode *n1 = new loadBaseNode(); 7123 n1->add_req(NULL); 7124 n1->_opnds[0] = op_dst; 7125 7126 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7127 n2->add_req(n_region, n_src, n1); 7128 n2->_opnds[0] = op_dst; 7129 n2->_opnds[1] = op_src; 7130 n2->_opnds[2] = op_dst; 7131 n2->_bottom_type = _bottom_type; 7132 7133 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7134 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7135 7136 nodes->push(n1); 7137 nodes->push(n2); 7138 %} 7139 %} 7140 7141 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7142 match(Set dst (DecodeN src)); 7143 effect(TEMP_DEF dst, TEMP crx); 7144 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7145 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7146 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 7147 ins_cost(3 * DEFAULT_COST); 7148 7149 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7150 postalloc_expand %{ 7151 loadBaseNode *n1 = new loadBaseNode(); 7152 n1->add_req(NULL); 7153 n1->_opnds[0] = op_dst; 7154 7155 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7156 n_compare->add_req(n_region, n_src); 7157 n_compare->_opnds[0] = op_crx; 7158 n_compare->_opnds[1] = op_src; 7159 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7160 7161 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7162 n2->add_req(n_region, n_src, n1); 7163 n2->_opnds[0] = op_dst; 7164 n2->_opnds[1] = op_src; 7165 n2->_opnds[2] = op_dst; 7166 n2->_bottom_type = _bottom_type; 7167 7168 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7169 n_cond_set->add_req(n_region, n_compare, n2); 7170 n_cond_set->_opnds[0] = op_dst; 7171 n_cond_set->_opnds[1] = op_crx; 7172 n_cond_set->_opnds[2] = op_dst; 7173 n_cond_set->_bottom_type = _bottom_type; 7174 7175 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7176 ra_->set_oop(n_cond_set, true); 7177 7178 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7179 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7180 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7181 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7182 7183 nodes->push(n1); 7184 nodes->push(n_compare); 7185 nodes->push(n2); 7186 nodes->push(n_cond_set); 7187 %} 7188 %} 7189 7190 // src != 0, shift != 0, base != 0 7191 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7192 match(Set dst (DecodeN src)); 7193 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7194 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7195 Universe::narrow_oop_shift() != 0 && 7196 Universe::narrow_oop_base() != 0); 7197 ins_cost(2 * DEFAULT_COST); 7198 7199 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7200 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7201 %} 7202 7203 // Compressed OOPs with narrow_oop_shift == 0. 7204 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7205 match(Set dst (DecodeN src)); 7206 predicate(Universe::narrow_oop_shift() == 0); 7207 ins_cost(DEFAULT_COST); 7208 7209 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7210 // variable size, 0 or 4. 7211 ins_encode %{ 7212 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7213 __ mr_if_needed($dst$$Register, $src$$Register); 7214 %} 7215 ins_pipe(pipe_class_default); 7216 %} 7217 7218 // Convert compressed oop into int for vectors alignment masking. 7219 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7220 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7221 predicate(Universe::narrow_oop_shift() == 0); 7222 ins_cost(DEFAULT_COST); 7223 7224 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7225 // variable size, 0 or 4. 7226 ins_encode %{ 7227 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7228 __ mr_if_needed($dst$$Register, $src$$Register); 7229 %} 7230 ins_pipe(pipe_class_default); 7231 %} 7232 7233 // Convert klass pointer into compressed form. 7234 7235 // Nodes for postalloc expand. 7236 7237 // Shift node for expand. 7238 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7239 // The match rule is needed to make it a 'MachTypeNode'! 7240 match(Set dst (EncodePKlass src)); 7241 predicate(false); 7242 7243 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7244 size(4); 7245 ins_encode %{ 7246 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7247 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7248 %} 7249 ins_pipe(pipe_class_default); 7250 %} 7251 7252 // Add node for expand. 7253 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7254 // The match rule is needed to make it a 'MachTypeNode'! 7255 match(Set dst (EncodePKlass (Binary base src))); 7256 predicate(false); 7257 7258 format %{ "SUB $dst, $base, $src \t// encode" %} 7259 size(4); 7260 ins_encode %{ 7261 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7262 __ subf($dst$$Register, $base$$Register, $src$$Register); 7263 %} 7264 ins_pipe(pipe_class_default); 7265 %} 7266 7267 // Disjoint narrow oop base. 7268 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7269 match(Set dst (EncodePKlass src)); 7270 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 7271 7272 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7273 size(4); 7274 ins_encode %{ 7275 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7276 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 7277 %} 7278 ins_pipe(pipe_class_default); 7279 %} 7280 7281 // shift != 0, base != 0 7282 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7283 match(Set dst (EncodePKlass (Binary base src))); 7284 predicate(false); 7285 7286 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7287 postalloc_expand %{ 7288 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7289 n1->add_req(n_region, n_base, n_src); 7290 n1->_opnds[0] = op_dst; 7291 n1->_opnds[1] = op_base; 7292 n1->_opnds[2] = op_src; 7293 n1->_bottom_type = _bottom_type; 7294 7295 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7296 n2->add_req(n_region, n1); 7297 n2->_opnds[0] = op_dst; 7298 n2->_opnds[1] = op_dst; 7299 n2->_bottom_type = _bottom_type; 7300 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7301 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7302 7303 nodes->push(n1); 7304 nodes->push(n2); 7305 %} 7306 %} 7307 7308 // shift != 0, base != 0 7309 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7310 match(Set dst (EncodePKlass src)); 7311 //predicate(Universe::narrow_klass_shift() != 0 && 7312 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 7313 7314 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7315 ins_cost(DEFAULT_COST*2); // Don't count constant. 7316 expand %{ 7317 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 7318 iRegLdst base; 7319 loadConL_Ex(base, baseImm); 7320 encodePKlass_not_null_Ex(dst, base, src); 7321 %} 7322 %} 7323 7324 // Decode nodes. 7325 7326 // Shift node for expand. 7327 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7328 // The match rule is needed to make it a 'MachTypeNode'! 7329 match(Set dst (DecodeNKlass src)); 7330 predicate(false); 7331 7332 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7333 size(4); 7334 ins_encode %{ 7335 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7336 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7337 %} 7338 ins_pipe(pipe_class_default); 7339 %} 7340 7341 // Add node for expand. 7342 7343 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7344 // The match rule is needed to make it a 'MachTypeNode'! 7345 match(Set dst (DecodeNKlass (Binary base src))); 7346 predicate(false); 7347 7348 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7349 size(4); 7350 ins_encode %{ 7351 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7352 __ add($dst$$Register, $base$$Register, $src$$Register); 7353 %} 7354 ins_pipe(pipe_class_default); 7355 %} 7356 7357 // src != 0, shift != 0, base != 0 7358 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7359 match(Set dst (DecodeNKlass (Binary base src))); 7360 //effect(kill src); // We need a register for the immediate result after shifting. 7361 predicate(false); 7362 7363 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7364 postalloc_expand %{ 7365 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7366 n1->add_req(n_region, n_base, n_src); 7367 n1->_opnds[0] = op_dst; 7368 n1->_opnds[1] = op_base; 7369 n1->_opnds[2] = op_src; 7370 n1->_bottom_type = _bottom_type; 7371 7372 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7373 n2->add_req(n_region, n1); 7374 n2->_opnds[0] = op_dst; 7375 n2->_opnds[1] = op_dst; 7376 n2->_bottom_type = _bottom_type; 7377 7378 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7379 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7380 7381 nodes->push(n1); 7382 nodes->push(n2); 7383 %} 7384 %} 7385 7386 // src != 0, shift != 0, base != 0 7387 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7388 match(Set dst (DecodeNKlass src)); 7389 // predicate(Universe::narrow_klass_shift() != 0 && 7390 // Universe::narrow_klass_base() != 0); 7391 7392 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7393 7394 ins_cost(DEFAULT_COST*2); // Don't count constant. 7395 expand %{ 7396 // We add first, then we shift. Like this, we can get along with one register less. 7397 // But we have to load the base pre-shifted. 7398 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7399 iRegLdst base; 7400 loadConL_Ex(base, baseImm); 7401 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7402 %} 7403 %} 7404 7405 //----------MemBar Instructions----------------------------------------------- 7406 // Memory barrier flavors 7407 7408 instruct membar_acquire() %{ 7409 match(LoadFence); 7410 ins_cost(4*MEMORY_REF_COST); 7411 7412 format %{ "MEMBAR-acquire" %} 7413 size(4); 7414 ins_encode %{ 7415 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7416 __ acquire(); 7417 %} 7418 ins_pipe(pipe_class_default); 7419 %} 7420 7421 instruct unnecessary_membar_acquire() %{ 7422 match(MemBarAcquire); 7423 ins_cost(0); 7424 7425 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7426 size(0); 7427 ins_encode( /*empty*/ ); 7428 ins_pipe(pipe_class_default); 7429 %} 7430 7431 instruct membar_acquire_lock() %{ 7432 match(MemBarAcquireLock); 7433 ins_cost(0); 7434 7435 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7436 size(0); 7437 ins_encode( /*empty*/ ); 7438 ins_pipe(pipe_class_default); 7439 %} 7440 7441 instruct membar_release() %{ 7442 match(MemBarRelease); 7443 match(StoreFence); 7444 ins_cost(4*MEMORY_REF_COST); 7445 7446 format %{ "MEMBAR-release" %} 7447 size(4); 7448 ins_encode %{ 7449 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7450 __ release(); 7451 %} 7452 ins_pipe(pipe_class_default); 7453 %} 7454 7455 instruct membar_storestore() %{ 7456 match(MemBarStoreStore); 7457 ins_cost(4*MEMORY_REF_COST); 7458 7459 format %{ "MEMBAR-store-store" %} 7460 size(4); 7461 ins_encode %{ 7462 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7463 __ membar(Assembler::StoreStore); 7464 %} 7465 ins_pipe(pipe_class_default); 7466 %} 7467 7468 instruct membar_release_lock() %{ 7469 match(MemBarReleaseLock); 7470 ins_cost(0); 7471 7472 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7473 size(0); 7474 ins_encode( /*empty*/ ); 7475 ins_pipe(pipe_class_default); 7476 %} 7477 7478 instruct membar_volatile() %{ 7479 match(MemBarVolatile); 7480 ins_cost(4*MEMORY_REF_COST); 7481 7482 format %{ "MEMBAR-volatile" %} 7483 size(4); 7484 ins_encode %{ 7485 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7486 __ fence(); 7487 %} 7488 ins_pipe(pipe_class_default); 7489 %} 7490 7491 // This optimization is wrong on PPC. The following pattern is not supported: 7492 // MemBarVolatile 7493 // ^ ^ 7494 // | | 7495 // CtrlProj MemProj 7496 // ^ ^ 7497 // | | 7498 // | Load 7499 // | 7500 // MemBarVolatile 7501 // 7502 // The first MemBarVolatile could get optimized out! According to 7503 // Vladimir, this pattern can not occur on Oracle platforms. 7504 // However, it does occur on PPC64 (because of membars in 7505 // inline_unsafe_load_store). 7506 // 7507 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7508 // Don't forget to look at the implementation of post_store_load_barrier again, 7509 // we did other fixes in that method. 7510 //instruct unnecessary_membar_volatile() %{ 7511 // match(MemBarVolatile); 7512 // predicate(Matcher::post_store_load_barrier(n)); 7513 // ins_cost(0); 7514 // 7515 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7516 // size(0); 7517 // ins_encode( /*empty*/ ); 7518 // ins_pipe(pipe_class_default); 7519 //%} 7520 7521 instruct membar_CPUOrder() %{ 7522 match(MemBarCPUOrder); 7523 ins_cost(0); 7524 7525 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7526 size(0); 7527 ins_encode( /*empty*/ ); 7528 ins_pipe(pipe_class_default); 7529 %} 7530 7531 //----------Conditional Move--------------------------------------------------- 7532 7533 // Cmove using isel. 7534 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7535 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7536 predicate(VM_Version::has_isel()); 7537 ins_cost(DEFAULT_COST); 7538 7539 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7540 size(4); 7541 ins_encode %{ 7542 // This is a Power7 instruction for which no machine description 7543 // exists. Anyways, the scheduler should be off on Power7. 7544 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7545 int cc = $cmp$$cmpcode; 7546 __ isel($dst$$Register, $crx$$CondRegister, 7547 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7548 %} 7549 ins_pipe(pipe_class_default); 7550 %} 7551 7552 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7553 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7554 predicate(!VM_Version::has_isel()); 7555 ins_cost(DEFAULT_COST+BRANCH_COST); 7556 7557 ins_variable_size_depending_on_alignment(true); 7558 7559 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7560 // Worst case is branch + move + stop, no stop without scheduler 7561 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7562 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7563 ins_pipe(pipe_class_default); 7564 %} 7565 7566 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7567 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7568 ins_cost(DEFAULT_COST+BRANCH_COST); 7569 7570 ins_variable_size_depending_on_alignment(true); 7571 7572 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7573 // Worst case is branch + move + stop, no stop without scheduler 7574 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7575 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7576 ins_pipe(pipe_class_default); 7577 %} 7578 7579 // Cmove using isel. 7580 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7581 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7582 predicate(VM_Version::has_isel()); 7583 ins_cost(DEFAULT_COST); 7584 7585 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7586 size(4); 7587 ins_encode %{ 7588 // This is a Power7 instruction for which no machine description 7589 // exists. Anyways, the scheduler should be off on Power7. 7590 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7591 int cc = $cmp$$cmpcode; 7592 __ isel($dst$$Register, $crx$$CondRegister, 7593 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7594 %} 7595 ins_pipe(pipe_class_default); 7596 %} 7597 7598 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7599 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7600 predicate(!VM_Version::has_isel()); 7601 ins_cost(DEFAULT_COST+BRANCH_COST); 7602 7603 ins_variable_size_depending_on_alignment(true); 7604 7605 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7606 // Worst case is branch + move + stop, no stop without scheduler. 7607 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7608 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7609 ins_pipe(pipe_class_default); 7610 %} 7611 7612 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7613 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7614 ins_cost(DEFAULT_COST+BRANCH_COST); 7615 7616 ins_variable_size_depending_on_alignment(true); 7617 7618 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7619 // Worst case is branch + move + stop, no stop without scheduler. 7620 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7621 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7622 ins_pipe(pipe_class_default); 7623 %} 7624 7625 // Cmove using isel. 7626 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7627 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7628 predicate(VM_Version::has_isel()); 7629 ins_cost(DEFAULT_COST); 7630 7631 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7632 size(4); 7633 ins_encode %{ 7634 // This is a Power7 instruction for which no machine description 7635 // exists. Anyways, the scheduler should be off on Power7. 7636 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7637 int cc = $cmp$$cmpcode; 7638 __ isel($dst$$Register, $crx$$CondRegister, 7639 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7640 %} 7641 ins_pipe(pipe_class_default); 7642 %} 7643 7644 // Conditional move for RegN. Only cmov(reg, reg). 7645 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7646 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7647 predicate(!VM_Version::has_isel()); 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_reg(dst, crx, src, cmp) ); 7656 ins_pipe(pipe_class_default); 7657 %} 7658 7659 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7660 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7661 ins_cost(DEFAULT_COST+BRANCH_COST); 7662 7663 ins_variable_size_depending_on_alignment(true); 7664 7665 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7666 // Worst case is branch + move + stop, no stop without scheduler. 7667 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7668 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7669 ins_pipe(pipe_class_default); 7670 %} 7671 7672 // Cmove using isel. 7673 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7674 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7675 predicate(VM_Version::has_isel()); 7676 ins_cost(DEFAULT_COST); 7677 7678 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7679 size(4); 7680 ins_encode %{ 7681 // This is a Power7 instruction for which no machine description 7682 // exists. Anyways, the scheduler should be off on Power7. 7683 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7684 int cc = $cmp$$cmpcode; 7685 __ isel($dst$$Register, $crx$$CondRegister, 7686 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7687 %} 7688 ins_pipe(pipe_class_default); 7689 %} 7690 7691 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7692 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7693 predicate(!VM_Version::has_isel()); 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_reg(dst, crx, src, cmp) ); 7702 ins_pipe(pipe_class_default); 7703 %} 7704 7705 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7706 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7707 ins_cost(DEFAULT_COST+BRANCH_COST); 7708 7709 ins_variable_size_depending_on_alignment(true); 7710 7711 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7712 // Worst case is branch + move + stop, no stop without scheduler. 7713 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7714 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7715 ins_pipe(pipe_class_default); 7716 %} 7717 7718 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7719 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7720 ins_cost(DEFAULT_COST+BRANCH_COST); 7721 7722 ins_variable_size_depending_on_alignment(true); 7723 7724 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7725 // Worst case is branch + move + stop, no stop without scheduler. 7726 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7727 ins_encode %{ 7728 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7729 Label done; 7730 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7731 // Branch if not (cmp crx). 7732 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7733 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7734 // TODO PPC port __ endgroup_if_needed(_size == 12); 7735 __ bind(done); 7736 %} 7737 ins_pipe(pipe_class_default); 7738 %} 7739 7740 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7741 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7742 ins_cost(DEFAULT_COST+BRANCH_COST); 7743 7744 ins_variable_size_depending_on_alignment(true); 7745 7746 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7747 // Worst case is branch + move + stop, no stop without scheduler. 7748 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7749 ins_encode %{ 7750 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7751 Label done; 7752 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7753 // Branch if not (cmp crx). 7754 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7755 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7756 // TODO PPC port __ endgroup_if_needed(_size == 12); 7757 __ bind(done); 7758 %} 7759 ins_pipe(pipe_class_default); 7760 %} 7761 7762 //----------Conditional_store-------------------------------------------------- 7763 // Conditional-store of the updated heap-top. 7764 // Used during allocation of the shared heap. 7765 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7766 7767 // As compareAndSwapL, but return flag register instead of boolean value in 7768 // int register. 7769 // Used by sun/misc/AtomicLongCSImpl.java. 7770 // Mem_ptr must be a memory operand, else this node does not get 7771 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7772 // can be rematerialized which leads to errors. 7773 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7774 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7775 effect(TEMP cr0); 7776 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7777 ins_encode %{ 7778 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7779 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7780 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7781 noreg, NULL, true); 7782 %} 7783 ins_pipe(pipe_class_default); 7784 %} 7785 7786 // As compareAndSwapP, but return flag register instead of boolean value in 7787 // int register. 7788 // This instruction is matched if UseTLAB is off. 7789 // Mem_ptr must be a memory operand, else this node does not get 7790 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7791 // can be rematerialized which leads to errors. 7792 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7793 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7794 ins_cost(2*MEMORY_REF_COST); 7795 7796 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7797 ins_encode %{ 7798 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7799 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7800 %} 7801 ins_pipe(pipe_class_memory); 7802 %} 7803 7804 // Implement LoadPLocked. Must be ordered against changes of the memory location 7805 // by storePConditional. 7806 // Don't know whether this is ever used. 7807 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7808 match(Set dst (LoadPLocked mem)); 7809 ins_cost(2*MEMORY_REF_COST); 7810 7811 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7812 size(4); 7813 ins_encode %{ 7814 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7815 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7816 %} 7817 ins_pipe(pipe_class_memory); 7818 %} 7819 7820 //----------Compare-And-Swap--------------------------------------------------- 7821 7822 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7823 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7824 // matched. 7825 7826 // Strong versions: 7827 7828 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7829 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7830 predicate(VM_Version::has_lqarx()); 7831 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7832 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7833 ins_encode %{ 7834 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7835 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7836 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7837 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7838 $res$$Register, true); 7839 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7840 __ isync(); 7841 } else { 7842 __ sync(); 7843 } 7844 %} 7845 ins_pipe(pipe_class_default); 7846 %} 7847 7848 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7849 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7850 predicate(!VM_Version::has_lqarx()); 7851 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7852 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7853 ins_encode %{ 7854 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7855 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7856 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7857 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7858 $res$$Register, true); 7859 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7860 __ isync(); 7861 } else { 7862 __ sync(); 7863 } 7864 %} 7865 ins_pipe(pipe_class_default); 7866 %} 7867 7868 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7869 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7870 predicate(VM_Version::has_lqarx()); 7871 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7872 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7873 ins_encode %{ 7874 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7875 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7876 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7877 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7878 $res$$Register, true); 7879 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7880 __ isync(); 7881 } else { 7882 __ sync(); 7883 } 7884 %} 7885 ins_pipe(pipe_class_default); 7886 %} 7887 7888 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7889 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7890 predicate(!VM_Version::has_lqarx()); 7891 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7892 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7893 ins_encode %{ 7894 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7895 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7896 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7897 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7898 $res$$Register, true); 7899 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7900 __ isync(); 7901 } else { 7902 __ sync(); 7903 } 7904 %} 7905 ins_pipe(pipe_class_default); 7906 %} 7907 7908 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7909 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7910 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7911 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7912 ins_encode %{ 7913 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7914 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7915 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7916 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7917 $res$$Register, true); 7918 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7919 __ isync(); 7920 } else { 7921 __ sync(); 7922 } 7923 %} 7924 ins_pipe(pipe_class_default); 7925 %} 7926 7927 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7928 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7929 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7930 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7931 ins_encode %{ 7932 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7933 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7934 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7935 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7936 $res$$Register, true); 7937 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7938 __ isync(); 7939 } else { 7940 __ sync(); 7941 } 7942 %} 7943 ins_pipe(pipe_class_default); 7944 %} 7945 7946 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7947 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 7948 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7949 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7950 ins_encode %{ 7951 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7952 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7953 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7954 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7955 $res$$Register, NULL, true); 7956 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7957 __ isync(); 7958 } else { 7959 __ sync(); 7960 } 7961 %} 7962 ins_pipe(pipe_class_default); 7963 %} 7964 7965 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7966 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 7967 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7968 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7969 ins_encode %{ 7970 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7971 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7972 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7973 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7974 $res$$Register, NULL, true); 7975 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7976 __ isync(); 7977 } else { 7978 __ sync(); 7979 } 7980 %} 7981 ins_pipe(pipe_class_default); 7982 %} 7983 7984 // Weak versions: 7985 7986 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7987 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7988 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7989 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7990 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7991 ins_encode %{ 7992 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7993 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7994 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7995 MacroAssembler::MemBarNone, 7996 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7997 %} 7998 ins_pipe(pipe_class_default); 7999 %} 8000 8001 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8002 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8003 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8004 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8005 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8006 ins_encode %{ 8007 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8008 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8009 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8010 MacroAssembler::MemBarNone, 8011 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8012 %} 8013 ins_pipe(pipe_class_default); 8014 %} 8015 8016 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8017 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8018 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8019 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8020 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8021 ins_encode %{ 8022 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8023 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8024 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8025 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8026 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8027 %} 8028 ins_pipe(pipe_class_default); 8029 %} 8030 8031 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8032 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8033 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8034 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8035 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8036 ins_encode %{ 8037 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8038 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8039 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8040 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8041 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8042 %} 8043 ins_pipe(pipe_class_default); 8044 %} 8045 8046 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8047 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8048 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8049 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8050 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8051 ins_encode %{ 8052 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8053 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8054 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8055 MacroAssembler::MemBarNone, 8056 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8057 %} 8058 ins_pipe(pipe_class_default); 8059 %} 8060 8061 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8062 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8063 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8064 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8065 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8066 ins_encode %{ 8067 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8068 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8069 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8070 MacroAssembler::MemBarNone, 8071 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8072 %} 8073 ins_pipe(pipe_class_default); 8074 %} 8075 8076 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8077 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8078 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8079 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8080 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8081 ins_encode %{ 8082 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8083 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8084 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8085 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8086 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8087 %} 8088 ins_pipe(pipe_class_default); 8089 %} 8090 8091 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8092 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8093 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8094 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8095 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8096 ins_encode %{ 8097 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8098 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8099 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8100 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8101 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8102 %} 8103 ins_pipe(pipe_class_default); 8104 %} 8105 8106 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8107 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8108 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8109 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8110 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8111 ins_encode %{ 8112 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8113 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8114 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8115 MacroAssembler::MemBarNone, 8116 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8117 %} 8118 ins_pipe(pipe_class_default); 8119 %} 8120 8121 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8122 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8123 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8124 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8125 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8126 ins_encode %{ 8127 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8128 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8129 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8130 // value is never passed to caller. 8131 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8132 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8133 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8134 %} 8135 ins_pipe(pipe_class_default); 8136 %} 8137 8138 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8139 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8140 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8141 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8142 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8143 ins_encode %{ 8144 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8145 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8146 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8147 MacroAssembler::MemBarNone, 8148 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8149 %} 8150 ins_pipe(pipe_class_default); 8151 %} 8152 8153 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8154 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8155 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8156 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8157 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8158 ins_encode %{ 8159 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8160 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8161 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8162 // value is never passed to caller. 8163 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8164 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8165 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8166 %} 8167 ins_pipe(pipe_class_default); 8168 %} 8169 8170 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8171 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8172 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8173 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8174 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8175 ins_encode %{ 8176 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8177 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8178 // value is never passed to caller. 8179 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8180 MacroAssembler::MemBarNone, 8181 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8182 %} 8183 ins_pipe(pipe_class_default); 8184 %} 8185 8186 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8187 match(Set res (WeakCompareAndSwapL 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 CMPXCHGD acq $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 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8195 // value is never passed to caller. 8196 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8197 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8198 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8199 %} 8200 ins_pipe(pipe_class_default); 8201 %} 8202 8203 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8204 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8205 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8206 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8207 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8208 ins_encode %{ 8209 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8210 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8211 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8212 MacroAssembler::MemBarNone, 8213 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8214 %} 8215 ins_pipe(pipe_class_default); 8216 %} 8217 8218 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8219 match(Set res (WeakCompareAndSwapP 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 CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8223 ins_encode %{ 8224 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8225 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8226 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8227 // value is never passed to caller. 8228 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8229 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8230 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8231 %} 8232 ins_pipe(pipe_class_default); 8233 %} 8234 8235 // CompareAndExchange 8236 8237 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8238 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8239 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8240 effect(TEMP_DEF res, TEMP cr0); 8241 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8242 ins_encode %{ 8243 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8244 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8245 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8246 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8247 noreg, true); 8248 %} 8249 ins_pipe(pipe_class_default); 8250 %} 8251 8252 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8253 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8254 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8255 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8256 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8257 ins_encode %{ 8258 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8259 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8260 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8261 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8262 noreg, true); 8263 %} 8264 ins_pipe(pipe_class_default); 8265 %} 8266 8267 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8268 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8269 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8270 effect(TEMP_DEF res, TEMP cr0); 8271 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8272 ins_encode %{ 8273 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8274 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8275 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8276 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8277 noreg, true); 8278 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8279 __ isync(); 8280 } else { 8281 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8282 __ sync(); 8283 } 8284 %} 8285 ins_pipe(pipe_class_default); 8286 %} 8287 8288 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8289 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8290 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8291 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8292 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8293 ins_encode %{ 8294 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8295 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8296 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8297 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8298 noreg, true); 8299 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8300 __ isync(); 8301 } else { 8302 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8303 __ sync(); 8304 } 8305 %} 8306 ins_pipe(pipe_class_default); 8307 %} 8308 8309 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8310 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8311 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8312 effect(TEMP_DEF res, TEMP cr0); 8313 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8314 ins_encode %{ 8315 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8316 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8317 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8318 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8319 noreg, true); 8320 %} 8321 ins_pipe(pipe_class_default); 8322 %} 8323 8324 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8325 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8326 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8327 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8328 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8329 ins_encode %{ 8330 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8331 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8332 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8333 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8334 noreg, true); 8335 %} 8336 ins_pipe(pipe_class_default); 8337 %} 8338 8339 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8340 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8341 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8342 effect(TEMP_DEF res, TEMP cr0); 8343 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8344 ins_encode %{ 8345 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8346 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8347 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8348 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8349 noreg, true); 8350 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8351 __ isync(); 8352 } else { 8353 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8354 __ sync(); 8355 } 8356 %} 8357 ins_pipe(pipe_class_default); 8358 %} 8359 8360 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8361 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8362 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8363 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8364 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8365 ins_encode %{ 8366 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8367 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8368 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8369 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8370 noreg, true); 8371 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8372 __ isync(); 8373 } else { 8374 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8375 __ sync(); 8376 } 8377 %} 8378 ins_pipe(pipe_class_default); 8379 %} 8380 8381 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8382 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8383 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8384 effect(TEMP_DEF res, TEMP cr0); 8385 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8386 ins_encode %{ 8387 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8388 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8389 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8390 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8391 noreg, true); 8392 %} 8393 ins_pipe(pipe_class_default); 8394 %} 8395 8396 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8397 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8398 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8399 effect(TEMP_DEF res, TEMP cr0); 8400 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8401 ins_encode %{ 8402 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8403 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8404 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8405 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8406 noreg, true); 8407 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8408 __ isync(); 8409 } else { 8410 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8411 __ sync(); 8412 } 8413 %} 8414 ins_pipe(pipe_class_default); 8415 %} 8416 8417 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8418 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8419 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8420 effect(TEMP_DEF res, TEMP cr0); 8421 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8422 ins_encode %{ 8423 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8424 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8425 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8426 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8427 noreg, true); 8428 %} 8429 ins_pipe(pipe_class_default); 8430 %} 8431 8432 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8433 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8434 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8435 effect(TEMP_DEF res, TEMP cr0); 8436 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8437 ins_encode %{ 8438 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8439 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8440 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8441 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8442 noreg, true); 8443 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8444 __ isync(); 8445 } else { 8446 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8447 __ sync(); 8448 } 8449 %} 8450 ins_pipe(pipe_class_default); 8451 %} 8452 8453 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8454 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8455 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8456 effect(TEMP_DEF res, TEMP cr0); 8457 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8458 ins_encode %{ 8459 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8460 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8461 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8462 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8463 noreg, NULL, true); 8464 %} 8465 ins_pipe(pipe_class_default); 8466 %} 8467 8468 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8469 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8470 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8471 effect(TEMP_DEF res, TEMP cr0); 8472 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8473 ins_encode %{ 8474 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8475 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8476 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8477 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8478 noreg, NULL, true); 8479 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8480 __ isync(); 8481 } else { 8482 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8483 __ sync(); 8484 } 8485 %} 8486 ins_pipe(pipe_class_default); 8487 %} 8488 8489 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8490 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8491 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8492 effect(TEMP_DEF res, TEMP cr0); 8493 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8494 ins_encode %{ 8495 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8496 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8497 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8498 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8499 noreg, NULL, true); 8500 %} 8501 ins_pipe(pipe_class_default); 8502 %} 8503 8504 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8505 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8506 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8507 effect(TEMP_DEF res, TEMP cr0); 8508 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8509 ins_encode %{ 8510 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8511 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8512 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8513 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8514 noreg, NULL, true); 8515 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8516 __ isync(); 8517 } else { 8518 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8519 __ sync(); 8520 } 8521 %} 8522 ins_pipe(pipe_class_default); 8523 %} 8524 8525 // Special RMW 8526 8527 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8528 match(Set res (GetAndAddB mem_ptr src)); 8529 predicate(VM_Version::has_lqarx()); 8530 effect(TEMP_DEF res, TEMP cr0); 8531 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8532 ins_encode %{ 8533 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8534 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8535 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8536 __ isync(); 8537 } else { 8538 __ sync(); 8539 } 8540 %} 8541 ins_pipe(pipe_class_default); 8542 %} 8543 8544 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8545 match(Set res (GetAndAddB mem_ptr src)); 8546 predicate(!VM_Version::has_lqarx()); 8547 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8548 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8549 ins_encode %{ 8550 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8551 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8552 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8553 __ isync(); 8554 } else { 8555 __ sync(); 8556 } 8557 %} 8558 ins_pipe(pipe_class_default); 8559 %} 8560 8561 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8562 match(Set res (GetAndAddS mem_ptr src)); 8563 predicate(VM_Version::has_lqarx()); 8564 effect(TEMP_DEF res, TEMP cr0); 8565 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8566 ins_encode %{ 8567 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8568 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8569 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8570 __ isync(); 8571 } else { 8572 __ sync(); 8573 } 8574 %} 8575 ins_pipe(pipe_class_default); 8576 %} 8577 8578 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8579 match(Set res (GetAndAddS mem_ptr src)); 8580 predicate(!VM_Version::has_lqarx()); 8581 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8582 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8583 ins_encode %{ 8584 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8585 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8586 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8587 __ isync(); 8588 } else { 8589 __ sync(); 8590 } 8591 %} 8592 ins_pipe(pipe_class_default); 8593 %} 8594 8595 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8596 match(Set res (GetAndAddI mem_ptr src)); 8597 effect(TEMP_DEF res, TEMP cr0); 8598 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8599 ins_encode %{ 8600 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8601 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8602 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8603 __ isync(); 8604 } else { 8605 __ sync(); 8606 } 8607 %} 8608 ins_pipe(pipe_class_default); 8609 %} 8610 8611 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8612 match(Set res (GetAndAddL mem_ptr src)); 8613 effect(TEMP_DEF res, TEMP cr0); 8614 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8615 ins_encode %{ 8616 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8617 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8618 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8619 __ isync(); 8620 } else { 8621 __ sync(); 8622 } 8623 %} 8624 ins_pipe(pipe_class_default); 8625 %} 8626 8627 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8628 match(Set res (GetAndSetB mem_ptr src)); 8629 predicate(VM_Version::has_lqarx()); 8630 effect(TEMP_DEF res, TEMP cr0); 8631 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8632 ins_encode %{ 8633 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8634 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8635 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8636 __ isync(); 8637 } else { 8638 __ sync(); 8639 } 8640 %} 8641 ins_pipe(pipe_class_default); 8642 %} 8643 8644 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8645 match(Set res (GetAndSetB mem_ptr src)); 8646 predicate(!VM_Version::has_lqarx()); 8647 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8648 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8649 ins_encode %{ 8650 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8651 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8652 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8653 __ isync(); 8654 } else { 8655 __ sync(); 8656 } 8657 %} 8658 ins_pipe(pipe_class_default); 8659 %} 8660 8661 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8662 match(Set res (GetAndSetS mem_ptr src)); 8663 predicate(VM_Version::has_lqarx()); 8664 effect(TEMP_DEF res, TEMP cr0); 8665 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8666 ins_encode %{ 8667 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8668 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8669 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8670 __ isync(); 8671 } else { 8672 __ sync(); 8673 } 8674 %} 8675 ins_pipe(pipe_class_default); 8676 %} 8677 8678 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8679 match(Set res (GetAndSetS mem_ptr src)); 8680 predicate(!VM_Version::has_lqarx()); 8681 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8682 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8683 ins_encode %{ 8684 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8685 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8686 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8687 __ isync(); 8688 } else { 8689 __ sync(); 8690 } 8691 %} 8692 ins_pipe(pipe_class_default); 8693 %} 8694 8695 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8696 match(Set res (GetAndSetI mem_ptr src)); 8697 effect(TEMP_DEF res, TEMP cr0); 8698 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8699 ins_encode %{ 8700 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8701 MacroAssembler::cmpxchgx_hint_atomic_update()); 8702 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8703 __ isync(); 8704 } else { 8705 __ sync(); 8706 } 8707 %} 8708 ins_pipe(pipe_class_default); 8709 %} 8710 8711 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8712 match(Set res (GetAndSetL mem_ptr src)); 8713 effect(TEMP_DEF res, TEMP cr0); 8714 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8715 ins_encode %{ 8716 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8717 MacroAssembler::cmpxchgx_hint_atomic_update()); 8718 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8719 __ isync(); 8720 } else { 8721 __ sync(); 8722 } 8723 %} 8724 ins_pipe(pipe_class_default); 8725 %} 8726 8727 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8728 match(Set res (GetAndSetP mem_ptr src)); 8729 effect(TEMP_DEF res, TEMP cr0); 8730 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8731 ins_encode %{ 8732 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8733 MacroAssembler::cmpxchgx_hint_atomic_update()); 8734 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8735 __ isync(); 8736 } else { 8737 __ sync(); 8738 } 8739 %} 8740 ins_pipe(pipe_class_default); 8741 %} 8742 8743 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8744 match(Set res (GetAndSetN mem_ptr src)); 8745 effect(TEMP_DEF res, TEMP cr0); 8746 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8747 ins_encode %{ 8748 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8749 MacroAssembler::cmpxchgx_hint_atomic_update()); 8750 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8751 __ isync(); 8752 } else { 8753 __ sync(); 8754 } 8755 %} 8756 ins_pipe(pipe_class_default); 8757 %} 8758 8759 //----------Arithmetic Instructions-------------------------------------------- 8760 // Addition Instructions 8761 8762 // Register Addition 8763 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8764 match(Set dst (AddI src1 src2)); 8765 format %{ "ADD $dst, $src1, $src2" %} 8766 size(4); 8767 ins_encode %{ 8768 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8769 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8770 %} 8771 ins_pipe(pipe_class_default); 8772 %} 8773 8774 // Expand does not work with above instruct. (??) 8775 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8776 // no match-rule 8777 effect(DEF dst, USE src1, USE src2); 8778 format %{ "ADD $dst, $src1, $src2" %} 8779 size(4); 8780 ins_encode %{ 8781 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8782 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8783 %} 8784 ins_pipe(pipe_class_default); 8785 %} 8786 8787 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8788 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8789 ins_cost(DEFAULT_COST*3); 8790 8791 expand %{ 8792 // FIXME: we should do this in the ideal world. 8793 iRegIdst tmp1; 8794 iRegIdst tmp2; 8795 addI_reg_reg(tmp1, src1, src2); 8796 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8797 addI_reg_reg(dst, tmp1, tmp2); 8798 %} 8799 %} 8800 8801 // Immediate Addition 8802 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8803 match(Set dst (AddI src1 src2)); 8804 format %{ "ADDI $dst, $src1, $src2" %} 8805 size(4); 8806 ins_encode %{ 8807 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8808 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8809 %} 8810 ins_pipe(pipe_class_default); 8811 %} 8812 8813 // Immediate Addition with 16-bit shifted operand 8814 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8815 match(Set dst (AddI src1 src2)); 8816 format %{ "ADDIS $dst, $src1, $src2" %} 8817 size(4); 8818 ins_encode %{ 8819 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8820 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8821 %} 8822 ins_pipe(pipe_class_default); 8823 %} 8824 8825 // Long Addition 8826 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8827 match(Set dst (AddL src1 src2)); 8828 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8829 size(4); 8830 ins_encode %{ 8831 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8832 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8833 %} 8834 ins_pipe(pipe_class_default); 8835 %} 8836 8837 // Expand does not work with above instruct. (??) 8838 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8839 // no match-rule 8840 effect(DEF dst, USE src1, USE src2); 8841 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8842 size(4); 8843 ins_encode %{ 8844 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8845 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8846 %} 8847 ins_pipe(pipe_class_default); 8848 %} 8849 8850 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8851 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8852 ins_cost(DEFAULT_COST*3); 8853 8854 expand %{ 8855 // FIXME: we should do this in the ideal world. 8856 iRegLdst tmp1; 8857 iRegLdst tmp2; 8858 addL_reg_reg(tmp1, src1, src2); 8859 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8860 addL_reg_reg(dst, tmp1, tmp2); 8861 %} 8862 %} 8863 8864 // AddL + ConvL2I. 8865 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8866 match(Set dst (ConvL2I (AddL src1 src2))); 8867 8868 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8869 size(4); 8870 ins_encode %{ 8871 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8872 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8873 %} 8874 ins_pipe(pipe_class_default); 8875 %} 8876 8877 // No constant pool entries required. 8878 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8879 match(Set dst (AddL src1 src2)); 8880 8881 format %{ "ADDI $dst, $src1, $src2" %} 8882 size(4); 8883 ins_encode %{ 8884 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8885 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8886 %} 8887 ins_pipe(pipe_class_default); 8888 %} 8889 8890 // Long Immediate Addition with 16-bit shifted operand. 8891 // No constant pool entries required. 8892 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8893 match(Set dst (AddL src1 src2)); 8894 8895 format %{ "ADDIS $dst, $src1, $src2" %} 8896 size(4); 8897 ins_encode %{ 8898 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8899 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8900 %} 8901 ins_pipe(pipe_class_default); 8902 %} 8903 8904 // Pointer Register Addition 8905 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8906 match(Set dst (AddP src1 src2)); 8907 format %{ "ADD $dst, $src1, $src2" %} 8908 size(4); 8909 ins_encode %{ 8910 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8911 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8912 %} 8913 ins_pipe(pipe_class_default); 8914 %} 8915 8916 // Pointer Immediate Addition 8917 // No constant pool entries required. 8918 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8919 match(Set dst (AddP src1 src2)); 8920 8921 format %{ "ADDI $dst, $src1, $src2" %} 8922 size(4); 8923 ins_encode %{ 8924 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8925 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8926 %} 8927 ins_pipe(pipe_class_default); 8928 %} 8929 8930 // Pointer Immediate Addition with 16-bit shifted operand. 8931 // No constant pool entries required. 8932 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8933 match(Set dst (AddP src1 src2)); 8934 8935 format %{ "ADDIS $dst, $src1, $src2" %} 8936 size(4); 8937 ins_encode %{ 8938 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8939 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8940 %} 8941 ins_pipe(pipe_class_default); 8942 %} 8943 8944 //--------------------- 8945 // Subtraction Instructions 8946 8947 // Register Subtraction 8948 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8949 match(Set dst (SubI src1 src2)); 8950 format %{ "SUBF $dst, $src2, $src1" %} 8951 size(4); 8952 ins_encode %{ 8953 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8954 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8955 %} 8956 ins_pipe(pipe_class_default); 8957 %} 8958 8959 // Immediate Subtraction 8960 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 8961 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 8962 8963 // SubI from constant (using subfic). 8964 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 8965 match(Set dst (SubI src1 src2)); 8966 format %{ "SUBI $dst, $src1, $src2" %} 8967 8968 size(4); 8969 ins_encode %{ 8970 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 8971 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 8972 %} 8973 ins_pipe(pipe_class_default); 8974 %} 8975 8976 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 8977 // positive integers and 0xF...F for negative ones. 8978 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 8979 // no match-rule, false predicate 8980 effect(DEF dst, USE src); 8981 predicate(false); 8982 8983 format %{ "SRAWI $dst, $src, #31" %} 8984 size(4); 8985 ins_encode %{ 8986 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 8987 __ srawi($dst$$Register, $src$$Register, 0x1f); 8988 %} 8989 ins_pipe(pipe_class_default); 8990 %} 8991 8992 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 8993 match(Set dst (AbsI src)); 8994 ins_cost(DEFAULT_COST*3); 8995 8996 expand %{ 8997 iRegIdst tmp1; 8998 iRegIdst tmp2; 8999 signmask32I_regI(tmp1, src); 9000 xorI_reg_reg(tmp2, tmp1, src); 9001 subI_reg_reg(dst, tmp2, tmp1); 9002 %} 9003 %} 9004 9005 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9006 match(Set dst (SubI zero src2)); 9007 format %{ "NEG $dst, $src2" %} 9008 size(4); 9009 ins_encode %{ 9010 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9011 __ neg($dst$$Register, $src2$$Register); 9012 %} 9013 ins_pipe(pipe_class_default); 9014 %} 9015 9016 // Long subtraction 9017 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9018 match(Set dst (SubL src1 src2)); 9019 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9020 size(4); 9021 ins_encode %{ 9022 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9023 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9024 %} 9025 ins_pipe(pipe_class_default); 9026 %} 9027 9028 // SubL + convL2I. 9029 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9030 match(Set dst (ConvL2I (SubL src1 src2))); 9031 9032 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9033 size(4); 9034 ins_encode %{ 9035 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9036 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9037 %} 9038 ins_pipe(pipe_class_default); 9039 %} 9040 9041 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9042 // positive longs and 0xF...F for negative ones. 9043 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9044 // no match-rule, false predicate 9045 effect(DEF dst, USE src); 9046 predicate(false); 9047 9048 format %{ "SRADI $dst, $src, #63" %} 9049 size(4); 9050 ins_encode %{ 9051 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9052 __ sradi($dst$$Register, $src$$Register, 0x3f); 9053 %} 9054 ins_pipe(pipe_class_default); 9055 %} 9056 9057 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9058 // positive longs and 0xF...F for negative ones. 9059 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9060 // no match-rule, false predicate 9061 effect(DEF dst, USE src); 9062 predicate(false); 9063 9064 format %{ "SRADI $dst, $src, #63" %} 9065 size(4); 9066 ins_encode %{ 9067 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9068 __ sradi($dst$$Register, $src$$Register, 0x3f); 9069 %} 9070 ins_pipe(pipe_class_default); 9071 %} 9072 9073 // Long negation 9074 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9075 match(Set dst (SubL zero src2)); 9076 format %{ "NEG $dst, $src2 \t// long" %} 9077 size(4); 9078 ins_encode %{ 9079 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9080 __ neg($dst$$Register, $src2$$Register); 9081 %} 9082 ins_pipe(pipe_class_default); 9083 %} 9084 9085 // NegL + ConvL2I. 9086 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9087 match(Set dst (ConvL2I (SubL zero src2))); 9088 9089 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9090 size(4); 9091 ins_encode %{ 9092 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9093 __ neg($dst$$Register, $src2$$Register); 9094 %} 9095 ins_pipe(pipe_class_default); 9096 %} 9097 9098 // Multiplication Instructions 9099 // Integer Multiplication 9100 9101 // Register Multiplication 9102 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9103 match(Set dst (MulI src1 src2)); 9104 ins_cost(DEFAULT_COST); 9105 9106 format %{ "MULLW $dst, $src1, $src2" %} 9107 size(4); 9108 ins_encode %{ 9109 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9110 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9111 %} 9112 ins_pipe(pipe_class_default); 9113 %} 9114 9115 // Immediate Multiplication 9116 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9117 match(Set dst (MulI src1 src2)); 9118 ins_cost(DEFAULT_COST); 9119 9120 format %{ "MULLI $dst, $src1, $src2" %} 9121 size(4); 9122 ins_encode %{ 9123 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9124 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9125 %} 9126 ins_pipe(pipe_class_default); 9127 %} 9128 9129 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9130 match(Set dst (MulL src1 src2)); 9131 ins_cost(DEFAULT_COST); 9132 9133 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9134 size(4); 9135 ins_encode %{ 9136 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9137 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9138 %} 9139 ins_pipe(pipe_class_default); 9140 %} 9141 9142 // Multiply high for optimized long division by constant. 9143 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9144 match(Set dst (MulHiL src1 src2)); 9145 ins_cost(DEFAULT_COST); 9146 9147 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9148 size(4); 9149 ins_encode %{ 9150 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9151 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9152 %} 9153 ins_pipe(pipe_class_default); 9154 %} 9155 9156 // Immediate Multiplication 9157 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9158 match(Set dst (MulL src1 src2)); 9159 ins_cost(DEFAULT_COST); 9160 9161 format %{ "MULLI $dst, $src1, $src2" %} 9162 size(4); 9163 ins_encode %{ 9164 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9165 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9166 %} 9167 ins_pipe(pipe_class_default); 9168 %} 9169 9170 // Integer Division with Immediate -1: Negate. 9171 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9172 match(Set dst (DivI src1 src2)); 9173 ins_cost(DEFAULT_COST); 9174 9175 format %{ "NEG $dst, $src1 \t// /-1" %} 9176 size(4); 9177 ins_encode %{ 9178 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9179 __ neg($dst$$Register, $src1$$Register); 9180 %} 9181 ins_pipe(pipe_class_default); 9182 %} 9183 9184 // Integer Division with constant, but not -1. 9185 // We should be able to improve this by checking the type of src2. 9186 // It might well be that src2 is known to be positive. 9187 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9188 match(Set dst (DivI src1 src2)); 9189 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9190 ins_cost(2*DEFAULT_COST); 9191 9192 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9193 size(4); 9194 ins_encode %{ 9195 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9196 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9197 %} 9198 ins_pipe(pipe_class_default); 9199 %} 9200 9201 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9202 effect(USE_DEF dst, USE src1, USE crx); 9203 predicate(false); 9204 9205 ins_variable_size_depending_on_alignment(true); 9206 9207 format %{ "CMOVE $dst, neg($src1), $crx" %} 9208 // Worst case is branch + move + stop, no stop without scheduler. 9209 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 9210 ins_encode %{ 9211 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9212 Label done; 9213 __ bne($crx$$CondRegister, done); 9214 __ neg($dst$$Register, $src1$$Register); 9215 // TODO PPC port __ endgroup_if_needed(_size == 12); 9216 __ bind(done); 9217 %} 9218 ins_pipe(pipe_class_default); 9219 %} 9220 9221 // Integer Division with Registers not containing constants. 9222 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9223 match(Set dst (DivI src1 src2)); 9224 ins_cost(10*DEFAULT_COST); 9225 9226 expand %{ 9227 immI16 imm %{ (int)-1 %} 9228 flagsReg tmp1; 9229 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9230 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9231 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9232 %} 9233 %} 9234 9235 // Long Division with Immediate -1: Negate. 9236 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9237 match(Set dst (DivL src1 src2)); 9238 ins_cost(DEFAULT_COST); 9239 9240 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9241 size(4); 9242 ins_encode %{ 9243 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9244 __ neg($dst$$Register, $src1$$Register); 9245 %} 9246 ins_pipe(pipe_class_default); 9247 %} 9248 9249 // Long Division with constant, but not -1. 9250 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9251 match(Set dst (DivL src1 src2)); 9252 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9253 ins_cost(2*DEFAULT_COST); 9254 9255 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9256 size(4); 9257 ins_encode %{ 9258 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9259 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9260 %} 9261 ins_pipe(pipe_class_default); 9262 %} 9263 9264 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9265 effect(USE_DEF dst, USE src1, USE crx); 9266 predicate(false); 9267 9268 ins_variable_size_depending_on_alignment(true); 9269 9270 format %{ "CMOVE $dst, neg($src1), $crx" %} 9271 // Worst case is branch + move + stop, no stop without scheduler. 9272 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 9273 ins_encode %{ 9274 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9275 Label done; 9276 __ bne($crx$$CondRegister, done); 9277 __ neg($dst$$Register, $src1$$Register); 9278 // TODO PPC port __ endgroup_if_needed(_size == 12); 9279 __ bind(done); 9280 %} 9281 ins_pipe(pipe_class_default); 9282 %} 9283 9284 // Long Division with Registers not containing constants. 9285 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9286 match(Set dst (DivL src1 src2)); 9287 ins_cost(10*DEFAULT_COST); 9288 9289 expand %{ 9290 immL16 imm %{ (int)-1 %} 9291 flagsReg tmp1; 9292 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9293 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9294 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9295 %} 9296 %} 9297 9298 // Integer Remainder with registers. 9299 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9300 match(Set dst (ModI src1 src2)); 9301 ins_cost(10*DEFAULT_COST); 9302 9303 expand %{ 9304 immI16 imm %{ (int)-1 %} 9305 flagsReg tmp1; 9306 iRegIdst tmp2; 9307 iRegIdst tmp3; 9308 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9309 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9310 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9311 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9312 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9313 %} 9314 %} 9315 9316 // Long Remainder with registers 9317 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9318 match(Set dst (ModL src1 src2)); 9319 ins_cost(10*DEFAULT_COST); 9320 9321 expand %{ 9322 immL16 imm %{ (int)-1 %} 9323 flagsReg tmp1; 9324 iRegLdst tmp2; 9325 iRegLdst tmp3; 9326 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9327 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9328 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9329 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9330 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9331 %} 9332 %} 9333 9334 // Integer Shift Instructions 9335 9336 // Register Shift Left 9337 9338 // Clear all but the lowest #mask bits. 9339 // Used to normalize shift amounts in registers. 9340 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9341 // no match-rule, false predicate 9342 effect(DEF dst, USE src, USE mask); 9343 predicate(false); 9344 9345 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9346 size(4); 9347 ins_encode %{ 9348 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9349 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9350 %} 9351 ins_pipe(pipe_class_default); 9352 %} 9353 9354 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9355 // no match-rule, false predicate 9356 effect(DEF dst, USE src1, USE src2); 9357 predicate(false); 9358 9359 format %{ "SLW $dst, $src1, $src2" %} 9360 size(4); 9361 ins_encode %{ 9362 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9363 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9364 %} 9365 ins_pipe(pipe_class_default); 9366 %} 9367 9368 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9369 match(Set dst (LShiftI src1 src2)); 9370 ins_cost(DEFAULT_COST*2); 9371 expand %{ 9372 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9373 iRegIdst tmpI; 9374 maskI_reg_imm(tmpI, src2, mask); 9375 lShiftI_reg_reg(dst, src1, tmpI); 9376 %} 9377 %} 9378 9379 // Register Shift Left Immediate 9380 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9381 match(Set dst (LShiftI src1 src2)); 9382 9383 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9384 size(4); 9385 ins_encode %{ 9386 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9387 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9388 %} 9389 ins_pipe(pipe_class_default); 9390 %} 9391 9392 // AndI with negpow2-constant + LShiftI 9393 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9394 match(Set dst (LShiftI (AndI src1 src2) src3)); 9395 predicate(UseRotateAndMaskInstructionsPPC64); 9396 9397 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9398 size(4); 9399 ins_encode %{ 9400 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9401 long src2 = $src2$$constant; 9402 long src3 = $src3$$constant; 9403 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9404 if (maskbits >= 32) { 9405 __ li($dst$$Register, 0); // addi 9406 } else { 9407 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9408 } 9409 %} 9410 ins_pipe(pipe_class_default); 9411 %} 9412 9413 // RShiftI + AndI with negpow2-constant + LShiftI 9414 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9415 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9416 predicate(UseRotateAndMaskInstructionsPPC64); 9417 9418 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9419 size(4); 9420 ins_encode %{ 9421 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9422 long src2 = $src2$$constant; 9423 long src3 = $src3$$constant; 9424 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9425 if (maskbits >= 32) { 9426 __ li($dst$$Register, 0); // addi 9427 } else { 9428 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9429 } 9430 %} 9431 ins_pipe(pipe_class_default); 9432 %} 9433 9434 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9435 // no match-rule, false predicate 9436 effect(DEF dst, USE src1, USE src2); 9437 predicate(false); 9438 9439 format %{ "SLD $dst, $src1, $src2" %} 9440 size(4); 9441 ins_encode %{ 9442 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9443 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9444 %} 9445 ins_pipe(pipe_class_default); 9446 %} 9447 9448 // Register Shift Left 9449 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9450 match(Set dst (LShiftL src1 src2)); 9451 ins_cost(DEFAULT_COST*2); 9452 expand %{ 9453 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9454 iRegIdst tmpI; 9455 maskI_reg_imm(tmpI, src2, mask); 9456 lShiftL_regL_regI(dst, src1, tmpI); 9457 %} 9458 %} 9459 9460 // Register Shift Left Immediate 9461 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9462 match(Set dst (LShiftL src1 src2)); 9463 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9464 size(4); 9465 ins_encode %{ 9466 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9467 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9468 %} 9469 ins_pipe(pipe_class_default); 9470 %} 9471 9472 // If we shift more than 32 bits, we need not convert I2L. 9473 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9474 match(Set dst (LShiftL (ConvI2L src1) src2)); 9475 ins_cost(DEFAULT_COST); 9476 9477 size(4); 9478 format %{ "SLDI $dst, i2l($src1), $src2" %} 9479 ins_encode %{ 9480 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9481 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9482 %} 9483 ins_pipe(pipe_class_default); 9484 %} 9485 9486 // Shift a postivie int to the left. 9487 // Clrlsldi clears the upper 32 bits and shifts. 9488 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9489 match(Set dst (LShiftL (ConvI2L src1) src2)); 9490 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9491 9492 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9493 size(4); 9494 ins_encode %{ 9495 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9496 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9497 %} 9498 ins_pipe(pipe_class_default); 9499 %} 9500 9501 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9502 // no match-rule, false predicate 9503 effect(DEF dst, USE src1, USE src2); 9504 predicate(false); 9505 9506 format %{ "SRAW $dst, $src1, $src2" %} 9507 size(4); 9508 ins_encode %{ 9509 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9510 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9511 %} 9512 ins_pipe(pipe_class_default); 9513 %} 9514 9515 // Register Arithmetic Shift Right 9516 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9517 match(Set dst (RShiftI src1 src2)); 9518 ins_cost(DEFAULT_COST*2); 9519 expand %{ 9520 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9521 iRegIdst tmpI; 9522 maskI_reg_imm(tmpI, src2, mask); 9523 arShiftI_reg_reg(dst, src1, tmpI); 9524 %} 9525 %} 9526 9527 // Register Arithmetic Shift Right Immediate 9528 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9529 match(Set dst (RShiftI src1 src2)); 9530 9531 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9532 size(4); 9533 ins_encode %{ 9534 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9535 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9536 %} 9537 ins_pipe(pipe_class_default); 9538 %} 9539 9540 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9541 // no match-rule, false predicate 9542 effect(DEF dst, USE src1, USE src2); 9543 predicate(false); 9544 9545 format %{ "SRAD $dst, $src1, $src2" %} 9546 size(4); 9547 ins_encode %{ 9548 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9549 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9550 %} 9551 ins_pipe(pipe_class_default); 9552 %} 9553 9554 // Register Shift Right Arithmetic Long 9555 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9556 match(Set dst (RShiftL src1 src2)); 9557 ins_cost(DEFAULT_COST*2); 9558 9559 expand %{ 9560 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9561 iRegIdst tmpI; 9562 maskI_reg_imm(tmpI, src2, mask); 9563 arShiftL_regL_regI(dst, src1, tmpI); 9564 %} 9565 %} 9566 9567 // Register Shift Right Immediate 9568 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9569 match(Set dst (RShiftL src1 src2)); 9570 9571 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9572 size(4); 9573 ins_encode %{ 9574 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9575 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9576 %} 9577 ins_pipe(pipe_class_default); 9578 %} 9579 9580 // RShiftL + ConvL2I 9581 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9582 match(Set dst (ConvL2I (RShiftL src1 src2))); 9583 9584 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9585 size(4); 9586 ins_encode %{ 9587 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9588 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9589 %} 9590 ins_pipe(pipe_class_default); 9591 %} 9592 9593 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9594 // no match-rule, false predicate 9595 effect(DEF dst, USE src1, USE src2); 9596 predicate(false); 9597 9598 format %{ "SRW $dst, $src1, $src2" %} 9599 size(4); 9600 ins_encode %{ 9601 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9602 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9603 %} 9604 ins_pipe(pipe_class_default); 9605 %} 9606 9607 // Register Shift Right 9608 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9609 match(Set dst (URShiftI src1 src2)); 9610 ins_cost(DEFAULT_COST*2); 9611 9612 expand %{ 9613 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9614 iRegIdst tmpI; 9615 maskI_reg_imm(tmpI, src2, mask); 9616 urShiftI_reg_reg(dst, src1, tmpI); 9617 %} 9618 %} 9619 9620 // Register Shift Right Immediate 9621 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9622 match(Set dst (URShiftI src1 src2)); 9623 9624 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9625 size(4); 9626 ins_encode %{ 9627 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9628 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9629 %} 9630 ins_pipe(pipe_class_default); 9631 %} 9632 9633 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9634 // no match-rule, false predicate 9635 effect(DEF dst, USE src1, USE src2); 9636 predicate(false); 9637 9638 format %{ "SRD $dst, $src1, $src2" %} 9639 size(4); 9640 ins_encode %{ 9641 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9642 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9643 %} 9644 ins_pipe(pipe_class_default); 9645 %} 9646 9647 // Register Shift Right 9648 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9649 match(Set dst (URShiftL src1 src2)); 9650 ins_cost(DEFAULT_COST*2); 9651 9652 expand %{ 9653 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9654 iRegIdst tmpI; 9655 maskI_reg_imm(tmpI, src2, mask); 9656 urShiftL_regL_regI(dst, src1, tmpI); 9657 %} 9658 %} 9659 9660 // Register Shift Right Immediate 9661 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9662 match(Set dst (URShiftL src1 src2)); 9663 9664 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9665 size(4); 9666 ins_encode %{ 9667 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9668 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9669 %} 9670 ins_pipe(pipe_class_default); 9671 %} 9672 9673 // URShiftL + ConvL2I. 9674 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9675 match(Set dst (ConvL2I (URShiftL src1 src2))); 9676 9677 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9678 size(4); 9679 ins_encode %{ 9680 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9681 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9682 %} 9683 ins_pipe(pipe_class_default); 9684 %} 9685 9686 // Register Shift Right Immediate with a CastP2X 9687 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9688 match(Set dst (URShiftL (CastP2X src1) src2)); 9689 9690 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9691 size(4); 9692 ins_encode %{ 9693 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9694 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9695 %} 9696 ins_pipe(pipe_class_default); 9697 %} 9698 9699 // Bitfield Extract: URShiftI + AndI 9700 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9701 match(Set dst (AndI (URShiftI src1 src2) src3)); 9702 9703 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9704 size(4); 9705 ins_encode %{ 9706 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9707 int rshift = ($src2$$constant) & 0x1f; 9708 int length = log2_long(((jlong) $src3$$constant) + 1); 9709 if (rshift + length > 32) { 9710 // if necessary, adjust mask to omit rotated bits. 9711 length = 32 - rshift; 9712 } 9713 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9714 %} 9715 ins_pipe(pipe_class_default); 9716 %} 9717 9718 // Bitfield Extract: URShiftL + AndL 9719 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9720 match(Set dst (AndL (URShiftL src1 src2) src3)); 9721 9722 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9723 size(4); 9724 ins_encode %{ 9725 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9726 int rshift = ($src2$$constant) & 0x3f; 9727 int length = log2_long(((jlong) $src3$$constant) + 1); 9728 if (rshift + length > 64) { 9729 // if necessary, adjust mask to omit rotated bits. 9730 length = 64 - rshift; 9731 } 9732 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9733 %} 9734 ins_pipe(pipe_class_default); 9735 %} 9736 9737 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9738 match(Set dst (ConvL2I (ConvI2L src))); 9739 9740 format %{ "EXTSW $dst, $src \t// int->int" %} 9741 size(4); 9742 ins_encode %{ 9743 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9744 __ extsw($dst$$Register, $src$$Register); 9745 %} 9746 ins_pipe(pipe_class_default); 9747 %} 9748 9749 //----------Rotate Instructions------------------------------------------------ 9750 9751 // Rotate Left by 8-bit immediate 9752 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9753 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9754 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9755 9756 format %{ "ROTLWI $dst, $src, $lshift" %} 9757 size(4); 9758 ins_encode %{ 9759 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9760 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9761 %} 9762 ins_pipe(pipe_class_default); 9763 %} 9764 9765 // Rotate Right by 8-bit immediate 9766 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9767 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9768 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9769 9770 format %{ "ROTRWI $dst, $rshift" %} 9771 size(4); 9772 ins_encode %{ 9773 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9774 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9775 %} 9776 ins_pipe(pipe_class_default); 9777 %} 9778 9779 //----------Floating Point Arithmetic Instructions----------------------------- 9780 9781 // Add float single precision 9782 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9783 match(Set dst (AddF src1 src2)); 9784 9785 format %{ "FADDS $dst, $src1, $src2" %} 9786 size(4); 9787 ins_encode %{ 9788 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9789 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9790 %} 9791 ins_pipe(pipe_class_default); 9792 %} 9793 9794 // Add float double precision 9795 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9796 match(Set dst (AddD src1 src2)); 9797 9798 format %{ "FADD $dst, $src1, $src2" %} 9799 size(4); 9800 ins_encode %{ 9801 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9802 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9803 %} 9804 ins_pipe(pipe_class_default); 9805 %} 9806 9807 // Sub float single precision 9808 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9809 match(Set dst (SubF src1 src2)); 9810 9811 format %{ "FSUBS $dst, $src1, $src2" %} 9812 size(4); 9813 ins_encode %{ 9814 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9815 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9816 %} 9817 ins_pipe(pipe_class_default); 9818 %} 9819 9820 // Sub float double precision 9821 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9822 match(Set dst (SubD src1 src2)); 9823 format %{ "FSUB $dst, $src1, $src2" %} 9824 size(4); 9825 ins_encode %{ 9826 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9827 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9828 %} 9829 ins_pipe(pipe_class_default); 9830 %} 9831 9832 // Mul float single precision 9833 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9834 match(Set dst (MulF src1 src2)); 9835 format %{ "FMULS $dst, $src1, $src2" %} 9836 size(4); 9837 ins_encode %{ 9838 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9839 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9840 %} 9841 ins_pipe(pipe_class_default); 9842 %} 9843 9844 // Mul float double precision 9845 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9846 match(Set dst (MulD src1 src2)); 9847 format %{ "FMUL $dst, $src1, $src2" %} 9848 size(4); 9849 ins_encode %{ 9850 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9851 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9852 %} 9853 ins_pipe(pipe_class_default); 9854 %} 9855 9856 // Div float single precision 9857 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9858 match(Set dst (DivF src1 src2)); 9859 format %{ "FDIVS $dst, $src1, $src2" %} 9860 size(4); 9861 ins_encode %{ 9862 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9863 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9864 %} 9865 ins_pipe(pipe_class_default); 9866 %} 9867 9868 // Div float double precision 9869 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9870 match(Set dst (DivD src1 src2)); 9871 format %{ "FDIV $dst, $src1, $src2" %} 9872 size(4); 9873 ins_encode %{ 9874 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9875 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9876 %} 9877 ins_pipe(pipe_class_default); 9878 %} 9879 9880 // Absolute float single precision 9881 instruct absF_reg(regF dst, regF src) %{ 9882 match(Set dst (AbsF src)); 9883 format %{ "FABS $dst, $src \t// float" %} 9884 size(4); 9885 ins_encode %{ 9886 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9887 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9888 %} 9889 ins_pipe(pipe_class_default); 9890 %} 9891 9892 // Absolute float double precision 9893 instruct absD_reg(regD dst, regD src) %{ 9894 match(Set dst (AbsD src)); 9895 format %{ "FABS $dst, $src \t// double" %} 9896 size(4); 9897 ins_encode %{ 9898 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9899 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9900 %} 9901 ins_pipe(pipe_class_default); 9902 %} 9903 9904 instruct negF_reg(regF dst, regF src) %{ 9905 match(Set dst (NegF src)); 9906 format %{ "FNEG $dst, $src \t// float" %} 9907 size(4); 9908 ins_encode %{ 9909 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9910 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9911 %} 9912 ins_pipe(pipe_class_default); 9913 %} 9914 9915 instruct negD_reg(regD dst, regD src) %{ 9916 match(Set dst (NegD src)); 9917 format %{ "FNEG $dst, $src \t// double" %} 9918 size(4); 9919 ins_encode %{ 9920 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9921 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9922 %} 9923 ins_pipe(pipe_class_default); 9924 %} 9925 9926 // AbsF + NegF. 9927 instruct negF_absF_reg(regF dst, regF src) %{ 9928 match(Set dst (NegF (AbsF src))); 9929 format %{ "FNABS $dst, $src \t// float" %} 9930 size(4); 9931 ins_encode %{ 9932 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9933 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9934 %} 9935 ins_pipe(pipe_class_default); 9936 %} 9937 9938 // AbsD + NegD. 9939 instruct negD_absD_reg(regD dst, regD src) %{ 9940 match(Set dst (NegD (AbsD src))); 9941 format %{ "FNABS $dst, $src \t// double" %} 9942 size(4); 9943 ins_encode %{ 9944 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9945 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9946 %} 9947 ins_pipe(pipe_class_default); 9948 %} 9949 9950 // VM_Version::has_fsqrt() decides if this node will be used. 9951 // Sqrt float double precision 9952 instruct sqrtD_reg(regD dst, regD src) %{ 9953 match(Set dst (SqrtD src)); 9954 format %{ "FSQRT $dst, $src" %} 9955 size(4); 9956 ins_encode %{ 9957 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 9958 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 9959 %} 9960 ins_pipe(pipe_class_default); 9961 %} 9962 9963 // Single-precision sqrt. 9964 instruct sqrtF_reg(regF dst, regF src) %{ 9965 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 9966 predicate(VM_Version::has_fsqrts()); 9967 ins_cost(DEFAULT_COST); 9968 9969 format %{ "FSQRTS $dst, $src" %} 9970 size(4); 9971 ins_encode %{ 9972 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 9973 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 9974 %} 9975 ins_pipe(pipe_class_default); 9976 %} 9977 9978 instruct roundDouble_nop(regD dst) %{ 9979 match(Set dst (RoundDouble dst)); 9980 ins_cost(0); 9981 9982 format %{ " -- \t// RoundDouble not needed - empty" %} 9983 size(0); 9984 // PPC results are already "rounded" (i.e., normal-format IEEE). 9985 ins_encode( /*empty*/ ); 9986 ins_pipe(pipe_class_default); 9987 %} 9988 9989 instruct roundFloat_nop(regF dst) %{ 9990 match(Set dst (RoundFloat dst)); 9991 ins_cost(0); 9992 9993 format %{ " -- \t// RoundFloat not needed - empty" %} 9994 size(0); 9995 // PPC results are already "rounded" (i.e., normal-format IEEE). 9996 ins_encode( /*empty*/ ); 9997 ins_pipe(pipe_class_default); 9998 %} 9999 10000 10001 // Multiply-Accumulate 10002 // src1 * src2 + src3 10003 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10004 match(Set dst (FmaF src3 (Binary src1 src2))); 10005 10006 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10007 size(4); 10008 ins_encode %{ 10009 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10010 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10011 %} 10012 ins_pipe(pipe_class_default); 10013 %} 10014 10015 // src1 * src2 + src3 10016 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10017 match(Set dst (FmaD src3 (Binary src1 src2))); 10018 10019 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10020 size(4); 10021 ins_encode %{ 10022 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10023 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10024 %} 10025 ins_pipe(pipe_class_default); 10026 %} 10027 10028 // -src1 * src2 + src3 = -(src1*src2-src3) 10029 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10030 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10031 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10032 10033 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10034 size(4); 10035 ins_encode %{ 10036 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10037 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10038 %} 10039 ins_pipe(pipe_class_default); 10040 %} 10041 10042 // -src1 * src2 + src3 = -(src1*src2-src3) 10043 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10044 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10045 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10046 10047 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10048 size(4); 10049 ins_encode %{ 10050 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10051 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10052 %} 10053 ins_pipe(pipe_class_default); 10054 %} 10055 10056 // -src1 * src2 - src3 = -(src1*src2+src3) 10057 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10058 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10059 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10060 10061 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10062 size(4); 10063 ins_encode %{ 10064 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10065 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10066 %} 10067 ins_pipe(pipe_class_default); 10068 %} 10069 10070 // -src1 * src2 - src3 = -(src1*src2+src3) 10071 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10072 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10073 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10074 10075 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10076 size(4); 10077 ins_encode %{ 10078 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10079 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10080 %} 10081 ins_pipe(pipe_class_default); 10082 %} 10083 10084 // src1 * src2 - src3 10085 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10086 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10087 10088 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10089 size(4); 10090 ins_encode %{ 10091 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10092 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10093 %} 10094 ins_pipe(pipe_class_default); 10095 %} 10096 10097 // src1 * src2 - src3 10098 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10099 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10100 10101 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10102 size(4); 10103 ins_encode %{ 10104 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10105 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10106 %} 10107 ins_pipe(pipe_class_default); 10108 %} 10109 10110 10111 //----------Logical Instructions----------------------------------------------- 10112 10113 // And Instructions 10114 10115 // Register And 10116 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10117 match(Set dst (AndI src1 src2)); 10118 format %{ "AND $dst, $src1, $src2" %} 10119 size(4); 10120 ins_encode %{ 10121 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10122 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10123 %} 10124 ins_pipe(pipe_class_default); 10125 %} 10126 10127 // Left shifted Immediate And 10128 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10129 match(Set dst (AndI src1 src2)); 10130 effect(KILL cr0); 10131 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10132 size(4); 10133 ins_encode %{ 10134 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10135 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10136 %} 10137 ins_pipe(pipe_class_default); 10138 %} 10139 10140 // Immediate And 10141 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10142 match(Set dst (AndI src1 src2)); 10143 effect(KILL cr0); 10144 10145 format %{ "ANDI $dst, $src1, $src2" %} 10146 size(4); 10147 ins_encode %{ 10148 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10149 // FIXME: avoid andi_ ? 10150 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10151 %} 10152 ins_pipe(pipe_class_default); 10153 %} 10154 10155 // Immediate And where the immediate is a negative power of 2. 10156 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10157 match(Set dst (AndI src1 src2)); 10158 format %{ "ANDWI $dst, $src1, $src2" %} 10159 size(4); 10160 ins_encode %{ 10161 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10162 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10163 %} 10164 ins_pipe(pipe_class_default); 10165 %} 10166 10167 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10168 match(Set dst (AndI src1 src2)); 10169 format %{ "ANDWI $dst, $src1, $src2" %} 10170 size(4); 10171 ins_encode %{ 10172 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10173 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10174 %} 10175 ins_pipe(pipe_class_default); 10176 %} 10177 10178 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10179 match(Set dst (AndI src1 src2)); 10180 predicate(UseRotateAndMaskInstructionsPPC64); 10181 format %{ "ANDWI $dst, $src1, $src2" %} 10182 size(4); 10183 ins_encode %{ 10184 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10185 __ rlwinm($dst$$Register, $src1$$Register, 0, 10186 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10187 %} 10188 ins_pipe(pipe_class_default); 10189 %} 10190 10191 // Register And Long 10192 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10193 match(Set dst (AndL src1 src2)); 10194 ins_cost(DEFAULT_COST); 10195 10196 format %{ "AND $dst, $src1, $src2 \t// long" %} 10197 size(4); 10198 ins_encode %{ 10199 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10200 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10201 %} 10202 ins_pipe(pipe_class_default); 10203 %} 10204 10205 // Immediate And long 10206 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10207 match(Set dst (AndL src1 src2)); 10208 effect(KILL cr0); 10209 10210 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10211 size(4); 10212 ins_encode %{ 10213 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10214 // FIXME: avoid andi_ ? 10215 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10216 %} 10217 ins_pipe(pipe_class_default); 10218 %} 10219 10220 // Immediate And Long where the immediate is a negative power of 2. 10221 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10222 match(Set dst (AndL src1 src2)); 10223 format %{ "ANDDI $dst, $src1, $src2" %} 10224 size(4); 10225 ins_encode %{ 10226 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10227 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10228 %} 10229 ins_pipe(pipe_class_default); 10230 %} 10231 10232 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10233 match(Set dst (AndL src1 src2)); 10234 format %{ "ANDDI $dst, $src1, $src2" %} 10235 size(4); 10236 ins_encode %{ 10237 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10238 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10239 %} 10240 ins_pipe(pipe_class_default); 10241 %} 10242 10243 // AndL + ConvL2I. 10244 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10245 match(Set dst (ConvL2I (AndL src1 src2))); 10246 ins_cost(DEFAULT_COST); 10247 10248 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10249 size(4); 10250 ins_encode %{ 10251 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10252 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10253 %} 10254 ins_pipe(pipe_class_default); 10255 %} 10256 10257 // Or Instructions 10258 10259 // Register Or 10260 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10261 match(Set dst (OrI src1 src2)); 10262 format %{ "OR $dst, $src1, $src2" %} 10263 size(4); 10264 ins_encode %{ 10265 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10266 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10267 %} 10268 ins_pipe(pipe_class_default); 10269 %} 10270 10271 // Expand does not work with above instruct. (??) 10272 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10273 // no match-rule 10274 effect(DEF dst, USE src1, USE src2); 10275 format %{ "OR $dst, $src1, $src2" %} 10276 size(4); 10277 ins_encode %{ 10278 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10279 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10280 %} 10281 ins_pipe(pipe_class_default); 10282 %} 10283 10284 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10285 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10286 ins_cost(DEFAULT_COST*3); 10287 10288 expand %{ 10289 // FIXME: we should do this in the ideal world. 10290 iRegIdst tmp1; 10291 iRegIdst tmp2; 10292 orI_reg_reg(tmp1, src1, src2); 10293 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10294 orI_reg_reg(dst, tmp1, tmp2); 10295 %} 10296 %} 10297 10298 // Immediate Or 10299 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10300 match(Set dst (OrI src1 src2)); 10301 format %{ "ORI $dst, $src1, $src2" %} 10302 size(4); 10303 ins_encode %{ 10304 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10305 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10306 %} 10307 ins_pipe(pipe_class_default); 10308 %} 10309 10310 // Register Or Long 10311 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10312 match(Set dst (OrL src1 src2)); 10313 ins_cost(DEFAULT_COST); 10314 10315 size(4); 10316 format %{ "OR $dst, $src1, $src2 \t// long" %} 10317 ins_encode %{ 10318 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10319 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10320 %} 10321 ins_pipe(pipe_class_default); 10322 %} 10323 10324 // OrL + ConvL2I. 10325 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10326 match(Set dst (ConvL2I (OrL src1 src2))); 10327 ins_cost(DEFAULT_COST); 10328 10329 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10330 size(4); 10331 ins_encode %{ 10332 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10333 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10334 %} 10335 ins_pipe(pipe_class_default); 10336 %} 10337 10338 // Immediate Or long 10339 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10340 match(Set dst (OrL src1 con)); 10341 ins_cost(DEFAULT_COST); 10342 10343 format %{ "ORI $dst, $src1, $con \t// long" %} 10344 size(4); 10345 ins_encode %{ 10346 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10347 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10348 %} 10349 ins_pipe(pipe_class_default); 10350 %} 10351 10352 // Xor Instructions 10353 10354 // Register Xor 10355 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10356 match(Set dst (XorI src1 src2)); 10357 format %{ "XOR $dst, $src1, $src2" %} 10358 size(4); 10359 ins_encode %{ 10360 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10361 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10362 %} 10363 ins_pipe(pipe_class_default); 10364 %} 10365 10366 // Expand does not work with above instruct. (??) 10367 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10368 // no match-rule 10369 effect(DEF dst, USE src1, USE src2); 10370 format %{ "XOR $dst, $src1, $src2" %} 10371 size(4); 10372 ins_encode %{ 10373 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10374 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10375 %} 10376 ins_pipe(pipe_class_default); 10377 %} 10378 10379 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10380 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10381 ins_cost(DEFAULT_COST*3); 10382 10383 expand %{ 10384 // FIXME: we should do this in the ideal world. 10385 iRegIdst tmp1; 10386 iRegIdst tmp2; 10387 xorI_reg_reg(tmp1, src1, src2); 10388 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10389 xorI_reg_reg(dst, tmp1, tmp2); 10390 %} 10391 %} 10392 10393 // Immediate Xor 10394 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10395 match(Set dst (XorI src1 src2)); 10396 format %{ "XORI $dst, $src1, $src2" %} 10397 size(4); 10398 ins_encode %{ 10399 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10400 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10401 %} 10402 ins_pipe(pipe_class_default); 10403 %} 10404 10405 // Register Xor Long 10406 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10407 match(Set dst (XorL src1 src2)); 10408 ins_cost(DEFAULT_COST); 10409 10410 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10411 size(4); 10412 ins_encode %{ 10413 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10414 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10415 %} 10416 ins_pipe(pipe_class_default); 10417 %} 10418 10419 // XorL + ConvL2I. 10420 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10421 match(Set dst (ConvL2I (XorL src1 src2))); 10422 ins_cost(DEFAULT_COST); 10423 10424 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10425 size(4); 10426 ins_encode %{ 10427 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10428 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10429 %} 10430 ins_pipe(pipe_class_default); 10431 %} 10432 10433 // Immediate Xor Long 10434 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10435 match(Set dst (XorL src1 src2)); 10436 ins_cost(DEFAULT_COST); 10437 10438 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10439 size(4); 10440 ins_encode %{ 10441 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10442 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10443 %} 10444 ins_pipe(pipe_class_default); 10445 %} 10446 10447 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10448 match(Set dst (XorI src1 src2)); 10449 ins_cost(DEFAULT_COST); 10450 10451 format %{ "NOT $dst, $src1 ($src2)" %} 10452 size(4); 10453 ins_encode %{ 10454 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10455 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10456 %} 10457 ins_pipe(pipe_class_default); 10458 %} 10459 10460 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10461 match(Set dst (XorL src1 src2)); 10462 ins_cost(DEFAULT_COST); 10463 10464 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10465 size(4); 10466 ins_encode %{ 10467 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10468 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10469 %} 10470 ins_pipe(pipe_class_default); 10471 %} 10472 10473 // And-complement 10474 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10475 match(Set dst (AndI (XorI src1 src2) src3)); 10476 ins_cost(DEFAULT_COST); 10477 10478 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10479 size(4); 10480 ins_encode( enc_andc(dst, src3, src1) ); 10481 ins_pipe(pipe_class_default); 10482 %} 10483 10484 // And-complement 10485 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10486 // no match-rule, false predicate 10487 effect(DEF dst, USE src1, USE src2); 10488 predicate(false); 10489 10490 format %{ "ANDC $dst, $src1, $src2" %} 10491 size(4); 10492 ins_encode %{ 10493 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10494 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10495 %} 10496 ins_pipe(pipe_class_default); 10497 %} 10498 10499 //----------Moves between int/long and float/double---------------------------- 10500 // 10501 // The following rules move values from int/long registers/stack-locations 10502 // to float/double registers/stack-locations and vice versa, without doing any 10503 // conversions. These rules are used to implement the bit-conversion methods 10504 // of java.lang.Float etc., e.g. 10505 // int floatToIntBits(float value) 10506 // float intBitsToFloat(int bits) 10507 // 10508 // Notes on the implementation on ppc64: 10509 // For Power7 and earlier, the rules are limited to those which move between a 10510 // register and a stack-location, because we always have to go through memory 10511 // when moving between a float register and an integer register. 10512 // This restriction is removed in Power8 with the introduction of the mtfprd 10513 // and mffprd instructions. 10514 10515 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10516 match(Set dst (MoveL2D src)); 10517 predicate(VM_Version::has_mtfprd()); 10518 10519 format %{ "MTFPRD $dst, $src" %} 10520 size(4); 10521 ins_encode %{ 10522 __ mtfprd($dst$$FloatRegister, $src$$Register); 10523 %} 10524 ins_pipe(pipe_class_default); 10525 %} 10526 10527 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10528 // no match-rule, false predicate 10529 effect(DEF dst, USE src); 10530 predicate(false); 10531 10532 format %{ "MTFPRWA $dst, $src" %} 10533 size(4); 10534 ins_encode %{ 10535 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10536 %} 10537 ins_pipe(pipe_class_default); 10538 %} 10539 10540 //---------- Chain stack slots between similar types -------- 10541 10542 // These are needed so that the rules below can match. 10543 10544 // Load integer from stack slot 10545 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10546 match(Set dst src); 10547 ins_cost(MEMORY_REF_COST); 10548 10549 format %{ "LWZ $dst, $src" %} 10550 size(4); 10551 ins_encode( enc_lwz(dst, src) ); 10552 ins_pipe(pipe_class_memory); 10553 %} 10554 10555 // Store integer to stack slot 10556 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10557 match(Set dst src); 10558 ins_cost(MEMORY_REF_COST); 10559 10560 format %{ "STW $src, $dst \t// stk" %} 10561 size(4); 10562 ins_encode( enc_stw(src, dst) ); // rs=rt 10563 ins_pipe(pipe_class_memory); 10564 %} 10565 10566 // Load long from stack slot 10567 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10568 match(Set dst src); 10569 ins_cost(MEMORY_REF_COST); 10570 10571 format %{ "LD $dst, $src \t// long" %} 10572 size(4); 10573 ins_encode( enc_ld(dst, src) ); 10574 ins_pipe(pipe_class_memory); 10575 %} 10576 10577 // Store long to stack slot 10578 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10579 match(Set dst src); 10580 ins_cost(MEMORY_REF_COST); 10581 10582 format %{ "STD $src, $dst \t// long" %} 10583 size(4); 10584 ins_encode( enc_std(src, dst) ); // rs=rt 10585 ins_pipe(pipe_class_memory); 10586 %} 10587 10588 //----------Moves between int and float 10589 10590 // Move float value from float stack-location to integer register. 10591 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10592 match(Set dst (MoveF2I src)); 10593 ins_cost(MEMORY_REF_COST); 10594 10595 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10596 size(4); 10597 ins_encode( enc_lwz(dst, src) ); 10598 ins_pipe(pipe_class_memory); 10599 %} 10600 10601 // Move float value from float register to integer stack-location. 10602 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10603 match(Set dst (MoveF2I src)); 10604 ins_cost(MEMORY_REF_COST); 10605 10606 format %{ "STFS $src, $dst \t// MoveF2I" %} 10607 size(4); 10608 ins_encode( enc_stfs(src, dst) ); 10609 ins_pipe(pipe_class_memory); 10610 %} 10611 10612 // Move integer value from integer stack-location to float register. 10613 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10614 match(Set dst (MoveI2F src)); 10615 ins_cost(MEMORY_REF_COST); 10616 10617 format %{ "LFS $dst, $src \t// MoveI2F" %} 10618 size(4); 10619 ins_encode %{ 10620 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10621 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10622 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10623 %} 10624 ins_pipe(pipe_class_memory); 10625 %} 10626 10627 // Move integer value from integer register to float stack-location. 10628 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10629 match(Set dst (MoveI2F src)); 10630 ins_cost(MEMORY_REF_COST); 10631 10632 format %{ "STW $src, $dst \t// MoveI2F" %} 10633 size(4); 10634 ins_encode( enc_stw(src, dst) ); 10635 ins_pipe(pipe_class_memory); 10636 %} 10637 10638 //----------Moves between long and float 10639 10640 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10641 // no match-rule, false predicate 10642 effect(DEF dst, USE src); 10643 predicate(false); 10644 10645 format %{ "storeD $src, $dst \t// STACK" %} 10646 size(4); 10647 ins_encode( enc_stfd(src, dst) ); 10648 ins_pipe(pipe_class_default); 10649 %} 10650 10651 //----------Moves between long and double 10652 10653 // Move double value from double stack-location to long register. 10654 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10655 match(Set dst (MoveD2L src)); 10656 ins_cost(MEMORY_REF_COST); 10657 size(4); 10658 format %{ "LD $dst, $src \t// MoveD2L" %} 10659 ins_encode( enc_ld(dst, src) ); 10660 ins_pipe(pipe_class_memory); 10661 %} 10662 10663 // Move double value from double register to long stack-location. 10664 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10665 match(Set dst (MoveD2L src)); 10666 effect(DEF dst, USE src); 10667 ins_cost(MEMORY_REF_COST); 10668 10669 format %{ "STFD $src, $dst \t// MoveD2L" %} 10670 size(4); 10671 ins_encode( enc_stfd(src, dst) ); 10672 ins_pipe(pipe_class_memory); 10673 %} 10674 10675 // Move long value from long stack-location to double register. 10676 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10677 match(Set dst (MoveL2D src)); 10678 ins_cost(MEMORY_REF_COST); 10679 10680 format %{ "LFD $dst, $src \t// MoveL2D" %} 10681 size(4); 10682 ins_encode( enc_lfd(dst, src) ); 10683 ins_pipe(pipe_class_memory); 10684 %} 10685 10686 // Move long value from long register to double stack-location. 10687 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10688 match(Set dst (MoveL2D src)); 10689 ins_cost(MEMORY_REF_COST); 10690 10691 format %{ "STD $src, $dst \t// MoveL2D" %} 10692 size(4); 10693 ins_encode( enc_std(src, dst) ); 10694 ins_pipe(pipe_class_memory); 10695 %} 10696 10697 //----------Register Move Instructions----------------------------------------- 10698 10699 // Replicate for Superword 10700 10701 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10702 predicate(false); 10703 effect(DEF dst, USE src); 10704 10705 format %{ "MR $dst, $src \t// replicate " %} 10706 // variable size, 0 or 4. 10707 ins_encode %{ 10708 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10709 __ mr_if_needed($dst$$Register, $src$$Register); 10710 %} 10711 ins_pipe(pipe_class_default); 10712 %} 10713 10714 //----------Cast instructions (Java-level type cast)--------------------------- 10715 10716 // Cast Long to Pointer for unsafe natives. 10717 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10718 match(Set dst (CastX2P src)); 10719 10720 format %{ "MR $dst, $src \t// Long->Ptr" %} 10721 // variable size, 0 or 4. 10722 ins_encode %{ 10723 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10724 __ mr_if_needed($dst$$Register, $src$$Register); 10725 %} 10726 ins_pipe(pipe_class_default); 10727 %} 10728 10729 // Cast Pointer to Long for unsafe natives. 10730 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10731 match(Set dst (CastP2X src)); 10732 10733 format %{ "MR $dst, $src \t// Ptr->Long" %} 10734 // variable size, 0 or 4. 10735 ins_encode %{ 10736 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10737 __ mr_if_needed($dst$$Register, $src$$Register); 10738 %} 10739 ins_pipe(pipe_class_default); 10740 %} 10741 10742 instruct castPP(iRegPdst dst) %{ 10743 match(Set dst (CastPP dst)); 10744 format %{ " -- \t// castPP of $dst" %} 10745 size(0); 10746 ins_encode( /*empty*/ ); 10747 ins_pipe(pipe_class_default); 10748 %} 10749 10750 instruct castII(iRegIdst dst) %{ 10751 match(Set dst (CastII dst)); 10752 format %{ " -- \t// castII of $dst" %} 10753 size(0); 10754 ins_encode( /*empty*/ ); 10755 ins_pipe(pipe_class_default); 10756 %} 10757 10758 instruct checkCastPP(iRegPdst dst) %{ 10759 match(Set dst (CheckCastPP dst)); 10760 format %{ " -- \t// checkcastPP of $dst" %} 10761 size(0); 10762 ins_encode( /*empty*/ ); 10763 ins_pipe(pipe_class_default); 10764 %} 10765 10766 //----------Convert instructions----------------------------------------------- 10767 10768 // Convert to boolean. 10769 10770 // int_to_bool(src) : { 1 if src != 0 10771 // { 0 else 10772 // 10773 // strategy: 10774 // 1) Count leading zeros of 32 bit-value src, 10775 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10776 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10777 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10778 10779 // convI2Bool 10780 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10781 match(Set dst (Conv2B src)); 10782 predicate(UseCountLeadingZerosInstructionsPPC64); 10783 ins_cost(DEFAULT_COST); 10784 10785 expand %{ 10786 immI shiftAmount %{ 0x5 %} 10787 uimmI16 mask %{ 0x1 %} 10788 iRegIdst tmp1; 10789 iRegIdst tmp2; 10790 countLeadingZerosI(tmp1, src); 10791 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10792 xorI_reg_uimm16(dst, tmp2, mask); 10793 %} 10794 %} 10795 10796 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10797 match(Set dst (Conv2B src)); 10798 effect(TEMP crx); 10799 predicate(!UseCountLeadingZerosInstructionsPPC64); 10800 ins_cost(DEFAULT_COST); 10801 10802 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10803 "LI $dst, #0\n\t" 10804 "BEQ $crx, done\n\t" 10805 "LI $dst, #1\n" 10806 "done:" %} 10807 size(16); 10808 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10809 ins_pipe(pipe_class_compare); 10810 %} 10811 10812 // ConvI2B + XorI 10813 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10814 match(Set dst (XorI (Conv2B src) mask)); 10815 predicate(UseCountLeadingZerosInstructionsPPC64); 10816 ins_cost(DEFAULT_COST); 10817 10818 expand %{ 10819 immI shiftAmount %{ 0x5 %} 10820 iRegIdst tmp1; 10821 countLeadingZerosI(tmp1, src); 10822 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10823 %} 10824 %} 10825 10826 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10827 match(Set dst (XorI (Conv2B src) mask)); 10828 effect(TEMP crx); 10829 predicate(!UseCountLeadingZerosInstructionsPPC64); 10830 ins_cost(DEFAULT_COST); 10831 10832 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10833 "LI $dst, #1\n\t" 10834 "BEQ $crx, done\n\t" 10835 "LI $dst, #0\n" 10836 "done:" %} 10837 size(16); 10838 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10839 ins_pipe(pipe_class_compare); 10840 %} 10841 10842 // AndI 0b0..010..0 + ConvI2B 10843 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10844 match(Set dst (Conv2B (AndI src mask))); 10845 predicate(UseRotateAndMaskInstructionsPPC64); 10846 ins_cost(DEFAULT_COST); 10847 10848 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10849 size(4); 10850 ins_encode %{ 10851 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10852 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10853 %} 10854 ins_pipe(pipe_class_default); 10855 %} 10856 10857 // Convert pointer to boolean. 10858 // 10859 // ptr_to_bool(src) : { 1 if src != 0 10860 // { 0 else 10861 // 10862 // strategy: 10863 // 1) Count leading zeros of 64 bit-value src, 10864 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10865 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10866 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10867 10868 // ConvP2B 10869 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10870 match(Set dst (Conv2B src)); 10871 predicate(UseCountLeadingZerosInstructionsPPC64); 10872 ins_cost(DEFAULT_COST); 10873 10874 expand %{ 10875 immI shiftAmount %{ 0x6 %} 10876 uimmI16 mask %{ 0x1 %} 10877 iRegIdst tmp1; 10878 iRegIdst tmp2; 10879 countLeadingZerosP(tmp1, src); 10880 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10881 xorI_reg_uimm16(dst, tmp2, mask); 10882 %} 10883 %} 10884 10885 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10886 match(Set dst (Conv2B src)); 10887 effect(TEMP crx); 10888 predicate(!UseCountLeadingZerosInstructionsPPC64); 10889 ins_cost(DEFAULT_COST); 10890 10891 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10892 "LI $dst, #0\n\t" 10893 "BEQ $crx, done\n\t" 10894 "LI $dst, #1\n" 10895 "done:" %} 10896 size(16); 10897 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10898 ins_pipe(pipe_class_compare); 10899 %} 10900 10901 // ConvP2B + XorI 10902 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10903 match(Set dst (XorI (Conv2B src) mask)); 10904 predicate(UseCountLeadingZerosInstructionsPPC64); 10905 ins_cost(DEFAULT_COST); 10906 10907 expand %{ 10908 immI shiftAmount %{ 0x6 %} 10909 iRegIdst tmp1; 10910 countLeadingZerosP(tmp1, src); 10911 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10912 %} 10913 %} 10914 10915 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10916 match(Set dst (XorI (Conv2B src) mask)); 10917 effect(TEMP crx); 10918 predicate(!UseCountLeadingZerosInstructionsPPC64); 10919 ins_cost(DEFAULT_COST); 10920 10921 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10922 "LI $dst, #1\n\t" 10923 "BEQ $crx, done\n\t" 10924 "LI $dst, #0\n" 10925 "done:" %} 10926 size(16); 10927 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10928 ins_pipe(pipe_class_compare); 10929 %} 10930 10931 // if src1 < src2, return -1 else return 0 10932 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10933 match(Set dst (CmpLTMask src1 src2)); 10934 ins_cost(DEFAULT_COST*4); 10935 10936 expand %{ 10937 iRegLdst src1s; 10938 iRegLdst src2s; 10939 iRegLdst diff; 10940 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10941 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10942 subL_reg_reg(diff, src1s, src2s); 10943 // Need to consider >=33 bit result, therefore we need signmaskL. 10944 signmask64I_regL(dst, diff); 10945 %} 10946 %} 10947 10948 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 10949 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 10950 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 10951 size(4); 10952 ins_encode %{ 10953 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 10954 __ srawi($dst$$Register, $src1$$Register, 0x1f); 10955 %} 10956 ins_pipe(pipe_class_default); 10957 %} 10958 10959 //----------Arithmetic Conversion Instructions--------------------------------- 10960 10961 // Convert to Byte -- nop 10962 // Convert to Short -- nop 10963 10964 // Convert to Int 10965 10966 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 10967 match(Set dst (RShiftI (LShiftI src amount) amount)); 10968 format %{ "EXTSB $dst, $src \t// byte->int" %} 10969 size(4); 10970 ins_encode %{ 10971 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 10972 __ extsb($dst$$Register, $src$$Register); 10973 %} 10974 ins_pipe(pipe_class_default); 10975 %} 10976 10977 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 10978 effect(DEF dst, USE src); 10979 10980 size(4); 10981 ins_encode %{ 10982 __ extsh($dst$$Register, $src$$Register); 10983 %} 10984 ins_pipe(pipe_class_default); 10985 %} 10986 10987 // LShiftI 16 + RShiftI 16 converts short to int. 10988 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 10989 match(Set dst (RShiftI (LShiftI src amount) amount)); 10990 format %{ "EXTSH $dst, $src \t// short->int" %} 10991 size(4); 10992 ins_encode %{ 10993 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 10994 __ extsh($dst$$Register, $src$$Register); 10995 %} 10996 ins_pipe(pipe_class_default); 10997 %} 10998 10999 // ConvL2I + ConvI2L: Sign extend int in long register. 11000 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11001 match(Set dst (ConvI2L (ConvL2I src))); 11002 11003 format %{ "EXTSW $dst, $src \t// long->long" %} 11004 size(4); 11005 ins_encode %{ 11006 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11007 __ extsw($dst$$Register, $src$$Register); 11008 %} 11009 ins_pipe(pipe_class_default); 11010 %} 11011 11012 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11013 match(Set dst (ConvL2I src)); 11014 format %{ "MR $dst, $src \t// long->int" %} 11015 // variable size, 0 or 4 11016 ins_encode %{ 11017 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11018 __ mr_if_needed($dst$$Register, $src$$Register); 11019 %} 11020 ins_pipe(pipe_class_default); 11021 %} 11022 11023 instruct convD2IRaw_regD(regD dst, regD src) %{ 11024 // no match-rule, false predicate 11025 effect(DEF dst, USE src); 11026 predicate(false); 11027 11028 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11029 size(4); 11030 ins_encode %{ 11031 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11032 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11033 %} 11034 ins_pipe(pipe_class_default); 11035 %} 11036 11037 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 11038 // no match-rule, false predicate 11039 effect(DEF dst, USE crx, USE src); 11040 predicate(false); 11041 11042 ins_variable_size_depending_on_alignment(true); 11043 11044 format %{ "cmovI $crx, $dst, $src" %} 11045 // Worst case is branch + move + stop, no stop without scheduler. 11046 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 11047 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11048 ins_pipe(pipe_class_default); 11049 %} 11050 11051 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11052 // no match-rule, false predicate 11053 effect(DEF dst, USE crx, USE src); 11054 predicate(false); 11055 11056 ins_variable_size_depending_on_alignment(true); 11057 11058 format %{ "cmovI $crx, $dst, $src" %} 11059 // Worst case is branch + move + stop, no stop without scheduler. 11060 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 11061 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11062 ins_pipe(pipe_class_default); 11063 %} 11064 11065 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11066 // no match-rule, false predicate 11067 effect(DEF dst, USE crx, USE mem); 11068 predicate(false); 11069 11070 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11071 postalloc_expand %{ 11072 // 11073 // replaces 11074 // 11075 // region dst crx mem 11076 // \ | | / 11077 // dst=cmovI_bso_stackSlotL_conLvalue0 11078 // 11079 // with 11080 // 11081 // region dst 11082 // \ / 11083 // dst=loadConI16(0) 11084 // | 11085 // ^ region dst crx mem 11086 // | \ | | / 11087 // dst=cmovI_bso_stackSlotL 11088 // 11089 11090 // Create new nodes. 11091 MachNode *m1 = new loadConI16Node(); 11092 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11093 11094 // inputs for new nodes 11095 m1->add_req(n_region); 11096 m2->add_req(n_region, n_crx, n_mem); 11097 11098 // precedences for new nodes 11099 m2->add_prec(m1); 11100 11101 // operands for new nodes 11102 m1->_opnds[0] = op_dst; 11103 m1->_opnds[1] = new immI16Oper(0); 11104 11105 m2->_opnds[0] = op_dst; 11106 m2->_opnds[1] = op_crx; 11107 m2->_opnds[2] = op_mem; 11108 11109 // registers for new nodes 11110 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11111 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11112 11113 // Insert new nodes. 11114 nodes->push(m1); 11115 nodes->push(m2); 11116 %} 11117 %} 11118 11119 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11120 // no match-rule, false predicate 11121 effect(DEF dst, USE crx, USE src); 11122 predicate(false); 11123 11124 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11125 postalloc_expand %{ 11126 // 11127 // replaces 11128 // 11129 // region dst crx src 11130 // \ | | / 11131 // dst=cmovI_bso_reg_conLvalue0 11132 // 11133 // with 11134 // 11135 // region dst 11136 // \ / 11137 // dst=loadConI16(0) 11138 // | 11139 // ^ region dst crx src 11140 // | \ | | / 11141 // dst=cmovI_bso_reg 11142 // 11143 11144 // Create new nodes. 11145 MachNode *m1 = new loadConI16Node(); 11146 MachNode *m2 = new cmovI_bso_regNode(); 11147 11148 // inputs for new nodes 11149 m1->add_req(n_region); 11150 m2->add_req(n_region, n_crx, n_src); 11151 11152 // precedences for new nodes 11153 m2->add_prec(m1); 11154 11155 // operands for new nodes 11156 m1->_opnds[0] = op_dst; 11157 m1->_opnds[1] = new immI16Oper(0); 11158 11159 m2->_opnds[0] = op_dst; 11160 m2->_opnds[1] = op_crx; 11161 m2->_opnds[2] = op_src; 11162 11163 // registers for new nodes 11164 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11165 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11166 11167 // Insert new nodes. 11168 nodes->push(m1); 11169 nodes->push(m2); 11170 %} 11171 %} 11172 11173 // Double to Int conversion, NaN is mapped to 0. 11174 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11175 match(Set dst (ConvD2I src)); 11176 predicate(!VM_Version::has_mtfprd()); 11177 ins_cost(DEFAULT_COST); 11178 11179 expand %{ 11180 regD tmpD; 11181 stackSlotL tmpS; 11182 flagsReg crx; 11183 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11184 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11185 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11186 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11187 %} 11188 %} 11189 11190 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11191 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11192 match(Set dst (ConvD2I src)); 11193 predicate(VM_Version::has_mtfprd()); 11194 ins_cost(DEFAULT_COST); 11195 11196 expand %{ 11197 regD tmpD; 11198 flagsReg crx; 11199 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11200 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11201 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11202 %} 11203 %} 11204 11205 instruct convF2IRaw_regF(regF dst, regF src) %{ 11206 // no match-rule, false predicate 11207 effect(DEF dst, USE src); 11208 predicate(false); 11209 11210 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11211 size(4); 11212 ins_encode %{ 11213 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11214 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11215 %} 11216 ins_pipe(pipe_class_default); 11217 %} 11218 11219 // Float to Int conversion, NaN is mapped to 0. 11220 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11221 match(Set dst (ConvF2I src)); 11222 predicate(!VM_Version::has_mtfprd()); 11223 ins_cost(DEFAULT_COST); 11224 11225 expand %{ 11226 regF tmpF; 11227 stackSlotL tmpS; 11228 flagsReg crx; 11229 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11230 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11231 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11232 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11233 %} 11234 %} 11235 11236 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11237 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11238 match(Set dst (ConvF2I src)); 11239 predicate(VM_Version::has_mtfprd()); 11240 ins_cost(DEFAULT_COST); 11241 11242 expand %{ 11243 regF tmpF; 11244 flagsReg crx; 11245 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11246 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11247 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11248 %} 11249 %} 11250 11251 // Convert to Long 11252 11253 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11254 match(Set dst (ConvI2L src)); 11255 format %{ "EXTSW $dst, $src \t// int->long" %} 11256 size(4); 11257 ins_encode %{ 11258 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11259 __ extsw($dst$$Register, $src$$Register); 11260 %} 11261 ins_pipe(pipe_class_default); 11262 %} 11263 11264 // Zero-extend: convert unsigned int to long (convUI2L). 11265 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11266 match(Set dst (AndL (ConvI2L src) mask)); 11267 ins_cost(DEFAULT_COST); 11268 11269 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11270 size(4); 11271 ins_encode %{ 11272 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11273 __ clrldi($dst$$Register, $src$$Register, 32); 11274 %} 11275 ins_pipe(pipe_class_default); 11276 %} 11277 11278 // Zero-extend: convert unsigned int to long in long register. 11279 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11280 match(Set dst (AndL src mask)); 11281 ins_cost(DEFAULT_COST); 11282 11283 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11284 size(4); 11285 ins_encode %{ 11286 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11287 __ clrldi($dst$$Register, $src$$Register, 32); 11288 %} 11289 ins_pipe(pipe_class_default); 11290 %} 11291 11292 instruct convF2LRaw_regF(regF dst, regF src) %{ 11293 // no match-rule, false predicate 11294 effect(DEF dst, USE src); 11295 predicate(false); 11296 11297 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11298 size(4); 11299 ins_encode %{ 11300 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11301 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11302 %} 11303 ins_pipe(pipe_class_default); 11304 %} 11305 11306 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 11307 // no match-rule, false predicate 11308 effect(DEF dst, USE crx, USE src); 11309 predicate(false); 11310 11311 ins_variable_size_depending_on_alignment(true); 11312 11313 format %{ "cmovL $crx, $dst, $src" %} 11314 // Worst case is branch + move + stop, no stop without scheduler. 11315 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 11316 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11317 ins_pipe(pipe_class_default); 11318 %} 11319 11320 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11321 // no match-rule, false predicate 11322 effect(DEF dst, USE crx, USE src); 11323 predicate(false); 11324 11325 ins_variable_size_depending_on_alignment(true); 11326 11327 format %{ "cmovL $crx, $dst, $src" %} 11328 // Worst case is branch + move + stop, no stop without scheduler. 11329 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 11330 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11331 ins_pipe(pipe_class_default); 11332 %} 11333 11334 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11335 // no match-rule, false predicate 11336 effect(DEF dst, USE crx, USE mem); 11337 predicate(false); 11338 11339 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11340 postalloc_expand %{ 11341 // 11342 // replaces 11343 // 11344 // region dst crx mem 11345 // \ | | / 11346 // dst=cmovL_bso_stackSlotL_conLvalue0 11347 // 11348 // with 11349 // 11350 // region dst 11351 // \ / 11352 // dst=loadConL16(0) 11353 // | 11354 // ^ region dst crx mem 11355 // | \ | | / 11356 // dst=cmovL_bso_stackSlotL 11357 // 11358 11359 // Create new nodes. 11360 MachNode *m1 = new loadConL16Node(); 11361 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11362 11363 // inputs for new nodes 11364 m1->add_req(n_region); 11365 m2->add_req(n_region, n_crx, n_mem); 11366 m2->add_prec(m1); 11367 11368 // operands for new nodes 11369 m1->_opnds[0] = op_dst; 11370 m1->_opnds[1] = new immL16Oper(0); 11371 m2->_opnds[0] = op_dst; 11372 m2->_opnds[1] = op_crx; 11373 m2->_opnds[2] = op_mem; 11374 11375 // registers for new nodes 11376 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11377 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11378 11379 // Insert new nodes. 11380 nodes->push(m1); 11381 nodes->push(m2); 11382 %} 11383 %} 11384 11385 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11386 // no match-rule, false predicate 11387 effect(DEF dst, USE crx, USE src); 11388 predicate(false); 11389 11390 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11391 postalloc_expand %{ 11392 // 11393 // replaces 11394 // 11395 // region dst crx src 11396 // \ | | / 11397 // dst=cmovL_bso_reg_conLvalue0 11398 // 11399 // with 11400 // 11401 // region dst 11402 // \ / 11403 // dst=loadConL16(0) 11404 // | 11405 // ^ region dst crx src 11406 // | \ | | / 11407 // dst=cmovL_bso_reg 11408 // 11409 11410 // Create new nodes. 11411 MachNode *m1 = new loadConL16Node(); 11412 MachNode *m2 = new cmovL_bso_regNode(); 11413 11414 // inputs for new nodes 11415 m1->add_req(n_region); 11416 m2->add_req(n_region, n_crx, n_src); 11417 m2->add_prec(m1); 11418 11419 // operands for new nodes 11420 m1->_opnds[0] = op_dst; 11421 m1->_opnds[1] = new immL16Oper(0); 11422 m2->_opnds[0] = op_dst; 11423 m2->_opnds[1] = op_crx; 11424 m2->_opnds[2] = op_src; 11425 11426 // registers for new nodes 11427 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11428 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11429 11430 // Insert new nodes. 11431 nodes->push(m1); 11432 nodes->push(m2); 11433 %} 11434 %} 11435 11436 // Float to Long conversion, NaN is mapped to 0. 11437 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11438 match(Set dst (ConvF2L src)); 11439 predicate(!VM_Version::has_mtfprd()); 11440 ins_cost(DEFAULT_COST); 11441 11442 expand %{ 11443 regF tmpF; 11444 stackSlotL tmpS; 11445 flagsReg crx; 11446 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11447 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11448 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11449 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11450 %} 11451 %} 11452 11453 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11454 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11455 match(Set dst (ConvF2L src)); 11456 predicate(VM_Version::has_mtfprd()); 11457 ins_cost(DEFAULT_COST); 11458 11459 expand %{ 11460 regF tmpF; 11461 flagsReg crx; 11462 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11463 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11464 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11465 %} 11466 %} 11467 11468 instruct convD2LRaw_regD(regD dst, regD src) %{ 11469 // no match-rule, false predicate 11470 effect(DEF dst, USE src); 11471 predicate(false); 11472 11473 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11474 size(4); 11475 ins_encode %{ 11476 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11477 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11478 %} 11479 ins_pipe(pipe_class_default); 11480 %} 11481 11482 // Double to Long conversion, NaN is mapped to 0. 11483 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11484 match(Set dst (ConvD2L src)); 11485 predicate(!VM_Version::has_mtfprd()); 11486 ins_cost(DEFAULT_COST); 11487 11488 expand %{ 11489 regD tmpD; 11490 stackSlotL tmpS; 11491 flagsReg crx; 11492 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11493 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11494 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11495 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11496 %} 11497 %} 11498 11499 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11500 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11501 match(Set dst (ConvD2L src)); 11502 predicate(VM_Version::has_mtfprd()); 11503 ins_cost(DEFAULT_COST); 11504 11505 expand %{ 11506 regD tmpD; 11507 flagsReg crx; 11508 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11509 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11510 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11511 %} 11512 %} 11513 11514 // Convert to Float 11515 11516 // Placed here as needed in expand. 11517 instruct convL2DRaw_regD(regD dst, regD src) %{ 11518 // no match-rule, false predicate 11519 effect(DEF dst, USE src); 11520 predicate(false); 11521 11522 format %{ "FCFID $dst, $src \t// convL2D" %} 11523 size(4); 11524 ins_encode %{ 11525 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11526 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11527 %} 11528 ins_pipe(pipe_class_default); 11529 %} 11530 11531 // Placed here as needed in expand. 11532 instruct convD2F_reg(regF dst, regD src) %{ 11533 match(Set dst (ConvD2F src)); 11534 format %{ "FRSP $dst, $src \t// convD2F" %} 11535 size(4); 11536 ins_encode %{ 11537 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11538 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11539 %} 11540 ins_pipe(pipe_class_default); 11541 %} 11542 11543 // Integer to Float conversion. 11544 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11545 match(Set dst (ConvI2F src)); 11546 predicate(!VM_Version::has_fcfids()); 11547 ins_cost(DEFAULT_COST); 11548 11549 expand %{ 11550 iRegLdst tmpL; 11551 stackSlotL tmpS; 11552 regD tmpD; 11553 regD tmpD2; 11554 convI2L_reg(tmpL, src); // Sign-extension int to long. 11555 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11556 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11557 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11558 convD2F_reg(dst, tmpD2); // Convert double to float. 11559 %} 11560 %} 11561 11562 instruct convL2FRaw_regF(regF dst, regD src) %{ 11563 // no match-rule, false predicate 11564 effect(DEF dst, USE src); 11565 predicate(false); 11566 11567 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11568 size(4); 11569 ins_encode %{ 11570 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11571 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11572 %} 11573 ins_pipe(pipe_class_default); 11574 %} 11575 11576 // Integer to Float conversion. Special version for Power7. 11577 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11578 match(Set dst (ConvI2F src)); 11579 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11580 ins_cost(DEFAULT_COST); 11581 11582 expand %{ 11583 iRegLdst tmpL; 11584 stackSlotL tmpS; 11585 regD tmpD; 11586 convI2L_reg(tmpL, src); // Sign-extension int to long. 11587 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11588 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11589 convL2FRaw_regF(dst, tmpD); // Convert to float. 11590 %} 11591 %} 11592 11593 // Integer to Float conversion. Special version for Power8. 11594 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11595 match(Set dst (ConvI2F src)); 11596 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11597 ins_cost(DEFAULT_COST); 11598 11599 expand %{ 11600 regD tmpD; 11601 moveI2D_reg(tmpD, src); 11602 convL2FRaw_regF(dst, tmpD); // Convert to float. 11603 %} 11604 %} 11605 11606 // L2F to avoid runtime call. 11607 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11608 match(Set dst (ConvL2F src)); 11609 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11610 ins_cost(DEFAULT_COST); 11611 11612 expand %{ 11613 stackSlotL tmpS; 11614 regD tmpD; 11615 regL_to_stkL(tmpS, src); // Store long to stack. 11616 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11617 convL2FRaw_regF(dst, tmpD); // Convert to float. 11618 %} 11619 %} 11620 11621 // L2F to avoid runtime call. Special version for Power8. 11622 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11623 match(Set dst (ConvL2F src)); 11624 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11625 ins_cost(DEFAULT_COST); 11626 11627 expand %{ 11628 regD tmpD; 11629 moveL2D_reg(tmpD, src); 11630 convL2FRaw_regF(dst, tmpD); // Convert to float. 11631 %} 11632 %} 11633 11634 // Moved up as used in expand. 11635 //instruct convD2F_reg(regF dst, regD src) %{%} 11636 11637 // Convert to Double 11638 11639 // Integer to Double conversion. 11640 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11641 match(Set dst (ConvI2D src)); 11642 predicate(!VM_Version::has_mtfprd()); 11643 ins_cost(DEFAULT_COST); 11644 11645 expand %{ 11646 iRegLdst tmpL; 11647 stackSlotL tmpS; 11648 regD tmpD; 11649 convI2L_reg(tmpL, src); // Sign-extension int to long. 11650 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11651 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11652 convL2DRaw_regD(dst, tmpD); // Convert to double. 11653 %} 11654 %} 11655 11656 // Integer to Double conversion. Special version for Power8. 11657 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11658 match(Set dst (ConvI2D src)); 11659 predicate(VM_Version::has_mtfprd()); 11660 ins_cost(DEFAULT_COST); 11661 11662 expand %{ 11663 regD tmpD; 11664 moveI2D_reg(tmpD, src); 11665 convL2DRaw_regD(dst, tmpD); // Convert to double. 11666 %} 11667 %} 11668 11669 // Long to Double conversion 11670 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11671 match(Set dst (ConvL2D src)); 11672 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11673 11674 expand %{ 11675 regD tmpD; 11676 moveL2D_stack_reg(tmpD, src); 11677 convL2DRaw_regD(dst, tmpD); 11678 %} 11679 %} 11680 11681 // Long to Double conversion. Special version for Power8. 11682 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11683 match(Set dst (ConvL2D src)); 11684 predicate(VM_Version::has_mtfprd()); 11685 ins_cost(DEFAULT_COST); 11686 11687 expand %{ 11688 regD tmpD; 11689 moveL2D_reg(tmpD, src); 11690 convL2DRaw_regD(dst, tmpD); // Convert to double. 11691 %} 11692 %} 11693 11694 instruct convF2D_reg(regD dst, regF src) %{ 11695 match(Set dst (ConvF2D src)); 11696 format %{ "FMR $dst, $src \t// float->double" %} 11697 // variable size, 0 or 4 11698 ins_encode %{ 11699 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11700 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11701 %} 11702 ins_pipe(pipe_class_default); 11703 %} 11704 11705 //----------Control Flow Instructions------------------------------------------ 11706 // Compare Instructions 11707 11708 // Compare Integers 11709 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11710 match(Set crx (CmpI src1 src2)); 11711 size(4); 11712 format %{ "CMPW $crx, $src1, $src2" %} 11713 ins_encode %{ 11714 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11715 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11716 %} 11717 ins_pipe(pipe_class_compare); 11718 %} 11719 11720 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11721 match(Set crx (CmpI src1 src2)); 11722 format %{ "CMPWI $crx, $src1, $src2" %} 11723 size(4); 11724 ins_encode %{ 11725 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11726 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11727 %} 11728 ins_pipe(pipe_class_compare); 11729 %} 11730 11731 // (src1 & src2) == 0? 11732 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11733 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11734 // r0 is killed 11735 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11736 size(4); 11737 ins_encode %{ 11738 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11739 __ andi_(R0, $src1$$Register, $src2$$constant); 11740 %} 11741 ins_pipe(pipe_class_compare); 11742 %} 11743 11744 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11745 match(Set crx (CmpL src1 src2)); 11746 format %{ "CMPD $crx, $src1, $src2" %} 11747 size(4); 11748 ins_encode %{ 11749 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11750 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11751 %} 11752 ins_pipe(pipe_class_compare); 11753 %} 11754 11755 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11756 match(Set crx (CmpL src1 src2)); 11757 format %{ "CMPDI $crx, $src1, $src2" %} 11758 size(4); 11759 ins_encode %{ 11760 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11761 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11762 %} 11763 ins_pipe(pipe_class_compare); 11764 %} 11765 11766 // Added CmpUL for LoopPredicate. 11767 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11768 match(Set crx (CmpUL src1 src2)); 11769 format %{ "CMPLD $crx, $src1, $src2" %} 11770 size(4); 11771 ins_encode %{ 11772 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11773 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11774 %} 11775 ins_pipe(pipe_class_compare); 11776 %} 11777 11778 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11779 match(Set crx (CmpUL src1 src2)); 11780 format %{ "CMPLDI $crx, $src1, $src2" %} 11781 size(4); 11782 ins_encode %{ 11783 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11784 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11785 %} 11786 ins_pipe(pipe_class_compare); 11787 %} 11788 11789 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11790 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11791 // r0 is killed 11792 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11793 size(4); 11794 ins_encode %{ 11795 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11796 __ and_(R0, $src1$$Register, $src2$$Register); 11797 %} 11798 ins_pipe(pipe_class_compare); 11799 %} 11800 11801 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11802 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11803 // r0 is killed 11804 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11805 size(4); 11806 ins_encode %{ 11807 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11808 __ andi_(R0, $src1$$Register, $src2$$constant); 11809 %} 11810 ins_pipe(pipe_class_compare); 11811 %} 11812 11813 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11814 // no match-rule, false predicate 11815 effect(DEF dst, USE crx); 11816 predicate(false); 11817 11818 ins_variable_size_depending_on_alignment(true); 11819 11820 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11821 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11822 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16); 11823 ins_encode %{ 11824 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11825 Label done; 11826 // li(Rdst, 0); // equal -> 0 11827 __ beq($crx$$CondRegister, done); 11828 __ li($dst$$Register, 1); // greater -> +1 11829 __ bgt($crx$$CondRegister, done); 11830 __ li($dst$$Register, -1); // unordered or less -> -1 11831 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11832 __ bind(done); 11833 %} 11834 ins_pipe(pipe_class_compare); 11835 %} 11836 11837 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11838 // no match-rule, false predicate 11839 effect(DEF dst, USE crx); 11840 predicate(false); 11841 11842 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11843 postalloc_expand %{ 11844 // 11845 // replaces 11846 // 11847 // region crx 11848 // \ | 11849 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11850 // 11851 // with 11852 // 11853 // region 11854 // \ 11855 // dst=loadConI16(0) 11856 // | 11857 // ^ region crx 11858 // | \ | 11859 // dst=cmovI_conIvalueMinus1_conIvalue1 11860 // 11861 11862 // Create new nodes. 11863 MachNode *m1 = new loadConI16Node(); 11864 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11865 11866 // inputs for new nodes 11867 m1->add_req(n_region); 11868 m2->add_req(n_region, n_crx); 11869 m2->add_prec(m1); 11870 11871 // operands for new nodes 11872 m1->_opnds[0] = op_dst; 11873 m1->_opnds[1] = new immI16Oper(0); 11874 m2->_opnds[0] = op_dst; 11875 m2->_opnds[1] = op_crx; 11876 11877 // registers for new nodes 11878 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11879 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11880 11881 // Insert new nodes. 11882 nodes->push(m1); 11883 nodes->push(m2); 11884 %} 11885 %} 11886 11887 // Manifest a CmpL3 result in an integer register. Very painful. 11888 // This is the test to avoid. 11889 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11890 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11891 match(Set dst (CmpL3 src1 src2)); 11892 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11893 11894 expand %{ 11895 flagsReg tmp1; 11896 cmpL_reg_reg(tmp1, src1, src2); 11897 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11898 %} 11899 %} 11900 11901 // Implicit range checks. 11902 // A range check in the ideal world has one of the following shapes: 11903 // - (If le (CmpU length index)), (IfTrue throw exception) 11904 // - (If lt (CmpU index length)), (IfFalse throw exception) 11905 // 11906 // Match range check 'If le (CmpU length index)'. 11907 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11908 match(If cmp (CmpU src_length index)); 11909 effect(USE labl); 11910 predicate(TrapBasedRangeChecks && 11911 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11912 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11913 (Matcher::branches_to_uncommon_trap(_leaf))); 11914 11915 ins_is_TrapBasedCheckNode(true); 11916 11917 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11918 size(4); 11919 ins_encode %{ 11920 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11921 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11922 __ trap_range_check_le($src_length$$Register, $index$$constant); 11923 } else { 11924 // Both successors are uncommon traps, probability is 0. 11925 // Node got flipped during fixup flow. 11926 assert($cmp$$cmpcode == 0x9, "must be greater"); 11927 __ trap_range_check_g($src_length$$Register, $index$$constant); 11928 } 11929 %} 11930 ins_pipe(pipe_class_trap); 11931 %} 11932 11933 // Match range check 'If lt (CmpU index length)'. 11934 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11935 match(If cmp (CmpU src_index src_length)); 11936 effect(USE labl); 11937 predicate(TrapBasedRangeChecks && 11938 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11939 _leaf->as_If()->_prob >= PROB_ALWAYS && 11940 (Matcher::branches_to_uncommon_trap(_leaf))); 11941 11942 ins_is_TrapBasedCheckNode(true); 11943 11944 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 11945 size(4); 11946 ins_encode %{ 11947 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 11948 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11949 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 11950 } else { 11951 // Both successors are uncommon traps, probability is 0. 11952 // Node got flipped during fixup flow. 11953 assert($cmp$$cmpcode == 0x8, "must be less"); 11954 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 11955 } 11956 %} 11957 ins_pipe(pipe_class_trap); 11958 %} 11959 11960 // Match range check 'If lt (CmpU index length)'. 11961 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 11962 match(If cmp (CmpU src_index length)); 11963 effect(USE labl); 11964 predicate(TrapBasedRangeChecks && 11965 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11966 _leaf->as_If()->_prob >= PROB_ALWAYS && 11967 (Matcher::branches_to_uncommon_trap(_leaf))); 11968 11969 ins_is_TrapBasedCheckNode(true); 11970 11971 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 11972 size(4); 11973 ins_encode %{ 11974 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11975 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11976 __ trap_range_check_ge($src_index$$Register, $length$$constant); 11977 } else { 11978 // Both successors are uncommon traps, probability is 0. 11979 // Node got flipped during fixup flow. 11980 assert($cmp$$cmpcode == 0x8, "must be less"); 11981 __ trap_range_check_l($src_index$$Register, $length$$constant); 11982 } 11983 %} 11984 ins_pipe(pipe_class_trap); 11985 %} 11986 11987 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11988 match(Set crx (CmpU src1 src2)); 11989 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 11990 size(4); 11991 ins_encode %{ 11992 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11993 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11994 %} 11995 ins_pipe(pipe_class_compare); 11996 %} 11997 11998 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 11999 match(Set crx (CmpU src1 src2)); 12000 size(4); 12001 format %{ "CMPLWI $crx, $src1, $src2" %} 12002 ins_encode %{ 12003 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12004 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12005 %} 12006 ins_pipe(pipe_class_compare); 12007 %} 12008 12009 // Implicit zero checks (more implicit null checks). 12010 // No constant pool entries required. 12011 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12012 match(If cmp (CmpN value zero)); 12013 effect(USE labl); 12014 predicate(TrapBasedNullChecks && 12015 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12016 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12017 Matcher::branches_to_uncommon_trap(_leaf)); 12018 ins_cost(1); 12019 12020 ins_is_TrapBasedCheckNode(true); 12021 12022 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12023 size(4); 12024 ins_encode %{ 12025 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12026 if ($cmp$$cmpcode == 0xA) { 12027 __ trap_null_check($value$$Register); 12028 } else { 12029 // Both successors are uncommon traps, probability is 0. 12030 // Node got flipped during fixup flow. 12031 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12032 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12033 } 12034 %} 12035 ins_pipe(pipe_class_trap); 12036 %} 12037 12038 // Compare narrow oops. 12039 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12040 match(Set crx (CmpN src1 src2)); 12041 12042 size(4); 12043 ins_cost(2); 12044 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12045 ins_encode %{ 12046 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12047 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12048 %} 12049 ins_pipe(pipe_class_compare); 12050 %} 12051 12052 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12053 match(Set crx (CmpN src1 src2)); 12054 // Make this more expensive than zeroCheckN_iReg_imm0. 12055 ins_cost(2); 12056 12057 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12058 size(4); 12059 ins_encode %{ 12060 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12061 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12062 %} 12063 ins_pipe(pipe_class_compare); 12064 %} 12065 12066 // Implicit zero checks (more implicit null checks). 12067 // No constant pool entries required. 12068 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12069 match(If cmp (CmpP value zero)); 12070 effect(USE labl); 12071 predicate(TrapBasedNullChecks && 12072 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12073 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12074 Matcher::branches_to_uncommon_trap(_leaf)); 12075 ins_cost(1); // Should not be cheaper than zeroCheckN. 12076 12077 ins_is_TrapBasedCheckNode(true); 12078 12079 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12080 size(4); 12081 ins_encode %{ 12082 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12083 if ($cmp$$cmpcode == 0xA) { 12084 __ trap_null_check($value$$Register); 12085 } else { 12086 // Both successors are uncommon traps, probability is 0. 12087 // Node got flipped during fixup flow. 12088 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12089 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12090 } 12091 %} 12092 ins_pipe(pipe_class_trap); 12093 %} 12094 12095 // Compare Pointers 12096 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12097 match(Set crx (CmpP src1 src2)); 12098 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12099 size(4); 12100 ins_encode %{ 12101 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12102 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12103 %} 12104 ins_pipe(pipe_class_compare); 12105 %} 12106 12107 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12108 match(Set crx (CmpP src1 src2)); 12109 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12110 size(4); 12111 ins_encode %{ 12112 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12113 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12114 %} 12115 ins_pipe(pipe_class_compare); 12116 %} 12117 12118 // Used in postalloc expand. 12119 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12120 // This match rule prevents reordering of node before a safepoint. 12121 // This only makes sense if this instructions is used exclusively 12122 // for the expansion of EncodeP! 12123 match(Set crx (CmpP src1 src2)); 12124 predicate(false); 12125 12126 format %{ "CMPDI $crx, $src1, $src2" %} 12127 size(4); 12128 ins_encode %{ 12129 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12130 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12131 %} 12132 ins_pipe(pipe_class_compare); 12133 %} 12134 12135 //----------Float Compares---------------------------------------------------- 12136 12137 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12138 // Needs matchrule, see cmpDUnordered. 12139 match(Set crx (CmpF src1 src2)); 12140 // no match-rule, false predicate 12141 predicate(false); 12142 12143 format %{ "cmpFUrd $crx, $src1, $src2" %} 12144 size(4); 12145 ins_encode %{ 12146 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12147 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12148 %} 12149 ins_pipe(pipe_class_default); 12150 %} 12151 12152 instruct cmov_bns_less(flagsReg crx) %{ 12153 // no match-rule, false predicate 12154 effect(DEF crx); 12155 predicate(false); 12156 12157 ins_variable_size_depending_on_alignment(true); 12158 12159 format %{ "cmov $crx" %} 12160 // Worst case is branch + move + stop, no stop without scheduler. 12161 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12); 12162 ins_encode %{ 12163 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12164 Label done; 12165 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12166 __ li(R0, 0); 12167 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12168 // TODO PPC port __ endgroup_if_needed(_size == 16); 12169 __ bind(done); 12170 %} 12171 ins_pipe(pipe_class_default); 12172 %} 12173 12174 // Compare floating, generate condition code. 12175 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12176 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12177 // 12178 // The following code sequence occurs a lot in mpegaudio: 12179 // 12180 // block BXX: 12181 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12182 // cmpFUrd CCR6, F11, F9 12183 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12184 // cmov CCR6 12185 // 8: instruct branchConSched: 12186 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12187 match(Set crx (CmpF src1 src2)); 12188 ins_cost(DEFAULT_COST+BRANCH_COST); 12189 12190 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12191 postalloc_expand %{ 12192 // 12193 // replaces 12194 // 12195 // region src1 src2 12196 // \ | | 12197 // crx=cmpF_reg_reg 12198 // 12199 // with 12200 // 12201 // region src1 src2 12202 // \ | | 12203 // crx=cmpFUnordered_reg_reg 12204 // | 12205 // ^ region 12206 // | \ 12207 // crx=cmov_bns_less 12208 // 12209 12210 // Create new nodes. 12211 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12212 MachNode *m2 = new cmov_bns_lessNode(); 12213 12214 // inputs for new nodes 12215 m1->add_req(n_region, n_src1, n_src2); 12216 m2->add_req(n_region); 12217 m2->add_prec(m1); 12218 12219 // operands for new nodes 12220 m1->_opnds[0] = op_crx; 12221 m1->_opnds[1] = op_src1; 12222 m1->_opnds[2] = op_src2; 12223 m2->_opnds[0] = op_crx; 12224 12225 // registers for new nodes 12226 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12227 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12228 12229 // Insert new nodes. 12230 nodes->push(m1); 12231 nodes->push(m2); 12232 %} 12233 %} 12234 12235 // Compare float, generate -1,0,1 12236 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12237 match(Set dst (CmpF3 src1 src2)); 12238 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12239 12240 expand %{ 12241 flagsReg tmp1; 12242 cmpFUnordered_reg_reg(tmp1, src1, src2); 12243 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12244 %} 12245 %} 12246 12247 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12248 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12249 // node right before the conditional move using it. 12250 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12251 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12252 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12253 // conditional move was supposed to be spilled. 12254 match(Set crx (CmpD src1 src2)); 12255 // False predicate, shall not be matched. 12256 predicate(false); 12257 12258 format %{ "cmpFUrd $crx, $src1, $src2" %} 12259 size(4); 12260 ins_encode %{ 12261 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12262 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12263 %} 12264 ins_pipe(pipe_class_default); 12265 %} 12266 12267 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12268 match(Set crx (CmpD src1 src2)); 12269 ins_cost(DEFAULT_COST+BRANCH_COST); 12270 12271 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12272 postalloc_expand %{ 12273 // 12274 // replaces 12275 // 12276 // region src1 src2 12277 // \ | | 12278 // crx=cmpD_reg_reg 12279 // 12280 // with 12281 // 12282 // region src1 src2 12283 // \ | | 12284 // crx=cmpDUnordered_reg_reg 12285 // | 12286 // ^ region 12287 // | \ 12288 // crx=cmov_bns_less 12289 // 12290 12291 // create new nodes 12292 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12293 MachNode *m2 = new cmov_bns_lessNode(); 12294 12295 // inputs for new nodes 12296 m1->add_req(n_region, n_src1, n_src2); 12297 m2->add_req(n_region); 12298 m2->add_prec(m1); 12299 12300 // operands for new nodes 12301 m1->_opnds[0] = op_crx; 12302 m1->_opnds[1] = op_src1; 12303 m1->_opnds[2] = op_src2; 12304 m2->_opnds[0] = op_crx; 12305 12306 // registers for new nodes 12307 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12308 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12309 12310 // Insert new nodes. 12311 nodes->push(m1); 12312 nodes->push(m2); 12313 %} 12314 %} 12315 12316 // Compare double, generate -1,0,1 12317 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12318 match(Set dst (CmpD3 src1 src2)); 12319 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12320 12321 expand %{ 12322 flagsReg tmp1; 12323 cmpDUnordered_reg_reg(tmp1, src1, src2); 12324 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12325 %} 12326 %} 12327 12328 //----------Branches--------------------------------------------------------- 12329 // Jump 12330 12331 // Direct Branch. 12332 instruct branch(label labl) %{ 12333 match(Goto); 12334 effect(USE labl); 12335 ins_cost(BRANCH_COST); 12336 12337 format %{ "B $labl" %} 12338 size(4); 12339 ins_encode %{ 12340 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12341 Label d; // dummy 12342 __ bind(d); 12343 Label* p = $labl$$label; 12344 // `p' is `NULL' when this encoding class is used only to 12345 // determine the size of the encoded instruction. 12346 Label& l = (NULL == p)? d : *(p); 12347 __ b(l); 12348 %} 12349 ins_pipe(pipe_class_default); 12350 %} 12351 12352 // Conditional Near Branch 12353 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12354 // Same match rule as `branchConFar'. 12355 match(If cmp crx); 12356 effect(USE lbl); 12357 ins_cost(BRANCH_COST); 12358 12359 // If set to 1 this indicates that the current instruction is a 12360 // short variant of a long branch. This avoids using this 12361 // instruction in first-pass matching. It will then only be used in 12362 // the `Shorten_branches' pass. 12363 ins_short_branch(1); 12364 12365 format %{ "B$cmp $crx, $lbl" %} 12366 size(4); 12367 ins_encode( enc_bc(crx, cmp, lbl) ); 12368 ins_pipe(pipe_class_default); 12369 %} 12370 12371 // This is for cases when the ppc64 `bc' instruction does not 12372 // reach far enough. So we emit a far branch here, which is more 12373 // expensive. 12374 // 12375 // Conditional Far Branch 12376 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12377 // Same match rule as `branchCon'. 12378 match(If cmp crx); 12379 effect(USE crx, USE lbl); 12380 predicate(!false /* TODO: PPC port HB_Schedule*/); 12381 // Higher cost than `branchCon'. 12382 ins_cost(5*BRANCH_COST); 12383 12384 // This is not a short variant of a branch, but the long variant. 12385 ins_short_branch(0); 12386 12387 format %{ "B_FAR$cmp $crx, $lbl" %} 12388 size(8); 12389 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12390 ins_pipe(pipe_class_default); 12391 %} 12392 12393 // Conditional Branch used with Power6 scheduler (can be far or short). 12394 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12395 // Same match rule as `branchCon'. 12396 match(If cmp crx); 12397 effect(USE crx, USE lbl); 12398 predicate(false /* TODO: PPC port HB_Schedule*/); 12399 // Higher cost than `branchCon'. 12400 ins_cost(5*BRANCH_COST); 12401 12402 // Actually size doesn't depend on alignment but on shortening. 12403 ins_variable_size_depending_on_alignment(true); 12404 // long variant. 12405 ins_short_branch(0); 12406 12407 format %{ "B_FAR$cmp $crx, $lbl" %} 12408 size(8); // worst case 12409 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12410 ins_pipe(pipe_class_default); 12411 %} 12412 12413 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12414 match(CountedLoopEnd cmp crx); 12415 effect(USE labl); 12416 ins_cost(BRANCH_COST); 12417 12418 // short variant. 12419 ins_short_branch(1); 12420 12421 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12422 size(4); 12423 ins_encode( enc_bc(crx, cmp, labl) ); 12424 ins_pipe(pipe_class_default); 12425 %} 12426 12427 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12428 match(CountedLoopEnd cmp crx); 12429 effect(USE labl); 12430 predicate(!false /* TODO: PPC port HB_Schedule */); 12431 ins_cost(BRANCH_COST); 12432 12433 // Long variant. 12434 ins_short_branch(0); 12435 12436 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12437 size(8); 12438 ins_encode( enc_bc_far(crx, cmp, labl) ); 12439 ins_pipe(pipe_class_default); 12440 %} 12441 12442 // Conditional Branch used with Power6 scheduler (can be far or short). 12443 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12444 match(CountedLoopEnd cmp crx); 12445 effect(USE labl); 12446 predicate(false /* TODO: PPC port HB_Schedule */); 12447 // Higher cost than `branchCon'. 12448 ins_cost(5*BRANCH_COST); 12449 12450 // Actually size doesn't depend on alignment but on shortening. 12451 ins_variable_size_depending_on_alignment(true); 12452 // Long variant. 12453 ins_short_branch(0); 12454 12455 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12456 size(8); // worst case 12457 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12458 ins_pipe(pipe_class_default); 12459 %} 12460 12461 // ============================================================================ 12462 // Java runtime operations, intrinsics and other complex operations. 12463 12464 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12465 // array for an instance of the superklass. Set a hidden internal cache on a 12466 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12467 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12468 // 12469 // GL TODO: Improve this. 12470 // - result should not be a TEMP 12471 // - Add match rule as on sparc avoiding additional Cmp. 12472 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12473 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12474 match(Set result (PartialSubtypeCheck subklass superklass)); 12475 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12476 ins_cost(DEFAULT_COST*10); 12477 12478 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12479 ins_encode %{ 12480 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12481 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12482 $tmp_klass$$Register, NULL, $result$$Register); 12483 %} 12484 ins_pipe(pipe_class_default); 12485 %} 12486 12487 // inlined locking and unlocking 12488 12489 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12490 match(Set crx (FastLock oop box)); 12491 effect(TEMP tmp1, TEMP tmp2); 12492 predicate(!Compile::current()->use_rtm()); 12493 12494 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12495 ins_encode %{ 12496 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12497 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12498 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12499 UseBiasedLocking && !UseOptoBiasInlining); 12500 // If locking was successfull, crx should indicate 'EQ'. 12501 // The compiler generates a branch to the runtime call to 12502 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12503 %} 12504 ins_pipe(pipe_class_compare); 12505 %} 12506 12507 // Separate version for TM. Use bound register for box to enable USE_KILL. 12508 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12509 match(Set crx (FastLock oop box)); 12510 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12511 predicate(Compile::current()->use_rtm()); 12512 12513 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12514 ins_encode %{ 12515 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12516 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12517 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12518 /*Biased Locking*/ false, 12519 _rtm_counters, _stack_rtm_counters, 12520 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12521 /*TM*/ true, ra_->C->profile_rtm()); 12522 // If locking was successfull, crx should indicate 'EQ'. 12523 // The compiler generates a branch to the runtime call to 12524 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12525 %} 12526 ins_pipe(pipe_class_compare); 12527 %} 12528 12529 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12530 match(Set crx (FastUnlock oop box)); 12531 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12532 predicate(!Compile::current()->use_rtm()); 12533 12534 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12535 ins_encode %{ 12536 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12537 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12538 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12539 UseBiasedLocking && !UseOptoBiasInlining, 12540 false); 12541 // If unlocking was successfull, crx should indicate 'EQ'. 12542 // The compiler generates a branch to the runtime call to 12543 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12544 %} 12545 ins_pipe(pipe_class_compare); 12546 %} 12547 12548 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12549 match(Set crx (FastUnlock oop box)); 12550 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12551 predicate(Compile::current()->use_rtm()); 12552 12553 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12554 ins_encode %{ 12555 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12556 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12557 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12558 /*Biased Locking*/ false, /*TM*/ true); 12559 // If unlocking was successfull, crx should indicate 'EQ'. 12560 // The compiler generates a branch to the runtime call to 12561 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12562 %} 12563 ins_pipe(pipe_class_compare); 12564 %} 12565 12566 // Align address. 12567 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12568 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12569 12570 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12571 size(4); 12572 ins_encode %{ 12573 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12574 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12575 %} 12576 ins_pipe(pipe_class_default); 12577 %} 12578 12579 // Array size computation. 12580 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12581 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12582 12583 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12584 size(4); 12585 ins_encode %{ 12586 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12587 __ subf($dst$$Register, $start$$Register, $end$$Register); 12588 %} 12589 ins_pipe(pipe_class_default); 12590 %} 12591 12592 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12593 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12594 match(Set dummy (ClearArray cnt base)); 12595 effect(USE_KILL base, KILL ctr); 12596 ins_cost(2 * MEMORY_REF_COST); 12597 12598 format %{ "ClearArray $cnt, $base" %} 12599 ins_encode %{ 12600 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12601 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12602 %} 12603 ins_pipe(pipe_class_default); 12604 %} 12605 12606 // Clear-array with constant large array length. 12607 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12608 match(Set dummy (ClearArray cnt base)); 12609 effect(USE_KILL base, TEMP tmp, KILL ctr); 12610 ins_cost(3 * MEMORY_REF_COST); 12611 12612 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12613 ins_encode %{ 12614 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12615 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12616 %} 12617 ins_pipe(pipe_class_default); 12618 %} 12619 12620 // Clear-array with dynamic array length. 12621 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12622 match(Set dummy (ClearArray cnt base)); 12623 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12624 ins_cost(4 * MEMORY_REF_COST); 12625 12626 format %{ "ClearArray $cnt, $base" %} 12627 ins_encode %{ 12628 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12629 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12630 %} 12631 ins_pipe(pipe_class_default); 12632 %} 12633 12634 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12635 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12636 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12637 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12638 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12639 ins_cost(300); 12640 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12641 ins_encode %{ 12642 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12643 __ string_compare($str1$$Register, $str2$$Register, 12644 $cnt1$$Register, $cnt2$$Register, 12645 $tmp$$Register, 12646 $result$$Register, StrIntrinsicNode::LL); 12647 %} 12648 ins_pipe(pipe_class_default); 12649 %} 12650 12651 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12652 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12653 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12654 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12655 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12656 ins_cost(300); 12657 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12658 ins_encode %{ 12659 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12660 __ string_compare($str1$$Register, $str2$$Register, 12661 $cnt1$$Register, $cnt2$$Register, 12662 $tmp$$Register, 12663 $result$$Register, StrIntrinsicNode::UU); 12664 %} 12665 ins_pipe(pipe_class_default); 12666 %} 12667 12668 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12669 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12670 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12671 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12672 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12673 ins_cost(300); 12674 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12675 ins_encode %{ 12676 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12677 __ string_compare($str1$$Register, $str2$$Register, 12678 $cnt1$$Register, $cnt2$$Register, 12679 $tmp$$Register, 12680 $result$$Register, StrIntrinsicNode::LU); 12681 %} 12682 ins_pipe(pipe_class_default); 12683 %} 12684 12685 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12686 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12687 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12688 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12689 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12690 ins_cost(300); 12691 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12692 ins_encode %{ 12693 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12694 __ string_compare($str2$$Register, $str1$$Register, 12695 $cnt2$$Register, $cnt1$$Register, 12696 $tmp$$Register, 12697 $result$$Register, StrIntrinsicNode::UL); 12698 %} 12699 ins_pipe(pipe_class_default); 12700 %} 12701 12702 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12703 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12704 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12705 match(Set result (StrEquals (Binary str1 str2) cnt)); 12706 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12707 ins_cost(300); 12708 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12709 ins_encode %{ 12710 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12711 __ array_equals(false, $str1$$Register, $str2$$Register, 12712 $cnt$$Register, $tmp$$Register, 12713 $result$$Register, true /* byte */); 12714 %} 12715 ins_pipe(pipe_class_default); 12716 %} 12717 12718 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12719 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12720 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12721 match(Set result (StrEquals (Binary str1 str2) cnt)); 12722 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12723 ins_cost(300); 12724 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12725 ins_encode %{ 12726 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12727 __ array_equals(false, $str1$$Register, $str2$$Register, 12728 $cnt$$Register, $tmp$$Register, 12729 $result$$Register, false /* byte */); 12730 %} 12731 ins_pipe(pipe_class_default); 12732 %} 12733 12734 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12735 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12736 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12737 match(Set result (AryEq ary1 ary2)); 12738 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12739 ins_cost(300); 12740 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12741 ins_encode %{ 12742 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12743 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12744 $tmp1$$Register, $tmp2$$Register, 12745 $result$$Register, true /* byte */); 12746 %} 12747 ins_pipe(pipe_class_default); 12748 %} 12749 12750 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12751 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12752 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12753 match(Set result (AryEq ary1 ary2)); 12754 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12755 ins_cost(300); 12756 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12757 ins_encode %{ 12758 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12759 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12760 $tmp1$$Register, $tmp2$$Register, 12761 $result$$Register, false /* byte */); 12762 %} 12763 ins_pipe(pipe_class_default); 12764 %} 12765 12766 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12767 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12768 iRegIdst tmp1, iRegIdst tmp2, 12769 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12770 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12771 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12772 // Required for EA: check if it is still a type_array. 12773 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12774 ins_cost(150); 12775 12776 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12777 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12778 12779 ins_encode %{ 12780 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12781 immPOper *needleOper = (immPOper *)$needleImm; 12782 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12783 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12784 jchar chr; 12785 #ifdef VM_LITTLE_ENDIAN 12786 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12787 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12788 #else 12789 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12790 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12791 #endif 12792 __ string_indexof_char($result$$Register, 12793 $haystack$$Register, $haycnt$$Register, 12794 R0, chr, 12795 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12796 %} 12797 ins_pipe(pipe_class_compare); 12798 %} 12799 12800 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12801 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12802 iRegIdst tmp1, iRegIdst tmp2, 12803 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12804 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12805 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12806 // Required for EA: check if it is still a type_array. 12807 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12808 ins_cost(150); 12809 12810 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12811 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12812 12813 ins_encode %{ 12814 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12815 immPOper *needleOper = (immPOper *)$needleImm; 12816 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12817 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12818 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12819 __ string_indexof_char($result$$Register, 12820 $haystack$$Register, $haycnt$$Register, 12821 R0, chr, 12822 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12823 %} 12824 ins_pipe(pipe_class_compare); 12825 %} 12826 12827 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12828 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12829 iRegIdst tmp1, iRegIdst tmp2, 12830 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12831 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12832 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12833 // Required for EA: check if it is still a type_array. 12834 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12835 ins_cost(150); 12836 12837 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12838 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12839 12840 ins_encode %{ 12841 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12842 immPOper *needleOper = (immPOper *)$needleImm; 12843 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12844 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12845 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12846 __ string_indexof_char($result$$Register, 12847 $haystack$$Register, $haycnt$$Register, 12848 R0, chr, 12849 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12850 %} 12851 ins_pipe(pipe_class_compare); 12852 %} 12853 12854 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12855 rscratch2RegP needle, immI_1 needlecntImm, 12856 iRegIdst tmp1, iRegIdst tmp2, 12857 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12858 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12859 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12860 // Required for EA: check if it is still a type_array. 12861 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12862 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12863 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12864 ins_cost(180); 12865 12866 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12867 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12868 ins_encode %{ 12869 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12870 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12871 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12872 guarantee(needle_values, "sanity"); 12873 jchar chr; 12874 #ifdef VM_LITTLE_ENDIAN 12875 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12876 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12877 #else 12878 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12879 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12880 #endif 12881 __ string_indexof_char($result$$Register, 12882 $haystack$$Register, $haycnt$$Register, 12883 R0, chr, 12884 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12885 %} 12886 ins_pipe(pipe_class_compare); 12887 %} 12888 12889 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12890 rscratch2RegP needle, immI_1 needlecntImm, 12891 iRegIdst tmp1, iRegIdst tmp2, 12892 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12893 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12894 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12895 // Required for EA: check if it is still a type_array. 12896 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12897 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12898 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12899 ins_cost(180); 12900 12901 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12902 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12903 ins_encode %{ 12904 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12905 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12906 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12907 guarantee(needle_values, "sanity"); 12908 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12909 __ string_indexof_char($result$$Register, 12910 $haystack$$Register, $haycnt$$Register, 12911 R0, chr, 12912 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12913 %} 12914 ins_pipe(pipe_class_compare); 12915 %} 12916 12917 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12918 rscratch2RegP needle, immI_1 needlecntImm, 12919 iRegIdst tmp1, iRegIdst tmp2, 12920 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12921 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12922 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12923 // Required for EA: check if it is still a type_array. 12924 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12925 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12926 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12927 ins_cost(180); 12928 12929 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12930 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12931 ins_encode %{ 12932 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12933 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12934 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12935 guarantee(needle_values, "sanity"); 12936 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12937 __ string_indexof_char($result$$Register, 12938 $haystack$$Register, $haycnt$$Register, 12939 R0, chr, 12940 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12941 %} 12942 ins_pipe(pipe_class_compare); 12943 %} 12944 12945 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12946 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12947 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12948 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12949 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12950 ins_cost(180); 12951 12952 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 12953 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12954 ins_encode %{ 12955 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12956 __ string_indexof_char($result$$Register, 12957 $haystack$$Register, $haycnt$$Register, 12958 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12959 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12960 %} 12961 ins_pipe(pipe_class_compare); 12962 %} 12963 12964 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12965 iRegPsrc needle, uimmI15 needlecntImm, 12966 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12967 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12968 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12969 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12970 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12971 // Required for EA: check if it is still a type_array. 12972 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12973 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12974 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12975 ins_cost(250); 12976 12977 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12978 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12979 ins_encode %{ 12980 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12981 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12982 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12983 12984 __ string_indexof($result$$Register, 12985 $haystack$$Register, $haycnt$$Register, 12986 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12987 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12988 %} 12989 ins_pipe(pipe_class_compare); 12990 %} 12991 12992 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12993 iRegPsrc needle, uimmI15 needlecntImm, 12994 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12995 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12996 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12997 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12998 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12999 // Required for EA: check if it is still a type_array. 13000 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13001 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13002 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13003 ins_cost(250); 13004 13005 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13006 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13007 ins_encode %{ 13008 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13009 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13010 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13011 13012 __ string_indexof($result$$Register, 13013 $haystack$$Register, $haycnt$$Register, 13014 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13015 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13016 %} 13017 ins_pipe(pipe_class_compare); 13018 %} 13019 13020 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13021 iRegPsrc needle, uimmI15 needlecntImm, 13022 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13023 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13024 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13025 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13026 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13027 // Required for EA: check if it is still a type_array. 13028 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13029 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13030 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13031 ins_cost(250); 13032 13033 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13034 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13035 ins_encode %{ 13036 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13037 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13038 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13039 13040 __ string_indexof($result$$Register, 13041 $haystack$$Register, $haycnt$$Register, 13042 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13043 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13044 %} 13045 ins_pipe(pipe_class_compare); 13046 %} 13047 13048 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13049 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13050 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13051 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13052 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13053 TEMP_DEF result, 13054 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13055 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13056 ins_cost(300); 13057 13058 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13059 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13060 ins_encode %{ 13061 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13062 __ string_indexof($result$$Register, 13063 $haystack$$Register, $haycnt$$Register, 13064 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13065 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13066 %} 13067 ins_pipe(pipe_class_compare); 13068 %} 13069 13070 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13071 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13072 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13073 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13074 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13075 TEMP_DEF result, 13076 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13077 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13078 ins_cost(300); 13079 13080 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13081 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13082 ins_encode %{ 13083 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13084 __ string_indexof($result$$Register, 13085 $haystack$$Register, $haycnt$$Register, 13086 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13087 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13088 %} 13089 ins_pipe(pipe_class_compare); 13090 %} 13091 13092 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13093 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13094 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13095 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13096 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13097 TEMP_DEF result, 13098 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13099 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13100 ins_cost(300); 13101 13102 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13103 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13104 ins_encode %{ 13105 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13106 __ string_indexof($result$$Register, 13107 $haystack$$Register, $haycnt$$Register, 13108 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13109 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13110 %} 13111 ins_pipe(pipe_class_compare); 13112 %} 13113 13114 // char[] to byte[] compression 13115 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13116 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13117 match(Set result (StrCompressedCopy src (Binary dst len))); 13118 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13119 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13120 ins_cost(300); 13121 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13122 ins_encode %{ 13123 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13124 Label Lskip, Ldone; 13125 __ li($result$$Register, 0); 13126 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13127 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13128 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13129 __ beq(CCR0, Lskip); 13130 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13131 __ bind(Lskip); 13132 __ mr($result$$Register, $len$$Register); 13133 __ bind(Ldone); 13134 %} 13135 ins_pipe(pipe_class_default); 13136 %} 13137 13138 // byte[] to char[] inflation 13139 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13140 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13141 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13142 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13143 ins_cost(300); 13144 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13145 ins_encode %{ 13146 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13147 Label Ldone; 13148 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13149 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13150 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13151 __ beq(CCR0, Ldone); 13152 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13153 __ bind(Ldone); 13154 %} 13155 ins_pipe(pipe_class_default); 13156 %} 13157 13158 // StringCoding.java intrinsics 13159 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13160 regCTR ctr, flagsRegCR0 cr0) 13161 %{ 13162 match(Set result (HasNegatives ary1 len)); 13163 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13164 ins_cost(300); 13165 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13166 ins_encode %{ 13167 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13168 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13169 $tmp1$$Register, $tmp2$$Register); 13170 %} 13171 ins_pipe(pipe_class_default); 13172 %} 13173 13174 // encode char[] to byte[] in ISO_8859_1 13175 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13176 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13177 match(Set result (EncodeISOArray src (Binary dst len))); 13178 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13179 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13180 ins_cost(300); 13181 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13182 ins_encode %{ 13183 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13184 Label Lslow, Lfailure1, Lfailure2, Ldone; 13185 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13186 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13187 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13188 __ beq(CCR0, Ldone); 13189 __ bind(Lslow); 13190 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13191 __ li($result$$Register, 0); 13192 __ b(Ldone); 13193 13194 __ bind(Lfailure1); 13195 __ mr($result$$Register, $len$$Register); 13196 __ mfctr($tmp1$$Register); 13197 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13198 __ beq(CCR0, Ldone); 13199 __ b(Lslow); 13200 13201 __ bind(Lfailure2); 13202 __ mfctr($result$$Register); // Remaining characters. 13203 13204 __ bind(Ldone); 13205 __ subf($result$$Register, $result$$Register, $len$$Register); 13206 %} 13207 ins_pipe(pipe_class_default); 13208 %} 13209 13210 13211 //---------- Min/Max Instructions --------------------------------------------- 13212 13213 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13214 match(Set dst (MinI src1 src2)); 13215 ins_cost(DEFAULT_COST*6); 13216 13217 expand %{ 13218 iRegLdst src1s; 13219 iRegLdst src2s; 13220 iRegLdst diff; 13221 iRegLdst sm; 13222 iRegLdst doz; // difference or zero 13223 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13224 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13225 subL_reg_reg(diff, src2s, src1s); 13226 // Need to consider >=33 bit result, therefore we need signmaskL. 13227 signmask64L_regL(sm, diff); 13228 andL_reg_reg(doz, diff, sm); // <=0 13229 addI_regL_regL(dst, doz, src1s); 13230 %} 13231 %} 13232 13233 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13234 match(Set dst (MinI src1 src2)); 13235 effect(KILL cr0); 13236 predicate(VM_Version::has_isel()); 13237 ins_cost(DEFAULT_COST*2); 13238 13239 ins_encode %{ 13240 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13241 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13242 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13243 %} 13244 ins_pipe(pipe_class_default); 13245 %} 13246 13247 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13248 match(Set dst (MaxI src1 src2)); 13249 ins_cost(DEFAULT_COST*6); 13250 13251 expand %{ 13252 iRegLdst src1s; 13253 iRegLdst src2s; 13254 iRegLdst diff; 13255 iRegLdst sm; 13256 iRegLdst doz; // difference or zero 13257 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13258 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13259 subL_reg_reg(diff, src2s, src1s); 13260 // Need to consider >=33 bit result, therefore we need signmaskL. 13261 signmask64L_regL(sm, diff); 13262 andcL_reg_reg(doz, diff, sm); // >=0 13263 addI_regL_regL(dst, doz, src1s); 13264 %} 13265 %} 13266 13267 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13268 match(Set dst (MaxI src1 src2)); 13269 effect(KILL cr0); 13270 predicate(VM_Version::has_isel()); 13271 ins_cost(DEFAULT_COST*2); 13272 13273 ins_encode %{ 13274 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13275 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13276 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13277 %} 13278 ins_pipe(pipe_class_default); 13279 %} 13280 13281 //---------- Population Count Instructions ------------------------------------ 13282 13283 // Popcnt for Power7. 13284 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13285 match(Set dst (PopCountI src)); 13286 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13287 ins_cost(DEFAULT_COST); 13288 13289 format %{ "POPCNTW $dst, $src" %} 13290 size(4); 13291 ins_encode %{ 13292 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13293 __ popcntw($dst$$Register, $src$$Register); 13294 %} 13295 ins_pipe(pipe_class_default); 13296 %} 13297 13298 // Popcnt for Power7. 13299 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13300 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13301 match(Set dst (PopCountL src)); 13302 ins_cost(DEFAULT_COST); 13303 13304 format %{ "POPCNTD $dst, $src" %} 13305 size(4); 13306 ins_encode %{ 13307 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13308 __ popcntd($dst$$Register, $src$$Register); 13309 %} 13310 ins_pipe(pipe_class_default); 13311 %} 13312 13313 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13314 match(Set dst (CountLeadingZerosI src)); 13315 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13316 ins_cost(DEFAULT_COST); 13317 13318 format %{ "CNTLZW $dst, $src" %} 13319 size(4); 13320 ins_encode %{ 13321 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13322 __ cntlzw($dst$$Register, $src$$Register); 13323 %} 13324 ins_pipe(pipe_class_default); 13325 %} 13326 13327 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13328 match(Set dst (CountLeadingZerosL src)); 13329 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13330 ins_cost(DEFAULT_COST); 13331 13332 format %{ "CNTLZD $dst, $src" %} 13333 size(4); 13334 ins_encode %{ 13335 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13336 __ cntlzd($dst$$Register, $src$$Register); 13337 %} 13338 ins_pipe(pipe_class_default); 13339 %} 13340 13341 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13342 // no match-rule, false predicate 13343 effect(DEF dst, USE src); 13344 predicate(false); 13345 13346 format %{ "CNTLZD $dst, $src" %} 13347 size(4); 13348 ins_encode %{ 13349 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13350 __ cntlzd($dst$$Register, $src$$Register); 13351 %} 13352 ins_pipe(pipe_class_default); 13353 %} 13354 13355 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13356 match(Set dst (CountTrailingZerosI src)); 13357 predicate(UseCountLeadingZerosInstructionsPPC64); 13358 ins_cost(DEFAULT_COST); 13359 13360 expand %{ 13361 immI16 imm1 %{ (int)-1 %} 13362 immI16 imm2 %{ (int)32 %} 13363 immI_minus1 m1 %{ -1 %} 13364 iRegIdst tmpI1; 13365 iRegIdst tmpI2; 13366 iRegIdst tmpI3; 13367 addI_reg_imm16(tmpI1, src, imm1); 13368 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13369 countLeadingZerosI(tmpI3, tmpI2); 13370 subI_imm16_reg(dst, imm2, tmpI3); 13371 %} 13372 %} 13373 13374 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13375 match(Set dst (CountTrailingZerosL src)); 13376 predicate(UseCountLeadingZerosInstructionsPPC64); 13377 ins_cost(DEFAULT_COST); 13378 13379 expand %{ 13380 immL16 imm1 %{ (long)-1 %} 13381 immI16 imm2 %{ (int)64 %} 13382 iRegLdst tmpL1; 13383 iRegLdst tmpL2; 13384 iRegIdst tmpL3; 13385 addL_reg_imm16(tmpL1, src, imm1); 13386 andcL_reg_reg(tmpL2, tmpL1, src); 13387 countLeadingZerosL(tmpL3, tmpL2); 13388 subI_imm16_reg(dst, imm2, tmpL3); 13389 %} 13390 %} 13391 13392 // Expand nodes for byte_reverse_int. 13393 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13394 effect(DEF dst, USE src, USE pos, USE shift); 13395 predicate(false); 13396 13397 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13398 size(4); 13399 ins_encode %{ 13400 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13401 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13402 %} 13403 ins_pipe(pipe_class_default); 13404 %} 13405 13406 // As insrwi_a, but with USE_DEF. 13407 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13408 effect(USE_DEF dst, USE src, USE pos, USE shift); 13409 predicate(false); 13410 13411 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13412 size(4); 13413 ins_encode %{ 13414 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13415 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13416 %} 13417 ins_pipe(pipe_class_default); 13418 %} 13419 13420 // Just slightly faster than java implementation. 13421 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13422 match(Set dst (ReverseBytesI src)); 13423 ins_cost(7*DEFAULT_COST); 13424 13425 expand %{ 13426 immI16 imm24 %{ (int) 24 %} 13427 immI16 imm16 %{ (int) 16 %} 13428 immI16 imm8 %{ (int) 8 %} 13429 immI16 imm4 %{ (int) 4 %} 13430 immI16 imm0 %{ (int) 0 %} 13431 iRegLdst tmpI1; 13432 iRegLdst tmpI2; 13433 iRegLdst tmpI3; 13434 13435 urShiftI_reg_imm(tmpI1, src, imm24); 13436 insrwi_a(dst, tmpI1, imm24, imm8); 13437 urShiftI_reg_imm(tmpI2, src, imm16); 13438 insrwi(dst, tmpI2, imm8, imm16); 13439 urShiftI_reg_imm(tmpI3, src, imm8); 13440 insrwi(dst, tmpI3, imm8, imm8); 13441 insrwi(dst, src, imm0, imm8); 13442 %} 13443 %} 13444 13445 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13446 match(Set dst (ReverseBytesL src)); 13447 ins_cost(15*DEFAULT_COST); 13448 13449 expand %{ 13450 immI16 imm56 %{ (int) 56 %} 13451 immI16 imm48 %{ (int) 48 %} 13452 immI16 imm40 %{ (int) 40 %} 13453 immI16 imm32 %{ (int) 32 %} 13454 immI16 imm24 %{ (int) 24 %} 13455 immI16 imm16 %{ (int) 16 %} 13456 immI16 imm8 %{ (int) 8 %} 13457 immI16 imm0 %{ (int) 0 %} 13458 iRegLdst tmpL1; 13459 iRegLdst tmpL2; 13460 iRegLdst tmpL3; 13461 iRegLdst tmpL4; 13462 iRegLdst tmpL5; 13463 iRegLdst tmpL6; 13464 13465 // src : |a|b|c|d|e|f|g|h| 13466 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13467 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13468 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13469 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13470 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13471 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13472 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13473 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13474 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13475 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13476 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13477 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13478 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13479 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13480 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13481 %} 13482 %} 13483 13484 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13485 match(Set dst (ReverseBytesUS src)); 13486 ins_cost(2*DEFAULT_COST); 13487 13488 expand %{ 13489 immI16 imm16 %{ (int) 16 %} 13490 immI16 imm8 %{ (int) 8 %} 13491 13492 urShiftI_reg_imm(dst, src, imm8); 13493 insrwi(dst, src, imm16, imm8); 13494 %} 13495 %} 13496 13497 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13498 match(Set dst (ReverseBytesS src)); 13499 ins_cost(3*DEFAULT_COST); 13500 13501 expand %{ 13502 immI16 imm16 %{ (int) 16 %} 13503 immI16 imm8 %{ (int) 8 %} 13504 iRegLdst tmpI1; 13505 13506 urShiftI_reg_imm(tmpI1, src, imm8); 13507 insrwi(tmpI1, src, imm16, imm8); 13508 extsh(dst, tmpI1); 13509 %} 13510 %} 13511 13512 // Load Integer reversed byte order 13513 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13514 match(Set dst (ReverseBytesI (LoadI mem))); 13515 ins_cost(MEMORY_REF_COST); 13516 13517 size(4); 13518 ins_encode %{ 13519 __ lwbrx($dst$$Register, $mem$$Register); 13520 %} 13521 ins_pipe(pipe_class_default); 13522 %} 13523 13524 // Load Long - aligned and reversed 13525 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13526 match(Set dst (ReverseBytesL (LoadL mem))); 13527 predicate(VM_Version::has_ldbrx()); 13528 ins_cost(MEMORY_REF_COST); 13529 13530 size(4); 13531 ins_encode %{ 13532 __ ldbrx($dst$$Register, $mem$$Register); 13533 %} 13534 ins_pipe(pipe_class_default); 13535 %} 13536 13537 // Load unsigned short / char reversed byte order 13538 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13539 match(Set dst (ReverseBytesUS (LoadUS mem))); 13540 ins_cost(MEMORY_REF_COST); 13541 13542 size(4); 13543 ins_encode %{ 13544 __ lhbrx($dst$$Register, $mem$$Register); 13545 %} 13546 ins_pipe(pipe_class_default); 13547 %} 13548 13549 // Load short reversed byte order 13550 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13551 match(Set dst (ReverseBytesS (LoadS mem))); 13552 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13553 13554 size(8); 13555 ins_encode %{ 13556 __ lhbrx($dst$$Register, $mem$$Register); 13557 __ extsh($dst$$Register, $dst$$Register); 13558 %} 13559 ins_pipe(pipe_class_default); 13560 %} 13561 13562 // Store Integer reversed byte order 13563 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13564 match(Set mem (StoreI mem (ReverseBytesI src))); 13565 ins_cost(MEMORY_REF_COST); 13566 13567 size(4); 13568 ins_encode %{ 13569 __ stwbrx($src$$Register, $mem$$Register); 13570 %} 13571 ins_pipe(pipe_class_default); 13572 %} 13573 13574 // Store Long reversed byte order 13575 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13576 match(Set mem (StoreL mem (ReverseBytesL src))); 13577 predicate(VM_Version::has_stdbrx()); 13578 ins_cost(MEMORY_REF_COST); 13579 13580 size(4); 13581 ins_encode %{ 13582 __ stdbrx($src$$Register, $mem$$Register); 13583 %} 13584 ins_pipe(pipe_class_default); 13585 %} 13586 13587 // Store unsigned short / char reversed byte order 13588 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13589 match(Set mem (StoreC mem (ReverseBytesUS src))); 13590 ins_cost(MEMORY_REF_COST); 13591 13592 size(4); 13593 ins_encode %{ 13594 __ sthbrx($src$$Register, $mem$$Register); 13595 %} 13596 ins_pipe(pipe_class_default); 13597 %} 13598 13599 // Store short reversed byte order 13600 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13601 match(Set mem (StoreC mem (ReverseBytesS src))); 13602 ins_cost(MEMORY_REF_COST); 13603 13604 size(4); 13605 ins_encode %{ 13606 __ sthbrx($src$$Register, $mem$$Register); 13607 %} 13608 ins_pipe(pipe_class_default); 13609 %} 13610 13611 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13612 effect(DEF temp1, USE src); 13613 13614 size(4); 13615 ins_encode %{ 13616 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13617 %} 13618 ins_pipe(pipe_class_default); 13619 %} 13620 13621 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13622 effect(DEF dst, USE src, USE imm1); 13623 13624 size(4); 13625 ins_encode %{ 13626 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13627 %} 13628 ins_pipe(pipe_class_default); 13629 %} 13630 13631 //---------- Replicate Vector Instructions ------------------------------------ 13632 13633 // Insrdi does replicate if src == dst. 13634 instruct repl32(iRegLdst dst) %{ 13635 predicate(false); 13636 effect(USE_DEF dst); 13637 13638 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13639 size(4); 13640 ins_encode %{ 13641 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13642 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13643 %} 13644 ins_pipe(pipe_class_default); 13645 %} 13646 13647 // Insrdi does replicate if src == dst. 13648 instruct repl48(iRegLdst dst) %{ 13649 predicate(false); 13650 effect(USE_DEF dst); 13651 13652 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13653 size(4); 13654 ins_encode %{ 13655 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13656 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13657 %} 13658 ins_pipe(pipe_class_default); 13659 %} 13660 13661 // Insrdi does replicate if src == dst. 13662 instruct repl56(iRegLdst dst) %{ 13663 predicate(false); 13664 effect(USE_DEF dst); 13665 13666 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13667 size(4); 13668 ins_encode %{ 13669 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13670 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 13671 %} 13672 ins_pipe(pipe_class_default); 13673 %} 13674 13675 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13676 match(Set dst (ReplicateB src)); 13677 predicate(n->as_Vector()->length() == 8); 13678 expand %{ 13679 moveReg(dst, src); 13680 repl56(dst); 13681 repl48(dst); 13682 repl32(dst); 13683 %} 13684 %} 13685 13686 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 13687 match(Set dst (ReplicateB zero)); 13688 predicate(n->as_Vector()->length() == 8); 13689 format %{ "LI $dst, #0 \t// replicate8B" %} 13690 size(4); 13691 ins_encode %{ 13692 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13693 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13694 %} 13695 ins_pipe(pipe_class_default); 13696 %} 13697 13698 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13699 match(Set dst (ReplicateB src)); 13700 predicate(n->as_Vector()->length() == 8); 13701 format %{ "LI $dst, #-1 \t// replicate8B" %} 13702 size(4); 13703 ins_encode %{ 13704 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13705 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13706 %} 13707 ins_pipe(pipe_class_default); 13708 %} 13709 13710 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 13711 match(Set dst (ReplicateB src)); 13712 predicate(n->as_Vector()->length() == 16); 13713 13714 expand %{ 13715 iRegLdst tmpL; 13716 vecX tmpV; 13717 immI8 imm1 %{ (int) 1 %} 13718 moveReg(tmpL, src); 13719 repl56(tmpL); 13720 repl48(tmpL); 13721 mtvsrwz(tmpV, tmpL); 13722 xxspltw(dst, tmpV, imm1); 13723 %} 13724 %} 13725 13726 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 13727 match(Set dst (ReplicateB zero)); 13728 predicate(n->as_Vector()->length() == 16); 13729 13730 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 13731 size(4); 13732 ins_encode %{ 13733 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13734 %} 13735 ins_pipe(pipe_class_default); 13736 %} 13737 13738 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 13739 match(Set dst (ReplicateB src)); 13740 predicate(n->as_Vector()->length() == 16); 13741 13742 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13743 size(4); 13744 ins_encode %{ 13745 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13746 %} 13747 ins_pipe(pipe_class_default); 13748 %} 13749 13750 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13751 match(Set dst (ReplicateS src)); 13752 predicate(n->as_Vector()->length() == 4); 13753 expand %{ 13754 moveReg(dst, src); 13755 repl48(dst); 13756 repl32(dst); 13757 %} 13758 %} 13759 13760 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 13761 match(Set dst (ReplicateS zero)); 13762 predicate(n->as_Vector()->length() == 4); 13763 format %{ "LI $dst, #0 \t// replicate4C" %} 13764 size(4); 13765 ins_encode %{ 13766 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13767 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13768 %} 13769 ins_pipe(pipe_class_default); 13770 %} 13771 13772 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13773 match(Set dst (ReplicateS src)); 13774 predicate(n->as_Vector()->length() == 4); 13775 format %{ "LI $dst, -1 \t// replicate4C" %} 13776 size(4); 13777 ins_encode %{ 13778 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13779 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13780 %} 13781 ins_pipe(pipe_class_default); 13782 %} 13783 13784 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 13785 match(Set dst (ReplicateS src)); 13786 predicate(n->as_Vector()->length() == 8); 13787 13788 expand %{ 13789 iRegLdst tmpL; 13790 vecX tmpV; 13791 immI8 zero %{ (int) 0 %} 13792 moveReg(tmpL, src); 13793 repl48(tmpL); 13794 repl32(tmpL); 13795 mtvsrd(tmpV, tmpL); 13796 xxpermdi(dst, tmpV, tmpV, zero); 13797 %} 13798 %} 13799 13800 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 13801 match(Set dst (ReplicateS zero)); 13802 predicate(n->as_Vector()->length() == 8); 13803 13804 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 13805 size(4); 13806 ins_encode %{ 13807 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13808 %} 13809 ins_pipe(pipe_class_default); 13810 %} 13811 13812 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 13813 match(Set dst (ReplicateS src)); 13814 predicate(n->as_Vector()->length() == 8); 13815 13816 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13817 size(4); 13818 ins_encode %{ 13819 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13820 %} 13821 ins_pipe(pipe_class_default); 13822 %} 13823 13824 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13825 match(Set dst (ReplicateI src)); 13826 predicate(n->as_Vector()->length() == 2); 13827 ins_cost(2 * DEFAULT_COST); 13828 expand %{ 13829 moveReg(dst, src); 13830 repl32(dst); 13831 %} 13832 %} 13833 13834 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 13835 match(Set dst (ReplicateI zero)); 13836 predicate(n->as_Vector()->length() == 2); 13837 format %{ "LI $dst, #0 \t// replicate4C" %} 13838 size(4); 13839 ins_encode %{ 13840 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13841 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13842 %} 13843 ins_pipe(pipe_class_default); 13844 %} 13845 13846 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13847 match(Set dst (ReplicateI src)); 13848 predicate(n->as_Vector()->length() == 2); 13849 format %{ "LI $dst, -1 \t// replicate4C" %} 13850 size(4); 13851 ins_encode %{ 13852 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13853 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13854 %} 13855 ins_pipe(pipe_class_default); 13856 %} 13857 13858 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 13859 match(Set dst (ReplicateI src)); 13860 predicate(n->as_Vector()->length() == 4); 13861 ins_cost(2 * DEFAULT_COST); 13862 13863 expand %{ 13864 iRegLdst tmpL; 13865 vecX tmpV; 13866 immI8 zero %{ (int) 0 %} 13867 moveReg(tmpL, src); 13868 repl32(tmpL); 13869 mtvsrd(tmpV, tmpL); 13870 xxpermdi(dst, tmpV, tmpV, zero); 13871 %} 13872 %} 13873 13874 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 13875 match(Set dst (ReplicateI zero)); 13876 predicate(n->as_Vector()->length() == 4); 13877 13878 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 13879 size(4); 13880 ins_encode %{ 13881 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13882 %} 13883 ins_pipe(pipe_class_default); 13884 %} 13885 13886 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 13887 match(Set dst (ReplicateI src)); 13888 predicate(n->as_Vector()->length() == 4); 13889 13890 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 13891 size(4); 13892 ins_encode %{ 13893 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13894 %} 13895 ins_pipe(pipe_class_default); 13896 %} 13897 13898 // Move float to int register via stack, replicate. 13899 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 13900 match(Set dst (ReplicateF src)); 13901 predicate(n->as_Vector()->length() == 2); 13902 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13903 expand %{ 13904 stackSlotL tmpS; 13905 iRegIdst tmpI; 13906 moveF2I_reg_stack(tmpS, src); // Move float to stack. 13907 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 13908 moveReg(dst, tmpI); // Move int to long reg. 13909 repl32(dst); // Replicate bitpattern. 13910 %} 13911 %} 13912 13913 // Replicate scalar constant to packed float values in Double register 13914 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 13915 match(Set dst (ReplicateF src)); 13916 predicate(n->as_Vector()->length() == 2); 13917 ins_cost(5 * DEFAULT_COST); 13918 13919 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 13920 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 13921 %} 13922 13923 // Replicate scalar zero constant to packed float values in Double register 13924 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 13925 match(Set dst (ReplicateF zero)); 13926 predicate(n->as_Vector()->length() == 2); 13927 13928 format %{ "LI $dst, #0 \t// replicate2F" %} 13929 ins_encode %{ 13930 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13931 __ li($dst$$Register, 0x0); 13932 %} 13933 ins_pipe(pipe_class_default); 13934 %} 13935 13936 13937 //----------Overflow Math Instructions----------------------------------------- 13938 13939 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 13940 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 13941 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 13942 13943 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 13944 match(Set cr0 (OverflowAddL op1 op2)); 13945 13946 format %{ "add_ $op1, $op2\t# overflow check long" %} 13947 ins_encode %{ 13948 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13949 __ li(R0, 0); 13950 __ mtxer(R0); // clear XER.SO 13951 __ addo_(R0, $op1$$Register, $op2$$Register); 13952 %} 13953 ins_pipe(pipe_class_default); 13954 %} 13955 13956 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 13957 match(Set cr0 (OverflowSubL op1 op2)); 13958 13959 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 13960 ins_encode %{ 13961 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13962 __ li(R0, 0); 13963 __ mtxer(R0); // clear XER.SO 13964 __ subfo_(R0, $op2$$Register, $op1$$Register); 13965 %} 13966 ins_pipe(pipe_class_default); 13967 %} 13968 13969 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 13970 match(Set cr0 (OverflowSubL zero op2)); 13971 13972 format %{ "nego_ R0, $op2\t# overflow check long" %} 13973 ins_encode %{ 13974 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13975 __ li(R0, 0); 13976 __ mtxer(R0); // clear XER.SO 13977 __ nego_(R0, $op2$$Register); 13978 %} 13979 ins_pipe(pipe_class_default); 13980 %} 13981 13982 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 13983 match(Set cr0 (OverflowMulL op1 op2)); 13984 13985 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 13986 ins_encode %{ 13987 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13988 __ li(R0, 0); 13989 __ mtxer(R0); // clear XER.SO 13990 __ mulldo_(R0, $op1$$Register, $op2$$Register); 13991 %} 13992 ins_pipe(pipe_class_default); 13993 %} 13994 13995 13996 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 13997 match(Set dst (ReplicateF src)); 13998 predicate(n->as_Vector()->length() == 4); 13999 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14000 expand %{ 14001 stackSlotL tmpS; 14002 iRegIdst tmpI; 14003 iRegLdst tmpL; 14004 vecX tmpV; 14005 immI8 zero %{ (int) 0 %} 14006 14007 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14008 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14009 moveReg(tmpL, tmpI); // Move int to long reg. 14010 repl32(tmpL); // Replicate bitpattern. 14011 mtvsrd(tmpV, tmpL); 14012 xxpermdi(dst, tmpV, tmpV, zero); 14013 %} 14014 %} 14015 14016 instruct repl4F_immF_Ex(vecX dst, immF src) %{ 14017 match(Set dst (ReplicateF src)); 14018 predicate(n->as_Vector()->length() == 4); 14019 ins_cost(10 * DEFAULT_COST); 14020 14021 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase) ); 14022 %} 14023 14024 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14025 match(Set dst (ReplicateF zero)); 14026 predicate(n->as_Vector()->length() == 4); 14027 14028 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14029 ins_encode %{ 14030 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14031 %} 14032 ins_pipe(pipe_class_default); 14033 %} 14034 14035 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14036 match(Set dst (ReplicateD src)); 14037 predicate(n->as_Vector()->length() == 2); 14038 expand %{ 14039 stackSlotL tmpS; 14040 iRegLdst tmpL; 14041 iRegLdst tmp; 14042 vecX tmpV; 14043 immI8 zero %{ (int) 0 %} 14044 moveD2L_reg_stack(tmpS, src); 14045 moveD2L_stack_reg(tmpL, tmpS); 14046 mtvsrd(tmpV, tmpL); 14047 xxpermdi(dst, tmpV, tmpV, zero); 14048 %} 14049 %} 14050 14051 instruct repl2D_immI0(vecX dst, immI_0 zero) %{ 14052 match(Set dst (ReplicateD zero)); 14053 predicate(n->as_Vector()->length() == 2); 14054 14055 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14056 size(4); 14057 ins_encode %{ 14058 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14059 %} 14060 ins_pipe(pipe_class_default); 14061 %} 14062 14063 instruct repl2D_immIminus1(vecX dst, immI_minus1 src) %{ 14064 match(Set dst (ReplicateD src)); 14065 predicate(n->as_Vector()->length() == 2); 14066 14067 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14068 size(4); 14069 ins_encode %{ 14070 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14071 %} 14072 ins_pipe(pipe_class_default); 14073 %} 14074 14075 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14076 predicate(false); 14077 effect(DEF dst, USE src); 14078 14079 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register"%} 14080 size(4); 14081 ins_encode %{ 14082 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14083 %} 14084 ins_pipe(pipe_class_default); 14085 %} 14086 14087 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14088 effect(DEF dst, USE src, USE zero); 14089 14090 format %{ "XXSPLATD $dst, $src, $zero \t// Permute 16-byte register"%} 14091 size(4); 14092 ins_encode %{ 14093 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14094 %} 14095 ins_pipe(pipe_class_default); 14096 %} 14097 14098 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14099 effect(DEF dst, USE src1, USE src2, USE zero); 14100 14101 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Permute 16-byte register"%} 14102 size(4); 14103 ins_encode %{ 14104 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14105 %} 14106 ins_pipe(pipe_class_default); 14107 %} 14108 14109 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14110 match(Set dst (ReplicateL src)); 14111 predicate(n->as_Vector()->length() == 2); 14112 expand %{ 14113 vecX tmpV; 14114 immI8 zero %{ (int) 0 %} 14115 mtvsrd(tmpV, src); 14116 xxpermdi(dst, tmpV, tmpV, zero); 14117 %} 14118 %} 14119 14120 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14121 match(Set dst (ReplicateL zero)); 14122 predicate(n->as_Vector()->length() == 2); 14123 14124 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14125 size(4); 14126 ins_encode %{ 14127 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14128 %} 14129 ins_pipe(pipe_class_default); 14130 %} 14131 14132 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14133 match(Set dst (ReplicateL src)); 14134 predicate(n->as_Vector()->length() == 2); 14135 14136 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14137 size(4); 14138 ins_encode %{ 14139 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14140 %} 14141 ins_pipe(pipe_class_default); 14142 %} 14143 14144 // ============================================================================ 14145 // Safepoint Instruction 14146 14147 instruct safePoint_poll(iRegPdst poll) %{ 14148 match(SafePoint poll); 14149 14150 // It caused problems to add the effect that r0 is killed, but this 14151 // effect no longer needs to be mentioned, since r0 is not contained 14152 // in a reg_class. 14153 14154 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14155 size(4); 14156 ins_encode( enc_poll(0x0, poll) ); 14157 ins_pipe(pipe_class_default); 14158 %} 14159 14160 // ============================================================================ 14161 // Call Instructions 14162 14163 // Call Java Static Instruction 14164 14165 // Schedulable version of call static node. 14166 instruct CallStaticJavaDirect(method meth) %{ 14167 match(CallStaticJava); 14168 effect(USE meth); 14169 ins_cost(CALL_COST); 14170 14171 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14172 14173 format %{ "CALL,static $meth \t// ==> " %} 14174 size(4); 14175 ins_encode( enc_java_static_call(meth) ); 14176 ins_pipe(pipe_class_call); 14177 %} 14178 14179 // Call Java Dynamic Instruction 14180 14181 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14182 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14183 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14184 // The call destination must still be placed in the constant pool. 14185 instruct CallDynamicJavaDirectSched(method meth) %{ 14186 match(CallDynamicJava); // To get all the data fields we need ... 14187 effect(USE meth); 14188 predicate(false); // ... but never match. 14189 14190 ins_field_load_ic_hi_node(loadConL_hiNode*); 14191 ins_field_load_ic_node(loadConLNode*); 14192 ins_num_consts(1 /* 1 patchable constant: call destination */); 14193 14194 format %{ "BL \t// dynamic $meth ==> " %} 14195 size(4); 14196 ins_encode( enc_java_dynamic_call_sched(meth) ); 14197 ins_pipe(pipe_class_call); 14198 %} 14199 14200 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14201 // We use postalloc expanded calls if we use inline caches 14202 // and do not update method data. 14203 // 14204 // This instruction has two constants: inline cache (IC) and call destination. 14205 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14206 // one constant. 14207 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14208 match(CallDynamicJava); 14209 effect(USE meth); 14210 predicate(UseInlineCaches); 14211 ins_cost(CALL_COST); 14212 14213 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14214 14215 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14216 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14217 %} 14218 14219 // Compound version of call dynamic java 14220 // We use postalloc expanded calls if we use inline caches 14221 // and do not update method data. 14222 instruct CallDynamicJavaDirect(method meth) %{ 14223 match(CallDynamicJava); 14224 effect(USE meth); 14225 predicate(!UseInlineCaches); 14226 ins_cost(CALL_COST); 14227 14228 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14229 ins_num_consts(4); 14230 14231 format %{ "CALL,dynamic $meth \t// ==> " %} 14232 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14233 ins_pipe(pipe_class_call); 14234 %} 14235 14236 // Call Runtime Instruction 14237 14238 instruct CallRuntimeDirect(method meth) %{ 14239 match(CallRuntime); 14240 effect(USE meth); 14241 ins_cost(CALL_COST); 14242 14243 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14244 // env for callee, C-toc. 14245 ins_num_consts(3); 14246 14247 format %{ "CALL,runtime" %} 14248 ins_encode( enc_java_to_runtime_call(meth) ); 14249 ins_pipe(pipe_class_call); 14250 %} 14251 14252 // Call Leaf 14253 14254 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14255 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14256 effect(DEF dst, USE src); 14257 14258 ins_num_consts(1); 14259 14260 format %{ "MTCTR $src" %} 14261 size(4); 14262 ins_encode( enc_leaf_call_mtctr(src) ); 14263 ins_pipe(pipe_class_default); 14264 %} 14265 14266 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 14267 instruct CallLeafDirect(method meth) %{ 14268 match(CallLeaf); // To get the data all the data fields we need ... 14269 effect(USE meth); 14270 predicate(false); // but never match. 14271 14272 format %{ "BCTRL \t// leaf call $meth ==> " %} 14273 size(4); 14274 ins_encode %{ 14275 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 14276 __ bctrl(); 14277 %} 14278 ins_pipe(pipe_class_call); 14279 %} 14280 14281 // postalloc expand of CallLeafDirect. 14282 // Load adress to call from TOC, then bl to it. 14283 instruct CallLeafDirect_Ex(method meth) %{ 14284 match(CallLeaf); 14285 effect(USE meth); 14286 ins_cost(CALL_COST); 14287 14288 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14289 // env for callee, C-toc. 14290 ins_num_consts(3); 14291 14292 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14293 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14294 %} 14295 14296 // Call runtime without safepoint - same as CallLeaf. 14297 // postalloc expand of CallLeafNoFPDirect. 14298 // Load adress to call from TOC, then bl to it. 14299 instruct CallLeafNoFPDirect_Ex(method meth) %{ 14300 match(CallLeafNoFP); 14301 effect(USE meth); 14302 ins_cost(CALL_COST); 14303 14304 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14305 // env for callee, C-toc. 14306 ins_num_consts(3); 14307 14308 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14309 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14310 %} 14311 14312 // Tail Call; Jump from runtime stub to Java code. 14313 // Also known as an 'interprocedural jump'. 14314 // Target of jump will eventually return to caller. 14315 // TailJump below removes the return address. 14316 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 14317 match(TailCall jump_target method_oop); 14318 ins_cost(CALL_COST); 14319 14320 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 14321 "BCTR \t// tail call" %} 14322 size(8); 14323 ins_encode %{ 14324 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14325 __ mtctr($jump_target$$Register); 14326 __ bctr(); 14327 %} 14328 ins_pipe(pipe_class_call); 14329 %} 14330 14331 // Return Instruction 14332 instruct Ret() %{ 14333 match(Return); 14334 format %{ "BLR \t// branch to link register" %} 14335 size(4); 14336 ins_encode %{ 14337 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 14338 // LR is restored in MachEpilogNode. Just do the RET here. 14339 __ blr(); 14340 %} 14341 ins_pipe(pipe_class_default); 14342 %} 14343 14344 // Tail Jump; remove the return address; jump to target. 14345 // TailCall above leaves the return address around. 14346 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14347 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14348 // "restore" before this instruction (in Epilogue), we need to materialize it 14349 // in %i0. 14350 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14351 match(TailJump jump_target ex_oop); 14352 ins_cost(CALL_COST); 14353 14354 format %{ "LD R4_ARG2 = LR\n\t" 14355 "MTCTR $jump_target\n\t" 14356 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14357 size(12); 14358 ins_encode %{ 14359 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14360 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 14361 __ mtctr($jump_target$$Register); 14362 __ bctr(); 14363 %} 14364 ins_pipe(pipe_class_call); 14365 %} 14366 14367 // Create exception oop: created by stack-crawling runtime code. 14368 // Created exception is now available to this handler, and is setup 14369 // just prior to jumping to this handler. No code emitted. 14370 instruct CreateException(rarg1RegP ex_oop) %{ 14371 match(Set ex_oop (CreateEx)); 14372 ins_cost(0); 14373 14374 format %{ " -- \t// exception oop; no code emitted" %} 14375 size(0); 14376 ins_encode( /*empty*/ ); 14377 ins_pipe(pipe_class_default); 14378 %} 14379 14380 // Rethrow exception: The exception oop will come in the first 14381 // argument position. Then JUMP (not call) to the rethrow stub code. 14382 instruct RethrowException() %{ 14383 match(Rethrow); 14384 ins_cost(CALL_COST); 14385 14386 format %{ "Jmp rethrow_stub" %} 14387 ins_encode %{ 14388 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14389 cbuf.set_insts_mark(); 14390 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 14391 %} 14392 ins_pipe(pipe_class_call); 14393 %} 14394 14395 // Die now. 14396 instruct ShouldNotReachHere() %{ 14397 match(Halt); 14398 ins_cost(CALL_COST); 14399 14400 format %{ "ShouldNotReachHere" %} 14401 size(4); 14402 ins_encode %{ 14403 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 14404 __ trap_should_not_reach_here(); 14405 %} 14406 ins_pipe(pipe_class_default); 14407 %} 14408 14409 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 14410 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 14411 // Get a DEF on threadRegP, no costs, no encoding, use 14412 // 'ins_should_rematerialize(true)' to avoid spilling. 14413 instruct tlsLoadP(threadRegP dst) %{ 14414 match(Set dst (ThreadLocal)); 14415 ins_cost(0); 14416 14417 ins_should_rematerialize(true); 14418 14419 format %{ " -- \t// $dst=Thread::current(), empty" %} 14420 size(0); 14421 ins_encode( /*empty*/ ); 14422 ins_pipe(pipe_class_empty); 14423 %} 14424 14425 //---Some PPC specific nodes--------------------------------------------------- 14426 14427 // Stop a group. 14428 instruct endGroup() %{ 14429 ins_cost(0); 14430 14431 ins_is_nop(true); 14432 14433 format %{ "End Bundle (ori r1, r1, 0)" %} 14434 size(4); 14435 ins_encode %{ 14436 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 14437 __ endgroup(); 14438 %} 14439 ins_pipe(pipe_class_default); 14440 %} 14441 14442 // Nop instructions 14443 14444 instruct fxNop() %{ 14445 ins_cost(0); 14446 14447 ins_is_nop(true); 14448 14449 format %{ "fxNop" %} 14450 size(4); 14451 ins_encode %{ 14452 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14453 __ nop(); 14454 %} 14455 ins_pipe(pipe_class_default); 14456 %} 14457 14458 instruct fpNop0() %{ 14459 ins_cost(0); 14460 14461 ins_is_nop(true); 14462 14463 format %{ "fpNop0" %} 14464 size(4); 14465 ins_encode %{ 14466 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14467 __ fpnop0(); 14468 %} 14469 ins_pipe(pipe_class_default); 14470 %} 14471 14472 instruct fpNop1() %{ 14473 ins_cost(0); 14474 14475 ins_is_nop(true); 14476 14477 format %{ "fpNop1" %} 14478 size(4); 14479 ins_encode %{ 14480 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14481 __ fpnop1(); 14482 %} 14483 ins_pipe(pipe_class_default); 14484 %} 14485 14486 instruct brNop0() %{ 14487 ins_cost(0); 14488 size(4); 14489 format %{ "brNop0" %} 14490 ins_encode %{ 14491 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14492 __ brnop0(); 14493 %} 14494 ins_is_nop(true); 14495 ins_pipe(pipe_class_default); 14496 %} 14497 14498 instruct brNop1() %{ 14499 ins_cost(0); 14500 14501 ins_is_nop(true); 14502 14503 format %{ "brNop1" %} 14504 size(4); 14505 ins_encode %{ 14506 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14507 __ brnop1(); 14508 %} 14509 ins_pipe(pipe_class_default); 14510 %} 14511 14512 instruct brNop2() %{ 14513 ins_cost(0); 14514 14515 ins_is_nop(true); 14516 14517 format %{ "brNop2" %} 14518 size(4); 14519 ins_encode %{ 14520 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14521 __ brnop2(); 14522 %} 14523 ins_pipe(pipe_class_default); 14524 %} 14525 14526 //----------PEEPHOLE RULES----------------------------------------------------- 14527 // These must follow all instruction definitions as they use the names 14528 // defined in the instructions definitions. 14529 // 14530 // peepmatch ( root_instr_name [preceeding_instruction]* ); 14531 // 14532 // peepconstraint %{ 14533 // (instruction_number.operand_name relational_op instruction_number.operand_name 14534 // [, ...] ); 14535 // // instruction numbers are zero-based using left to right order in peepmatch 14536 // 14537 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14538 // // provide an instruction_number.operand_name for each operand that appears 14539 // // in the replacement instruction's match rule 14540 // 14541 // ---------VM FLAGS--------------------------------------------------------- 14542 // 14543 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14544 // 14545 // Each peephole rule is given an identifying number starting with zero and 14546 // increasing by one in the order seen by the parser. An individual peephole 14547 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14548 // on the command-line. 14549 // 14550 // ---------CURRENT LIMITATIONS---------------------------------------------- 14551 // 14552 // Only match adjacent instructions in same basic block 14553 // Only equality constraints 14554 // Only constraints between operands, not (0.dest_reg == EAX_enc) 14555 // Only one replacement instruction 14556 // 14557 // ---------EXAMPLE---------------------------------------------------------- 14558 // 14559 // // pertinent parts of existing instructions in architecture description 14560 // instruct movI(eRegI dst, eRegI src) %{ 14561 // match(Set dst (CopyI src)); 14562 // %} 14563 // 14564 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 14565 // match(Set dst (AddI dst src)); 14566 // effect(KILL cr); 14567 // %} 14568 // 14569 // // Change (inc mov) to lea 14570 // peephole %{ 14571 // // increment preceeded by register-register move 14572 // peepmatch ( incI_eReg movI ); 14573 // // require that the destination register of the increment 14574 // // match the destination register of the move 14575 // peepconstraint ( 0.dst == 1.dst ); 14576 // // construct a replacement instruction that sets 14577 // // the destination to ( move's source register + one ) 14578 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14579 // %} 14580 // 14581 // Implementation no longer uses movX instructions since 14582 // machine-independent system no longer uses CopyX nodes. 14583 // 14584 // peephole %{ 14585 // peepmatch ( incI_eReg movI ); 14586 // peepconstraint ( 0.dst == 1.dst ); 14587 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14588 // %} 14589 // 14590 // peephole %{ 14591 // peepmatch ( decI_eReg movI ); 14592 // peepconstraint ( 0.dst == 1.dst ); 14593 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14594 // %} 14595 // 14596 // peephole %{ 14597 // peepmatch ( addI_eReg_imm movI ); 14598 // peepconstraint ( 0.dst == 1.dst ); 14599 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14600 // %} 14601 // 14602 // peephole %{ 14603 // peepmatch ( addP_eReg_imm movP ); 14604 // peepconstraint ( 0.dst == 1.dst ); 14605 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 14606 // %} 14607 14608 // // Change load of spilled value to only a spill 14609 // instruct storeI(memory mem, eRegI src) %{ 14610 // match(Set mem (StoreI mem src)); 14611 // %} 14612 // 14613 // instruct loadI(eRegI dst, memory mem) %{ 14614 // match(Set dst (LoadI mem)); 14615 // %} 14616 // 14617 peephole %{ 14618 peepmatch ( loadI storeI ); 14619 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14620 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 14621 %} 14622 14623 peephole %{ 14624 peepmatch ( loadL storeL ); 14625 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14626 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 14627 %} 14628 14629 peephole %{ 14630 peepmatch ( loadP storeP ); 14631 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 14632 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 14633 %} 14634 14635 //----------SMARTSPILL RULES--------------------------------------------------- 14636 // These must follow all instruction definitions as they use the names 14637 // defined in the instructions definitions.