1 // 2 // Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2018 SAP SE. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // 27 // PPC64 Architecture Description File 28 // 29 30 //----------REGISTER DEFINITION BLOCK------------------------------------------ 31 // This information is used by the matcher and the register allocator to 32 // describe individual registers and classes of registers within the target 33 // architecture. 34 register %{ 35 //----------Architecture Description Register Definitions---------------------- 36 // General Registers 37 // "reg_def" name (register save type, C convention save type, 38 // ideal register type, encoding); 39 // 40 // Register Save Types: 41 // 42 // NS = No-Save: The register allocator assumes that these registers 43 // can be used without saving upon entry to the method, & 44 // that they do not need to be saved at call sites. 45 // 46 // SOC = Save-On-Call: The register allocator assumes that these registers 47 // can be used without saving upon entry to the method, 48 // but that they must be saved at call sites. 49 // These are called "volatiles" on ppc. 50 // 51 // SOE = Save-On-Entry: The register allocator assumes that these registers 52 // must be saved before using them upon entry to the 53 // method, but they do not need to be saved at call 54 // sites. 55 // These are called "nonvolatiles" on ppc. 56 // 57 // AS = Always-Save: The register allocator assumes that these registers 58 // must be saved before using them upon entry to the 59 // method, & that they must be saved at call sites. 60 // 61 // Ideal Register Type is used to determine how to save & restore a 62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 64 // 65 // The encoding number is the actual bit-pattern placed into the opcodes. 66 // 67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI 68 // Supplement Version 1.7 as of 2003-10-29. 69 // 70 // For each 64-bit register we must define two registers: the register 71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half', 72 // e.g. R3_H, which is needed by the allocator, but is not used 73 // for stores, loads, etc. 74 75 // ---------------------------- 76 // Integer/Long Registers 77 // ---------------------------- 78 79 // PPC64 has 32 64-bit integer registers. 80 81 // types: v = volatile, nv = non-volatile, s = system 82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs 83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() ); 84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP 85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() ); 86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC 87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() ); 88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret 89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() ); 90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2 91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() ); 92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3 93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() ); 94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4 95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() ); 96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5 97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() ); 98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6 99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() ); 100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7 101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() ); 102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8 103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next()); 104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch 105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next()); 106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch 107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next()); 108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id 109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next()); 110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv 111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next()); 112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv 113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next()); 114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv 115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next()); 116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv 117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next()); 118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv 119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next()); 120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv 121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next()); 122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv 123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next()); 124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv 125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next()); 126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv 127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next()); 128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv 129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next()); 130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv 131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next()); 132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv 133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next()); 134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv 135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next()); 136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv 137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next()); 138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv 139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next()); 140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv 141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next()); 142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv 143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next()); 144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv 145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next()); 146 147 148 // ---------------------------- 149 // Float/Double Registers 150 // ---------------------------- 151 152 // Double Registers 153 // The rules of ADL require that double registers be defined in pairs. 154 // Each pair must be two 32-bit values, but not necessarily a pair of 155 // single float registers. In each pair, ADLC-assigned register numbers 156 // must be adjacent, with the lower number even. Finally, when the 157 // CPU stores such a register pair to memory, the word associated with 158 // the lower ADLC-assigned number must be stored to the lower address. 159 160 // PPC64 has 32 64-bit floating-point registers. Each can store a single 161 // or double precision floating-point value. 162 163 // types: v = volatile, nv = non-volatile, s = system 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch 165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret 167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2 169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3 171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4 173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5 175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6 177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7 179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8 181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9 183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10 185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next()); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11 187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next()); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12 189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next()); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13 191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next()); 192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv 193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next()); 194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv 195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next()); 196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv 197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next()); 198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv 199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next()); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv 201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next()); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv 203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next()); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv 205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next()); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv 207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next()); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv 209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next()); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv 211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next()); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv 213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next()); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv 215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next()); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv 217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next()); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv 219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next()); 220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv 221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next()); 222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv 223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next()); 224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv 225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next()); 226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv 227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next()); 228 229 // ---------------------------- 230 // Special Registers 231 // ---------------------------- 232 233 // Condition Codes Flag Registers 234 235 // PPC64 has 8 condition code "registers" which are all contained 236 // in the CR register. 237 238 // types: v = volatile, nv = non-volatile, s = system 239 reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v 240 reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v 241 reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv 242 reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv 243 reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv 244 reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v 245 reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v 246 reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg()); // v 247 248 // Special registers of PPC64 249 250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v 251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v 252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v 253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v 254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v 255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v 256 257 // ---------------------------- 258 // Vector-Scalar Registers 259 // ---------------------------- 260 reg_def VSR0 ( SOC, SOC, Op_VecX, 0, NULL); 261 reg_def VSR1 ( SOC, SOC, Op_VecX, 1, NULL); 262 reg_def VSR2 ( SOC, SOC, Op_VecX, 2, NULL); 263 reg_def VSR3 ( SOC, SOC, Op_VecX, 3, NULL); 264 reg_def VSR4 ( SOC, SOC, Op_VecX, 4, NULL); 265 reg_def VSR5 ( SOC, SOC, Op_VecX, 5, NULL); 266 reg_def VSR6 ( SOC, SOC, Op_VecX, 6, NULL); 267 reg_def VSR7 ( SOC, SOC, Op_VecX, 7, NULL); 268 reg_def VSR8 ( SOC, SOC, Op_VecX, 8, NULL); 269 reg_def VSR9 ( SOC, SOC, Op_VecX, 9, NULL); 270 reg_def VSR10 ( SOC, SOC, Op_VecX, 10, NULL); 271 reg_def VSR11 ( SOC, SOC, Op_VecX, 11, NULL); 272 reg_def VSR12 ( SOC, SOC, Op_VecX, 12, NULL); 273 reg_def VSR13 ( SOC, SOC, Op_VecX, 13, NULL); 274 reg_def VSR14 ( SOC, SOC, Op_VecX, 14, NULL); 275 reg_def VSR15 ( SOC, SOC, Op_VecX, 15, NULL); 276 reg_def VSR16 ( SOC, SOC, Op_VecX, 16, NULL); 277 reg_def VSR17 ( SOC, SOC, Op_VecX, 17, NULL); 278 reg_def VSR18 ( SOC, SOC, Op_VecX, 18, NULL); 279 reg_def VSR19 ( SOC, SOC, Op_VecX, 19, NULL); 280 reg_def VSR20 ( SOC, SOC, Op_VecX, 20, NULL); 281 reg_def VSR21 ( SOC, SOC, Op_VecX, 21, NULL); 282 reg_def VSR22 ( SOC, SOC, Op_VecX, 22, NULL); 283 reg_def VSR23 ( SOC, SOC, Op_VecX, 23, NULL); 284 reg_def VSR24 ( SOC, SOC, Op_VecX, 24, NULL); 285 reg_def VSR25 ( SOC, SOC, Op_VecX, 25, NULL); 286 reg_def VSR26 ( SOC, SOC, Op_VecX, 26, NULL); 287 reg_def VSR27 ( SOC, SOC, Op_VecX, 27, NULL); 288 reg_def VSR28 ( SOC, SOC, Op_VecX, 28, NULL); 289 reg_def VSR29 ( SOC, SOC, Op_VecX, 29, NULL); 290 reg_def VSR30 ( SOC, SOC, Op_VecX, 30, NULL); 291 reg_def VSR31 ( SOC, SOC, Op_VecX, 31, NULL); 292 reg_def VSR32 ( SOC, SOC, Op_VecX, 32, NULL); 293 reg_def VSR33 ( SOC, SOC, Op_VecX, 33, NULL); 294 reg_def VSR34 ( SOC, SOC, Op_VecX, 34, NULL); 295 reg_def VSR35 ( SOC, SOC, Op_VecX, 35, NULL); 296 reg_def VSR36 ( SOC, SOC, Op_VecX, 36, NULL); 297 reg_def VSR37 ( SOC, SOC, Op_VecX, 37, NULL); 298 reg_def VSR38 ( SOC, SOC, Op_VecX, 38, NULL); 299 reg_def VSR39 ( SOC, SOC, Op_VecX, 39, NULL); 300 reg_def VSR40 ( SOC, SOC, Op_VecX, 40, NULL); 301 reg_def VSR41 ( SOC, SOC, Op_VecX, 41, NULL); 302 reg_def VSR42 ( SOC, SOC, Op_VecX, 42, NULL); 303 reg_def VSR43 ( SOC, SOC, Op_VecX, 43, NULL); 304 reg_def VSR44 ( SOC, SOC, Op_VecX, 44, NULL); 305 reg_def VSR45 ( SOC, SOC, Op_VecX, 45, NULL); 306 reg_def VSR46 ( SOC, SOC, Op_VecX, 46, NULL); 307 reg_def VSR47 ( SOC, SOC, Op_VecX, 47, NULL); 308 reg_def VSR48 ( SOC, SOC, Op_VecX, 48, NULL); 309 reg_def VSR49 ( SOC, SOC, Op_VecX, 49, NULL); 310 reg_def VSR50 ( SOC, SOC, Op_VecX, 50, NULL); 311 reg_def VSR51 ( SOC, SOC, Op_VecX, 51, NULL); 312 reg_def VSR52 ( SOC, SOC, Op_VecX, 52, NULL); 313 reg_def VSR53 ( SOC, SOC, Op_VecX, 53, NULL); 314 reg_def VSR54 ( SOC, SOC, Op_VecX, 54, NULL); 315 reg_def VSR55 ( SOC, SOC, Op_VecX, 55, NULL); 316 reg_def VSR56 ( SOC, SOC, Op_VecX, 56, NULL); 317 reg_def VSR57 ( SOC, SOC, Op_VecX, 57, NULL); 318 reg_def VSR58 ( SOC, SOC, Op_VecX, 58, NULL); 319 reg_def VSR59 ( SOC, SOC, Op_VecX, 59, NULL); 320 reg_def VSR60 ( SOC, SOC, Op_VecX, 60, NULL); 321 reg_def VSR61 ( SOC, SOC, Op_VecX, 61, NULL); 322 reg_def VSR62 ( SOC, SOC, Op_VecX, 62, NULL); 323 reg_def VSR63 ( SOC, SOC, Op_VecX, 63, NULL); 324 325 // ---------------------------- 326 // Specify priority of register selection within phases of register 327 // allocation. Highest priority is first. A useful heuristic is to 328 // give registers a low priority when they are required by machine 329 // instructions, like EAX and EDX on I486, and choose no-save registers 330 // before save-on-call, & save-on-call before save-on-entry. Registers 331 // which participate in fixed calling sequences should come last. 332 // Registers which are used as pairs must fall on an even boundary. 333 334 // It's worth about 1% on SPEC geomean to get this right. 335 336 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 337 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 338 // R3_num. Therefore, R3_num may not be (and in reality is not) 339 // the same as R3->encoding()! Furthermore, we cannot make any 340 // assumptions on ordering, e.g. R3_num may be less than R2_num. 341 // Additionally, the function 342 // static enum RC rc_class(OptoReg::Name reg ) 343 // maps a given <register>_num value to its chunk type (except for flags) 344 // and its current implementation relies on chunk0 and chunk1 having a 345 // size of 64 each. 346 347 // If you change this allocation class, please have a look at the 348 // default values for the parameters RoundRobinIntegerRegIntervalStart 349 // and RoundRobinFloatRegIntervalStart 350 351 alloc_class chunk0 ( 352 // Chunk0 contains *all* 64 integer registers halves. 353 354 // "non-volatile" registers 355 R14, R14_H, 356 R15, R15_H, 357 R17, R17_H, 358 R18, R18_H, 359 R19, R19_H, 360 R20, R20_H, 361 R21, R21_H, 362 R22, R22_H, 363 R23, R23_H, 364 R24, R24_H, 365 R25, R25_H, 366 R26, R26_H, 367 R27, R27_H, 368 R28, R28_H, 369 R29, R29_H, 370 R30, R30_H, 371 R31, R31_H, 372 373 // scratch/special registers 374 R11, R11_H, 375 R12, R12_H, 376 377 // argument registers 378 R10, R10_H, 379 R9, R9_H, 380 R8, R8_H, 381 R7, R7_H, 382 R6, R6_H, 383 R5, R5_H, 384 R4, R4_H, 385 R3, R3_H, 386 387 // special registers, not available for allocation 388 R16, R16_H, // R16_thread 389 R13, R13_H, // system thread id 390 R2, R2_H, // may be used for TOC 391 R1, R1_H, // SP 392 R0, R0_H // R0 (scratch) 393 ); 394 395 // If you change this allocation class, please have a look at the 396 // default values for the parameters RoundRobinIntegerRegIntervalStart 397 // and RoundRobinFloatRegIntervalStart 398 399 alloc_class chunk1 ( 400 // Chunk1 contains *all* 64 floating-point registers halves. 401 402 // scratch register 403 F0, F0_H, 404 405 // argument registers 406 F13, F13_H, 407 F12, F12_H, 408 F11, F11_H, 409 F10, F10_H, 410 F9, F9_H, 411 F8, F8_H, 412 F7, F7_H, 413 F6, F6_H, 414 F5, F5_H, 415 F4, F4_H, 416 F3, F3_H, 417 F2, F2_H, 418 F1, F1_H, 419 420 // non-volatile registers 421 F14, F14_H, 422 F15, F15_H, 423 F16, F16_H, 424 F17, F17_H, 425 F18, F18_H, 426 F19, F19_H, 427 F20, F20_H, 428 F21, F21_H, 429 F22, F22_H, 430 F23, F23_H, 431 F24, F24_H, 432 F25, F25_H, 433 F26, F26_H, 434 F27, F27_H, 435 F28, F28_H, 436 F29, F29_H, 437 F30, F30_H, 438 F31, F31_H 439 ); 440 441 alloc_class chunk2 ( 442 // Chunk2 contains *all* 8 condition code registers. 443 444 CCR0, 445 CCR1, 446 CCR2, 447 CCR3, 448 CCR4, 449 CCR5, 450 CCR6, 451 CCR7 452 ); 453 454 alloc_class chunk3 ( 455 VSR0, 456 VSR1, 457 VSR2, 458 VSR3, 459 VSR4, 460 VSR5, 461 VSR6, 462 VSR7, 463 VSR8, 464 VSR9, 465 VSR10, 466 VSR11, 467 VSR12, 468 VSR13, 469 VSR14, 470 VSR15, 471 VSR16, 472 VSR17, 473 VSR18, 474 VSR19, 475 VSR20, 476 VSR21, 477 VSR22, 478 VSR23, 479 VSR24, 480 VSR25, 481 VSR26, 482 VSR27, 483 VSR28, 484 VSR29, 485 VSR30, 486 VSR31, 487 VSR32, 488 VSR33, 489 VSR34, 490 VSR35, 491 VSR36, 492 VSR37, 493 VSR38, 494 VSR39, 495 VSR40, 496 VSR41, 497 VSR42, 498 VSR43, 499 VSR44, 500 VSR45, 501 VSR46, 502 VSR47, 503 VSR48, 504 VSR49, 505 VSR50, 506 VSR51, 507 VSR52, 508 VSR53, 509 VSR54, 510 VSR55, 511 VSR56, 512 VSR57, 513 VSR58, 514 VSR59, 515 VSR60, 516 VSR61, 517 VSR62, 518 VSR63 519 ); 520 521 alloc_class chunk4 ( 522 // special registers 523 // These registers are not allocated, but used for nodes generated by postalloc expand. 524 SR_XER, 525 SR_LR, 526 SR_CTR, 527 SR_VRSAVE, 528 SR_SPEFSCR, 529 SR_PPR 530 ); 531 532 //-------Architecture Description Register Classes----------------------- 533 534 // Several register classes are automatically defined based upon 535 // information in this architecture description. 536 537 // 1) reg_class inline_cache_reg ( as defined in frame section ) 538 // 2) reg_class compiler_method_oop_reg ( as defined in frame section ) 539 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 540 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 541 // 542 543 // ---------------------------- 544 // 32 Bit Register Classes 545 // ---------------------------- 546 547 // We specify registers twice, once as read/write, and once read-only. 548 // We use the read-only registers for source operands. With this, we 549 // can include preset read only registers in this class, as a hard-coded 550 // '0'-register. (We used to simulate this on ppc.) 551 552 // 32 bit registers that can be read and written i.e. these registers 553 // can be dest (or src) of normal instructions. 554 reg_class bits32_reg_rw( 555 /*R0*/ // R0 556 /*R1*/ // SP 557 R2, // TOC 558 R3, 559 R4, 560 R5, 561 R6, 562 R7, 563 R8, 564 R9, 565 R10, 566 R11, 567 R12, 568 /*R13*/ // system thread id 569 R14, 570 R15, 571 /*R16*/ // R16_thread 572 R17, 573 R18, 574 R19, 575 R20, 576 R21, 577 R22, 578 R23, 579 R24, 580 R25, 581 R26, 582 R27, 583 R28, 584 /*R29,*/ // global TOC 585 R30, 586 R31 587 ); 588 589 // 32 bit registers that can only be read i.e. these registers can 590 // only be src of all instructions. 591 reg_class bits32_reg_ro( 592 /*R0*/ // R0 593 /*R1*/ // SP 594 R2 // TOC 595 R3, 596 R4, 597 R5, 598 R6, 599 R7, 600 R8, 601 R9, 602 R10, 603 R11, 604 R12, 605 /*R13*/ // system thread id 606 R14, 607 R15, 608 /*R16*/ // R16_thread 609 R17, 610 R18, 611 R19, 612 R20, 613 R21, 614 R22, 615 R23, 616 R24, 617 R25, 618 R26, 619 R27, 620 R28, 621 /*R29,*/ 622 R30, 623 R31 624 ); 625 626 reg_class rscratch1_bits32_reg(R11); 627 reg_class rscratch2_bits32_reg(R12); 628 reg_class rarg1_bits32_reg(R3); 629 reg_class rarg2_bits32_reg(R4); 630 reg_class rarg3_bits32_reg(R5); 631 reg_class rarg4_bits32_reg(R6); 632 633 // ---------------------------- 634 // 64 Bit Register Classes 635 // ---------------------------- 636 // 64-bit build means 64-bit pointers means hi/lo pairs 637 638 reg_class rscratch1_bits64_reg(R11_H, R11); 639 reg_class rscratch2_bits64_reg(R12_H, R12); 640 reg_class rarg1_bits64_reg(R3_H, R3); 641 reg_class rarg2_bits64_reg(R4_H, R4); 642 reg_class rarg3_bits64_reg(R5_H, R5); 643 reg_class rarg4_bits64_reg(R6_H, R6); 644 // Thread register, 'written' by tlsLoadP, see there. 645 reg_class thread_bits64_reg(R16_H, R16); 646 647 reg_class r19_bits64_reg(R19_H, R19); 648 649 // 64 bit registers that can be read and written i.e. these registers 650 // can be dest (or src) of normal instructions. 651 reg_class bits64_reg_rw( 652 /*R0_H, R0*/ // R0 653 /*R1_H, R1*/ // SP 654 R2_H, R2, // TOC 655 R3_H, R3, 656 R4_H, R4, 657 R5_H, R5, 658 R6_H, R6, 659 R7_H, R7, 660 R8_H, R8, 661 R9_H, R9, 662 R10_H, R10, 663 R11_H, R11, 664 R12_H, R12, 665 /*R13_H, R13*/ // system thread id 666 R14_H, R14, 667 R15_H, R15, 668 /*R16_H, R16*/ // R16_thread 669 R17_H, R17, 670 R18_H, R18, 671 R19_H, R19, 672 R20_H, R20, 673 R21_H, R21, 674 R22_H, R22, 675 R23_H, R23, 676 R24_H, R24, 677 R25_H, R25, 678 R26_H, R26, 679 R27_H, R27, 680 R28_H, R28, 681 /*R29_H, R29,*/ 682 R30_H, R30, 683 R31_H, R31 684 ); 685 686 // 64 bit registers used excluding r2, r11 and r12 687 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses 688 // r2, r11 and r12 internally. 689 reg_class bits64_reg_leaf_call( 690 /*R0_H, R0*/ // R0 691 /*R1_H, R1*/ // SP 692 /*R2_H, R2*/ // TOC 693 R3_H, R3, 694 R4_H, R4, 695 R5_H, R5, 696 R6_H, R6, 697 R7_H, R7, 698 R8_H, R8, 699 R9_H, R9, 700 R10_H, R10, 701 /*R11_H, R11*/ 702 /*R12_H, R12*/ 703 /*R13_H, R13*/ // system thread id 704 R14_H, R14, 705 R15_H, R15, 706 /*R16_H, R16*/ // R16_thread 707 R17_H, R17, 708 R18_H, R18, 709 R19_H, R19, 710 R20_H, R20, 711 R21_H, R21, 712 R22_H, R22, 713 R23_H, R23, 714 R24_H, R24, 715 R25_H, R25, 716 R26_H, R26, 717 R27_H, R27, 718 R28_H, R28, 719 /*R29_H, R29,*/ 720 R30_H, R30, 721 R31_H, R31 722 ); 723 724 // Used to hold the TOC to avoid collisions with expanded DynamicCall 725 // which uses r19 as inline cache internally and expanded LeafCall which uses 726 // r2, r11 and r12 internally. 727 reg_class bits64_constant_table_base( 728 /*R0_H, R0*/ // R0 729 /*R1_H, R1*/ // SP 730 /*R2_H, R2*/ // TOC 731 R3_H, R3, 732 R4_H, R4, 733 R5_H, R5, 734 R6_H, R6, 735 R7_H, R7, 736 R8_H, R8, 737 R9_H, R9, 738 R10_H, R10, 739 /*R11_H, R11*/ 740 /*R12_H, R12*/ 741 /*R13_H, R13*/ // system thread id 742 R14_H, R14, 743 R15_H, R15, 744 /*R16_H, R16*/ // R16_thread 745 R17_H, R17, 746 R18_H, R18, 747 /*R19_H, R19*/ 748 R20_H, R20, 749 R21_H, R21, 750 R22_H, R22, 751 R23_H, R23, 752 R24_H, R24, 753 R25_H, R25, 754 R26_H, R26, 755 R27_H, R27, 756 R28_H, R28, 757 /*R29_H, R29,*/ 758 R30_H, R30, 759 R31_H, R31 760 ); 761 762 // 64 bit registers that can only be read i.e. these registers can 763 // only be src of all instructions. 764 reg_class bits64_reg_ro( 765 /*R0_H, R0*/ // R0 766 R1_H, R1, 767 R2_H, R2, // TOC 768 R3_H, R3, 769 R4_H, R4, 770 R5_H, R5, 771 R6_H, R6, 772 R7_H, R7, 773 R8_H, R8, 774 R9_H, R9, 775 R10_H, R10, 776 R11_H, R11, 777 R12_H, R12, 778 /*R13_H, R13*/ // system thread id 779 R14_H, R14, 780 R15_H, R15, 781 R16_H, R16, // R16_thread 782 R17_H, R17, 783 R18_H, R18, 784 R19_H, R19, 785 R20_H, R20, 786 R21_H, R21, 787 R22_H, R22, 788 R23_H, R23, 789 R24_H, R24, 790 R25_H, R25, 791 R26_H, R26, 792 R27_H, R27, 793 R28_H, R28, 794 /*R29_H, R29,*/ // TODO: let allocator handle TOC!! 795 R30_H, R30, 796 R31_H, R31 797 ); 798 799 800 // ---------------------------- 801 // Special Class for Condition Code Flags Register 802 803 reg_class int_flags( 804 /*CCR0*/ // scratch 805 /*CCR1*/ // scratch 806 /*CCR2*/ // nv! 807 /*CCR3*/ // nv! 808 /*CCR4*/ // nv! 809 CCR5, 810 CCR6, 811 CCR7 812 ); 813 814 reg_class int_flags_ro( 815 CCR0, 816 CCR1, 817 CCR2, 818 CCR3, 819 CCR4, 820 CCR5, 821 CCR6, 822 CCR7 823 ); 824 825 reg_class int_flags_CR0(CCR0); 826 reg_class int_flags_CR1(CCR1); 827 reg_class int_flags_CR6(CCR6); 828 reg_class ctr_reg(SR_CTR); 829 830 // ---------------------------- 831 // Float Register Classes 832 // ---------------------------- 833 834 reg_class flt_reg( 835 F0, 836 F1, 837 F2, 838 F3, 839 F4, 840 F5, 841 F6, 842 F7, 843 F8, 844 F9, 845 F10, 846 F11, 847 F12, 848 F13, 849 F14, // nv! 850 F15, // nv! 851 F16, // nv! 852 F17, // nv! 853 F18, // nv! 854 F19, // nv! 855 F20, // nv! 856 F21, // nv! 857 F22, // nv! 858 F23, // nv! 859 F24, // nv! 860 F25, // nv! 861 F26, // nv! 862 F27, // nv! 863 F28, // nv! 864 F29, // nv! 865 F30, // nv! 866 F31 // nv! 867 ); 868 869 // Double precision float registers have virtual `high halves' that 870 // are needed by the allocator. 871 reg_class dbl_reg( 872 F0, F0_H, 873 F1, F1_H, 874 F2, F2_H, 875 F3, F3_H, 876 F4, F4_H, 877 F5, F5_H, 878 F6, F6_H, 879 F7, F7_H, 880 F8, F8_H, 881 F9, F9_H, 882 F10, F10_H, 883 F11, F11_H, 884 F12, F12_H, 885 F13, F13_H, 886 F14, F14_H, // nv! 887 F15, F15_H, // nv! 888 F16, F16_H, // nv! 889 F17, F17_H, // nv! 890 F18, F18_H, // nv! 891 F19, F19_H, // nv! 892 F20, F20_H, // nv! 893 F21, F21_H, // nv! 894 F22, F22_H, // nv! 895 F23, F23_H, // nv! 896 F24, F24_H, // nv! 897 F25, F25_H, // nv! 898 F26, F26_H, // nv! 899 F27, F27_H, // nv! 900 F28, F28_H, // nv! 901 F29, F29_H, // nv! 902 F30, F30_H, // nv! 903 F31, F31_H // nv! 904 ); 905 906 // ---------------------------- 907 // Vector-Scalar Register Class 908 // ---------------------------- 909 910 reg_class vs_reg( 911 // Attention: Only these ones are saved & restored at safepoint by RegisterSaver. 912 VSR32, 913 VSR33, 914 VSR34, 915 VSR35, 916 VSR36, 917 VSR37, 918 VSR38, 919 VSR39, 920 VSR40, 921 VSR41, 922 VSR42, 923 VSR43, 924 VSR44, 925 VSR45, 926 VSR46, 927 VSR47, 928 VSR48, 929 VSR49, 930 VSR50, 931 VSR51 932 // VSR52-VSR63 // nv! 933 ); 934 935 %} 936 937 //----------DEFINITION BLOCK--------------------------------------------------- 938 // Define name --> value mappings to inform the ADLC of an integer valued name 939 // Current support includes integer values in the range [0, 0x7FFFFFFF] 940 // Format: 941 // int_def <name> ( <int_value>, <expression>); 942 // Generated Code in ad_<arch>.hpp 943 // #define <name> (<expression>) 944 // // value == <int_value> 945 // Generated code in ad_<arch>.cpp adlc_verification() 946 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 947 // 948 definitions %{ 949 // The default cost (of an ALU instruction). 950 int_def DEFAULT_COST_LOW ( 30, 30); 951 int_def DEFAULT_COST ( 100, 100); 952 int_def HUGE_COST (1000000, 1000000); 953 954 // Memory refs 955 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 956 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 957 958 // Branches are even more expensive. 959 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 960 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 961 %} 962 963 964 //----------SOURCE BLOCK------------------------------------------------------- 965 // This is a block of C++ code which provides values, functions, and 966 // definitions necessary in the rest of the architecture description. 967 source_hpp %{ 968 // Header information of the source block. 969 // Method declarations/definitions which are used outside 970 // the ad-scope can conveniently be defined here. 971 // 972 // To keep related declarations/definitions/uses close together, 973 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 974 975 // Returns true if Node n is followed by a MemBar node that 976 // will do an acquire. If so, this node must not do the acquire 977 // operation. 978 bool followed_by_acquire(const Node *n); 979 %} 980 981 source %{ 982 983 // Should the Matcher clone shifts on addressing modes, expecting them 984 // to be subsumed into complex addressing expressions or compute them 985 // into registers? 986 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 987 return clone_base_plus_offset_address(m, mstack, address_visited); 988 } 989 990 void Compile::reshape_address(AddPNode* addp) { 991 } 992 993 // Optimize load-acquire. 994 // 995 // Check if acquire is unnecessary due to following operation that does 996 // acquire anyways. 997 // Walk the pattern: 998 // 999 // n: Load.acq 1000 // | 1001 // MemBarAcquire 1002 // | | 1003 // Proj(ctrl) Proj(mem) 1004 // | | 1005 // MemBarRelease/Volatile 1006 // 1007 bool followed_by_acquire(const Node *load) { 1008 assert(load->is_Load(), "So far implemented only for loads."); 1009 1010 // Find MemBarAcquire. 1011 const Node *mba = NULL; 1012 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 1013 const Node *out = load->fast_out(i); 1014 if (out->Opcode() == Op_MemBarAcquire) { 1015 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 1016 mba = out; 1017 break; 1018 } 1019 } 1020 if (!mba) return false; 1021 1022 // Find following MemBar node. 1023 // 1024 // The following node must be reachable by control AND memory 1025 // edge to assure no other operations are in between the two nodes. 1026 // 1027 // So first get the Proj node, mem_proj, to use it to iterate forward. 1028 Node *mem_proj = NULL; 1029 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 1030 mem_proj = mba->fast_out(i); // Runs out of bounds and asserts if Proj not found. 1031 assert(mem_proj->is_Proj(), "only projections here"); 1032 ProjNode *proj = mem_proj->as_Proj(); 1033 if (proj->_con == TypeFunc::Memory && 1034 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 1035 break; 1036 } 1037 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 1038 1039 // Search MemBar behind Proj. If there are other memory operations 1040 // behind the Proj we lost. 1041 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 1042 Node *x = mem_proj->fast_out(j); 1043 // Proj might have an edge to a store or load node which precedes the membar. 1044 if (x->is_Mem()) return false; 1045 1046 // On PPC64 release and volatile are implemented by an instruction 1047 // that also has acquire semantics. I.e. there is no need for an 1048 // acquire before these. 1049 int xop = x->Opcode(); 1050 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 1051 // Make sure we're not missing Call/Phi/MergeMem by checking 1052 // control edges. The control edge must directly lead back 1053 // to the MemBarAcquire 1054 Node *ctrl_proj = x->in(0); 1055 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 1056 return true; 1057 } 1058 } 1059 } 1060 1061 return false; 1062 } 1063 1064 #define __ _masm. 1065 1066 // Tertiary op of a LoadP or StoreP encoding. 1067 #define REGP_OP true 1068 1069 // **************************************************************************** 1070 1071 // REQUIRED FUNCTIONALITY 1072 1073 // !!!!! Special hack to get all type of calls to specify the byte offset 1074 // from the start of the call to the point where the return address 1075 // will point. 1076 1077 // PPC port: Removed use of lazy constant construct. 1078 1079 int MachCallStaticJavaNode::ret_addr_offset() { 1080 // It's only a single branch-and-link instruction. 1081 return 4; 1082 } 1083 1084 int MachCallDynamicJavaNode::ret_addr_offset() { 1085 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 1086 // postalloc expanded calls if we use inline caches and do not update method data. 1087 if (UseInlineCaches) 1088 return 4; 1089 1090 int vtable_index = this->_vtable_index; 1091 if (vtable_index < 0) { 1092 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 1093 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 1094 return 12; 1095 } else { 1096 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 1097 return 24; 1098 } 1099 } 1100 1101 int MachCallRuntimeNode::ret_addr_offset() { 1102 #if defined(ABI_ELFv2) 1103 return 28; 1104 #else 1105 return 40; 1106 #endif 1107 } 1108 1109 //============================================================================= 1110 1111 // condition code conversions 1112 1113 static int cc_to_boint(int cc) { 1114 return Assembler::bcondCRbiIs0 | (cc & 8); 1115 } 1116 1117 static int cc_to_inverse_boint(int cc) { 1118 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 1119 } 1120 1121 static int cc_to_biint(int cc, int flags_reg) { 1122 return (flags_reg << 2) | (cc & 3); 1123 } 1124 1125 //============================================================================= 1126 1127 // Compute padding required for nodes which need alignment. The padding 1128 // is the number of bytes (not instructions) which will be inserted before 1129 // the instruction. The padding must match the size of a NOP instruction. 1130 1131 // Currently not used on this platform. 1132 1133 //============================================================================= 1134 1135 // Indicate if the safepoint node needs the polling page as an input. 1136 bool SafePointNode::needs_polling_address_input() { 1137 // The address is loaded from thread by a seperate node. 1138 return true; 1139 } 1140 1141 //============================================================================= 1142 1143 // Emit an interrupt that is caught by the debugger (for debugging compiler). 1144 void emit_break(CodeBuffer &cbuf) { 1145 MacroAssembler _masm(&cbuf); 1146 __ illtrap(); 1147 } 1148 1149 #ifndef PRODUCT 1150 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1151 st->print("BREAKPOINT"); 1152 } 1153 #endif 1154 1155 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1156 emit_break(cbuf); 1157 } 1158 1159 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1160 return MachNode::size(ra_); 1161 } 1162 1163 //============================================================================= 1164 1165 void emit_nop(CodeBuffer &cbuf) { 1166 MacroAssembler _masm(&cbuf); 1167 __ nop(); 1168 } 1169 1170 static inline void emit_long(CodeBuffer &cbuf, int value) { 1171 *((int*)(cbuf.insts_end())) = value; 1172 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1173 } 1174 1175 //============================================================================= 1176 1177 %} // interrupt source 1178 1179 source_hpp %{ // Header information of the source block. 1180 1181 //-------------------------------------------------------------- 1182 //---< Used for optimization in Compile::Shorten_branches >--- 1183 //-------------------------------------------------------------- 1184 1185 class CallStubImpl { 1186 1187 public: 1188 1189 // Emit call stub, compiled java to interpreter. 1190 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1191 1192 // Size of call trampoline stub. 1193 // This doesn't need to be accurate to the byte, but it 1194 // must be larger than or equal to the real size of the stub. 1195 static uint size_call_trampoline() { 1196 return MacroAssembler::trampoline_stub_size; 1197 } 1198 1199 // number of relocations needed by a call trampoline stub 1200 static uint reloc_call_trampoline() { 1201 return 5; 1202 } 1203 1204 }; 1205 1206 %} // end source_hpp 1207 1208 source %{ 1209 1210 // Emit a trampoline stub for a call to a target which is too far away. 1211 // 1212 // code sequences: 1213 // 1214 // call-site: 1215 // branch-and-link to <destination> or <trampoline stub> 1216 // 1217 // Related trampoline stub for this call-site in the stub section: 1218 // load the call target from the constant pool 1219 // branch via CTR (LR/link still points to the call-site above) 1220 1221 void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1222 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1223 if (stub == NULL) { 1224 ciEnv::current()->record_out_of_memory_failure(); 1225 } 1226 } 1227 1228 //============================================================================= 1229 1230 // Emit an inline branch-and-link call and a related trampoline stub. 1231 // 1232 // code sequences: 1233 // 1234 // call-site: 1235 // branch-and-link to <destination> or <trampoline stub> 1236 // 1237 // Related trampoline stub for this call-site in the stub section: 1238 // load the call target from the constant pool 1239 // branch via CTR (LR/link still points to the call-site above) 1240 // 1241 1242 typedef struct { 1243 int insts_call_instruction_offset; 1244 int ret_addr_offset; 1245 } EmitCallOffsets; 1246 1247 // Emit a branch-and-link instruction that branches to a trampoline. 1248 // - Remember the offset of the branch-and-link instruction. 1249 // - Add a relocation at the branch-and-link instruction. 1250 // - Emit a branch-and-link. 1251 // - Remember the return pc offset. 1252 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1253 EmitCallOffsets offsets = { -1, -1 }; 1254 const int start_offset = __ offset(); 1255 offsets.insts_call_instruction_offset = __ offset(); 1256 1257 // No entry point given, use the current pc. 1258 if (entry_point == NULL) entry_point = __ pc(); 1259 1260 // Put the entry point as a constant into the constant pool. 1261 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1262 if (entry_point_toc_addr == NULL) { 1263 ciEnv::current()->record_out_of_memory_failure(); 1264 return offsets; 1265 } 1266 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1267 1268 // Emit the trampoline stub which will be related to the branch-and-link below. 1269 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1270 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1271 __ relocate(rtype); 1272 1273 // Note: At this point we do not have the address of the trampoline 1274 // stub, and the entry point might be too far away for bl, so __ pc() 1275 // serves as dummy and the bl will be patched later. 1276 __ bl((address) __ pc()); 1277 1278 offsets.ret_addr_offset = __ offset() - start_offset; 1279 1280 return offsets; 1281 } 1282 1283 //============================================================================= 1284 1285 // Factory for creating loadConL* nodes for large/small constant pool. 1286 1287 static inline jlong replicate_immF(float con) { 1288 // Replicate float con 2 times and pack into vector. 1289 int val = *((int*)&con); 1290 jlong lval = val; 1291 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1292 return lval; 1293 } 1294 1295 //============================================================================= 1296 1297 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1298 int Compile::ConstantTable::calculate_table_base_offset() const { 1299 return 0; // absolute addressing, no offset 1300 } 1301 1302 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1303 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1304 iRegPdstOper *op_dst = new iRegPdstOper(); 1305 MachNode *m1 = new loadToc_hiNode(); 1306 MachNode *m2 = new loadToc_loNode(); 1307 1308 m1->add_req(NULL); 1309 m2->add_req(NULL, m1); 1310 m1->_opnds[0] = op_dst; 1311 m2->_opnds[0] = op_dst; 1312 m2->_opnds[1] = op_dst; 1313 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1314 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1315 nodes->push(m1); 1316 nodes->push(m2); 1317 } 1318 1319 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1320 // Is postalloc expanded. 1321 ShouldNotReachHere(); 1322 } 1323 1324 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1325 return 0; 1326 } 1327 1328 #ifndef PRODUCT 1329 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1330 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1331 } 1332 #endif 1333 1334 //============================================================================= 1335 1336 #ifndef PRODUCT 1337 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1338 Compile* C = ra_->C; 1339 const long framesize = C->frame_slots() << LogBytesPerInt; 1340 1341 st->print("PROLOG\n\t"); 1342 if (C->need_stack_bang(framesize)) { 1343 st->print("stack_overflow_check\n\t"); 1344 } 1345 1346 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1347 st->print("save return pc\n\t"); 1348 st->print("push frame %ld\n\t", -framesize); 1349 } 1350 } 1351 #endif 1352 1353 // Macro used instead of the common __ to emulate the pipes of PPC. 1354 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1355 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1356 // still no scheduling of this code is possible, the micro scheduler is aware of the 1357 // code and can update its internal data. The following mechanism is used to achieve this: 1358 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1359 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1360 #if 0 // TODO: PPC port 1361 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1362 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1363 _masm. 1364 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1365 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1366 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1367 C->hb_scheduling()->_pdScheduling->advance_offset 1368 #else 1369 #define ___(op) if (UsePower6SchedulerPPC64) \ 1370 Unimplemented(); \ 1371 _masm. 1372 #define ___stop if (UsePower6SchedulerPPC64) \ 1373 Unimplemented() 1374 #define ___advance if (UsePower6SchedulerPPC64) \ 1375 Unimplemented() 1376 #endif 1377 1378 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1379 Compile* C = ra_->C; 1380 MacroAssembler _masm(&cbuf); 1381 1382 const long framesize = C->frame_size_in_bytes(); 1383 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1384 1385 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1386 1387 const Register return_pc = R20; // Must match return_addr() in frame section. 1388 const Register callers_sp = R21; 1389 const Register push_frame_temp = R22; 1390 const Register toc_temp = R23; 1391 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1392 1393 if (method_is_frameless) { 1394 // Add nop at beginning of all frameless methods to prevent any 1395 // oop instructions from getting overwritten by make_not_entrant 1396 // (patching attempt would fail). 1397 ___(nop) nop(); 1398 } else { 1399 // Get return pc. 1400 ___(mflr) mflr(return_pc); 1401 } 1402 1403 // Calls to C2R adapters often do not accept exceptional returns. 1404 // We require that their callers must bang for them. But be 1405 // careful, because some VM calls (such as call site linkage) can 1406 // use several kilobytes of stack. But the stack safety zone should 1407 // account for that. See bugs 4446381, 4468289, 4497237. 1408 1409 int bangsize = C->bang_size_in_bytes(); 1410 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1411 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1412 // Unfortunately we cannot use the function provided in 1413 // assembler.cpp as we have to emulate the pipes. So I had to 1414 // insert the code of generate_stack_overflow_check(), see 1415 // assembler.cpp for some illuminative comments. 1416 const int page_size = os::vm_page_size(); 1417 int bang_end = JavaThread::stack_shadow_zone_size(); 1418 1419 // This is how far the previous frame's stack banging extended. 1420 const int bang_end_safe = bang_end; 1421 1422 if (bangsize > page_size) { 1423 bang_end += bangsize; 1424 } 1425 1426 int bang_offset = bang_end_safe; 1427 1428 while (bang_offset <= bang_end) { 1429 // Need at least one stack bang at end of shadow zone. 1430 1431 // Again I had to copy code, this time from assembler_ppc.cpp, 1432 // bang_stack_with_offset - see there for comments. 1433 1434 // Stack grows down, caller passes positive offset. 1435 assert(bang_offset > 0, "must bang with positive offset"); 1436 1437 long stdoffset = -bang_offset; 1438 1439 if (Assembler::is_simm(stdoffset, 16)) { 1440 // Signed 16 bit offset, a simple std is ok. 1441 if (UseLoadInstructionsForStackBangingPPC64) { 1442 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1443 } else { 1444 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1445 } 1446 } else if (Assembler::is_simm(stdoffset, 31)) { 1447 // Use largeoffset calculations for addis & ld/std. 1448 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1449 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1450 1451 Register tmp = R11; 1452 ___(addis) addis(tmp, R1_SP, hi); 1453 if (UseLoadInstructionsForStackBangingPPC64) { 1454 ___(ld) ld(R0, lo, tmp); 1455 } else { 1456 ___(std) std(R0, lo, tmp); 1457 } 1458 } else { 1459 ShouldNotReachHere(); 1460 } 1461 1462 bang_offset += page_size; 1463 } 1464 // R11 trashed 1465 } // C->need_stack_bang(framesize) && UseStackBanging 1466 1467 unsigned int bytes = (unsigned int)framesize; 1468 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1469 ciMethod *currMethod = C->method(); 1470 1471 // Optimized version for most common case. 1472 if (UsePower6SchedulerPPC64 && 1473 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1474 !(false /* ConstantsALot TODO: PPC port*/)) { 1475 ___(or) mr(callers_sp, R1_SP); 1476 ___(std) std(return_pc, _abi(lr), R1_SP); 1477 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1478 return; 1479 } 1480 1481 if (!method_is_frameless) { 1482 // Get callers sp. 1483 ___(or) mr(callers_sp, R1_SP); 1484 1485 // Push method's frame, modifies SP. 1486 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1487 // The ABI is already accounted for in 'framesize' via the 1488 // 'out_preserve' area. 1489 Register tmp = push_frame_temp; 1490 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1491 if (Assembler::is_simm(-offset, 16)) { 1492 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1493 } else { 1494 long x = -offset; 1495 // Had to insert load_const(tmp, -offset). 1496 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1497 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1498 ___(rldicr) sldi(tmp, tmp, 32); 1499 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1500 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1501 1502 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1503 } 1504 } 1505 #if 0 // TODO: PPC port 1506 // For testing large constant pools, emit a lot of constants to constant pool. 1507 // "Randomize" const_size. 1508 if (ConstantsALot) { 1509 const int num_consts = const_size(); 1510 for (int i = 0; i < num_consts; i++) { 1511 __ long_constant(0xB0B5B00BBABE); 1512 } 1513 } 1514 #endif 1515 if (!method_is_frameless) { 1516 // Save return pc. 1517 ___(std) std(return_pc, _abi(lr), callers_sp); 1518 } 1519 1520 C->set_frame_complete(cbuf.insts_size()); 1521 } 1522 #undef ___ 1523 #undef ___stop 1524 #undef ___advance 1525 1526 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1527 // Variable size. determine dynamically. 1528 return MachNode::size(ra_); 1529 } 1530 1531 int MachPrologNode::reloc() const { 1532 // Return number of relocatable values contained in this instruction. 1533 return 1; // 1 reloc entry for load_const(toc). 1534 } 1535 1536 //============================================================================= 1537 1538 #ifndef PRODUCT 1539 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1540 Compile* C = ra_->C; 1541 1542 st->print("EPILOG\n\t"); 1543 st->print("restore return pc\n\t"); 1544 st->print("pop frame\n\t"); 1545 1546 if (do_polling() && C->is_method_compilation()) { 1547 st->print("touch polling page\n\t"); 1548 } 1549 } 1550 #endif 1551 1552 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1553 Compile* C = ra_->C; 1554 MacroAssembler _masm(&cbuf); 1555 1556 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1557 assert(framesize >= 0, "negative frame-size?"); 1558 1559 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1560 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1561 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1562 const Register polling_page = R12; 1563 1564 if (!method_is_frameless) { 1565 // Restore return pc relative to callers' sp. 1566 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1567 } 1568 1569 if (method_needs_polling) { 1570 if (SafepointMechanism::uses_thread_local_poll()) { 1571 __ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread); 1572 } else { 1573 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); 1574 } 1575 } 1576 1577 if (!method_is_frameless) { 1578 // Move return pc to LR. 1579 __ mtlr(return_pc); 1580 // Pop frame (fixed frame-size). 1581 __ addi(R1_SP, R1_SP, (int)framesize); 1582 } 1583 1584 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1585 __ reserved_stack_check(return_pc); 1586 } 1587 1588 if (method_needs_polling) { 1589 // We need to mark the code position where the load from the safepoint 1590 // polling page was emitted as relocInfo::poll_return_type here. 1591 __ relocate(relocInfo::poll_return_type); 1592 __ load_from_polling_page(polling_page); 1593 } 1594 } 1595 1596 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1597 // Variable size. Determine dynamically. 1598 return MachNode::size(ra_); 1599 } 1600 1601 int MachEpilogNode::reloc() const { 1602 // Return number of relocatable values contained in this instruction. 1603 return 1; // 1 for load_from_polling_page. 1604 } 1605 1606 const Pipeline * MachEpilogNode::pipeline() const { 1607 return MachNode::pipeline_class(); 1608 } 1609 1610 // This method seems to be obsolete. It is declared in machnode.hpp 1611 // and defined in all *.ad files, but it is never called. Should we 1612 // get rid of it? 1613 int MachEpilogNode::safepoint_offset() const { 1614 assert(do_polling(), "no return for this epilog node"); 1615 return 0; 1616 } 1617 1618 #if 0 // TODO: PPC port 1619 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1620 MacroAssembler _masm(&cbuf); 1621 if (LoadPollAddressFromThread) { 1622 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1623 } else { 1624 _masm.nop(); 1625 } 1626 } 1627 1628 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1629 if (LoadPollAddressFromThread) { 1630 return 4; 1631 } else { 1632 return 4; 1633 } 1634 } 1635 1636 #ifndef PRODUCT 1637 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1638 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1639 } 1640 #endif 1641 1642 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1643 return RSCRATCH1_BITS64_REG_mask(); 1644 } 1645 #endif // PPC port 1646 1647 // ============================================================================= 1648 1649 // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or 1650 // rc_stack. 1651 enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack }; 1652 1653 static enum RC rc_class(OptoReg::Name reg) { 1654 // Return the register class for the given register. The given register 1655 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1656 // enumeration in adGlobals_ppc.hpp. 1657 1658 if (reg == OptoReg::Bad) return rc_bad; 1659 1660 // We have 64 integer register halves, starting at index 0. 1661 if (reg < 64) return rc_int; 1662 1663 // We have 64 floating-point register halves, starting at index 64. 1664 if (reg < 64+64) return rc_float; 1665 1666 // We have 64 vector-scalar registers, starting at index 128. 1667 if (reg < 64+64+64) return rc_vs; 1668 1669 // Between float regs & stack are the flags regs. 1670 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1671 1672 return rc_stack; 1673 } 1674 1675 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1676 bool do_print, Compile* C, outputStream *st) { 1677 1678 assert(opcode == Assembler::LD_OPCODE || 1679 opcode == Assembler::STD_OPCODE || 1680 opcode == Assembler::LWZ_OPCODE || 1681 opcode == Assembler::STW_OPCODE || 1682 opcode == Assembler::LFD_OPCODE || 1683 opcode == Assembler::STFD_OPCODE || 1684 opcode == Assembler::LFS_OPCODE || 1685 opcode == Assembler::STFS_OPCODE, 1686 "opcode not supported"); 1687 1688 if (cbuf) { 1689 int d = 1690 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1691 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1692 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1693 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1694 } 1695 #ifndef PRODUCT 1696 else if (do_print) { 1697 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1698 op_str, 1699 Matcher::regName[reg], 1700 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1701 } 1702 #endif 1703 return 4; // size 1704 } 1705 1706 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1707 Compile* C = ra_->C; 1708 1709 // Get registers to move. 1710 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1711 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1712 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1713 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1714 1715 enum RC src_hi_rc = rc_class(src_hi); 1716 enum RC src_lo_rc = rc_class(src_lo); 1717 enum RC dst_hi_rc = rc_class(dst_hi); 1718 enum RC dst_lo_rc = rc_class(dst_lo); 1719 1720 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1721 if (src_hi != OptoReg::Bad) 1722 assert((src_lo&1)==0 && src_lo+1==src_hi && 1723 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1724 "expected aligned-adjacent pairs"); 1725 // Generate spill code! 1726 int size = 0; 1727 1728 if (src_lo == dst_lo && src_hi == dst_hi) 1729 return size; // Self copy, no move. 1730 1731 if (bottom_type()->isa_vect() != NULL && ideal_reg() == Op_VecX) { 1732 // Memory->Memory Spill. 1733 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1734 int src_offset = ra_->reg2offset(src_lo); 1735 int dst_offset = ra_->reg2offset(dst_lo); 1736 if (cbuf) { 1737 MacroAssembler _masm(cbuf); 1738 __ ld(R0, src_offset, R1_SP); 1739 __ std(R0, dst_offset, R1_SP); 1740 __ ld(R0, src_offset+8, R1_SP); 1741 __ std(R0, dst_offset+8, R1_SP); 1742 } 1743 size += 16; 1744 } 1745 // VectorSRegister->Memory Spill. 1746 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) { 1747 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1748 int dst_offset = ra_->reg2offset(dst_lo); 1749 if (cbuf) { 1750 MacroAssembler _masm(cbuf); 1751 __ addi(R0, R1_SP, dst_offset); 1752 __ stxvd2x(Rsrc, R0); 1753 } 1754 size += 8; 1755 } 1756 // Memory->VectorSRegister Spill. 1757 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) { 1758 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1759 int src_offset = ra_->reg2offset(src_lo); 1760 if (cbuf) { 1761 MacroAssembler _masm(cbuf); 1762 __ addi(R0, R1_SP, src_offset); 1763 __ lxvd2x(Rdst, R0); 1764 } 1765 size += 8; 1766 } 1767 // VectorSRegister->VectorSRegister. 1768 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) { 1769 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1770 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1771 if (cbuf) { 1772 MacroAssembler _masm(cbuf); 1773 __ xxlor(Rdst, Rsrc, Rsrc); 1774 } 1775 size += 4; 1776 } 1777 else { 1778 ShouldNotReachHere(); // No VSR spill. 1779 } 1780 return size; 1781 } 1782 1783 // -------------------------------------- 1784 // Memory->Memory Spill. Use R0 to hold the value. 1785 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1786 int src_offset = ra_->reg2offset(src_lo); 1787 int dst_offset = ra_->reg2offset(dst_lo); 1788 if (src_hi != OptoReg::Bad) { 1789 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1790 "expected same type of move for high parts"); 1791 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1792 if (!cbuf && !do_size) st->print("\n\t"); 1793 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1794 } else { 1795 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1796 if (!cbuf && !do_size) st->print("\n\t"); 1797 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1798 } 1799 return size; 1800 } 1801 1802 // -------------------------------------- 1803 // Check for float->int copy; requires a trip through memory. 1804 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1805 Unimplemented(); 1806 } 1807 1808 // -------------------------------------- 1809 // Check for integer reg-reg copy. 1810 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1811 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1812 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1813 size = (Rsrc != Rdst) ? 4 : 0; 1814 1815 if (cbuf) { 1816 MacroAssembler _masm(cbuf); 1817 if (size) { 1818 __ mr(Rdst, Rsrc); 1819 } 1820 } 1821 #ifndef PRODUCT 1822 else if (!do_size) { 1823 if (size) { 1824 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1825 } else { 1826 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1827 } 1828 } 1829 #endif 1830 return size; 1831 } 1832 1833 // Check for integer store. 1834 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1835 int dst_offset = ra_->reg2offset(dst_lo); 1836 if (src_hi != OptoReg::Bad) { 1837 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1838 "expected same type of move for high parts"); 1839 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1840 } else { 1841 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1842 } 1843 return size; 1844 } 1845 1846 // Check for integer load. 1847 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1848 int src_offset = ra_->reg2offset(src_lo); 1849 if (src_hi != OptoReg::Bad) { 1850 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1851 "expected same type of move for high parts"); 1852 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1853 } else { 1854 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1855 } 1856 return size; 1857 } 1858 1859 // Check for float reg-reg copy. 1860 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1861 if (cbuf) { 1862 MacroAssembler _masm(cbuf); 1863 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1864 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1865 __ fmr(Rdst, Rsrc); 1866 } 1867 #ifndef PRODUCT 1868 else if (!do_size) { 1869 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1870 } 1871 #endif 1872 return 4; 1873 } 1874 1875 // Check for float store. 1876 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1877 int dst_offset = ra_->reg2offset(dst_lo); 1878 if (src_hi != OptoReg::Bad) { 1879 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1880 "expected same type of move for high parts"); 1881 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1882 } else { 1883 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1884 } 1885 return size; 1886 } 1887 1888 // Check for float load. 1889 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1890 int src_offset = ra_->reg2offset(src_lo); 1891 if (src_hi != OptoReg::Bad) { 1892 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1893 "expected same type of move for high parts"); 1894 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1895 } else { 1896 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1897 } 1898 return size; 1899 } 1900 1901 // -------------------------------------------------------------------- 1902 // Check for hi bits still needing moving. Only happens for misaligned 1903 // arguments to native calls. 1904 if (src_hi == dst_hi) 1905 return size; // Self copy; no move. 1906 1907 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1908 ShouldNotReachHere(); // Unimplemented 1909 return 0; 1910 } 1911 1912 #ifndef PRODUCT 1913 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1914 if (!ra_) 1915 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1916 else 1917 implementation(NULL, ra_, false, st); 1918 } 1919 #endif 1920 1921 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1922 implementation(&cbuf, ra_, false, NULL); 1923 } 1924 1925 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1926 return implementation(NULL, ra_, true, NULL); 1927 } 1928 1929 #if 0 // TODO: PPC port 1930 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1931 #ifndef PRODUCT 1932 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1933 #endif 1934 assert(ra_->node_regs_max_index() != 0, ""); 1935 1936 // Get registers to move. 1937 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1938 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1939 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1940 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1941 1942 enum RC src_lo_rc = rc_class(src_lo); 1943 enum RC dst_lo_rc = rc_class(dst_lo); 1944 1945 if (src_lo == dst_lo && src_hi == dst_hi) 1946 return ppc64Opcode_none; // Self copy, no move. 1947 1948 // -------------------------------------- 1949 // Memory->Memory Spill. Use R0 to hold the value. 1950 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1951 return ppc64Opcode_compound; 1952 } 1953 1954 // -------------------------------------- 1955 // Check for float->int copy; requires a trip through memory. 1956 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1957 Unimplemented(); 1958 } 1959 1960 // -------------------------------------- 1961 // Check for integer reg-reg copy. 1962 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1963 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1964 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1965 if (Rsrc == Rdst) { 1966 return ppc64Opcode_none; 1967 } else { 1968 return ppc64Opcode_or; 1969 } 1970 } 1971 1972 // Check for integer store. 1973 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1974 if (src_hi != OptoReg::Bad) { 1975 return ppc64Opcode_std; 1976 } else { 1977 return ppc64Opcode_stw; 1978 } 1979 } 1980 1981 // Check for integer load. 1982 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1983 if (src_hi != OptoReg::Bad) { 1984 return ppc64Opcode_ld; 1985 } else { 1986 return ppc64Opcode_lwz; 1987 } 1988 } 1989 1990 // Check for float reg-reg copy. 1991 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1992 return ppc64Opcode_fmr; 1993 } 1994 1995 // Check for float store. 1996 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1997 if (src_hi != OptoReg::Bad) { 1998 return ppc64Opcode_stfd; 1999 } else { 2000 return ppc64Opcode_stfs; 2001 } 2002 } 2003 2004 // Check for float load. 2005 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 2006 if (src_hi != OptoReg::Bad) { 2007 return ppc64Opcode_lfd; 2008 } else { 2009 return ppc64Opcode_lfs; 2010 } 2011 } 2012 2013 // -------------------------------------------------------------------- 2014 // Check for hi bits still needing moving. Only happens for misaligned 2015 // arguments to native calls. 2016 if (src_hi == dst_hi) { 2017 return ppc64Opcode_none; // Self copy; no move. 2018 } 2019 2020 ShouldNotReachHere(); 2021 return ppc64Opcode_undefined; 2022 } 2023 #endif // PPC port 2024 2025 #ifndef PRODUCT 2026 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2027 st->print("NOP \t// %d nops to pad for loops.", _count); 2028 } 2029 #endif 2030 2031 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 2032 MacroAssembler _masm(&cbuf); 2033 // _count contains the number of nops needed for padding. 2034 for (int i = 0; i < _count; i++) { 2035 __ nop(); 2036 } 2037 } 2038 2039 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 2040 return _count * 4; 2041 } 2042 2043 #ifndef PRODUCT 2044 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2045 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2046 char reg_str[128]; 2047 ra_->dump_register(this, reg_str); 2048 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 2049 } 2050 #endif 2051 2052 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2053 MacroAssembler _masm(&cbuf); 2054 2055 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2056 int reg = ra_->get_encode(this); 2057 2058 if (Assembler::is_simm(offset, 16)) { 2059 __ addi(as_Register(reg), R1, offset); 2060 } else { 2061 ShouldNotReachHere(); 2062 } 2063 } 2064 2065 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2066 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2067 return 4; 2068 } 2069 2070 #ifndef PRODUCT 2071 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2072 st->print_cr("---- MachUEPNode ----"); 2073 st->print_cr("..."); 2074 } 2075 #endif 2076 2077 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2078 // This is the unverified entry point. 2079 MacroAssembler _masm(&cbuf); 2080 2081 // Inline_cache contains a klass. 2082 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 2083 Register receiver_klass = R12_scratch2; // tmp 2084 2085 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 2086 assert(R11_scratch1 == R11, "need prologue scratch register"); 2087 2088 // Check for NULL argument if we don't have implicit null checks. 2089 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 2090 if (TrapBasedNullChecks) { 2091 __ trap_null_check(R3_ARG1); 2092 } else { 2093 Label valid; 2094 __ cmpdi(CCR0, R3_ARG1, 0); 2095 __ bne_predict_taken(CCR0, valid); 2096 // We have a null argument, branch to ic_miss_stub. 2097 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2098 relocInfo::runtime_call_type); 2099 __ bind(valid); 2100 } 2101 } 2102 // Assume argument is not NULL, load klass from receiver. 2103 __ load_klass(receiver_klass, R3_ARG1); 2104 2105 if (TrapBasedICMissChecks) { 2106 __ trap_ic_miss_check(receiver_klass, ic_klass); 2107 } else { 2108 Label valid; 2109 __ cmpd(CCR0, receiver_klass, ic_klass); 2110 __ beq_predict_taken(CCR0, valid); 2111 // We have an unexpected klass, branch to ic_miss_stub. 2112 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2113 relocInfo::runtime_call_type); 2114 __ bind(valid); 2115 } 2116 2117 // Argument is valid and klass is as expected, continue. 2118 } 2119 2120 #if 0 // TODO: PPC port 2121 // Optimize UEP code on z (save a load_const() call in main path). 2122 int MachUEPNode::ep_offset() { 2123 return 0; 2124 } 2125 #endif 2126 2127 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2128 // Variable size. Determine dynamically. 2129 return MachNode::size(ra_); 2130 } 2131 2132 //============================================================================= 2133 2134 %} // interrupt source 2135 2136 source_hpp %{ // Header information of the source block. 2137 2138 class HandlerImpl { 2139 2140 public: 2141 2142 static int emit_exception_handler(CodeBuffer &cbuf); 2143 static int emit_deopt_handler(CodeBuffer& cbuf); 2144 2145 static uint size_exception_handler() { 2146 // The exception_handler is a b64_patchable. 2147 return MacroAssembler::b64_patchable_size; 2148 } 2149 2150 static uint size_deopt_handler() { 2151 // The deopt_handler is a bl64_patchable. 2152 return MacroAssembler::bl64_patchable_size; 2153 } 2154 2155 }; 2156 2157 %} // end source_hpp 2158 2159 source %{ 2160 2161 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2162 MacroAssembler _masm(&cbuf); 2163 2164 address base = __ start_a_stub(size_exception_handler()); 2165 if (base == NULL) return 0; // CodeBuffer::expand failed 2166 2167 int offset = __ offset(); 2168 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2169 relocInfo::runtime_call_type); 2170 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2171 __ end_a_stub(); 2172 2173 return offset; 2174 } 2175 2176 // The deopt_handler is like the exception handler, but it calls to 2177 // the deoptimization blob instead of jumping to the exception blob. 2178 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2179 MacroAssembler _masm(&cbuf); 2180 2181 address base = __ start_a_stub(size_deopt_handler()); 2182 if (base == NULL) return 0; // CodeBuffer::expand failed 2183 2184 int offset = __ offset(); 2185 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2186 relocInfo::runtime_call_type); 2187 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2188 __ end_a_stub(); 2189 2190 return offset; 2191 } 2192 2193 //============================================================================= 2194 2195 // Use a frame slots bias for frameless methods if accessing the stack. 2196 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2197 if (as_Register(reg_enc) == R1_SP) { 2198 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2199 } 2200 return 0; 2201 } 2202 2203 const bool Matcher::match_rule_supported(int opcode) { 2204 if (!has_match_rule(opcode)) 2205 return false; 2206 2207 switch (opcode) { 2208 case Op_SqrtD: 2209 return VM_Version::has_fsqrt(); 2210 case Op_CountLeadingZerosI: 2211 case Op_CountLeadingZerosL: 2212 if (!UseCountLeadingZerosInstructionsPPC64) 2213 return false; 2214 break; 2215 case Op_CountTrailingZerosI: 2216 case Op_CountTrailingZerosL: 2217 if (!UseCountLeadingZerosInstructionsPPC64 && 2218 !UseCountTrailingZerosInstructionsPPC64) 2219 return false; 2220 break; 2221 2222 case Op_PopCountI: 2223 case Op_PopCountL: 2224 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2225 2226 case Op_StrComp: 2227 return SpecialStringCompareTo; 2228 case Op_StrEquals: 2229 return SpecialStringEquals; 2230 case Op_StrIndexOf: 2231 return SpecialStringIndexOf; 2232 case Op_StrIndexOfChar: 2233 return SpecialStringIndexOf; 2234 } 2235 2236 return true; // Per default match rules are supported. 2237 } 2238 2239 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2240 2241 // TODO 2242 // identify extra cases that we might want to provide match rules for 2243 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2244 bool ret_value = match_rule_supported(opcode); 2245 // Add rules here. 2246 2247 return ret_value; // Per default match rules are supported. 2248 } 2249 2250 const bool Matcher::has_predicated_vectors(void) { 2251 return false; 2252 } 2253 2254 const int Matcher::float_pressure(int default_pressure_threshold) { 2255 return default_pressure_threshold; 2256 } 2257 2258 int Matcher::regnum_to_fpu_offset(int regnum) { 2259 // No user for this method? 2260 Unimplemented(); 2261 return 999; 2262 } 2263 2264 const bool Matcher::convL2FSupported(void) { 2265 // fcfids can do the conversion (>= Power7). 2266 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2267 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2268 } 2269 2270 // Vector width in bytes. 2271 const int Matcher::vector_width_in_bytes(BasicType bt) { 2272 if (SuperwordUseVSX) { 2273 assert(MaxVectorSize == 16, ""); 2274 return 16; 2275 } else { 2276 assert(MaxVectorSize == 8, ""); 2277 return 8; 2278 } 2279 } 2280 2281 // Vector ideal reg. 2282 const uint Matcher::vector_ideal_reg(int size) { 2283 if (SuperwordUseVSX) { 2284 assert(MaxVectorSize == 16 && size == 16, ""); 2285 return Op_VecX; 2286 } else { 2287 assert(MaxVectorSize == 8 && size == 8, ""); 2288 return Op_RegL; 2289 } 2290 } 2291 2292 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2293 fatal("vector shift is not supported"); 2294 return Node::NotAMachineReg; 2295 } 2296 2297 // Limits on vector size (number of elements) loaded into vector. 2298 const int Matcher::max_vector_size(const BasicType bt) { 2299 assert(is_java_primitive(bt), "only primitive type vectors"); 2300 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2301 } 2302 2303 const int Matcher::min_vector_size(const BasicType bt) { 2304 return max_vector_size(bt); // Same as max. 2305 } 2306 2307 // PPC doesn't support misaligned vectors store/load. 2308 const bool Matcher::misaligned_vectors_ok() { 2309 return !AlignVector; // can be changed by flag 2310 } 2311 2312 // PPC AES support not yet implemented 2313 const bool Matcher::pass_original_key_for_aes() { 2314 return false; 2315 } 2316 2317 // RETURNS: whether this branch offset is short enough that a short 2318 // branch can be used. 2319 // 2320 // If the platform does not provide any short branch variants, then 2321 // this method should return `false' for offset 0. 2322 // 2323 // `Compile::Fill_buffer' will decide on basis of this information 2324 // whether to do the pass `Compile::Shorten_branches' at all. 2325 // 2326 // And `Compile::Shorten_branches' will decide on basis of this 2327 // information whether to replace particular branch sites by short 2328 // ones. 2329 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2330 // Is the offset within the range of a ppc64 pc relative branch? 2331 bool b; 2332 2333 const int safety_zone = 3 * BytesPerInstWord; 2334 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2335 29 - 16 + 1 + 2); 2336 return b; 2337 } 2338 2339 const bool Matcher::isSimpleConstant64(jlong value) { 2340 // Probably always true, even if a temp register is required. 2341 return true; 2342 } 2343 /* TODO: PPC port 2344 // Make a new machine dependent decode node (with its operands). 2345 MachTypeNode *Matcher::make_decode_node() { 2346 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2347 "This method is only implemented for unscaled cOops mode so far"); 2348 MachTypeNode *decode = new decodeN_unscaledNode(); 2349 decode->set_opnd_array(0, new iRegPdstOper()); 2350 decode->set_opnd_array(1, new iRegNsrcOper()); 2351 return decode; 2352 } 2353 */ 2354 2355 // false => size gets scaled to BytesPerLong, ok. 2356 const bool Matcher::init_array_count_is_in_bytes = false; 2357 2358 // Use conditional move (CMOVL) on Power7. 2359 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2360 2361 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2362 // fsel doesn't accept a condition register as input, so this would be slightly different. 2363 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2364 2365 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2366 const bool Matcher::require_postalloc_expand = true; 2367 2368 // Do we need to mask the count passed to shift instructions or does 2369 // the cpu only look at the lower 5/6 bits anyway? 2370 // PowerPC requires masked shift counts. 2371 const bool Matcher::need_masked_shift_count = true; 2372 2373 // This affects two different things: 2374 // - how Decode nodes are matched 2375 // - how ImplicitNullCheck opportunities are recognized 2376 // If true, the matcher will try to remove all Decodes and match them 2377 // (as operands) into nodes. NullChecks are not prepared to deal with 2378 // Decodes by final_graph_reshaping(). 2379 // If false, final_graph_reshaping() forces the decode behind the Cmp 2380 // for a NullCheck. The matcher matches the Decode node into a register. 2381 // Implicit_null_check optimization moves the Decode along with the 2382 // memory operation back up before the NullCheck. 2383 bool Matcher::narrow_oop_use_complex_address() { 2384 // TODO: PPC port if (MatchDecodeNodes) return true; 2385 return false; 2386 } 2387 2388 bool Matcher::narrow_klass_use_complex_address() { 2389 NOT_LP64(ShouldNotCallThis()); 2390 assert(UseCompressedClassPointers, "only for compressed klass code"); 2391 // TODO: PPC port if (MatchDecodeNodes) return true; 2392 return false; 2393 } 2394 2395 bool Matcher::const_oop_prefer_decode() { 2396 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2397 return Universe::narrow_oop_base() == NULL; 2398 } 2399 2400 bool Matcher::const_klass_prefer_decode() { 2401 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2402 return Universe::narrow_klass_base() == NULL; 2403 } 2404 2405 // Is it better to copy float constants, or load them directly from memory? 2406 // Intel can load a float constant from a direct address, requiring no 2407 // extra registers. Most RISCs will have to materialize an address into a 2408 // register first, so they would do better to copy the constant from stack. 2409 const bool Matcher::rematerialize_float_constants = false; 2410 2411 // If CPU can load and store mis-aligned doubles directly then no fixup is 2412 // needed. Else we split the double into 2 integer pieces and move it 2413 // piece-by-piece. Only happens when passing doubles into C code as the 2414 // Java calling convention forces doubles to be aligned. 2415 const bool Matcher::misaligned_doubles_ok = true; 2416 2417 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2418 Unimplemented(); 2419 } 2420 2421 // Advertise here if the CPU requires explicit rounding operations 2422 // to implement the UseStrictFP mode. 2423 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2424 2425 // Do floats take an entire double register or just half? 2426 // 2427 // A float occupies a ppc64 double register. For the allocator, a 2428 // ppc64 double register appears as a pair of float registers. 2429 bool Matcher::float_in_double() { return true; } 2430 2431 // Do ints take an entire long register or just half? 2432 // The relevant question is how the int is callee-saved: 2433 // the whole long is written but de-opt'ing will have to extract 2434 // the relevant 32 bits. 2435 const bool Matcher::int_in_long = true; 2436 2437 // Constants for c2c and c calling conventions. 2438 2439 const MachRegisterNumbers iarg_reg[8] = { 2440 R3_num, R4_num, R5_num, R6_num, 2441 R7_num, R8_num, R9_num, R10_num 2442 }; 2443 2444 const MachRegisterNumbers farg_reg[13] = { 2445 F1_num, F2_num, F3_num, F4_num, 2446 F5_num, F6_num, F7_num, F8_num, 2447 F9_num, F10_num, F11_num, F12_num, 2448 F13_num 2449 }; 2450 2451 const MachRegisterNumbers vsarg_reg[64] = { 2452 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2453 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2454 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2455 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2456 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2457 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2458 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2459 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2460 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2461 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2462 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2463 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2464 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2465 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2466 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2467 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2468 }; 2469 2470 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2471 2472 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2473 2474 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2475 2476 // Return whether or not this register is ever used as an argument. This 2477 // function is used on startup to build the trampoline stubs in generateOptoStub. 2478 // Registers not mentioned will be killed by the VM call in the trampoline, and 2479 // arguments in those registers not be available to the callee. 2480 bool Matcher::can_be_java_arg(int reg) { 2481 // We return true for all registers contained in iarg_reg[] and 2482 // farg_reg[] and their virtual halves. 2483 // We must include the virtual halves in order to get STDs and LDs 2484 // instead of STWs and LWs in the trampoline stubs. 2485 2486 if ( reg == R3_num || reg == R3_H_num 2487 || reg == R4_num || reg == R4_H_num 2488 || reg == R5_num || reg == R5_H_num 2489 || reg == R6_num || reg == R6_H_num 2490 || reg == R7_num || reg == R7_H_num 2491 || reg == R8_num || reg == R8_H_num 2492 || reg == R9_num || reg == R9_H_num 2493 || reg == R10_num || reg == R10_H_num) 2494 return true; 2495 2496 if ( reg == F1_num || reg == F1_H_num 2497 || reg == F2_num || reg == F2_H_num 2498 || reg == F3_num || reg == F3_H_num 2499 || reg == F4_num || reg == F4_H_num 2500 || reg == F5_num || reg == F5_H_num 2501 || reg == F6_num || reg == F6_H_num 2502 || reg == F7_num || reg == F7_H_num 2503 || reg == F8_num || reg == F8_H_num 2504 || reg == F9_num || reg == F9_H_num 2505 || reg == F10_num || reg == F10_H_num 2506 || reg == F11_num || reg == F11_H_num 2507 || reg == F12_num || reg == F12_H_num 2508 || reg == F13_num || reg == F13_H_num) 2509 return true; 2510 2511 return false; 2512 } 2513 2514 bool Matcher::is_spillable_arg(int reg) { 2515 return can_be_java_arg(reg); 2516 } 2517 2518 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2519 return false; 2520 } 2521 2522 // Register for DIVI projection of divmodI. 2523 RegMask Matcher::divI_proj_mask() { 2524 ShouldNotReachHere(); 2525 return RegMask(); 2526 } 2527 2528 // Register for MODI projection of divmodI. 2529 RegMask Matcher::modI_proj_mask() { 2530 ShouldNotReachHere(); 2531 return RegMask(); 2532 } 2533 2534 // Register for DIVL projection of divmodL. 2535 RegMask Matcher::divL_proj_mask() { 2536 ShouldNotReachHere(); 2537 return RegMask(); 2538 } 2539 2540 // Register for MODL projection of divmodL. 2541 RegMask Matcher::modL_proj_mask() { 2542 ShouldNotReachHere(); 2543 return RegMask(); 2544 } 2545 2546 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2547 return RegMask(); 2548 } 2549 2550 const bool Matcher::convi2l_type_required = true; 2551 2552 %} 2553 2554 //----------ENCODING BLOCK----------------------------------------------------- 2555 // This block specifies the encoding classes used by the compiler to output 2556 // byte streams. Encoding classes are parameterized macros used by 2557 // Machine Instruction Nodes in order to generate the bit encoding of the 2558 // instruction. Operands specify their base encoding interface with the 2559 // interface keyword. There are currently supported four interfaces, 2560 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2561 // operand to generate a function which returns its register number when 2562 // queried. CONST_INTER causes an operand to generate a function which 2563 // returns the value of the constant when queried. MEMORY_INTER causes an 2564 // operand to generate four functions which return the Base Register, the 2565 // Index Register, the Scale Value, and the Offset Value of the operand when 2566 // queried. COND_INTER causes an operand to generate six functions which 2567 // return the encoding code (ie - encoding bits for the instruction) 2568 // associated with each basic boolean condition for a conditional instruction. 2569 // 2570 // Instructions specify two basic values for encoding. Again, a function 2571 // is available to check if the constant displacement is an oop. They use the 2572 // ins_encode keyword to specify their encoding classes (which must be 2573 // a sequence of enc_class names, and their parameters, specified in 2574 // the encoding block), and they use the 2575 // opcode keyword to specify, in order, their primary, secondary, and 2576 // tertiary opcode. Only the opcode sections which a particular instruction 2577 // needs for encoding need to be specified. 2578 encode %{ 2579 enc_class enc_unimplemented %{ 2580 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2581 MacroAssembler _masm(&cbuf); 2582 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2583 %} 2584 2585 enc_class enc_untested %{ 2586 #ifdef ASSERT 2587 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2588 MacroAssembler _masm(&cbuf); 2589 __ untested("Untested mach node encoding in AD file."); 2590 #else 2591 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2592 #endif 2593 %} 2594 2595 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2596 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2597 MacroAssembler _masm(&cbuf); 2598 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2599 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2600 %} 2601 2602 // Load acquire. 2603 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2604 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2605 MacroAssembler _masm(&cbuf); 2606 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2607 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2608 __ twi_0($dst$$Register); 2609 __ isync(); 2610 %} 2611 2612 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2613 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2614 2615 MacroAssembler _masm(&cbuf); 2616 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2617 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2618 %} 2619 2620 // Load acquire. 2621 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2622 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2623 2624 MacroAssembler _masm(&cbuf); 2625 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2626 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2627 __ twi_0($dst$$Register); 2628 __ isync(); 2629 %} 2630 2631 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2632 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2633 2634 MacroAssembler _masm(&cbuf); 2635 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2636 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2637 %} 2638 2639 // Load acquire. 2640 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2641 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2642 2643 MacroAssembler _masm(&cbuf); 2644 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2645 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2646 __ twi_0($dst$$Register); 2647 __ isync(); 2648 %} 2649 2650 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2651 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2652 MacroAssembler _masm(&cbuf); 2653 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2654 // Operand 'ds' requires 4-alignment. 2655 assert((Idisp & 0x3) == 0, "unaligned offset"); 2656 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2657 %} 2658 2659 // Load acquire. 2660 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2661 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2662 MacroAssembler _masm(&cbuf); 2663 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2664 // Operand 'ds' requires 4-alignment. 2665 assert((Idisp & 0x3) == 0, "unaligned offset"); 2666 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2667 __ twi_0($dst$$Register); 2668 __ isync(); 2669 %} 2670 2671 enc_class enc_lfd(RegF dst, memory mem) %{ 2672 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2673 MacroAssembler _masm(&cbuf); 2674 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2675 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2676 %} 2677 2678 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2679 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2680 2681 MacroAssembler _masm(&cbuf); 2682 int toc_offset = 0; 2683 2684 address const_toc_addr; 2685 // Create a non-oop constant, no relocation needed. 2686 // If it is an IC, it has a virtual_call_Relocation. 2687 const_toc_addr = __ long_constant((jlong)$src$$constant); 2688 if (const_toc_addr == NULL) { 2689 ciEnv::current()->record_out_of_memory_failure(); 2690 return; 2691 } 2692 2693 // Get the constant's TOC offset. 2694 toc_offset = __ offset_to_method_toc(const_toc_addr); 2695 2696 // Keep the current instruction offset in mind. 2697 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2698 2699 __ ld($dst$$Register, toc_offset, $toc$$Register); 2700 %} 2701 2702 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2703 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2704 2705 MacroAssembler _masm(&cbuf); 2706 2707 if (!ra_->C->in_scratch_emit_size()) { 2708 address const_toc_addr; 2709 // Create a non-oop constant, no relocation needed. 2710 // If it is an IC, it has a virtual_call_Relocation. 2711 const_toc_addr = __ long_constant((jlong)$src$$constant); 2712 if (const_toc_addr == NULL) { 2713 ciEnv::current()->record_out_of_memory_failure(); 2714 return; 2715 } 2716 2717 // Get the constant's TOC offset. 2718 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2719 // Store the toc offset of the constant. 2720 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2721 2722 // Also keep the current instruction offset in mind. 2723 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2724 } 2725 2726 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2727 %} 2728 2729 %} // encode 2730 2731 source %{ 2732 2733 typedef struct { 2734 loadConL_hiNode *_large_hi; 2735 loadConL_loNode *_large_lo; 2736 loadConLNode *_small; 2737 MachNode *_last; 2738 } loadConLNodesTuple; 2739 2740 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2741 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2742 loadConLNodesTuple nodes; 2743 2744 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2745 if (large_constant_pool) { 2746 // Create new nodes. 2747 loadConL_hiNode *m1 = new loadConL_hiNode(); 2748 loadConL_loNode *m2 = new loadConL_loNode(); 2749 2750 // inputs for new nodes 2751 m1->add_req(NULL, toc); 2752 m2->add_req(NULL, m1); 2753 2754 // operands for new nodes 2755 m1->_opnds[0] = new iRegLdstOper(); // dst 2756 m1->_opnds[1] = immSrc; // src 2757 m1->_opnds[2] = new iRegPdstOper(); // toc 2758 m2->_opnds[0] = new iRegLdstOper(); // dst 2759 m2->_opnds[1] = immSrc; // src 2760 m2->_opnds[2] = new iRegLdstOper(); // base 2761 2762 // Initialize ins_attrib TOC fields. 2763 m1->_const_toc_offset = -1; 2764 m2->_const_toc_offset_hi_node = m1; 2765 2766 // Initialize ins_attrib instruction offset. 2767 m1->_cbuf_insts_offset = -1; 2768 2769 // register allocation for new nodes 2770 ra_->set_pair(m1->_idx, reg_second, reg_first); 2771 ra_->set_pair(m2->_idx, reg_second, reg_first); 2772 2773 // Create result. 2774 nodes._large_hi = m1; 2775 nodes._large_lo = m2; 2776 nodes._small = NULL; 2777 nodes._last = nodes._large_lo; 2778 assert(m2->bottom_type()->isa_long(), "must be long"); 2779 } else { 2780 loadConLNode *m2 = new loadConLNode(); 2781 2782 // inputs for new nodes 2783 m2->add_req(NULL, toc); 2784 2785 // operands for new nodes 2786 m2->_opnds[0] = new iRegLdstOper(); // dst 2787 m2->_opnds[1] = immSrc; // src 2788 m2->_opnds[2] = new iRegPdstOper(); // toc 2789 2790 // Initialize ins_attrib instruction offset. 2791 m2->_cbuf_insts_offset = -1; 2792 2793 // register allocation for new nodes 2794 ra_->set_pair(m2->_idx, reg_second, reg_first); 2795 2796 // Create result. 2797 nodes._large_hi = NULL; 2798 nodes._large_lo = NULL; 2799 nodes._small = m2; 2800 nodes._last = nodes._small; 2801 assert(m2->bottom_type()->isa_long(), "must be long"); 2802 } 2803 2804 return nodes; 2805 } 2806 2807 typedef struct { 2808 loadConL_hiNode *_large_hi; 2809 loadConL_loNode *_large_lo; 2810 mtvsrdNode *_moved; 2811 xxspltdNode *_replicated; 2812 loadConLNode *_small; 2813 MachNode *_last; 2814 } loadConLReplicatedNodesTuple; 2815 2816 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2817 vecXOper *dst, immI_0Oper *zero, 2818 OptoReg::Name reg_second, OptoReg::Name reg_first, 2819 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2820 loadConLReplicatedNodesTuple nodes; 2821 2822 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2823 if (large_constant_pool) { 2824 // Create new nodes. 2825 loadConL_hiNode *m1 = new loadConL_hiNode(); 2826 loadConL_loNode *m2 = new loadConL_loNode(); 2827 mtvsrdNode *m3 = new mtvsrdNode(); 2828 xxspltdNode *m4 = new xxspltdNode(); 2829 2830 // inputs for new nodes 2831 m1->add_req(NULL, toc); 2832 m2->add_req(NULL, m1); 2833 m3->add_req(NULL, m2); 2834 m4->add_req(NULL, m3); 2835 2836 // operands for new nodes 2837 m1->_opnds[0] = new iRegLdstOper(); // dst 2838 m1->_opnds[1] = immSrc; // src 2839 m1->_opnds[2] = new iRegPdstOper(); // toc 2840 2841 m2->_opnds[0] = new iRegLdstOper(); // dst 2842 m2->_opnds[1] = immSrc; // src 2843 m2->_opnds[2] = new iRegLdstOper(); // base 2844 2845 m3->_opnds[0] = new vecXOper(); // dst 2846 m3->_opnds[1] = new iRegLdstOper(); // src 2847 2848 m4->_opnds[0] = new vecXOper(); // dst 2849 m4->_opnds[1] = new vecXOper(); // src 2850 m4->_opnds[2] = zero; 2851 2852 // Initialize ins_attrib TOC fields. 2853 m1->_const_toc_offset = -1; 2854 m2->_const_toc_offset_hi_node = m1; 2855 2856 // Initialize ins_attrib instruction offset. 2857 m1->_cbuf_insts_offset = -1; 2858 2859 // register allocation for new nodes 2860 ra_->set_pair(m1->_idx, reg_second, reg_first); 2861 ra_->set_pair(m2->_idx, reg_second, reg_first); 2862 ra_->set1(m3->_idx, reg_second); 2863 ra_->set2(m3->_idx, reg_vec_first); 2864 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2865 2866 // Create result. 2867 nodes._large_hi = m1; 2868 nodes._large_lo = m2; 2869 nodes._moved = m3; 2870 nodes._replicated = m4; 2871 nodes._small = NULL; 2872 nodes._last = nodes._replicated; 2873 assert(m2->bottom_type()->isa_long(), "must be long"); 2874 } else { 2875 loadConLNode *m2 = new loadConLNode(); 2876 mtvsrdNode *m3 = new mtvsrdNode(); 2877 xxspltdNode *m4 = new xxspltdNode(); 2878 2879 // inputs for new nodes 2880 m2->add_req(NULL, toc); 2881 2882 // operands for new nodes 2883 m2->_opnds[0] = new iRegLdstOper(); // dst 2884 m2->_opnds[1] = immSrc; // src 2885 m2->_opnds[2] = new iRegPdstOper(); // toc 2886 2887 m3->_opnds[0] = new vecXOper(); // dst 2888 m3->_opnds[1] = new iRegLdstOper(); // src 2889 2890 m4->_opnds[0] = new vecXOper(); // dst 2891 m4->_opnds[1] = new vecXOper(); // src 2892 m4->_opnds[2] = zero; 2893 2894 // Initialize ins_attrib instruction offset. 2895 m2->_cbuf_insts_offset = -1; 2896 ra_->set1(m3->_idx, reg_second); 2897 ra_->set2(m3->_idx, reg_vec_first); 2898 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2899 2900 // register allocation for new nodes 2901 ra_->set_pair(m2->_idx, reg_second, reg_first); 2902 2903 // Create result. 2904 nodes._large_hi = NULL; 2905 nodes._large_lo = NULL; 2906 nodes._small = m2; 2907 nodes._moved = m3; 2908 nodes._replicated = m4; 2909 nodes._last = nodes._replicated; 2910 assert(m2->bottom_type()->isa_long(), "must be long"); 2911 } 2912 2913 return nodes; 2914 } 2915 2916 %} // source 2917 2918 encode %{ 2919 // Postalloc expand emitter for loading a long constant from the method's TOC. 2920 // Enc_class needed as consttanttablebase is not supported by postalloc 2921 // expand. 2922 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2923 // Create new nodes. 2924 loadConLNodesTuple loadConLNodes = 2925 loadConLNodesTuple_create(ra_, n_toc, op_src, 2926 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2927 2928 // Push new nodes. 2929 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2930 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2931 2932 // some asserts 2933 assert(nodes->length() >= 1, "must have created at least 1 node"); 2934 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2935 %} 2936 2937 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2938 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2939 2940 MacroAssembler _masm(&cbuf); 2941 int toc_offset = 0; 2942 2943 intptr_t val = $src$$constant; 2944 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2945 address const_toc_addr; 2946 if (constant_reloc == relocInfo::oop_type) { 2947 // Create an oop constant and a corresponding relocation. 2948 AddressLiteral a = __ allocate_oop_address((jobject)val); 2949 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2950 __ relocate(a.rspec()); 2951 } else if (constant_reloc == relocInfo::metadata_type) { 2952 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2953 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2954 __ relocate(a.rspec()); 2955 } else { 2956 // Create a non-oop constant, no relocation needed. 2957 const_toc_addr = __ long_constant((jlong)$src$$constant); 2958 } 2959 2960 if (const_toc_addr == NULL) { 2961 ciEnv::current()->record_out_of_memory_failure(); 2962 return; 2963 } 2964 // Get the constant's TOC offset. 2965 toc_offset = __ offset_to_method_toc(const_toc_addr); 2966 2967 __ ld($dst$$Register, toc_offset, $toc$$Register); 2968 %} 2969 2970 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2971 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2972 2973 MacroAssembler _masm(&cbuf); 2974 if (!ra_->C->in_scratch_emit_size()) { 2975 intptr_t val = $src$$constant; 2976 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2977 address const_toc_addr; 2978 if (constant_reloc == relocInfo::oop_type) { 2979 // Create an oop constant and a corresponding relocation. 2980 AddressLiteral a = __ allocate_oop_address((jobject)val); 2981 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2982 __ relocate(a.rspec()); 2983 } else if (constant_reloc == relocInfo::metadata_type) { 2984 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2985 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2986 __ relocate(a.rspec()); 2987 } else { // non-oop pointers, e.g. card mark base, heap top 2988 // Create a non-oop constant, no relocation needed. 2989 const_toc_addr = __ long_constant((jlong)$src$$constant); 2990 } 2991 2992 if (const_toc_addr == NULL) { 2993 ciEnv::current()->record_out_of_memory_failure(); 2994 return; 2995 } 2996 // Get the constant's TOC offset. 2997 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2998 // Store the toc offset of the constant. 2999 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 3000 } 3001 3002 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 3003 %} 3004 3005 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 3006 // Enc_class needed as consttanttablebase is not supported by postalloc 3007 // expand. 3008 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 3009 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3010 if (large_constant_pool) { 3011 // Create new nodes. 3012 loadConP_hiNode *m1 = new loadConP_hiNode(); 3013 loadConP_loNode *m2 = new loadConP_loNode(); 3014 3015 // inputs for new nodes 3016 m1->add_req(NULL, n_toc); 3017 m2->add_req(NULL, m1); 3018 3019 // operands for new nodes 3020 m1->_opnds[0] = new iRegPdstOper(); // dst 3021 m1->_opnds[1] = op_src; // src 3022 m1->_opnds[2] = new iRegPdstOper(); // toc 3023 m2->_opnds[0] = new iRegPdstOper(); // dst 3024 m2->_opnds[1] = op_src; // src 3025 m2->_opnds[2] = new iRegLdstOper(); // base 3026 3027 // Initialize ins_attrib TOC fields. 3028 m1->_const_toc_offset = -1; 3029 m2->_const_toc_offset_hi_node = m1; 3030 3031 // Register allocation for new nodes. 3032 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3033 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3034 3035 nodes->push(m1); 3036 nodes->push(m2); 3037 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3038 } else { 3039 loadConPNode *m2 = new loadConPNode(); 3040 3041 // inputs for new nodes 3042 m2->add_req(NULL, n_toc); 3043 3044 // operands for new nodes 3045 m2->_opnds[0] = new iRegPdstOper(); // dst 3046 m2->_opnds[1] = op_src; // src 3047 m2->_opnds[2] = new iRegPdstOper(); // toc 3048 3049 // Register allocation for new nodes. 3050 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3051 3052 nodes->push(m2); 3053 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3054 } 3055 %} 3056 3057 // Enc_class needed as consttanttablebase is not supported by postalloc 3058 // expand. 3059 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3060 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3061 3062 MachNode *m2; 3063 if (large_constant_pool) { 3064 m2 = new loadConFCompNode(); 3065 } else { 3066 m2 = new loadConFNode(); 3067 } 3068 // inputs for new nodes 3069 m2->add_req(NULL, n_toc); 3070 3071 // operands for new nodes 3072 m2->_opnds[0] = op_dst; 3073 m2->_opnds[1] = op_src; 3074 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3075 3076 // register allocation for new nodes 3077 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3078 nodes->push(m2); 3079 %} 3080 3081 // Enc_class needed as consttanttablebase is not supported by postalloc 3082 // expand. 3083 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3084 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3085 3086 MachNode *m2; 3087 if (large_constant_pool) { 3088 m2 = new loadConDCompNode(); 3089 } else { 3090 m2 = new loadConDNode(); 3091 } 3092 // inputs for new nodes 3093 m2->add_req(NULL, n_toc); 3094 3095 // operands for new nodes 3096 m2->_opnds[0] = op_dst; 3097 m2->_opnds[1] = op_src; 3098 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3099 3100 // register allocation for new nodes 3101 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3102 nodes->push(m2); 3103 %} 3104 3105 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3106 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3107 MacroAssembler _masm(&cbuf); 3108 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3109 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3110 %} 3111 3112 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3113 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3114 MacroAssembler _masm(&cbuf); 3115 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3116 // Operand 'ds' requires 4-alignment. 3117 assert((Idisp & 0x3) == 0, "unaligned offset"); 3118 __ std($src$$Register, Idisp, $mem$$base$$Register); 3119 %} 3120 3121 enc_class enc_stfs(RegF src, memory mem) %{ 3122 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3123 MacroAssembler _masm(&cbuf); 3124 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3125 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3126 %} 3127 3128 enc_class enc_stfd(RegF src, memory mem) %{ 3129 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3130 MacroAssembler _masm(&cbuf); 3131 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3132 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3133 %} 3134 3135 // Use release_store for card-marking to ensure that previous 3136 // oop-stores are visible before the card-mark change. 3137 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3138 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3139 // FIXME: Implement this as a cmove and use a fixed condition code 3140 // register which is written on every transition to compiled code, 3141 // e.g. in call-stub and when returning from runtime stubs. 3142 // 3143 // Proposed code sequence for the cmove implementation: 3144 // 3145 // Label skip_release; 3146 // __ beq(CCRfixed, skip_release); 3147 // __ release(); 3148 // __ bind(skip_release); 3149 // __ stb(card mark); 3150 3151 MacroAssembler _masm(&cbuf); 3152 Label skip_storestore; 3153 3154 #if 0 // TODO: PPC port 3155 // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the 3156 // StoreStore barrier conditionally. 3157 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3158 __ cmpwi($crx$$CondRegister, R0, 0); 3159 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3160 #endif 3161 __ li(R0, 0); 3162 __ membar(Assembler::StoreStore); 3163 #if 0 // TODO: PPC port 3164 __ bind(skip_storestore); 3165 #endif 3166 3167 // Do the store. 3168 if ($mem$$index == 0) { 3169 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3170 } else { 3171 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3172 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3173 } 3174 %} 3175 3176 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3177 3178 if (VM_Version::has_isel()) { 3179 // use isel instruction with Power 7 3180 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3181 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3182 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3183 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3184 3185 n_compare->add_req(n_region, n_src); 3186 n_compare->_opnds[0] = op_crx; 3187 n_compare->_opnds[1] = op_src; 3188 n_compare->_opnds[2] = new immL16Oper(0); 3189 3190 n_sub_base->add_req(n_region, n_src); 3191 n_sub_base->_opnds[0] = op_dst; 3192 n_sub_base->_opnds[1] = op_src; 3193 n_sub_base->_bottom_type = _bottom_type; 3194 3195 n_shift->add_req(n_region, n_sub_base); 3196 n_shift->_opnds[0] = op_dst; 3197 n_shift->_opnds[1] = op_dst; 3198 n_shift->_bottom_type = _bottom_type; 3199 3200 n_cond_set->add_req(n_region, n_compare, n_shift); 3201 n_cond_set->_opnds[0] = op_dst; 3202 n_cond_set->_opnds[1] = op_crx; 3203 n_cond_set->_opnds[2] = op_dst; 3204 n_cond_set->_bottom_type = _bottom_type; 3205 3206 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3207 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3208 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3209 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3210 3211 nodes->push(n_compare); 3212 nodes->push(n_sub_base); 3213 nodes->push(n_shift); 3214 nodes->push(n_cond_set); 3215 3216 } else { 3217 // before Power 7 3218 moveRegNode *n_move = new moveRegNode(); 3219 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3220 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3221 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3222 3223 n_move->add_req(n_region, n_src); 3224 n_move->_opnds[0] = op_dst; 3225 n_move->_opnds[1] = op_src; 3226 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3227 3228 n_compare->add_req(n_region, n_src); 3229 n_compare->add_prec(n_move); 3230 3231 n_compare->_opnds[0] = op_crx; 3232 n_compare->_opnds[1] = op_src; 3233 n_compare->_opnds[2] = new immL16Oper(0); 3234 3235 n_sub_base->add_req(n_region, n_compare, n_src); 3236 n_sub_base->_opnds[0] = op_dst; 3237 n_sub_base->_opnds[1] = op_crx; 3238 n_sub_base->_opnds[2] = op_src; 3239 n_sub_base->_bottom_type = _bottom_type; 3240 3241 n_shift->add_req(n_region, n_sub_base); 3242 n_shift->_opnds[0] = op_dst; 3243 n_shift->_opnds[1] = op_dst; 3244 n_shift->_bottom_type = _bottom_type; 3245 3246 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3247 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3248 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3249 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3250 3251 nodes->push(n_move); 3252 nodes->push(n_compare); 3253 nodes->push(n_sub_base); 3254 nodes->push(n_shift); 3255 } 3256 3257 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3258 %} 3259 3260 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3261 3262 encodeP_subNode *n1 = new encodeP_subNode(); 3263 n1->add_req(n_region, n_src); 3264 n1->_opnds[0] = op_dst; 3265 n1->_opnds[1] = op_src; 3266 n1->_bottom_type = _bottom_type; 3267 3268 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3269 n2->add_req(n_region, n1); 3270 n2->_opnds[0] = op_dst; 3271 n2->_opnds[1] = op_dst; 3272 n2->_bottom_type = _bottom_type; 3273 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3274 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3275 3276 nodes->push(n1); 3277 nodes->push(n2); 3278 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3279 %} 3280 3281 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3282 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3283 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3284 3285 n_compare->add_req(n_region, n_src); 3286 n_compare->_opnds[0] = op_crx; 3287 n_compare->_opnds[1] = op_src; 3288 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3289 3290 n_shift->add_req(n_region, n_src); 3291 n_shift->_opnds[0] = op_dst; 3292 n_shift->_opnds[1] = op_src; 3293 n_shift->_bottom_type = _bottom_type; 3294 3295 if (VM_Version::has_isel()) { 3296 // use isel instruction with Power 7 3297 3298 decodeN_addNode *n_add_base = new decodeN_addNode(); 3299 n_add_base->add_req(n_region, n_shift); 3300 n_add_base->_opnds[0] = op_dst; 3301 n_add_base->_opnds[1] = op_dst; 3302 n_add_base->_bottom_type = _bottom_type; 3303 3304 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3305 n_cond_set->add_req(n_region, n_compare, n_add_base); 3306 n_cond_set->_opnds[0] = op_dst; 3307 n_cond_set->_opnds[1] = op_crx; 3308 n_cond_set->_opnds[2] = op_dst; 3309 n_cond_set->_bottom_type = _bottom_type; 3310 3311 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3312 ra_->set_oop(n_cond_set, true); 3313 3314 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3315 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3316 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3317 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3318 3319 nodes->push(n_compare); 3320 nodes->push(n_shift); 3321 nodes->push(n_add_base); 3322 nodes->push(n_cond_set); 3323 3324 } else { 3325 // before Power 7 3326 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3327 3328 n_add_base->add_req(n_region, n_compare, n_shift); 3329 n_add_base->_opnds[0] = op_dst; 3330 n_add_base->_opnds[1] = op_crx; 3331 n_add_base->_opnds[2] = op_dst; 3332 n_add_base->_bottom_type = _bottom_type; 3333 3334 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3335 ra_->set_oop(n_add_base, true); 3336 3337 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3338 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3339 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3340 3341 nodes->push(n_compare); 3342 nodes->push(n_shift); 3343 nodes->push(n_add_base); 3344 } 3345 %} 3346 3347 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3348 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3349 n1->add_req(n_region, n_src); 3350 n1->_opnds[0] = op_dst; 3351 n1->_opnds[1] = op_src; 3352 n1->_bottom_type = _bottom_type; 3353 3354 decodeN_addNode *n2 = new decodeN_addNode(); 3355 n2->add_req(n_region, n1); 3356 n2->_opnds[0] = op_dst; 3357 n2->_opnds[1] = op_dst; 3358 n2->_bottom_type = _bottom_type; 3359 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3360 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3361 3362 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3363 ra_->set_oop(n2, true); 3364 3365 nodes->push(n1); 3366 nodes->push(n2); 3367 %} 3368 3369 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3370 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3371 3372 MacroAssembler _masm(&cbuf); 3373 int cc = $cmp$$cmpcode; 3374 int flags_reg = $crx$$reg; 3375 Label done; 3376 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3377 // Branch if not (cmp crx). 3378 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3379 __ mr($dst$$Register, $src$$Register); 3380 // TODO PPC port __ endgroup_if_needed(_size == 12); 3381 __ bind(done); 3382 %} 3383 3384 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3385 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3386 3387 MacroAssembler _masm(&cbuf); 3388 Label done; 3389 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3390 // Branch if not (cmp crx). 3391 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3392 __ li($dst$$Register, $src$$constant); 3393 // TODO PPC port __ endgroup_if_needed(_size == 12); 3394 __ bind(done); 3395 %} 3396 3397 // This enc_class is needed so that scheduler gets proper 3398 // input mapping for latency computation. 3399 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3400 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3401 MacroAssembler _masm(&cbuf); 3402 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3403 %} 3404 3405 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3406 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3407 3408 MacroAssembler _masm(&cbuf); 3409 3410 Label done; 3411 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3412 __ li($dst$$Register, $zero$$constant); 3413 __ beq($crx$$CondRegister, done); 3414 __ li($dst$$Register, $notzero$$constant); 3415 __ bind(done); 3416 %} 3417 3418 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3419 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3420 3421 MacroAssembler _masm(&cbuf); 3422 3423 Label done; 3424 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3425 __ li($dst$$Register, $zero$$constant); 3426 __ beq($crx$$CondRegister, done); 3427 __ li($dst$$Register, $notzero$$constant); 3428 __ bind(done); 3429 %} 3430 3431 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3432 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3433 3434 MacroAssembler _masm(&cbuf); 3435 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3436 Label done; 3437 __ bso($crx$$CondRegister, done); 3438 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3439 // TODO PPC port __ endgroup_if_needed(_size == 12); 3440 __ bind(done); 3441 %} 3442 3443 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3444 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3445 3446 MacroAssembler _masm(&cbuf); 3447 Label done; 3448 __ bso($crx$$CondRegister, done); 3449 __ mffprd($dst$$Register, $src$$FloatRegister); 3450 // TODO PPC port __ endgroup_if_needed(_size == 12); 3451 __ bind(done); 3452 %} 3453 3454 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3455 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3456 3457 MacroAssembler _masm(&cbuf); 3458 Label d; // dummy 3459 __ bind(d); 3460 Label* p = ($lbl$$label); 3461 // `p' is `NULL' when this encoding class is used only to 3462 // determine the size of the encoded instruction. 3463 Label& l = (NULL == p)? d : *(p); 3464 int cc = $cmp$$cmpcode; 3465 int flags_reg = $crx$$reg; 3466 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3467 int bhint = Assembler::bhintNoHint; 3468 3469 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3470 if (_prob <= PROB_NEVER) { 3471 bhint = Assembler::bhintIsNotTaken; 3472 } else if (_prob >= PROB_ALWAYS) { 3473 bhint = Assembler::bhintIsTaken; 3474 } 3475 } 3476 3477 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3478 cc_to_biint(cc, flags_reg), 3479 l); 3480 %} 3481 3482 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3483 // The scheduler doesn't know about branch shortening, so we set the opcode 3484 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3485 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3486 3487 MacroAssembler _masm(&cbuf); 3488 Label d; // dummy 3489 __ bind(d); 3490 Label* p = ($lbl$$label); 3491 // `p' is `NULL' when this encoding class is used only to 3492 // determine the size of the encoded instruction. 3493 Label& l = (NULL == p)? d : *(p); 3494 int cc = $cmp$$cmpcode; 3495 int flags_reg = $crx$$reg; 3496 int bhint = Assembler::bhintNoHint; 3497 3498 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3499 if (_prob <= PROB_NEVER) { 3500 bhint = Assembler::bhintIsNotTaken; 3501 } else if (_prob >= PROB_ALWAYS) { 3502 bhint = Assembler::bhintIsTaken; 3503 } 3504 } 3505 3506 // Tell the conditional far branch to optimize itself when being relocated. 3507 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3508 cc_to_biint(cc, flags_reg), 3509 l, 3510 MacroAssembler::bc_far_optimize_on_relocate); 3511 %} 3512 3513 // Branch used with Power6 scheduling (can be shortened without changing the node). 3514 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3515 // The scheduler doesn't know about branch shortening, so we set the opcode 3516 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3517 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3518 3519 MacroAssembler _masm(&cbuf); 3520 Label d; // dummy 3521 __ bind(d); 3522 Label* p = ($lbl$$label); 3523 // `p' is `NULL' when this encoding class is used only to 3524 // determine the size of the encoded instruction. 3525 Label& l = (NULL == p)? d : *(p); 3526 int cc = $cmp$$cmpcode; 3527 int flags_reg = $crx$$reg; 3528 int bhint = Assembler::bhintNoHint; 3529 3530 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3531 if (_prob <= PROB_NEVER) { 3532 bhint = Assembler::bhintIsNotTaken; 3533 } else if (_prob >= PROB_ALWAYS) { 3534 bhint = Assembler::bhintIsTaken; 3535 } 3536 } 3537 3538 #if 0 // TODO: PPC port 3539 if (_size == 8) { 3540 // Tell the conditional far branch to optimize itself when being relocated. 3541 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3542 cc_to_biint(cc, flags_reg), 3543 l, 3544 MacroAssembler::bc_far_optimize_on_relocate); 3545 } else { 3546 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3547 cc_to_biint(cc, flags_reg), 3548 l); 3549 } 3550 #endif 3551 Unimplemented(); 3552 %} 3553 3554 // Postalloc expand emitter for loading a replicatef float constant from 3555 // the method's TOC. 3556 // Enc_class needed as consttanttablebase is not supported by postalloc 3557 // expand. 3558 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3559 // Create new nodes. 3560 3561 // Make an operand with the bit pattern to load as float. 3562 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3563 3564 loadConLNodesTuple loadConLNodes = 3565 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3566 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3567 3568 // Push new nodes. 3569 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3570 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3571 3572 assert(nodes->length() >= 1, "must have created at least 1 node"); 3573 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3574 %} 3575 3576 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3577 // Create new nodes. 3578 3579 // Make an operand with the bit pattern to load as float. 3580 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3581 immI_0Oper *op_zero = new immI_0Oper(0); 3582 3583 loadConLReplicatedNodesTuple loadConLNodes = 3584 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3585 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3586 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3587 3588 // Push new nodes. 3589 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3590 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3591 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3592 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3593 3594 assert(nodes->length() >= 1, "must have created at least 1 node"); 3595 %} 3596 3597 // This enc_class is needed so that scheduler gets proper 3598 // input mapping for latency computation. 3599 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3600 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3601 // Fake operand dst needed for PPC scheduler. 3602 assert($dst$$constant == 0x0, "dst must be 0x0"); 3603 3604 MacroAssembler _masm(&cbuf); 3605 // Mark the code position where the load from the safepoint 3606 // polling page was emitted as relocInfo::poll_type. 3607 __ relocate(relocInfo::poll_type); 3608 __ load_from_polling_page($poll$$Register); 3609 %} 3610 3611 // A Java static call or a runtime call. 3612 // 3613 // Branch-and-link relative to a trampoline. 3614 // The trampoline loads the target address and does a long branch to there. 3615 // In case we call java, the trampoline branches to a interpreter_stub 3616 // which loads the inline cache and the real call target from the constant pool. 3617 // 3618 // This basically looks like this: 3619 // 3620 // >>>> consts -+ -+ 3621 // | |- offset1 3622 // [call target1] | <-+ 3623 // [IC cache] |- offset2 3624 // [call target2] <--+ 3625 // 3626 // <<<< consts 3627 // >>>> insts 3628 // 3629 // bl offset16 -+ -+ ??? // How many bits available? 3630 // | | 3631 // <<<< insts | | 3632 // >>>> stubs | | 3633 // | |- trampoline_stub_Reloc 3634 // trampoline stub: | <-+ 3635 // r2 = toc | 3636 // r2 = [r2 + offset1] | // Load call target1 from const section 3637 // mtctr r2 | 3638 // bctr |- static_stub_Reloc 3639 // comp_to_interp_stub: <---+ 3640 // r1 = toc 3641 // ICreg = [r1 + IC_offset] // Load IC from const section 3642 // r1 = [r1 + offset2] // Load call target2 from const section 3643 // mtctr r1 3644 // bctr 3645 // 3646 // <<<< stubs 3647 // 3648 // The call instruction in the code either 3649 // - Branches directly to a compiled method if the offset is encodable in instruction. 3650 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3651 // - Branches to the compiled_to_interp stub if the target is interpreted. 3652 // 3653 // Further there are three relocations from the loads to the constants in 3654 // the constant section. 3655 // 3656 // Usage of r1 and r2 in the stubs allows to distinguish them. 3657 enc_class enc_java_static_call(method meth) %{ 3658 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3659 3660 MacroAssembler _masm(&cbuf); 3661 address entry_point = (address)$meth$$method; 3662 3663 if (!_method) { 3664 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3665 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3666 } else { 3667 // Remember the offset not the address. 3668 const int start_offset = __ offset(); 3669 3670 // The trampoline stub. 3671 // No entry point given, use the current pc. 3672 // Make sure branch fits into 3673 if (entry_point == 0) entry_point = __ pc(); 3674 3675 // Put the entry point as a constant into the constant pool. 3676 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3677 if (entry_point_toc_addr == NULL) { 3678 ciEnv::current()->record_out_of_memory_failure(); 3679 return; 3680 } 3681 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3682 3683 // Emit the trampoline stub which will be related to the branch-and-link below. 3684 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3685 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3686 int method_index = resolved_method_index(cbuf); 3687 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3688 : static_call_Relocation::spec(method_index)); 3689 3690 // The real call. 3691 // Note: At this point we do not have the address of the trampoline 3692 // stub, and the entry point might be too far away for bl, so __ pc() 3693 // serves as dummy and the bl will be patched later. 3694 cbuf.set_insts_mark(); 3695 __ bl(__ pc()); // Emits a relocation. 3696 3697 // The stub for call to interpreter. 3698 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3699 if (stub == NULL) { 3700 ciEnv::current()->record_failure("CodeCache is full"); 3701 return; 3702 } 3703 } 3704 %} 3705 3706 // Second node of expanded dynamic call - the call. 3707 enc_class enc_java_dynamic_call_sched(method meth) %{ 3708 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3709 3710 MacroAssembler _masm(&cbuf); 3711 3712 if (!ra_->C->in_scratch_emit_size()) { 3713 // Create a call trampoline stub for the given method. 3714 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3715 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3716 if (entry_point_const == NULL) { 3717 ciEnv::current()->record_out_of_memory_failure(); 3718 return; 3719 } 3720 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3721 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3722 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3723 3724 // Build relocation at call site with ic position as data. 3725 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3726 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3727 "must have one, but can't have both"); 3728 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3729 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3730 "must contain instruction offset"); 3731 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3732 ? _load_ic_hi_node->_cbuf_insts_offset 3733 : _load_ic_node->_cbuf_insts_offset; 3734 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3735 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3736 "should be load from TOC"); 3737 int method_index = resolved_method_index(cbuf); 3738 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3739 } 3740 3741 // At this point I do not have the address of the trampoline stub, 3742 // and the entry point might be too far away for bl. Pc() serves 3743 // as dummy and bl will be patched later. 3744 __ bl((address) __ pc()); 3745 %} 3746 3747 // postalloc expand emitter for virtual calls. 3748 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3749 3750 // Create the nodes for loading the IC from the TOC. 3751 loadConLNodesTuple loadConLNodes_IC = 3752 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3753 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3754 3755 // Create the call node. 3756 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3757 call->_method_handle_invoke = _method_handle_invoke; 3758 call->_vtable_index = _vtable_index; 3759 call->_method = _method; 3760 call->_bci = _bci; 3761 call->_optimized_virtual = _optimized_virtual; 3762 call->_tf = _tf; 3763 call->_entry_point = _entry_point; 3764 call->_cnt = _cnt; 3765 call->_argsize = _argsize; 3766 call->_oop_map = _oop_map; 3767 call->_jvms = _jvms; 3768 call->_jvmadj = _jvmadj; 3769 call->_in_rms = _in_rms; 3770 call->_nesting = _nesting; 3771 call->_override_symbolic_info = _override_symbolic_info; 3772 3773 // New call needs all inputs of old call. 3774 // Req... 3775 for (uint i = 0; i < req(); ++i) { 3776 // The expanded node does not need toc any more. 3777 // Add the inline cache constant here instead. This expresses the 3778 // register of the inline cache must be live at the call. 3779 // Else we would have to adapt JVMState by -1. 3780 if (i == mach_constant_base_node_input()) { 3781 call->add_req(loadConLNodes_IC._last); 3782 } else { 3783 call->add_req(in(i)); 3784 } 3785 } 3786 // ...as well as prec 3787 for (uint i = req(); i < len(); ++i) { 3788 call->add_prec(in(i)); 3789 } 3790 3791 // Remember nodes loading the inline cache into r19. 3792 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3793 call->_load_ic_node = loadConLNodes_IC._small; 3794 3795 // Operands for new nodes. 3796 call->_opnds[0] = _opnds[0]; 3797 call->_opnds[1] = _opnds[1]; 3798 3799 // Only the inline cache is associated with a register. 3800 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3801 3802 // Push new nodes. 3803 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3804 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3805 nodes->push(call); 3806 %} 3807 3808 // Compound version of call dynamic 3809 // Toc is only passed so that it can be used in ins_encode statement. 3810 // In the code we have to use $constanttablebase. 3811 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3812 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3813 MacroAssembler _masm(&cbuf); 3814 int start_offset = __ offset(); 3815 3816 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3817 #if 0 3818 int vtable_index = this->_vtable_index; 3819 if (_vtable_index < 0) { 3820 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3821 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3822 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3823 3824 // Virtual call relocation will point to ic load. 3825 address virtual_call_meta_addr = __ pc(); 3826 // Load a clear inline cache. 3827 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3828 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3829 if (!success) { 3830 ciEnv::current()->record_out_of_memory_failure(); 3831 return; 3832 } 3833 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3834 // to determine who we intended to call. 3835 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3836 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3837 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3838 "Fix constant in ret_addr_offset()"); 3839 } else { 3840 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3841 // Go thru the vtable. Get receiver klass. Receiver already 3842 // checked for non-null. If we'll go thru a C2I adapter, the 3843 // interpreter expects method in R19_method. 3844 3845 __ load_klass(R11_scratch1, R3); 3846 3847 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3848 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3849 __ li(R19_method, v_off); 3850 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3851 // NOTE: for vtable dispatches, the vtable entry will never be 3852 // null. However it may very well end up in handle_wrong_method 3853 // if the method is abstract for the particular class. 3854 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3855 // Call target. Either compiled code or C2I adapter. 3856 __ mtctr(R11_scratch1); 3857 __ bctrl(); 3858 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3859 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3860 } 3861 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3862 "Fix constant in ret_addr_offset()"); 3863 } 3864 #endif 3865 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3866 %} 3867 3868 // a runtime call 3869 enc_class enc_java_to_runtime_call (method meth) %{ 3870 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3871 3872 MacroAssembler _masm(&cbuf); 3873 const address start_pc = __ pc(); 3874 3875 #if defined(ABI_ELFv2) 3876 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3877 __ call_c(entry, relocInfo::runtime_call_type); 3878 #else 3879 // The function we're going to call. 3880 FunctionDescriptor fdtemp; 3881 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3882 3883 Register Rtoc = R12_scratch2; 3884 // Calculate the method's TOC. 3885 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3886 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3887 // pool entries; call_c_using_toc will optimize the call. 3888 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3889 if (!success) { 3890 ciEnv::current()->record_out_of_memory_failure(); 3891 return; 3892 } 3893 #endif 3894 3895 // Check the ret_addr_offset. 3896 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3897 "Fix constant in ret_addr_offset()"); 3898 %} 3899 3900 // Move to ctr for leaf call. 3901 // This enc_class is needed so that scheduler gets proper 3902 // input mapping for latency computation. 3903 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3904 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3905 MacroAssembler _masm(&cbuf); 3906 __ mtctr($src$$Register); 3907 %} 3908 3909 // Postalloc expand emitter for runtime leaf calls. 3910 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3911 loadConLNodesTuple loadConLNodes_Entry; 3912 #if defined(ABI_ELFv2) 3913 jlong entry_address = (jlong) this->entry_point(); 3914 assert(entry_address, "need address here"); 3915 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3916 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3917 #else 3918 // Get the struct that describes the function we are about to call. 3919 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3920 assert(fd, "need fd here"); 3921 jlong entry_address = (jlong) fd->entry(); 3922 // new nodes 3923 loadConLNodesTuple loadConLNodes_Env; 3924 loadConLNodesTuple loadConLNodes_Toc; 3925 3926 // Create nodes and operands for loading the entry point. 3927 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3928 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3929 3930 3931 // Create nodes and operands for loading the env pointer. 3932 if (fd->env() != NULL) { 3933 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3934 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3935 } else { 3936 loadConLNodes_Env._large_hi = NULL; 3937 loadConLNodes_Env._large_lo = NULL; 3938 loadConLNodes_Env._small = NULL; 3939 loadConLNodes_Env._last = new loadConL16Node(); 3940 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3941 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3942 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3943 } 3944 3945 // Create nodes and operands for loading the Toc point. 3946 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3947 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3948 #endif // ABI_ELFv2 3949 // mtctr node 3950 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3951 3952 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3953 mtctr->add_req(0, loadConLNodes_Entry._last); 3954 3955 mtctr->_opnds[0] = new iRegLdstOper(); 3956 mtctr->_opnds[1] = new iRegLdstOper(); 3957 3958 // call node 3959 MachCallLeafNode *call = new CallLeafDirectNode(); 3960 3961 call->_opnds[0] = _opnds[0]; 3962 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3963 3964 // Make the new call node look like the old one. 3965 call->_name = _name; 3966 call->_tf = _tf; 3967 call->_entry_point = _entry_point; 3968 call->_cnt = _cnt; 3969 call->_argsize = _argsize; 3970 call->_oop_map = _oop_map; 3971 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3972 call->_jvms = NULL; 3973 call->_jvmadj = _jvmadj; 3974 call->_in_rms = _in_rms; 3975 call->_nesting = _nesting; 3976 3977 3978 // New call needs all inputs of old call. 3979 // Req... 3980 for (uint i = 0; i < req(); ++i) { 3981 if (i != mach_constant_base_node_input()) { 3982 call->add_req(in(i)); 3983 } 3984 } 3985 3986 // These must be reqired edges, as the registers are live up to 3987 // the call. Else the constants are handled as kills. 3988 call->add_req(mtctr); 3989 #if !defined(ABI_ELFv2) 3990 call->add_req(loadConLNodes_Env._last); 3991 call->add_req(loadConLNodes_Toc._last); 3992 #endif 3993 3994 // ...as well as prec 3995 for (uint i = req(); i < len(); ++i) { 3996 call->add_prec(in(i)); 3997 } 3998 3999 // registers 4000 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 4001 4002 // Insert the new nodes. 4003 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 4004 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 4005 #if !defined(ABI_ELFv2) 4006 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 4007 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 4008 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 4009 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 4010 #endif 4011 nodes->push(mtctr); 4012 nodes->push(call); 4013 %} 4014 %} 4015 4016 //----------FRAME-------------------------------------------------------------- 4017 // Definition of frame structure and management information. 4018 4019 frame %{ 4020 // What direction does stack grow in (assumed to be same for native & Java). 4021 stack_direction(TOWARDS_LOW); 4022 4023 // These two registers define part of the calling convention between 4024 // compiled code and the interpreter. 4025 4026 // Inline Cache Register or method for I2C. 4027 inline_cache_reg(R19); // R19_method 4028 4029 // Method Oop Register when calling interpreter. 4030 interpreter_method_oop_reg(R19); // R19_method 4031 4032 // Optional: name the operand used by cisc-spilling to access 4033 // [stack_pointer + offset]. 4034 cisc_spilling_operand_name(indOffset); 4035 4036 // Number of stack slots consumed by a Monitor enter. 4037 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 4038 4039 // Compiled code's Frame Pointer. 4040 frame_pointer(R1); // R1_SP 4041 4042 // Interpreter stores its frame pointer in a register which is 4043 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 4044 // interpreted java to compiled java. 4045 // 4046 // R14_state holds pointer to caller's cInterpreter. 4047 interpreter_frame_pointer(R14); // R14_state 4048 4049 stack_alignment(frame::alignment_in_bytes); 4050 4051 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4052 4053 // Number of outgoing stack slots killed above the 4054 // out_preserve_stack_slots for calls to C. Supports the var-args 4055 // backing area for register parms. 4056 // 4057 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4058 4059 // The after-PROLOG location of the return address. Location of 4060 // return address specifies a type (REG or STACK) and a number 4061 // representing the register number (i.e. - use a register name) or 4062 // stack slot. 4063 // 4064 // A: Link register is stored in stack slot ... 4065 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4066 // J: Therefore, we make sure that the link register is also in R11_scratch1 4067 // at the end of the prolog. 4068 // B: We use R20, now. 4069 //return_addr(REG R20); 4070 4071 // G: After reading the comments made by all the luminaries on their 4072 // failure to tell the compiler where the return address really is, 4073 // I hardly dare to try myself. However, I'm convinced it's in slot 4074 // 4 what apparently works and saves us some spills. 4075 return_addr(STACK 4); 4076 4077 // This is the body of the function 4078 // 4079 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4080 // uint length, // length of array 4081 // bool is_outgoing) 4082 // 4083 // The `sig' array is to be updated. sig[j] represents the location 4084 // of the j-th argument, either a register or a stack slot. 4085 4086 // Comment taken from i486.ad: 4087 // Body of function which returns an integer array locating 4088 // arguments either in registers or in stack slots. Passed an array 4089 // of ideal registers called "sig" and a "length" count. Stack-slot 4090 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4091 // arguments for a CALLEE. Incoming stack arguments are 4092 // automatically biased by the preserve_stack_slots field above. 4093 calling_convention %{ 4094 // No difference between ingoing/outgoing. Just pass false. 4095 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4096 %} 4097 4098 // Comment taken from i486.ad: 4099 // Body of function which returns an integer array locating 4100 // arguments either in registers or in stack slots. Passed an array 4101 // of ideal registers called "sig" and a "length" count. Stack-slot 4102 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4103 // arguments for a CALLEE. Incoming stack arguments are 4104 // automatically biased by the preserve_stack_slots field above. 4105 c_calling_convention %{ 4106 // This is obviously always outgoing. 4107 // C argument in register AND stack slot. 4108 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4109 %} 4110 4111 // Location of native (C/C++) and interpreter return values. This 4112 // is specified to be the same as Java. In the 32-bit VM, long 4113 // values are actually returned from native calls in O0:O1 and 4114 // returned to the interpreter in I0:I1. The copying to and from 4115 // the register pairs is done by the appropriate call and epilog 4116 // opcodes. This simplifies the register allocator. 4117 c_return_value %{ 4118 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4119 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4120 "only return normal values"); 4121 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4122 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4123 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4124 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4125 %} 4126 4127 // Location of compiled Java return values. Same as C 4128 return_value %{ 4129 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4130 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4131 "only return normal values"); 4132 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4133 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4134 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4135 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4136 %} 4137 %} 4138 4139 4140 //----------ATTRIBUTES--------------------------------------------------------- 4141 4142 //----------Operand Attributes------------------------------------------------- 4143 op_attrib op_cost(1); // Required cost attribute. 4144 4145 //----------Instruction Attributes--------------------------------------------- 4146 4147 // Cost attribute. required. 4148 ins_attrib ins_cost(DEFAULT_COST); 4149 4150 // Is this instruction a non-matching short branch variant of some 4151 // long branch? Not required. 4152 ins_attrib ins_short_branch(0); 4153 4154 ins_attrib ins_is_TrapBasedCheckNode(true); 4155 4156 // Number of constants. 4157 // This instruction uses the given number of constants 4158 // (optional attribute). 4159 // This is needed to determine in time whether the constant pool will 4160 // exceed 4000 entries. Before postalloc_expand the overall number of constants 4161 // is determined. It's also used to compute the constant pool size 4162 // in Output(). 4163 ins_attrib ins_num_consts(0); 4164 4165 // Required alignment attribute (must be a power of 2) specifies the 4166 // alignment that some part of the instruction (not necessarily the 4167 // start) requires. If > 1, a compute_padding() function must be 4168 // provided for the instruction. 4169 ins_attrib ins_alignment(1); 4170 4171 // Enforce/prohibit rematerializations. 4172 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4173 // then rematerialization of that instruction is prohibited and the 4174 // instruction's value will be spilled if necessary. 4175 // Causes that MachNode::rematerialize() returns false. 4176 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 4177 // then rematerialization should be enforced and a copy of the instruction 4178 // should be inserted if possible; rematerialization is not guaranteed. 4179 // Note: this may result in rematerializations in front of every use. 4180 // Causes that MachNode::rematerialize() can return true. 4181 // (optional attribute) 4182 ins_attrib ins_cannot_rematerialize(false); 4183 ins_attrib ins_should_rematerialize(false); 4184 4185 // Instruction has variable size depending on alignment. 4186 ins_attrib ins_variable_size_depending_on_alignment(false); 4187 4188 // Instruction is a nop. 4189 ins_attrib ins_is_nop(false); 4190 4191 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4192 ins_attrib ins_use_mach_if_fast_lock_node(false); 4193 4194 // Field for the toc offset of a constant. 4195 // 4196 // This is needed if the toc offset is not encodable as an immediate in 4197 // the PPC load instruction. If so, the upper (hi) bits of the offset are 4198 // added to the toc, and from this a load with immediate is performed. 4199 // With postalloc expand, we get two nodes that require the same offset 4200 // but which don't know about each other. The offset is only known 4201 // when the constant is added to the constant pool during emitting. 4202 // It is generated in the 'hi'-node adding the upper bits, and saved 4203 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 4204 // the offset from there when it gets encoded. 4205 ins_attrib ins_field_const_toc_offset(0); 4206 ins_attrib ins_field_const_toc_offset_hi_node(0); 4207 4208 // A field that can hold the instructions offset in the code buffer. 4209 // Set in the nodes emitter. 4210 ins_attrib ins_field_cbuf_insts_offset(-1); 4211 4212 // Fields for referencing a call's load-IC-node. 4213 // If the toc offset can not be encoded as an immediate in a load, we 4214 // use two nodes. 4215 ins_attrib ins_field_load_ic_hi_node(0); 4216 ins_attrib ins_field_load_ic_node(0); 4217 4218 //----------OPERANDS----------------------------------------------------------- 4219 // Operand definitions must precede instruction definitions for correct 4220 // parsing in the ADLC because operands constitute user defined types 4221 // which are used in instruction definitions. 4222 // 4223 // Formats are generated automatically for constants and base registers. 4224 4225 operand vecX() %{ 4226 constraint(ALLOC_IN_RC(vs_reg)); 4227 match(VecX); 4228 4229 format %{ %} 4230 interface(REG_INTER); 4231 %} 4232 4233 //----------Simple Operands---------------------------------------------------- 4234 // Immediate Operands 4235 4236 // Integer Immediate: 32-bit 4237 operand immI() %{ 4238 match(ConI); 4239 op_cost(40); 4240 format %{ %} 4241 interface(CONST_INTER); 4242 %} 4243 4244 operand immI8() %{ 4245 predicate(Assembler::is_simm(n->get_int(), 8)); 4246 op_cost(0); 4247 match(ConI); 4248 format %{ %} 4249 interface(CONST_INTER); 4250 %} 4251 4252 // Integer Immediate: 16-bit 4253 operand immI16() %{ 4254 predicate(Assembler::is_simm(n->get_int(), 16)); 4255 op_cost(0); 4256 match(ConI); 4257 format %{ %} 4258 interface(CONST_INTER); 4259 %} 4260 4261 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4262 operand immIhi16() %{ 4263 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4264 match(ConI); 4265 op_cost(0); 4266 format %{ %} 4267 interface(CONST_INTER); 4268 %} 4269 4270 operand immInegpow2() %{ 4271 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 4272 match(ConI); 4273 op_cost(0); 4274 format %{ %} 4275 interface(CONST_INTER); 4276 %} 4277 4278 operand immIpow2minus1() %{ 4279 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 4280 match(ConI); 4281 op_cost(0); 4282 format %{ %} 4283 interface(CONST_INTER); 4284 %} 4285 4286 operand immIpowerOf2() %{ 4287 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 4288 match(ConI); 4289 op_cost(0); 4290 format %{ %} 4291 interface(CONST_INTER); 4292 %} 4293 4294 // Unsigned Integer Immediate: the values 0-31 4295 operand uimmI5() %{ 4296 predicate(Assembler::is_uimm(n->get_int(), 5)); 4297 match(ConI); 4298 op_cost(0); 4299 format %{ %} 4300 interface(CONST_INTER); 4301 %} 4302 4303 // Unsigned Integer Immediate: 6-bit 4304 operand uimmI6() %{ 4305 predicate(Assembler::is_uimm(n->get_int(), 6)); 4306 match(ConI); 4307 op_cost(0); 4308 format %{ %} 4309 interface(CONST_INTER); 4310 %} 4311 4312 // Unsigned Integer Immediate: 6-bit int, greater than 32 4313 operand uimmI6_ge32() %{ 4314 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4315 match(ConI); 4316 op_cost(0); 4317 format %{ %} 4318 interface(CONST_INTER); 4319 %} 4320 4321 // Unsigned Integer Immediate: 15-bit 4322 operand uimmI15() %{ 4323 predicate(Assembler::is_uimm(n->get_int(), 15)); 4324 match(ConI); 4325 op_cost(0); 4326 format %{ %} 4327 interface(CONST_INTER); 4328 %} 4329 4330 // Unsigned Integer Immediate: 16-bit 4331 operand uimmI16() %{ 4332 predicate(Assembler::is_uimm(n->get_int(), 16)); 4333 match(ConI); 4334 op_cost(0); 4335 format %{ %} 4336 interface(CONST_INTER); 4337 %} 4338 4339 // constant 'int 0'. 4340 operand immI_0() %{ 4341 predicate(n->get_int() == 0); 4342 match(ConI); 4343 op_cost(0); 4344 format %{ %} 4345 interface(CONST_INTER); 4346 %} 4347 4348 // constant 'int 1'. 4349 operand immI_1() %{ 4350 predicate(n->get_int() == 1); 4351 match(ConI); 4352 op_cost(0); 4353 format %{ %} 4354 interface(CONST_INTER); 4355 %} 4356 4357 // constant 'int -1'. 4358 operand immI_minus1() %{ 4359 predicate(n->get_int() == -1); 4360 match(ConI); 4361 op_cost(0); 4362 format %{ %} 4363 interface(CONST_INTER); 4364 %} 4365 4366 // int value 16. 4367 operand immI_16() %{ 4368 predicate(n->get_int() == 16); 4369 match(ConI); 4370 op_cost(0); 4371 format %{ %} 4372 interface(CONST_INTER); 4373 %} 4374 4375 // int value 24. 4376 operand immI_24() %{ 4377 predicate(n->get_int() == 24); 4378 match(ConI); 4379 op_cost(0); 4380 format %{ %} 4381 interface(CONST_INTER); 4382 %} 4383 4384 // Compressed oops constants 4385 // Pointer Immediate 4386 operand immN() %{ 4387 match(ConN); 4388 4389 op_cost(10); 4390 format %{ %} 4391 interface(CONST_INTER); 4392 %} 4393 4394 // NULL Pointer Immediate 4395 operand immN_0() %{ 4396 predicate(n->get_narrowcon() == 0); 4397 match(ConN); 4398 4399 op_cost(0); 4400 format %{ %} 4401 interface(CONST_INTER); 4402 %} 4403 4404 // Compressed klass constants 4405 operand immNKlass() %{ 4406 match(ConNKlass); 4407 4408 op_cost(0); 4409 format %{ %} 4410 interface(CONST_INTER); 4411 %} 4412 4413 // This operand can be used to avoid matching of an instruct 4414 // with chain rule. 4415 operand immNKlass_NM() %{ 4416 match(ConNKlass); 4417 predicate(false); 4418 op_cost(0); 4419 format %{ %} 4420 interface(CONST_INTER); 4421 %} 4422 4423 // Pointer Immediate: 64-bit 4424 operand immP() %{ 4425 match(ConP); 4426 op_cost(0); 4427 format %{ %} 4428 interface(CONST_INTER); 4429 %} 4430 4431 // Operand to avoid match of loadConP. 4432 // This operand can be used to avoid matching of an instruct 4433 // with chain rule. 4434 operand immP_NM() %{ 4435 match(ConP); 4436 predicate(false); 4437 op_cost(0); 4438 format %{ %} 4439 interface(CONST_INTER); 4440 %} 4441 4442 // costant 'pointer 0'. 4443 operand immP_0() %{ 4444 predicate(n->get_ptr() == 0); 4445 match(ConP); 4446 op_cost(0); 4447 format %{ %} 4448 interface(CONST_INTER); 4449 %} 4450 4451 // pointer 0x0 or 0x1 4452 operand immP_0or1() %{ 4453 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4454 match(ConP); 4455 op_cost(0); 4456 format %{ %} 4457 interface(CONST_INTER); 4458 %} 4459 4460 operand immL() %{ 4461 match(ConL); 4462 op_cost(40); 4463 format %{ %} 4464 interface(CONST_INTER); 4465 %} 4466 4467 operand immLmax30() %{ 4468 predicate((n->get_long() <= 30)); 4469 match(ConL); 4470 op_cost(0); 4471 format %{ %} 4472 interface(CONST_INTER); 4473 %} 4474 4475 // Long Immediate: 16-bit 4476 operand immL16() %{ 4477 predicate(Assembler::is_simm(n->get_long(), 16)); 4478 match(ConL); 4479 op_cost(0); 4480 format %{ %} 4481 interface(CONST_INTER); 4482 %} 4483 4484 // Long Immediate: 16-bit, 4-aligned 4485 operand immL16Alg4() %{ 4486 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4487 match(ConL); 4488 op_cost(0); 4489 format %{ %} 4490 interface(CONST_INTER); 4491 %} 4492 4493 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4494 operand immL32hi16() %{ 4495 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4496 match(ConL); 4497 op_cost(0); 4498 format %{ %} 4499 interface(CONST_INTER); 4500 %} 4501 4502 // Long Immediate: 32-bit 4503 operand immL32() %{ 4504 predicate(Assembler::is_simm(n->get_long(), 32)); 4505 match(ConL); 4506 op_cost(0); 4507 format %{ %} 4508 interface(CONST_INTER); 4509 %} 4510 4511 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4512 operand immLhighest16() %{ 4513 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4514 match(ConL); 4515 op_cost(0); 4516 format %{ %} 4517 interface(CONST_INTER); 4518 %} 4519 4520 operand immLnegpow2() %{ 4521 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4522 match(ConL); 4523 op_cost(0); 4524 format %{ %} 4525 interface(CONST_INTER); 4526 %} 4527 4528 operand immLpow2minus1() %{ 4529 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4530 (n->get_long() != (jlong)0xffffffffffffffffL)); 4531 match(ConL); 4532 op_cost(0); 4533 format %{ %} 4534 interface(CONST_INTER); 4535 %} 4536 4537 // constant 'long 0'. 4538 operand immL_0() %{ 4539 predicate(n->get_long() == 0L); 4540 match(ConL); 4541 op_cost(0); 4542 format %{ %} 4543 interface(CONST_INTER); 4544 %} 4545 4546 // constat ' long -1'. 4547 operand immL_minus1() %{ 4548 predicate(n->get_long() == -1L); 4549 match(ConL); 4550 op_cost(0); 4551 format %{ %} 4552 interface(CONST_INTER); 4553 %} 4554 4555 // Long Immediate: low 32-bit mask 4556 operand immL_32bits() %{ 4557 predicate(n->get_long() == 0xFFFFFFFFL); 4558 match(ConL); 4559 op_cost(0); 4560 format %{ %} 4561 interface(CONST_INTER); 4562 %} 4563 4564 // Unsigned Long Immediate: 16-bit 4565 operand uimmL16() %{ 4566 predicate(Assembler::is_uimm(n->get_long(), 16)); 4567 match(ConL); 4568 op_cost(0); 4569 format %{ %} 4570 interface(CONST_INTER); 4571 %} 4572 4573 // Float Immediate 4574 operand immF() %{ 4575 match(ConF); 4576 op_cost(40); 4577 format %{ %} 4578 interface(CONST_INTER); 4579 %} 4580 4581 // Float Immediate: +0.0f. 4582 operand immF_0() %{ 4583 predicate(jint_cast(n->getf()) == 0); 4584 match(ConF); 4585 4586 op_cost(0); 4587 format %{ %} 4588 interface(CONST_INTER); 4589 %} 4590 4591 // Double Immediate 4592 operand immD() %{ 4593 match(ConD); 4594 op_cost(40); 4595 format %{ %} 4596 interface(CONST_INTER); 4597 %} 4598 4599 // Integer Register Operands 4600 // Integer Destination Register 4601 // See definition of reg_class bits32_reg_rw. 4602 operand iRegIdst() %{ 4603 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4604 match(RegI); 4605 match(rscratch1RegI); 4606 match(rscratch2RegI); 4607 match(rarg1RegI); 4608 match(rarg2RegI); 4609 match(rarg3RegI); 4610 match(rarg4RegI); 4611 format %{ %} 4612 interface(REG_INTER); 4613 %} 4614 4615 // Integer Source Register 4616 // See definition of reg_class bits32_reg_ro. 4617 operand iRegIsrc() %{ 4618 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4619 match(RegI); 4620 match(rscratch1RegI); 4621 match(rscratch2RegI); 4622 match(rarg1RegI); 4623 match(rarg2RegI); 4624 match(rarg3RegI); 4625 match(rarg4RegI); 4626 format %{ %} 4627 interface(REG_INTER); 4628 %} 4629 4630 operand rscratch1RegI() %{ 4631 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4632 match(iRegIdst); 4633 format %{ %} 4634 interface(REG_INTER); 4635 %} 4636 4637 operand rscratch2RegI() %{ 4638 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4639 match(iRegIdst); 4640 format %{ %} 4641 interface(REG_INTER); 4642 %} 4643 4644 operand rarg1RegI() %{ 4645 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4646 match(iRegIdst); 4647 format %{ %} 4648 interface(REG_INTER); 4649 %} 4650 4651 operand rarg2RegI() %{ 4652 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4653 match(iRegIdst); 4654 format %{ %} 4655 interface(REG_INTER); 4656 %} 4657 4658 operand rarg3RegI() %{ 4659 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4660 match(iRegIdst); 4661 format %{ %} 4662 interface(REG_INTER); 4663 %} 4664 4665 operand rarg4RegI() %{ 4666 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4667 match(iRegIdst); 4668 format %{ %} 4669 interface(REG_INTER); 4670 %} 4671 4672 operand rarg1RegL() %{ 4673 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4674 match(iRegLdst); 4675 format %{ %} 4676 interface(REG_INTER); 4677 %} 4678 4679 operand rarg2RegL() %{ 4680 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4681 match(iRegLdst); 4682 format %{ %} 4683 interface(REG_INTER); 4684 %} 4685 4686 operand rarg3RegL() %{ 4687 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4688 match(iRegLdst); 4689 format %{ %} 4690 interface(REG_INTER); 4691 %} 4692 4693 operand rarg4RegL() %{ 4694 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4695 match(iRegLdst); 4696 format %{ %} 4697 interface(REG_INTER); 4698 %} 4699 4700 // Pointer Destination Register 4701 // See definition of reg_class bits64_reg_rw. 4702 operand iRegPdst() %{ 4703 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4704 match(RegP); 4705 match(rscratch1RegP); 4706 match(rscratch2RegP); 4707 match(rarg1RegP); 4708 match(rarg2RegP); 4709 match(rarg3RegP); 4710 match(rarg4RegP); 4711 format %{ %} 4712 interface(REG_INTER); 4713 %} 4714 4715 // Pointer Destination Register 4716 // Operand not using r11 and r12 (killed in epilog). 4717 operand iRegPdstNoScratch() %{ 4718 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4719 match(RegP); 4720 match(rarg1RegP); 4721 match(rarg2RegP); 4722 match(rarg3RegP); 4723 match(rarg4RegP); 4724 format %{ %} 4725 interface(REG_INTER); 4726 %} 4727 4728 // Pointer Source Register 4729 // See definition of reg_class bits64_reg_ro. 4730 operand iRegPsrc() %{ 4731 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4732 match(RegP); 4733 match(iRegPdst); 4734 match(rscratch1RegP); 4735 match(rscratch2RegP); 4736 match(rarg1RegP); 4737 match(rarg2RegP); 4738 match(rarg3RegP); 4739 match(rarg4RegP); 4740 match(threadRegP); 4741 format %{ %} 4742 interface(REG_INTER); 4743 %} 4744 4745 // Thread operand. 4746 operand threadRegP() %{ 4747 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4748 match(iRegPdst); 4749 format %{ "R16" %} 4750 interface(REG_INTER); 4751 %} 4752 4753 operand rscratch1RegP() %{ 4754 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4755 match(iRegPdst); 4756 format %{ "R11" %} 4757 interface(REG_INTER); 4758 %} 4759 4760 operand rscratch2RegP() %{ 4761 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4762 match(iRegPdst); 4763 format %{ %} 4764 interface(REG_INTER); 4765 %} 4766 4767 operand rarg1RegP() %{ 4768 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4769 match(iRegPdst); 4770 format %{ %} 4771 interface(REG_INTER); 4772 %} 4773 4774 operand rarg2RegP() %{ 4775 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4776 match(iRegPdst); 4777 format %{ %} 4778 interface(REG_INTER); 4779 %} 4780 4781 operand rarg3RegP() %{ 4782 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4783 match(iRegPdst); 4784 format %{ %} 4785 interface(REG_INTER); 4786 %} 4787 4788 operand rarg4RegP() %{ 4789 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4790 match(iRegPdst); 4791 format %{ %} 4792 interface(REG_INTER); 4793 %} 4794 4795 operand iRegNsrc() %{ 4796 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4797 match(RegN); 4798 match(iRegNdst); 4799 4800 format %{ %} 4801 interface(REG_INTER); 4802 %} 4803 4804 operand iRegNdst() %{ 4805 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4806 match(RegN); 4807 4808 format %{ %} 4809 interface(REG_INTER); 4810 %} 4811 4812 // Long Destination Register 4813 // See definition of reg_class bits64_reg_rw. 4814 operand iRegLdst() %{ 4815 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4816 match(RegL); 4817 match(rscratch1RegL); 4818 match(rscratch2RegL); 4819 format %{ %} 4820 interface(REG_INTER); 4821 %} 4822 4823 // Long Source Register 4824 // See definition of reg_class bits64_reg_ro. 4825 operand iRegLsrc() %{ 4826 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4827 match(RegL); 4828 match(iRegLdst); 4829 match(rscratch1RegL); 4830 match(rscratch2RegL); 4831 format %{ %} 4832 interface(REG_INTER); 4833 %} 4834 4835 // Special operand for ConvL2I. 4836 operand iRegL2Isrc(iRegLsrc reg) %{ 4837 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4838 match(ConvL2I reg); 4839 format %{ "ConvL2I($reg)" %} 4840 interface(REG_INTER) 4841 %} 4842 4843 operand rscratch1RegL() %{ 4844 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4845 match(RegL); 4846 format %{ %} 4847 interface(REG_INTER); 4848 %} 4849 4850 operand rscratch2RegL() %{ 4851 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4852 match(RegL); 4853 format %{ %} 4854 interface(REG_INTER); 4855 %} 4856 4857 // Condition Code Flag Registers 4858 operand flagsReg() %{ 4859 constraint(ALLOC_IN_RC(int_flags)); 4860 match(RegFlags); 4861 format %{ %} 4862 interface(REG_INTER); 4863 %} 4864 4865 operand flagsRegSrc() %{ 4866 constraint(ALLOC_IN_RC(int_flags_ro)); 4867 match(RegFlags); 4868 match(flagsReg); 4869 match(flagsRegCR0); 4870 format %{ %} 4871 interface(REG_INTER); 4872 %} 4873 4874 // Condition Code Flag Register CR0 4875 operand flagsRegCR0() %{ 4876 constraint(ALLOC_IN_RC(int_flags_CR0)); 4877 match(RegFlags); 4878 format %{ "CR0" %} 4879 interface(REG_INTER); 4880 %} 4881 4882 operand flagsRegCR1() %{ 4883 constraint(ALLOC_IN_RC(int_flags_CR1)); 4884 match(RegFlags); 4885 format %{ "CR1" %} 4886 interface(REG_INTER); 4887 %} 4888 4889 operand flagsRegCR6() %{ 4890 constraint(ALLOC_IN_RC(int_flags_CR6)); 4891 match(RegFlags); 4892 format %{ "CR6" %} 4893 interface(REG_INTER); 4894 %} 4895 4896 operand regCTR() %{ 4897 constraint(ALLOC_IN_RC(ctr_reg)); 4898 // RegFlags should work. Introducing a RegSpecial type would cause a 4899 // lot of changes. 4900 match(RegFlags); 4901 format %{"SR_CTR" %} 4902 interface(REG_INTER); 4903 %} 4904 4905 operand regD() %{ 4906 constraint(ALLOC_IN_RC(dbl_reg)); 4907 match(RegD); 4908 format %{ %} 4909 interface(REG_INTER); 4910 %} 4911 4912 operand regF() %{ 4913 constraint(ALLOC_IN_RC(flt_reg)); 4914 match(RegF); 4915 format %{ %} 4916 interface(REG_INTER); 4917 %} 4918 4919 // Special Registers 4920 4921 // Method Register 4922 operand inline_cache_regP(iRegPdst reg) %{ 4923 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4924 match(reg); 4925 format %{ %} 4926 interface(REG_INTER); 4927 %} 4928 4929 operand compiler_method_oop_regP(iRegPdst reg) %{ 4930 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4931 match(reg); 4932 format %{ %} 4933 interface(REG_INTER); 4934 %} 4935 4936 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4937 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4938 match(reg); 4939 format %{ %} 4940 interface(REG_INTER); 4941 %} 4942 4943 // Operands to remove register moves in unscaled mode. 4944 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4945 operand iRegP2N(iRegPsrc reg) %{ 4946 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4947 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4948 match(EncodeP reg); 4949 format %{ "$reg" %} 4950 interface(REG_INTER) 4951 %} 4952 4953 operand iRegN2P(iRegNsrc reg) %{ 4954 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4955 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4956 match(DecodeN reg); 4957 format %{ "$reg" %} 4958 interface(REG_INTER) 4959 %} 4960 4961 operand iRegN2P_klass(iRegNsrc reg) %{ 4962 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4963 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4964 match(DecodeNKlass reg); 4965 format %{ "$reg" %} 4966 interface(REG_INTER) 4967 %} 4968 4969 //----------Complex Operands--------------------------------------------------- 4970 // Indirect Memory Reference 4971 operand indirect(iRegPsrc reg) %{ 4972 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4973 match(reg); 4974 op_cost(100); 4975 format %{ "[$reg]" %} 4976 interface(MEMORY_INTER) %{ 4977 base($reg); 4978 index(0x0); 4979 scale(0x0); 4980 disp(0x0); 4981 %} 4982 %} 4983 4984 // Indirect with Offset 4985 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 4986 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4987 match(AddP reg offset); 4988 op_cost(100); 4989 format %{ "[$reg + $offset]" %} 4990 interface(MEMORY_INTER) %{ 4991 base($reg); 4992 index(0x0); 4993 scale(0x0); 4994 disp($offset); 4995 %} 4996 %} 4997 4998 // Indirect with 4-aligned Offset 4999 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 5000 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5001 match(AddP reg offset); 5002 op_cost(100); 5003 format %{ "[$reg + $offset]" %} 5004 interface(MEMORY_INTER) %{ 5005 base($reg); 5006 index(0x0); 5007 scale(0x0); 5008 disp($offset); 5009 %} 5010 %} 5011 5012 //----------Complex Operands for Compressed OOPs------------------------------- 5013 // Compressed OOPs with narrow_oop_shift == 0. 5014 5015 // Indirect Memory Reference, compressed OOP 5016 operand indirectNarrow(iRegNsrc reg) %{ 5017 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5018 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5019 match(DecodeN reg); 5020 op_cost(100); 5021 format %{ "[$reg]" %} 5022 interface(MEMORY_INTER) %{ 5023 base($reg); 5024 index(0x0); 5025 scale(0x0); 5026 disp(0x0); 5027 %} 5028 %} 5029 5030 operand indirectNarrow_klass(iRegNsrc reg) %{ 5031 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5032 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5033 match(DecodeNKlass reg); 5034 op_cost(100); 5035 format %{ "[$reg]" %} 5036 interface(MEMORY_INTER) %{ 5037 base($reg); 5038 index(0x0); 5039 scale(0x0); 5040 disp(0x0); 5041 %} 5042 %} 5043 5044 // Indirect with Offset, compressed OOP 5045 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 5046 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5047 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5048 match(AddP (DecodeN reg) offset); 5049 op_cost(100); 5050 format %{ "[$reg + $offset]" %} 5051 interface(MEMORY_INTER) %{ 5052 base($reg); 5053 index(0x0); 5054 scale(0x0); 5055 disp($offset); 5056 %} 5057 %} 5058 5059 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5060 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5061 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5062 match(AddP (DecodeNKlass reg) offset); 5063 op_cost(100); 5064 format %{ "[$reg + $offset]" %} 5065 interface(MEMORY_INTER) %{ 5066 base($reg); 5067 index(0x0); 5068 scale(0x0); 5069 disp($offset); 5070 %} 5071 %} 5072 5073 // Indirect with 4-aligned Offset, compressed OOP 5074 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 5075 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5076 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5077 match(AddP (DecodeN reg) offset); 5078 op_cost(100); 5079 format %{ "[$reg + $offset]" %} 5080 interface(MEMORY_INTER) %{ 5081 base($reg); 5082 index(0x0); 5083 scale(0x0); 5084 disp($offset); 5085 %} 5086 %} 5087 5088 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5089 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5090 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5091 match(AddP (DecodeNKlass reg) offset); 5092 op_cost(100); 5093 format %{ "[$reg + $offset]" %} 5094 interface(MEMORY_INTER) %{ 5095 base($reg); 5096 index(0x0); 5097 scale(0x0); 5098 disp($offset); 5099 %} 5100 %} 5101 5102 //----------Special Memory Operands-------------------------------------------- 5103 // Stack Slot Operand 5104 // 5105 // This operand is used for loading and storing temporary values on 5106 // the stack where a match requires a value to flow through memory. 5107 operand stackSlotI(sRegI reg) %{ 5108 constraint(ALLOC_IN_RC(stack_slots)); 5109 op_cost(100); 5110 //match(RegI); 5111 format %{ "[sp+$reg]" %} 5112 interface(MEMORY_INTER) %{ 5113 base(0x1); // R1_SP 5114 index(0x0); 5115 scale(0x0); 5116 disp($reg); // Stack Offset 5117 %} 5118 %} 5119 5120 operand stackSlotL(sRegL reg) %{ 5121 constraint(ALLOC_IN_RC(stack_slots)); 5122 op_cost(100); 5123 //match(RegL); 5124 format %{ "[sp+$reg]" %} 5125 interface(MEMORY_INTER) %{ 5126 base(0x1); // R1_SP 5127 index(0x0); 5128 scale(0x0); 5129 disp($reg); // Stack Offset 5130 %} 5131 %} 5132 5133 operand stackSlotP(sRegP reg) %{ 5134 constraint(ALLOC_IN_RC(stack_slots)); 5135 op_cost(100); 5136 //match(RegP); 5137 format %{ "[sp+$reg]" %} 5138 interface(MEMORY_INTER) %{ 5139 base(0x1); // R1_SP 5140 index(0x0); 5141 scale(0x0); 5142 disp($reg); // Stack Offset 5143 %} 5144 %} 5145 5146 operand stackSlotF(sRegF reg) %{ 5147 constraint(ALLOC_IN_RC(stack_slots)); 5148 op_cost(100); 5149 //match(RegF); 5150 format %{ "[sp+$reg]" %} 5151 interface(MEMORY_INTER) %{ 5152 base(0x1); // R1_SP 5153 index(0x0); 5154 scale(0x0); 5155 disp($reg); // Stack Offset 5156 %} 5157 %} 5158 5159 operand stackSlotD(sRegD reg) %{ 5160 constraint(ALLOC_IN_RC(stack_slots)); 5161 op_cost(100); 5162 //match(RegD); 5163 format %{ "[sp+$reg]" %} 5164 interface(MEMORY_INTER) %{ 5165 base(0x1); // R1_SP 5166 index(0x0); 5167 scale(0x0); 5168 disp($reg); // Stack Offset 5169 %} 5170 %} 5171 5172 // Operands for expressing Control Flow 5173 // NOTE: Label is a predefined operand which should not be redefined in 5174 // the AD file. It is generically handled within the ADLC. 5175 5176 //----------Conditional Branch Operands---------------------------------------- 5177 // Comparison Op 5178 // 5179 // This is the operation of the comparison, and is limited to the 5180 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5181 // (!=). 5182 // 5183 // Other attributes of the comparison, such as unsignedness, are specified 5184 // by the comparison instruction that sets a condition code flags register. 5185 // That result is represented by a flags operand whose subtype is appropriate 5186 // to the unsignedness (etc.) of the comparison. 5187 // 5188 // Later, the instruction which matches both the Comparison Op (a Bool) and 5189 // the flags (produced by the Cmp) specifies the coding of the comparison op 5190 // by matching a specific subtype of Bool operand below. 5191 5192 // When used for floating point comparisons: unordered same as less. 5193 operand cmpOp() %{ 5194 match(Bool); 5195 format %{ "" %} 5196 interface(COND_INTER) %{ 5197 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5198 // BO & BI 5199 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5200 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5201 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5202 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5203 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5204 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5205 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5206 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5207 %} 5208 %} 5209 5210 //----------OPERAND CLASSES---------------------------------------------------- 5211 // Operand Classes are groups of operands that are used to simplify 5212 // instruction definitions by not requiring the AD writer to specify 5213 // seperate instructions for every form of operand when the 5214 // instruction accepts multiple operand types with the same basic 5215 // encoding and format. The classic case of this is memory operands. 5216 // Indirect is not included since its use is limited to Compare & Swap. 5217 5218 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5219 // Memory operand where offsets are 4-aligned. Required for ld, std. 5220 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5221 opclass indirectMemory(indirect, indirectNarrow); 5222 5223 // Special opclass for I and ConvL2I. 5224 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5225 5226 // Operand classes to match encode and decode. iRegN_P2N is only used 5227 // for storeN. I have never seen an encode node elsewhere. 5228 opclass iRegN_P2N(iRegNsrc, iRegP2N); 5229 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5230 5231 //----------PIPELINE----------------------------------------------------------- 5232 5233 pipeline %{ 5234 5235 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5236 // J. Res. & Dev., No. 1, Jan. 2002. 5237 5238 //----------ATTRIBUTES--------------------------------------------------------- 5239 attributes %{ 5240 5241 // Power4 instructions are of fixed length. 5242 fixed_size_instructions; 5243 5244 // TODO: if `bundle' means number of instructions fetched 5245 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5246 // max instructions issued per cycle, this is 5. 5247 max_instructions_per_bundle = 8; 5248 5249 // A Power4 instruction is 4 bytes long. 5250 instruction_unit_size = 4; 5251 5252 // The Power4 processor fetches 64 bytes... 5253 instruction_fetch_unit_size = 64; 5254 5255 // ...in one line 5256 instruction_fetch_units = 1 5257 5258 // Unused, list one so that array generated by adlc is not empty. 5259 // Aix compiler chokes if _nop_count = 0. 5260 nops(fxNop); 5261 %} 5262 5263 //----------RESOURCES---------------------------------------------------------- 5264 // Resources are the functional units available to the machine 5265 resources( 5266 PPC_BR, // branch unit 5267 PPC_CR, // condition unit 5268 PPC_FX1, // integer arithmetic unit 1 5269 PPC_FX2, // integer arithmetic unit 2 5270 PPC_LDST1, // load/store unit 1 5271 PPC_LDST2, // load/store unit 2 5272 PPC_FP1, // float arithmetic unit 1 5273 PPC_FP2, // float arithmetic unit 2 5274 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5275 PPC_FX = PPC_FX1 | PPC_FX2, 5276 PPC_FP = PPC_FP1 | PPC_FP2 5277 ); 5278 5279 //----------PIPELINE DESCRIPTION----------------------------------------------- 5280 // Pipeline Description specifies the stages in the machine's pipeline 5281 pipe_desc( 5282 // Power4 longest pipeline path 5283 PPC_IF, // instruction fetch 5284 PPC_IC, 5285 //PPC_BP, // branch prediction 5286 PPC_D0, // decode 5287 PPC_D1, // decode 5288 PPC_D2, // decode 5289 PPC_D3, // decode 5290 PPC_Xfer1, 5291 PPC_GD, // group definition 5292 PPC_MP, // map 5293 PPC_ISS, // issue 5294 PPC_RF, // resource fetch 5295 PPC_EX1, // execute (all units) 5296 PPC_EX2, // execute (FP, LDST) 5297 PPC_EX3, // execute (FP, LDST) 5298 PPC_EX4, // execute (FP) 5299 PPC_EX5, // execute (FP) 5300 PPC_EX6, // execute (FP) 5301 PPC_WB, // write back 5302 PPC_Xfer2, 5303 PPC_CP 5304 ); 5305 5306 //----------PIPELINE CLASSES--------------------------------------------------- 5307 // Pipeline Classes describe the stages in which input and output are 5308 // referenced by the hardware pipeline. 5309 5310 // Simple pipeline classes. 5311 5312 // Default pipeline class. 5313 pipe_class pipe_class_default() %{ 5314 single_instruction; 5315 fixed_latency(2); 5316 %} 5317 5318 // Pipeline class for empty instructions. 5319 pipe_class pipe_class_empty() %{ 5320 single_instruction; 5321 fixed_latency(0); 5322 %} 5323 5324 // Pipeline class for compares. 5325 pipe_class pipe_class_compare() %{ 5326 single_instruction; 5327 fixed_latency(16); 5328 %} 5329 5330 // Pipeline class for traps. 5331 pipe_class pipe_class_trap() %{ 5332 single_instruction; 5333 fixed_latency(100); 5334 %} 5335 5336 // Pipeline class for memory operations. 5337 pipe_class pipe_class_memory() %{ 5338 single_instruction; 5339 fixed_latency(16); 5340 %} 5341 5342 // Pipeline class for call. 5343 pipe_class pipe_class_call() %{ 5344 single_instruction; 5345 fixed_latency(100); 5346 %} 5347 5348 // Define the class for the Nop node. 5349 define %{ 5350 MachNop = pipe_class_default; 5351 %} 5352 5353 %} 5354 5355 //----------INSTRUCTIONS------------------------------------------------------- 5356 5357 // Naming of instructions: 5358 // opA_operB / opA_operB_operC: 5359 // Operation 'op' with one or two source operands 'oper'. Result 5360 // type is A, source operand types are B and C. 5361 // Iff A == B == C, B and C are left out. 5362 // 5363 // The instructions are ordered according to the following scheme: 5364 // - loads 5365 // - load constants 5366 // - prefetch 5367 // - store 5368 // - encode/decode 5369 // - membar 5370 // - conditional moves 5371 // - compare & swap 5372 // - arithmetic and logic operations 5373 // * int: Add, Sub, Mul, Div, Mod 5374 // * int: lShift, arShift, urShift, rot 5375 // * float: Add, Sub, Mul, Div 5376 // * and, or, xor ... 5377 // - register moves: float <-> int, reg <-> stack, repl 5378 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5379 // - conv (low level type cast requiring bit changes (sign extend etc) 5380 // - compares, range & zero checks. 5381 // - branches 5382 // - complex operations, intrinsics, min, max, replicate 5383 // - lock 5384 // - Calls 5385 // 5386 // If there are similar instructions with different types they are sorted: 5387 // int before float 5388 // small before big 5389 // signed before unsigned 5390 // e.g., loadS before loadUS before loadI before loadF. 5391 5392 5393 //----------Load/Store Instructions-------------------------------------------- 5394 5395 //----------Load Instructions-------------------------------------------------- 5396 5397 // Converts byte to int. 5398 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5399 // reuses the 'amount' operand, but adlc expects that operand specification 5400 // and operands in match rule are equivalent. 5401 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5402 effect(DEF dst, USE src); 5403 format %{ "EXTSB $dst, $src \t// byte->int" %} 5404 size(4); 5405 ins_encode %{ 5406 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5407 __ extsb($dst$$Register, $src$$Register); 5408 %} 5409 ins_pipe(pipe_class_default); 5410 %} 5411 5412 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5413 // match-rule, false predicate 5414 match(Set dst (LoadB mem)); 5415 predicate(false); 5416 5417 format %{ "LBZ $dst, $mem" %} 5418 size(4); 5419 ins_encode( enc_lbz(dst, mem) ); 5420 ins_pipe(pipe_class_memory); 5421 %} 5422 5423 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5424 // match-rule, false predicate 5425 match(Set dst (LoadB mem)); 5426 predicate(false); 5427 5428 format %{ "LBZ $dst, $mem\n\t" 5429 "TWI $dst\n\t" 5430 "ISYNC" %} 5431 size(12); 5432 ins_encode( enc_lbz_ac(dst, mem) ); 5433 ins_pipe(pipe_class_memory); 5434 %} 5435 5436 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5437 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5438 match(Set dst (LoadB mem)); 5439 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5440 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5441 expand %{ 5442 iRegIdst tmp; 5443 loadUB_indirect(tmp, mem); 5444 convB2I_reg_2(dst, tmp); 5445 %} 5446 %} 5447 5448 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5449 match(Set dst (LoadB mem)); 5450 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5451 expand %{ 5452 iRegIdst tmp; 5453 loadUB_indirect_ac(tmp, mem); 5454 convB2I_reg_2(dst, tmp); 5455 %} 5456 %} 5457 5458 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5459 // match-rule, false predicate 5460 match(Set dst (LoadB mem)); 5461 predicate(false); 5462 5463 format %{ "LBZ $dst, $mem" %} 5464 size(4); 5465 ins_encode( enc_lbz(dst, mem) ); 5466 ins_pipe(pipe_class_memory); 5467 %} 5468 5469 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5470 // match-rule, false predicate 5471 match(Set dst (LoadB mem)); 5472 predicate(false); 5473 5474 format %{ "LBZ $dst, $mem\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 Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5483 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5484 match(Set dst (LoadB mem)); 5485 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5486 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5487 5488 expand %{ 5489 iRegIdst tmp; 5490 loadUB_indOffset16(tmp, mem); 5491 convB2I_reg_2(dst, tmp); 5492 %} 5493 %} 5494 5495 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5496 match(Set dst (LoadB mem)); 5497 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5498 5499 expand %{ 5500 iRegIdst tmp; 5501 loadUB_indOffset16_ac(tmp, mem); 5502 convB2I_reg_2(dst, tmp); 5503 %} 5504 %} 5505 5506 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5507 instruct loadUB(iRegIdst dst, memory mem) %{ 5508 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5509 match(Set dst (LoadUB mem)); 5510 ins_cost(MEMORY_REF_COST); 5511 5512 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5513 size(4); 5514 ins_encode( enc_lbz(dst, mem) ); 5515 ins_pipe(pipe_class_memory); 5516 %} 5517 5518 // Load Unsigned Byte (8bit UNsigned) acquire. 5519 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5520 match(Set dst (LoadUB mem)); 5521 ins_cost(3*MEMORY_REF_COST); 5522 5523 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5524 "TWI $dst\n\t" 5525 "ISYNC" %} 5526 size(12); 5527 ins_encode( enc_lbz_ac(dst, mem) ); 5528 ins_pipe(pipe_class_memory); 5529 %} 5530 5531 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5532 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5533 match(Set dst (ConvI2L (LoadUB mem))); 5534 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5535 ins_cost(MEMORY_REF_COST); 5536 5537 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5538 size(4); 5539 ins_encode( enc_lbz(dst, mem) ); 5540 ins_pipe(pipe_class_memory); 5541 %} 5542 5543 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5544 match(Set dst (ConvI2L (LoadUB mem))); 5545 ins_cost(3*MEMORY_REF_COST); 5546 5547 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5548 "TWI $dst\n\t" 5549 "ISYNC" %} 5550 size(12); 5551 ins_encode( enc_lbz_ac(dst, mem) ); 5552 ins_pipe(pipe_class_memory); 5553 %} 5554 5555 // Load Short (16bit signed) 5556 instruct loadS(iRegIdst dst, memory mem) %{ 5557 match(Set dst (LoadS mem)); 5558 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5559 ins_cost(MEMORY_REF_COST); 5560 5561 format %{ "LHA $dst, $mem" %} 5562 size(4); 5563 ins_encode %{ 5564 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5565 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5566 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5567 %} 5568 ins_pipe(pipe_class_memory); 5569 %} 5570 5571 // Load Short (16bit signed) acquire. 5572 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5573 match(Set dst (LoadS mem)); 5574 ins_cost(3*MEMORY_REF_COST); 5575 5576 format %{ "LHA $dst, $mem\t acquire\n\t" 5577 "TWI $dst\n\t" 5578 "ISYNC" %} 5579 size(12); 5580 ins_encode %{ 5581 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5582 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5583 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5584 __ twi_0($dst$$Register); 5585 __ isync(); 5586 %} 5587 ins_pipe(pipe_class_memory); 5588 %} 5589 5590 // Load Char (16bit unsigned) 5591 instruct loadUS(iRegIdst dst, memory mem) %{ 5592 match(Set dst (LoadUS mem)); 5593 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5594 ins_cost(MEMORY_REF_COST); 5595 5596 format %{ "LHZ $dst, $mem" %} 5597 size(4); 5598 ins_encode( enc_lhz(dst, mem) ); 5599 ins_pipe(pipe_class_memory); 5600 %} 5601 5602 // Load Char (16bit unsigned) acquire. 5603 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5604 match(Set dst (LoadUS mem)); 5605 ins_cost(3*MEMORY_REF_COST); 5606 5607 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5608 "TWI $dst\n\t" 5609 "ISYNC" %} 5610 size(12); 5611 ins_encode( enc_lhz_ac(dst, mem) ); 5612 ins_pipe(pipe_class_memory); 5613 %} 5614 5615 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5616 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5617 match(Set dst (ConvI2L (LoadUS mem))); 5618 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5619 ins_cost(MEMORY_REF_COST); 5620 5621 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5622 size(4); 5623 ins_encode( enc_lhz(dst, mem) ); 5624 ins_pipe(pipe_class_memory); 5625 %} 5626 5627 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5628 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5629 match(Set dst (ConvI2L (LoadUS mem))); 5630 ins_cost(3*MEMORY_REF_COST); 5631 5632 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5633 "TWI $dst\n\t" 5634 "ISYNC" %} 5635 size(12); 5636 ins_encode( enc_lhz_ac(dst, mem) ); 5637 ins_pipe(pipe_class_memory); 5638 %} 5639 5640 // Load Integer. 5641 instruct loadI(iRegIdst dst, memory mem) %{ 5642 match(Set dst (LoadI mem)); 5643 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5644 ins_cost(MEMORY_REF_COST); 5645 5646 format %{ "LWZ $dst, $mem" %} 5647 size(4); 5648 ins_encode( enc_lwz(dst, mem) ); 5649 ins_pipe(pipe_class_memory); 5650 %} 5651 5652 // Load Integer acquire. 5653 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5654 match(Set dst (LoadI mem)); 5655 ins_cost(3*MEMORY_REF_COST); 5656 5657 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5658 "TWI $dst\n\t" 5659 "ISYNC" %} 5660 size(12); 5661 ins_encode( enc_lwz_ac(dst, mem) ); 5662 ins_pipe(pipe_class_memory); 5663 %} 5664 5665 // Match loading integer and casting it to unsigned int in 5666 // long register. 5667 // LoadI + ConvI2L + AndL 0xffffffff. 5668 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5669 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5670 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5671 ins_cost(MEMORY_REF_COST); 5672 5673 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5674 size(4); 5675 ins_encode( enc_lwz(dst, mem) ); 5676 ins_pipe(pipe_class_memory); 5677 %} 5678 5679 // Match loading integer and casting it to long. 5680 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5681 match(Set dst (ConvI2L (LoadI mem))); 5682 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5683 ins_cost(MEMORY_REF_COST); 5684 5685 format %{ "LWA $dst, $mem \t// loadI2L" %} 5686 size(4); 5687 ins_encode %{ 5688 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5689 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5690 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5691 %} 5692 ins_pipe(pipe_class_memory); 5693 %} 5694 5695 // Match loading integer and casting it to long - acquire. 5696 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5697 match(Set dst (ConvI2L (LoadI mem))); 5698 ins_cost(3*MEMORY_REF_COST); 5699 5700 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5701 "TWI $dst\n\t" 5702 "ISYNC" %} 5703 size(12); 5704 ins_encode %{ 5705 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5706 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5707 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5708 __ twi_0($dst$$Register); 5709 __ isync(); 5710 %} 5711 ins_pipe(pipe_class_memory); 5712 %} 5713 5714 // Load Long - aligned 5715 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5716 match(Set dst (LoadL mem)); 5717 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5718 ins_cost(MEMORY_REF_COST); 5719 5720 format %{ "LD $dst, $mem \t// long" %} 5721 size(4); 5722 ins_encode( enc_ld(dst, mem) ); 5723 ins_pipe(pipe_class_memory); 5724 %} 5725 5726 // Load Long - aligned acquire. 5727 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5728 match(Set dst (LoadL mem)); 5729 ins_cost(3*MEMORY_REF_COST); 5730 5731 format %{ "LD $dst, $mem \t// long acquire\n\t" 5732 "TWI $dst\n\t" 5733 "ISYNC" %} 5734 size(12); 5735 ins_encode( enc_ld_ac(dst, mem) ); 5736 ins_pipe(pipe_class_memory); 5737 %} 5738 5739 // Load Long - UNaligned 5740 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5741 match(Set dst (LoadL_unaligned mem)); 5742 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5743 ins_cost(MEMORY_REF_COST); 5744 5745 format %{ "LD $dst, $mem \t// unaligned long" %} 5746 size(4); 5747 ins_encode( enc_ld(dst, mem) ); 5748 ins_pipe(pipe_class_memory); 5749 %} 5750 5751 // Load nodes for superwords 5752 5753 // Load Aligned Packed Byte 5754 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5755 predicate(n->as_LoadVector()->memory_size() == 8); 5756 match(Set dst (LoadVector mem)); 5757 ins_cost(MEMORY_REF_COST); 5758 5759 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5760 size(4); 5761 ins_encode( enc_ld(dst, mem) ); 5762 ins_pipe(pipe_class_memory); 5763 %} 5764 5765 // Load Aligned Packed Byte 5766 instruct loadV16(vecX dst, indirect mem) %{ 5767 predicate(n->as_LoadVector()->memory_size() == 16); 5768 match(Set dst (LoadVector mem)); 5769 ins_cost(MEMORY_REF_COST); 5770 5771 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5772 size(4); 5773 ins_encode %{ 5774 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5775 %} 5776 ins_pipe(pipe_class_default); 5777 %} 5778 5779 // Load Range, range = array length (=jint) 5780 instruct loadRange(iRegIdst dst, memory mem) %{ 5781 match(Set dst (LoadRange mem)); 5782 ins_cost(MEMORY_REF_COST); 5783 5784 format %{ "LWZ $dst, $mem \t// range" %} 5785 size(4); 5786 ins_encode( enc_lwz(dst, mem) ); 5787 ins_pipe(pipe_class_memory); 5788 %} 5789 5790 // Load Compressed Pointer 5791 instruct loadN(iRegNdst dst, memory mem) %{ 5792 match(Set dst (LoadN mem)); 5793 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5794 ins_cost(MEMORY_REF_COST); 5795 5796 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5797 size(4); 5798 ins_encode( enc_lwz(dst, mem) ); 5799 ins_pipe(pipe_class_memory); 5800 %} 5801 5802 // Load Compressed Pointer acquire. 5803 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5804 match(Set dst (LoadN mem)); 5805 ins_cost(3*MEMORY_REF_COST); 5806 5807 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5808 "TWI $dst\n\t" 5809 "ISYNC" %} 5810 size(12); 5811 ins_encode( enc_lwz_ac(dst, mem) ); 5812 ins_pipe(pipe_class_memory); 5813 %} 5814 5815 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5816 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5817 match(Set dst (DecodeN (LoadN mem))); 5818 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5819 ins_cost(MEMORY_REF_COST); 5820 5821 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5822 size(4); 5823 ins_encode( enc_lwz(dst, mem) ); 5824 ins_pipe(pipe_class_memory); 5825 %} 5826 5827 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5828 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5829 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5830 _kids[0]->_leaf->as_Load()->is_unordered()); 5831 ins_cost(MEMORY_REF_COST); 5832 5833 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5834 size(4); 5835 ins_encode( enc_lwz(dst, mem) ); 5836 ins_pipe(pipe_class_memory); 5837 %} 5838 5839 // Load Pointer 5840 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5841 match(Set dst (LoadP mem)); 5842 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5843 ins_cost(MEMORY_REF_COST); 5844 5845 format %{ "LD $dst, $mem \t// ptr" %} 5846 size(4); 5847 ins_encode( enc_ld(dst, mem) ); 5848 ins_pipe(pipe_class_memory); 5849 %} 5850 5851 // Load Pointer acquire. 5852 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5853 match(Set dst (LoadP mem)); 5854 ins_cost(3*MEMORY_REF_COST); 5855 5856 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5857 "TWI $dst\n\t" 5858 "ISYNC" %} 5859 size(12); 5860 ins_encode( enc_ld_ac(dst, mem) ); 5861 ins_pipe(pipe_class_memory); 5862 %} 5863 5864 // LoadP + CastP2L 5865 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5866 match(Set dst (CastP2X (LoadP mem))); 5867 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5868 ins_cost(MEMORY_REF_COST); 5869 5870 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5871 size(4); 5872 ins_encode( enc_ld(dst, mem) ); 5873 ins_pipe(pipe_class_memory); 5874 %} 5875 5876 // Load compressed klass pointer. 5877 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5878 match(Set dst (LoadNKlass mem)); 5879 ins_cost(MEMORY_REF_COST); 5880 5881 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5882 size(4); 5883 ins_encode( enc_lwz(dst, mem) ); 5884 ins_pipe(pipe_class_memory); 5885 %} 5886 5887 // Load Klass Pointer 5888 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5889 match(Set dst (LoadKlass mem)); 5890 ins_cost(MEMORY_REF_COST); 5891 5892 format %{ "LD $dst, $mem \t// klass ptr" %} 5893 size(4); 5894 ins_encode( enc_ld(dst, mem) ); 5895 ins_pipe(pipe_class_memory); 5896 %} 5897 5898 // Load Float 5899 instruct loadF(regF dst, memory mem) %{ 5900 match(Set dst (LoadF mem)); 5901 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5902 ins_cost(MEMORY_REF_COST); 5903 5904 format %{ "LFS $dst, $mem" %} 5905 size(4); 5906 ins_encode %{ 5907 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5908 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5909 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5910 %} 5911 ins_pipe(pipe_class_memory); 5912 %} 5913 5914 // Load Float acquire. 5915 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5916 match(Set dst (LoadF mem)); 5917 effect(TEMP cr0); 5918 ins_cost(3*MEMORY_REF_COST); 5919 5920 format %{ "LFS $dst, $mem \t// acquire\n\t" 5921 "FCMPU cr0, $dst, $dst\n\t" 5922 "BNE cr0, next\n" 5923 "next:\n\t" 5924 "ISYNC" %} 5925 size(16); 5926 ins_encode %{ 5927 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5928 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5929 Label next; 5930 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5931 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5932 __ bne(CCR0, next); 5933 __ bind(next); 5934 __ isync(); 5935 %} 5936 ins_pipe(pipe_class_memory); 5937 %} 5938 5939 // Load Double - aligned 5940 instruct loadD(regD dst, memory mem) %{ 5941 match(Set dst (LoadD mem)); 5942 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5943 ins_cost(MEMORY_REF_COST); 5944 5945 format %{ "LFD $dst, $mem" %} 5946 size(4); 5947 ins_encode( enc_lfd(dst, mem) ); 5948 ins_pipe(pipe_class_memory); 5949 %} 5950 5951 // Load Double - aligned acquire. 5952 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5953 match(Set dst (LoadD mem)); 5954 effect(TEMP cr0); 5955 ins_cost(3*MEMORY_REF_COST); 5956 5957 format %{ "LFD $dst, $mem \t// acquire\n\t" 5958 "FCMPU cr0, $dst, $dst\n\t" 5959 "BNE cr0, next\n" 5960 "next:\n\t" 5961 "ISYNC" %} 5962 size(16); 5963 ins_encode %{ 5964 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5965 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5966 Label next; 5967 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5968 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5969 __ bne(CCR0, next); 5970 __ bind(next); 5971 __ isync(); 5972 %} 5973 ins_pipe(pipe_class_memory); 5974 %} 5975 5976 // Load Double - UNaligned 5977 instruct loadD_unaligned(regD dst, memory mem) %{ 5978 match(Set dst (LoadD_unaligned mem)); 5979 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5980 ins_cost(MEMORY_REF_COST); 5981 5982 format %{ "LFD $dst, $mem" %} 5983 size(4); 5984 ins_encode( enc_lfd(dst, mem) ); 5985 ins_pipe(pipe_class_memory); 5986 %} 5987 5988 //----------Constants-------------------------------------------------------- 5989 5990 // Load MachConstantTableBase: add hi offset to global toc. 5991 // TODO: Handle hidden register r29 in bundler! 5992 instruct loadToc_hi(iRegLdst dst) %{ 5993 effect(DEF dst); 5994 ins_cost(DEFAULT_COST); 5995 5996 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 5997 size(4); 5998 ins_encode %{ 5999 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6000 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 6001 %} 6002 ins_pipe(pipe_class_default); 6003 %} 6004 6005 // Load MachConstantTableBase: add lo offset to global toc. 6006 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 6007 effect(DEF dst, USE src); 6008 ins_cost(DEFAULT_COST); 6009 6010 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 6011 size(4); 6012 ins_encode %{ 6013 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6014 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 6015 %} 6016 ins_pipe(pipe_class_default); 6017 %} 6018 6019 // Load 16-bit integer constant 0xssss???? 6020 instruct loadConI16(iRegIdst dst, immI16 src) %{ 6021 match(Set dst src); 6022 6023 format %{ "LI $dst, $src" %} 6024 size(4); 6025 ins_encode %{ 6026 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6027 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6028 %} 6029 ins_pipe(pipe_class_default); 6030 %} 6031 6032 // Load integer constant 0x????0000 6033 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 6034 match(Set dst src); 6035 ins_cost(DEFAULT_COST); 6036 6037 format %{ "LIS $dst, $src.hi" %} 6038 size(4); 6039 ins_encode %{ 6040 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6041 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 6042 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6043 %} 6044 ins_pipe(pipe_class_default); 6045 %} 6046 6047 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 6048 // and sign extended), this adds the low 16 bits. 6049 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6050 // no match-rule, false predicate 6051 effect(DEF dst, USE src1, USE src2); 6052 predicate(false); 6053 6054 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6055 size(4); 6056 ins_encode %{ 6057 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6058 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6059 %} 6060 ins_pipe(pipe_class_default); 6061 %} 6062 6063 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6064 match(Set dst src); 6065 ins_cost(DEFAULT_COST*2); 6066 6067 expand %{ 6068 // Would like to use $src$$constant. 6069 immI16 srcLo %{ _opnds[1]->constant() %} 6070 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6071 immIhi16 srcHi %{ _opnds[1]->constant() %} 6072 iRegIdst tmpI; 6073 loadConIhi16(tmpI, srcHi); 6074 loadConI32_lo16(dst, tmpI, srcLo); 6075 %} 6076 %} 6077 6078 // No constant pool entries required. 6079 instruct loadConL16(iRegLdst dst, immL16 src) %{ 6080 match(Set dst src); 6081 6082 format %{ "LI $dst, $src \t// long" %} 6083 size(4); 6084 ins_encode %{ 6085 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6086 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6087 %} 6088 ins_pipe(pipe_class_default); 6089 %} 6090 6091 // Load long constant 0xssssssss????0000 6092 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6093 match(Set dst src); 6094 ins_cost(DEFAULT_COST); 6095 6096 format %{ "LIS $dst, $src.hi \t// long" %} 6097 size(4); 6098 ins_encode %{ 6099 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6100 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6101 %} 6102 ins_pipe(pipe_class_default); 6103 %} 6104 6105 // To load a 32 bit constant: merge lower 16 bits into already loaded 6106 // high 16 bits. 6107 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6108 // no match-rule, false predicate 6109 effect(DEF dst, USE src1, USE src2); 6110 predicate(false); 6111 6112 format %{ "ORI $dst, $src1, $src2.lo" %} 6113 size(4); 6114 ins_encode %{ 6115 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6116 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6117 %} 6118 ins_pipe(pipe_class_default); 6119 %} 6120 6121 // Load 32-bit long constant 6122 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6123 match(Set dst src); 6124 ins_cost(DEFAULT_COST*2); 6125 6126 expand %{ 6127 // Would like to use $src$$constant. 6128 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6129 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6130 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6131 iRegLdst tmpL; 6132 loadConL32hi16(tmpL, srcHi); 6133 loadConL32_lo16(dst, tmpL, srcLo); 6134 %} 6135 %} 6136 6137 // Load long constant 0x????000000000000. 6138 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6139 match(Set dst src); 6140 ins_cost(DEFAULT_COST); 6141 6142 expand %{ 6143 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6144 immI shift32 %{ 32 %} 6145 iRegLdst tmpL; 6146 loadConL32hi16(tmpL, srcHi); 6147 lshiftL_regL_immI(dst, tmpL, shift32); 6148 %} 6149 %} 6150 6151 // Expand node for constant pool load: small offset. 6152 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6153 effect(DEF dst, USE src, USE toc); 6154 ins_cost(MEMORY_REF_COST); 6155 6156 ins_num_consts(1); 6157 // Needed so that CallDynamicJavaDirect can compute the address of this 6158 // instruction for relocation. 6159 ins_field_cbuf_insts_offset(int); 6160 6161 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6162 size(4); 6163 ins_encode( enc_load_long_constL(dst, src, toc) ); 6164 ins_pipe(pipe_class_memory); 6165 %} 6166 6167 // Expand node for constant pool load: large offset. 6168 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6169 effect(DEF dst, USE src, USE toc); 6170 predicate(false); 6171 6172 ins_num_consts(1); 6173 ins_field_const_toc_offset(int); 6174 // Needed so that CallDynamicJavaDirect can compute the address of this 6175 // instruction for relocation. 6176 ins_field_cbuf_insts_offset(int); 6177 6178 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6179 size(4); 6180 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6181 ins_pipe(pipe_class_default); 6182 %} 6183 6184 // Expand node for constant pool load: large offset. 6185 // No constant pool entries required. 6186 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6187 effect(DEF dst, USE src, USE base); 6188 predicate(false); 6189 6190 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6191 6192 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6193 size(4); 6194 ins_encode %{ 6195 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6196 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6197 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6198 %} 6199 ins_pipe(pipe_class_memory); 6200 %} 6201 6202 // Load long constant from constant table. Expand in case of 6203 // offset > 16 bit is needed. 6204 // Adlc adds toc node MachConstantTableBase. 6205 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6206 match(Set dst src); 6207 ins_cost(MEMORY_REF_COST); 6208 6209 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6210 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6211 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6212 %} 6213 6214 // Load NULL as compressed oop. 6215 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6216 match(Set dst src); 6217 ins_cost(DEFAULT_COST); 6218 6219 format %{ "LI $dst, $src \t// compressed ptr" %} 6220 size(4); 6221 ins_encode %{ 6222 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6223 __ li($dst$$Register, 0); 6224 %} 6225 ins_pipe(pipe_class_default); 6226 %} 6227 6228 // Load hi part of compressed oop constant. 6229 instruct loadConN_hi(iRegNdst dst, immN src) %{ 6230 effect(DEF dst, USE src); 6231 ins_cost(DEFAULT_COST); 6232 6233 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6234 size(4); 6235 ins_encode %{ 6236 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6237 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6238 %} 6239 ins_pipe(pipe_class_default); 6240 %} 6241 6242 // Add lo part of compressed oop constant to already loaded hi part. 6243 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6244 effect(DEF dst, USE src1, USE src2); 6245 ins_cost(DEFAULT_COST); 6246 6247 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6248 size(4); 6249 ins_encode %{ 6250 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6251 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6252 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6253 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6254 __ relocate(rspec, 1); 6255 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6256 %} 6257 ins_pipe(pipe_class_default); 6258 %} 6259 6260 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6261 effect(DEF dst, USE src, USE shift, USE mask_begin); 6262 6263 size(4); 6264 ins_encode %{ 6265 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6266 %} 6267 ins_pipe(pipe_class_default); 6268 %} 6269 6270 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6271 // leaving the upper 32 bits with sign-extension bits. 6272 // This clears these bits: dst = src & 0xFFFFFFFF. 6273 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6274 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6275 effect(DEF dst, USE src); 6276 predicate(false); 6277 6278 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6279 size(4); 6280 ins_encode %{ 6281 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6282 __ clrldi($dst$$Register, $src$$Register, 0x20); 6283 %} 6284 ins_pipe(pipe_class_default); 6285 %} 6286 6287 // Optimize DecodeN for disjoint base. 6288 // Load base of compressed oops into a register 6289 instruct loadBase(iRegLdst dst) %{ 6290 effect(DEF dst); 6291 6292 format %{ "LoadConst $dst, heapbase" %} 6293 ins_encode %{ 6294 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6295 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 6296 %} 6297 ins_pipe(pipe_class_default); 6298 %} 6299 6300 // Loading ConN must be postalloc expanded so that edges between 6301 // the nodes are safe. They may not interfere with a safepoint. 6302 // GL TODO: This needs three instructions: better put this into the constant pool. 6303 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6304 match(Set dst src); 6305 ins_cost(DEFAULT_COST*2); 6306 6307 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6308 postalloc_expand %{ 6309 MachNode *m1 = new loadConN_hiNode(); 6310 MachNode *m2 = new loadConN_loNode(); 6311 MachNode *m3 = new clearMs32bNode(); 6312 m1->add_req(NULL); 6313 m2->add_req(NULL, m1); 6314 m3->add_req(NULL, m2); 6315 m1->_opnds[0] = op_dst; 6316 m1->_opnds[1] = op_src; 6317 m2->_opnds[0] = op_dst; 6318 m2->_opnds[1] = op_dst; 6319 m2->_opnds[2] = op_src; 6320 m3->_opnds[0] = op_dst; 6321 m3->_opnds[1] = op_dst; 6322 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6323 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6324 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6325 nodes->push(m1); 6326 nodes->push(m2); 6327 nodes->push(m3); 6328 %} 6329 %} 6330 6331 // We have seen a safepoint between the hi and lo parts, and this node was handled 6332 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6333 // not a narrow oop. 6334 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6335 match(Set dst src); 6336 effect(DEF dst, USE src); 6337 ins_cost(DEFAULT_COST); 6338 6339 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6340 size(4); 6341 ins_encode %{ 6342 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6343 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 6344 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6345 %} 6346 ins_pipe(pipe_class_default); 6347 %} 6348 6349 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6350 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6351 match(Set dst src1); 6352 effect(TEMP src2); 6353 ins_cost(DEFAULT_COST); 6354 6355 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6356 size(4); 6357 ins_encode %{ 6358 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6359 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6360 %} 6361 ins_pipe(pipe_class_default); 6362 %} 6363 6364 // This needs a match rule so that build_oop_map knows this is 6365 // not a narrow oop. 6366 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6367 match(Set dst src1); 6368 effect(TEMP src2); 6369 ins_cost(DEFAULT_COST); 6370 6371 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6372 size(4); 6373 ins_encode %{ 6374 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6375 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 6376 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6377 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6378 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6379 6380 __ relocate(rspec, 1); 6381 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6382 %} 6383 ins_pipe(pipe_class_default); 6384 %} 6385 6386 // Loading ConNKlass must be postalloc expanded so that edges between 6387 // the nodes are safe. They may not interfere with a safepoint. 6388 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6389 match(Set dst src); 6390 ins_cost(DEFAULT_COST*2); 6391 6392 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6393 postalloc_expand %{ 6394 // Load high bits into register. Sign extended. 6395 MachNode *m1 = new loadConNKlass_hiNode(); 6396 m1->add_req(NULL); 6397 m1->_opnds[0] = op_dst; 6398 m1->_opnds[1] = op_src; 6399 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6400 nodes->push(m1); 6401 6402 MachNode *m2 = m1; 6403 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 6404 // Value might be 1-extended. Mask out these bits. 6405 m2 = new loadConNKlass_maskNode(); 6406 m2->add_req(NULL, m1); 6407 m2->_opnds[0] = op_dst; 6408 m2->_opnds[1] = op_src; 6409 m2->_opnds[2] = op_dst; 6410 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6411 nodes->push(m2); 6412 } 6413 6414 MachNode *m3 = new loadConNKlass_loNode(); 6415 m3->add_req(NULL, m2); 6416 m3->_opnds[0] = op_dst; 6417 m3->_opnds[1] = op_src; 6418 m3->_opnds[2] = op_dst; 6419 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6420 nodes->push(m3); 6421 %} 6422 %} 6423 6424 // 0x1 is used in object initialization (initial object header). 6425 // No constant pool entries required. 6426 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6427 match(Set dst src); 6428 6429 format %{ "LI $dst, $src \t// ptr" %} 6430 size(4); 6431 ins_encode %{ 6432 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6433 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6434 %} 6435 ins_pipe(pipe_class_default); 6436 %} 6437 6438 // Expand node for constant pool load: small offset. 6439 // The match rule is needed to generate the correct bottom_type(), 6440 // however this node should never match. The use of predicate is not 6441 // possible since ADLC forbids predicates for chain rules. The higher 6442 // costs do not prevent matching in this case. For that reason the 6443 // operand immP_NM with predicate(false) is used. 6444 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6445 match(Set dst src); 6446 effect(TEMP toc); 6447 6448 ins_num_consts(1); 6449 6450 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6451 size(4); 6452 ins_encode( enc_load_long_constP(dst, src, toc) ); 6453 ins_pipe(pipe_class_memory); 6454 %} 6455 6456 // Expand node for constant pool load: large offset. 6457 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6458 effect(DEF dst, USE src, USE toc); 6459 predicate(false); 6460 6461 ins_num_consts(1); 6462 ins_field_const_toc_offset(int); 6463 6464 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6465 size(4); 6466 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6467 ins_pipe(pipe_class_default); 6468 %} 6469 6470 // Expand node for constant pool load: large offset. 6471 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6472 match(Set dst src); 6473 effect(TEMP base); 6474 6475 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6476 6477 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6478 size(4); 6479 ins_encode %{ 6480 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6481 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6482 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6483 %} 6484 ins_pipe(pipe_class_memory); 6485 %} 6486 6487 // Load pointer constant from constant table. Expand in case an 6488 // offset > 16 bit is needed. 6489 // Adlc adds toc node MachConstantTableBase. 6490 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6491 match(Set dst src); 6492 ins_cost(MEMORY_REF_COST); 6493 6494 // This rule does not use "expand" because then 6495 // the result type is not known to be an Oop. An ADLC 6496 // enhancement will be needed to make that work - not worth it! 6497 6498 // If this instruction rematerializes, it prolongs the live range 6499 // of the toc node, causing illegal graphs. 6500 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6501 ins_cannot_rematerialize(true); 6502 6503 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6504 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6505 %} 6506 6507 // Expand node for constant pool load: small offset. 6508 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6509 effect(DEF dst, USE src, USE toc); 6510 ins_cost(MEMORY_REF_COST); 6511 6512 ins_num_consts(1); 6513 6514 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6515 size(4); 6516 ins_encode %{ 6517 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6518 address float_address = __ float_constant($src$$constant); 6519 if (float_address == NULL) { 6520 ciEnv::current()->record_out_of_memory_failure(); 6521 return; 6522 } 6523 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6524 %} 6525 ins_pipe(pipe_class_memory); 6526 %} 6527 6528 // Expand node for constant pool load: large offset. 6529 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6530 effect(DEF dst, USE src, USE toc); 6531 ins_cost(MEMORY_REF_COST); 6532 6533 ins_num_consts(1); 6534 6535 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6536 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6537 "ADDIS $toc, $toc, -offset_hi"%} 6538 size(12); 6539 ins_encode %{ 6540 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6541 FloatRegister Rdst = $dst$$FloatRegister; 6542 Register Rtoc = $toc$$Register; 6543 address float_address = __ float_constant($src$$constant); 6544 if (float_address == NULL) { 6545 ciEnv::current()->record_out_of_memory_failure(); 6546 return; 6547 } 6548 int offset = __ offset_to_method_toc(float_address); 6549 int hi = (offset + (1<<15))>>16; 6550 int lo = offset - hi * (1<<16); 6551 6552 __ addis(Rtoc, Rtoc, hi); 6553 __ lfs(Rdst, lo, Rtoc); 6554 __ addis(Rtoc, Rtoc, -hi); 6555 %} 6556 ins_pipe(pipe_class_memory); 6557 %} 6558 6559 // Adlc adds toc node MachConstantTableBase. 6560 instruct loadConF_Ex(regF dst, immF src) %{ 6561 match(Set dst src); 6562 ins_cost(MEMORY_REF_COST); 6563 6564 // See loadConP. 6565 ins_cannot_rematerialize(true); 6566 6567 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6568 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6569 %} 6570 6571 // Expand node for constant pool load: small offset. 6572 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6573 effect(DEF dst, USE src, USE toc); 6574 ins_cost(MEMORY_REF_COST); 6575 6576 ins_num_consts(1); 6577 6578 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6579 size(4); 6580 ins_encode %{ 6581 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6582 address float_address = __ double_constant($src$$constant); 6583 if (float_address == NULL) { 6584 ciEnv::current()->record_out_of_memory_failure(); 6585 return; 6586 } 6587 int offset = __ offset_to_method_toc(float_address); 6588 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6589 %} 6590 ins_pipe(pipe_class_memory); 6591 %} 6592 6593 // Expand node for constant pool load: large offset. 6594 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6595 effect(DEF dst, USE src, USE toc); 6596 ins_cost(MEMORY_REF_COST); 6597 6598 ins_num_consts(1); 6599 6600 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6601 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6602 "ADDIS $toc, $toc, -offset_hi" %} 6603 size(12); 6604 ins_encode %{ 6605 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6606 FloatRegister Rdst = $dst$$FloatRegister; 6607 Register Rtoc = $toc$$Register; 6608 address float_address = __ double_constant($src$$constant); 6609 if (float_address == NULL) { 6610 ciEnv::current()->record_out_of_memory_failure(); 6611 return; 6612 } 6613 int offset = __ offset_to_method_toc(float_address); 6614 int hi = (offset + (1<<15))>>16; 6615 int lo = offset - hi * (1<<16); 6616 6617 __ addis(Rtoc, Rtoc, hi); 6618 __ lfd(Rdst, lo, Rtoc); 6619 __ addis(Rtoc, Rtoc, -hi); 6620 %} 6621 ins_pipe(pipe_class_memory); 6622 %} 6623 6624 // Adlc adds toc node MachConstantTableBase. 6625 instruct loadConD_Ex(regD dst, immD src) %{ 6626 match(Set dst src); 6627 ins_cost(MEMORY_REF_COST); 6628 6629 // See loadConP. 6630 ins_cannot_rematerialize(true); 6631 6632 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6633 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6634 %} 6635 6636 // Prefetch instructions. 6637 // Must be safe to execute with invalid address (cannot fault). 6638 6639 // Special prefetch versions which use the dcbz instruction. 6640 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6641 match(PrefetchAllocation (AddP mem src)); 6642 predicate(AllocatePrefetchStyle == 3); 6643 ins_cost(MEMORY_REF_COST); 6644 6645 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6646 size(4); 6647 ins_encode %{ 6648 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6649 __ dcbz($src$$Register, $mem$$base$$Register); 6650 %} 6651 ins_pipe(pipe_class_memory); 6652 %} 6653 6654 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6655 match(PrefetchAllocation mem); 6656 predicate(AllocatePrefetchStyle == 3); 6657 ins_cost(MEMORY_REF_COST); 6658 6659 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6660 size(4); 6661 ins_encode %{ 6662 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6663 __ dcbz($mem$$base$$Register); 6664 %} 6665 ins_pipe(pipe_class_memory); 6666 %} 6667 6668 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6669 match(PrefetchAllocation (AddP mem src)); 6670 predicate(AllocatePrefetchStyle != 3); 6671 ins_cost(MEMORY_REF_COST); 6672 6673 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6674 size(4); 6675 ins_encode %{ 6676 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6677 __ dcbtst($src$$Register, $mem$$base$$Register); 6678 %} 6679 ins_pipe(pipe_class_memory); 6680 %} 6681 6682 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6683 match(PrefetchAllocation mem); 6684 predicate(AllocatePrefetchStyle != 3); 6685 ins_cost(MEMORY_REF_COST); 6686 6687 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6688 size(4); 6689 ins_encode %{ 6690 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6691 __ dcbtst($mem$$base$$Register); 6692 %} 6693 ins_pipe(pipe_class_memory); 6694 %} 6695 6696 //----------Store Instructions------------------------------------------------- 6697 6698 // Store Byte 6699 instruct storeB(memory mem, iRegIsrc src) %{ 6700 match(Set mem (StoreB mem src)); 6701 ins_cost(MEMORY_REF_COST); 6702 6703 format %{ "STB $src, $mem \t// byte" %} 6704 size(4); 6705 ins_encode %{ 6706 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6707 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6708 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6709 %} 6710 ins_pipe(pipe_class_memory); 6711 %} 6712 6713 // Store Char/Short 6714 instruct storeC(memory mem, iRegIsrc src) %{ 6715 match(Set mem (StoreC mem src)); 6716 ins_cost(MEMORY_REF_COST); 6717 6718 format %{ "STH $src, $mem \t// short" %} 6719 size(4); 6720 ins_encode %{ 6721 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6722 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6723 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6724 %} 6725 ins_pipe(pipe_class_memory); 6726 %} 6727 6728 // Store Integer 6729 instruct storeI(memory mem, iRegIsrc src) %{ 6730 match(Set mem (StoreI mem src)); 6731 ins_cost(MEMORY_REF_COST); 6732 6733 format %{ "STW $src, $mem" %} 6734 size(4); 6735 ins_encode( enc_stw(src, mem) ); 6736 ins_pipe(pipe_class_memory); 6737 %} 6738 6739 // ConvL2I + StoreI. 6740 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6741 match(Set mem (StoreI mem (ConvL2I src))); 6742 ins_cost(MEMORY_REF_COST); 6743 6744 format %{ "STW l2i($src), $mem" %} 6745 size(4); 6746 ins_encode( enc_stw(src, mem) ); 6747 ins_pipe(pipe_class_memory); 6748 %} 6749 6750 // Store Long 6751 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6752 match(Set mem (StoreL mem src)); 6753 ins_cost(MEMORY_REF_COST); 6754 6755 format %{ "STD $src, $mem \t// long" %} 6756 size(4); 6757 ins_encode( enc_std(src, mem) ); 6758 ins_pipe(pipe_class_memory); 6759 %} 6760 6761 // Store super word nodes. 6762 6763 // Store Aligned Packed Byte long register to memory 6764 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6765 predicate(n->as_StoreVector()->memory_size() == 8); 6766 match(Set mem (StoreVector mem src)); 6767 ins_cost(MEMORY_REF_COST); 6768 6769 format %{ "STD $mem, $src \t// packed8B" %} 6770 size(4); 6771 ins_encode( enc_std(src, mem) ); 6772 ins_pipe(pipe_class_memory); 6773 %} 6774 6775 // Store Packed Byte long register to memory 6776 instruct storeV16(indirect mem, vecX src) %{ 6777 predicate(n->as_StoreVector()->memory_size() == 16); 6778 match(Set mem (StoreVector mem src)); 6779 ins_cost(MEMORY_REF_COST); 6780 6781 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6782 size(4); 6783 ins_encode %{ 6784 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6785 %} 6786 ins_pipe(pipe_class_default); 6787 %} 6788 6789 // Store Compressed Oop 6790 instruct storeN(memory dst, iRegN_P2N src) %{ 6791 match(Set dst (StoreN dst src)); 6792 ins_cost(MEMORY_REF_COST); 6793 6794 format %{ "STW $src, $dst \t// compressed oop" %} 6795 size(4); 6796 ins_encode( enc_stw(src, dst) ); 6797 ins_pipe(pipe_class_memory); 6798 %} 6799 6800 // Store Compressed KLass 6801 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6802 match(Set dst (StoreNKlass dst src)); 6803 ins_cost(MEMORY_REF_COST); 6804 6805 format %{ "STW $src, $dst \t// compressed klass" %} 6806 size(4); 6807 ins_encode( enc_stw(src, dst) ); 6808 ins_pipe(pipe_class_memory); 6809 %} 6810 6811 // Store Pointer 6812 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6813 match(Set dst (StoreP dst src)); 6814 ins_cost(MEMORY_REF_COST); 6815 6816 format %{ "STD $src, $dst \t// ptr" %} 6817 size(4); 6818 ins_encode( enc_std(src, dst) ); 6819 ins_pipe(pipe_class_memory); 6820 %} 6821 6822 // Store Float 6823 instruct storeF(memory mem, regF src) %{ 6824 match(Set mem (StoreF mem src)); 6825 ins_cost(MEMORY_REF_COST); 6826 6827 format %{ "STFS $src, $mem" %} 6828 size(4); 6829 ins_encode( enc_stfs(src, mem) ); 6830 ins_pipe(pipe_class_memory); 6831 %} 6832 6833 // Store Double 6834 instruct storeD(memory mem, regD src) %{ 6835 match(Set mem (StoreD mem src)); 6836 ins_cost(MEMORY_REF_COST); 6837 6838 format %{ "STFD $src, $mem" %} 6839 size(4); 6840 ins_encode( enc_stfd(src, mem) ); 6841 ins_pipe(pipe_class_memory); 6842 %} 6843 6844 //----------Store Instructions With Zeros-------------------------------------- 6845 6846 // Card-mark for CMS garbage collection. 6847 // This cardmark does an optimization so that it must not always 6848 // do a releasing store. For this, it gets the address of 6849 // CMSCollectorCardTableBarrierSetBSExt::_requires_release as input. 6850 // (Using releaseFieldAddr in the match rule is a hack.) 6851 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6852 match(Set mem (StoreCM mem releaseFieldAddr)); 6853 effect(TEMP crx); 6854 predicate(false); 6855 ins_cost(MEMORY_REF_COST); 6856 6857 // See loadConP. 6858 ins_cannot_rematerialize(true); 6859 6860 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6861 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6862 ins_pipe(pipe_class_memory); 6863 %} 6864 6865 // Card-mark for CMS garbage collection. 6866 // This cardmark does an optimization so that it must not always 6867 // do a releasing store. For this, it needs the constant address of 6868 // CMSCollectorCardTableBarrierSetBSExt::_requires_release. 6869 // This constant address is split off here by expand so we can use 6870 // adlc / matcher functionality to load it from the constant section. 6871 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6872 match(Set mem (StoreCM mem zero)); 6873 predicate(UseConcMarkSweepGC); 6874 6875 expand %{ 6876 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableBarrierSetBSExt::requires_release_address() */ %} 6877 iRegLdst releaseFieldAddress; 6878 flagsReg crx; 6879 loadConL_Ex(releaseFieldAddress, baseImm); 6880 storeCM_CMS(mem, releaseFieldAddress, crx); 6881 %} 6882 %} 6883 6884 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6885 match(Set mem (StoreCM mem zero)); 6886 predicate(UseG1GC); 6887 ins_cost(MEMORY_REF_COST); 6888 6889 ins_cannot_rematerialize(true); 6890 6891 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6892 size(8); 6893 ins_encode %{ 6894 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6895 __ li(R0, 0); 6896 //__ release(); // G1: oops are allowed to get visible after dirty marking 6897 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6898 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6899 %} 6900 ins_pipe(pipe_class_memory); 6901 %} 6902 6903 // Convert oop pointer into compressed form. 6904 6905 // Nodes for postalloc expand. 6906 6907 // Shift node for expand. 6908 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6909 // The match rule is needed to make it a 'MachTypeNode'! 6910 match(Set dst (EncodeP src)); 6911 predicate(false); 6912 6913 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6914 size(4); 6915 ins_encode %{ 6916 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6917 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6918 %} 6919 ins_pipe(pipe_class_default); 6920 %} 6921 6922 // Add node for expand. 6923 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6924 // The match rule is needed to make it a 'MachTypeNode'! 6925 match(Set dst (EncodeP src)); 6926 predicate(false); 6927 6928 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6929 ins_encode %{ 6930 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6931 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6932 %} 6933 ins_pipe(pipe_class_default); 6934 %} 6935 6936 // Conditional sub base. 6937 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6938 // The match rule is needed to make it a 'MachTypeNode'! 6939 match(Set dst (EncodeP (Binary crx src1))); 6940 predicate(false); 6941 6942 format %{ "BEQ $crx, done\n\t" 6943 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6944 "done:" %} 6945 ins_encode %{ 6946 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6947 Label done; 6948 __ beq($crx$$CondRegister, done); 6949 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6950 __ bind(done); 6951 %} 6952 ins_pipe(pipe_class_default); 6953 %} 6954 6955 // Power 7 can use isel instruction 6956 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6957 // The match rule is needed to make it a 'MachTypeNode'! 6958 match(Set dst (EncodeP (Binary crx src1))); 6959 predicate(false); 6960 6961 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6962 size(4); 6963 ins_encode %{ 6964 // This is a Power7 instruction for which no machine description exists. 6965 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6966 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6967 %} 6968 ins_pipe(pipe_class_default); 6969 %} 6970 6971 // Disjoint narrow oop base. 6972 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6973 match(Set dst (EncodeP src)); 6974 predicate(Universe::narrow_oop_base_disjoint()); 6975 6976 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6977 size(4); 6978 ins_encode %{ 6979 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6980 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 6981 %} 6982 ins_pipe(pipe_class_default); 6983 %} 6984 6985 // shift != 0, base != 0 6986 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6987 match(Set dst (EncodeP src)); 6988 effect(TEMP crx); 6989 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6990 Universe::narrow_oop_shift() != 0 && 6991 Universe::narrow_oop_base_overlaps()); 6992 6993 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 6994 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 6995 %} 6996 6997 // shift != 0, base != 0 6998 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 6999 match(Set dst (EncodeP src)); 7000 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 7001 Universe::narrow_oop_shift() != 0 && 7002 Universe::narrow_oop_base_overlaps()); 7003 7004 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 7005 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 7006 %} 7007 7008 // shift != 0, base == 0 7009 // TODO: This is the same as encodeP_shift. Merge! 7010 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 7011 match(Set dst (EncodeP src)); 7012 predicate(Universe::narrow_oop_shift() != 0 && 7013 Universe::narrow_oop_base() ==0); 7014 7015 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 7016 size(4); 7017 ins_encode %{ 7018 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7019 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 7020 %} 7021 ins_pipe(pipe_class_default); 7022 %} 7023 7024 // Compressed OOPs with narrow_oop_shift == 0. 7025 // shift == 0, base == 0 7026 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 7027 match(Set dst (EncodeP src)); 7028 predicate(Universe::narrow_oop_shift() == 0); 7029 7030 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 7031 // variable size, 0 or 4. 7032 ins_encode %{ 7033 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7034 __ mr_if_needed($dst$$Register, $src$$Register); 7035 %} 7036 ins_pipe(pipe_class_default); 7037 %} 7038 7039 // Decode nodes. 7040 7041 // Shift node for expand. 7042 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 7043 // The match rule is needed to make it a 'MachTypeNode'! 7044 match(Set dst (DecodeN src)); 7045 predicate(false); 7046 7047 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 7048 size(4); 7049 ins_encode %{ 7050 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7051 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7052 %} 7053 ins_pipe(pipe_class_default); 7054 %} 7055 7056 // Add node for expand. 7057 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7058 // The match rule is needed to make it a 'MachTypeNode'! 7059 match(Set dst (DecodeN src)); 7060 predicate(false); 7061 7062 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7063 ins_encode %{ 7064 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7065 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7066 %} 7067 ins_pipe(pipe_class_default); 7068 %} 7069 7070 // conditianal add base for expand 7071 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7072 // The match rule is needed to make it a 'MachTypeNode'! 7073 // NOTICE that the rule is nonsense - we just have to make sure that: 7074 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7075 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7076 match(Set dst (DecodeN (Binary crx src))); 7077 predicate(false); 7078 7079 format %{ "BEQ $crx, done\n\t" 7080 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7081 "done:" %} 7082 ins_encode %{ 7083 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7084 Label done; 7085 __ beq($crx$$CondRegister, done); 7086 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7087 __ bind(done); 7088 %} 7089 ins_pipe(pipe_class_default); 7090 %} 7091 7092 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7093 // The match rule is needed to make it a 'MachTypeNode'! 7094 // NOTICE that the rule is nonsense - we just have to make sure that: 7095 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7096 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7097 match(Set dst (DecodeN (Binary crx src1))); 7098 predicate(false); 7099 7100 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7101 size(4); 7102 ins_encode %{ 7103 // This is a Power7 instruction for which no machine description exists. 7104 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7105 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7106 %} 7107 ins_pipe(pipe_class_default); 7108 %} 7109 7110 // shift != 0, base != 0 7111 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7112 match(Set dst (DecodeN src)); 7113 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7114 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7115 Universe::narrow_oop_shift() != 0 && 7116 Universe::narrow_oop_base() != 0); 7117 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7118 effect(TEMP crx); 7119 7120 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7121 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7122 %} 7123 7124 // shift != 0, base == 0 7125 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7126 match(Set dst (DecodeN src)); 7127 predicate(Universe::narrow_oop_shift() != 0 && 7128 Universe::narrow_oop_base() == 0); 7129 7130 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7131 size(4); 7132 ins_encode %{ 7133 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7134 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7135 %} 7136 ins_pipe(pipe_class_default); 7137 %} 7138 7139 // Optimize DecodeN for disjoint base. 7140 // Shift narrow oop and or it into register that already contains the heap base. 7141 // Base == dst must hold, and is assured by construction in postaloc_expand. 7142 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7143 match(Set dst (DecodeN src)); 7144 effect(TEMP base); 7145 predicate(false); 7146 7147 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7148 size(4); 7149 ins_encode %{ 7150 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7151 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 7152 %} 7153 ins_pipe(pipe_class_default); 7154 %} 7155 7156 // Optimize DecodeN for disjoint base. 7157 // This node requires only one cycle on the critical path. 7158 // We must postalloc_expand as we can not express use_def effects where 7159 // the used register is L and the def'ed register P. 7160 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7161 match(Set dst (DecodeN src)); 7162 effect(TEMP_DEF dst); 7163 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7164 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7165 Universe::narrow_oop_base_disjoint()); 7166 ins_cost(DEFAULT_COST); 7167 7168 format %{ "MOV $dst, heapbase \t\n" 7169 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7170 postalloc_expand %{ 7171 loadBaseNode *n1 = new loadBaseNode(); 7172 n1->add_req(NULL); 7173 n1->_opnds[0] = op_dst; 7174 7175 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7176 n2->add_req(n_region, n_src, n1); 7177 n2->_opnds[0] = op_dst; 7178 n2->_opnds[1] = op_src; 7179 n2->_opnds[2] = op_dst; 7180 n2->_bottom_type = _bottom_type; 7181 7182 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7183 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7184 7185 nodes->push(n1); 7186 nodes->push(n2); 7187 %} 7188 %} 7189 7190 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7191 match(Set dst (DecodeN src)); 7192 effect(TEMP_DEF dst, TEMP crx); 7193 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7194 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7195 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 7196 ins_cost(3 * DEFAULT_COST); 7197 7198 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7199 postalloc_expand %{ 7200 loadBaseNode *n1 = new loadBaseNode(); 7201 n1->add_req(NULL); 7202 n1->_opnds[0] = op_dst; 7203 7204 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7205 n_compare->add_req(n_region, n_src); 7206 n_compare->_opnds[0] = op_crx; 7207 n_compare->_opnds[1] = op_src; 7208 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7209 7210 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7211 n2->add_req(n_region, n_src, n1); 7212 n2->_opnds[0] = op_dst; 7213 n2->_opnds[1] = op_src; 7214 n2->_opnds[2] = op_dst; 7215 n2->_bottom_type = _bottom_type; 7216 7217 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7218 n_cond_set->add_req(n_region, n_compare, n2); 7219 n_cond_set->_opnds[0] = op_dst; 7220 n_cond_set->_opnds[1] = op_crx; 7221 n_cond_set->_opnds[2] = op_dst; 7222 n_cond_set->_bottom_type = _bottom_type; 7223 7224 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7225 ra_->set_oop(n_cond_set, true); 7226 7227 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7228 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7229 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7230 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7231 7232 nodes->push(n1); 7233 nodes->push(n_compare); 7234 nodes->push(n2); 7235 nodes->push(n_cond_set); 7236 %} 7237 %} 7238 7239 // src != 0, shift != 0, base != 0 7240 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7241 match(Set dst (DecodeN src)); 7242 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7243 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7244 Universe::narrow_oop_shift() != 0 && 7245 Universe::narrow_oop_base() != 0); 7246 ins_cost(2 * DEFAULT_COST); 7247 7248 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7249 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7250 %} 7251 7252 // Compressed OOPs with narrow_oop_shift == 0. 7253 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7254 match(Set dst (DecodeN src)); 7255 predicate(Universe::narrow_oop_shift() == 0); 7256 ins_cost(DEFAULT_COST); 7257 7258 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7259 // variable size, 0 or 4. 7260 ins_encode %{ 7261 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7262 __ mr_if_needed($dst$$Register, $src$$Register); 7263 %} 7264 ins_pipe(pipe_class_default); 7265 %} 7266 7267 // Convert compressed oop into int for vectors alignment masking. 7268 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7269 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7270 predicate(Universe::narrow_oop_shift() == 0); 7271 ins_cost(DEFAULT_COST); 7272 7273 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7274 // variable size, 0 or 4. 7275 ins_encode %{ 7276 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7277 __ mr_if_needed($dst$$Register, $src$$Register); 7278 %} 7279 ins_pipe(pipe_class_default); 7280 %} 7281 7282 // Convert klass pointer into compressed form. 7283 7284 // Nodes for postalloc expand. 7285 7286 // Shift node for expand. 7287 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7288 // The match rule is needed to make it a 'MachTypeNode'! 7289 match(Set dst (EncodePKlass src)); 7290 predicate(false); 7291 7292 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7293 size(4); 7294 ins_encode %{ 7295 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7296 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7297 %} 7298 ins_pipe(pipe_class_default); 7299 %} 7300 7301 // Add node for expand. 7302 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7303 // The match rule is needed to make it a 'MachTypeNode'! 7304 match(Set dst (EncodePKlass (Binary base src))); 7305 predicate(false); 7306 7307 format %{ "SUB $dst, $base, $src \t// encode" %} 7308 size(4); 7309 ins_encode %{ 7310 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7311 __ subf($dst$$Register, $base$$Register, $src$$Register); 7312 %} 7313 ins_pipe(pipe_class_default); 7314 %} 7315 7316 // Disjoint narrow oop base. 7317 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7318 match(Set dst (EncodePKlass src)); 7319 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 7320 7321 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7322 size(4); 7323 ins_encode %{ 7324 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7325 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 7326 %} 7327 ins_pipe(pipe_class_default); 7328 %} 7329 7330 // shift != 0, base != 0 7331 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7332 match(Set dst (EncodePKlass (Binary base src))); 7333 predicate(false); 7334 7335 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7336 postalloc_expand %{ 7337 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7338 n1->add_req(n_region, n_base, n_src); 7339 n1->_opnds[0] = op_dst; 7340 n1->_opnds[1] = op_base; 7341 n1->_opnds[2] = op_src; 7342 n1->_bottom_type = _bottom_type; 7343 7344 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7345 n2->add_req(n_region, n1); 7346 n2->_opnds[0] = op_dst; 7347 n2->_opnds[1] = op_dst; 7348 n2->_bottom_type = _bottom_type; 7349 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7350 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7351 7352 nodes->push(n1); 7353 nodes->push(n2); 7354 %} 7355 %} 7356 7357 // shift != 0, base != 0 7358 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7359 match(Set dst (EncodePKlass src)); 7360 //predicate(Universe::narrow_klass_shift() != 0 && 7361 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 7362 7363 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7364 ins_cost(DEFAULT_COST*2); // Don't count constant. 7365 expand %{ 7366 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 7367 iRegLdst base; 7368 loadConL_Ex(base, baseImm); 7369 encodePKlass_not_null_Ex(dst, base, src); 7370 %} 7371 %} 7372 7373 // Decode nodes. 7374 7375 // Shift node for expand. 7376 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7377 // The match rule is needed to make it a 'MachTypeNode'! 7378 match(Set dst (DecodeNKlass src)); 7379 predicate(false); 7380 7381 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7382 size(4); 7383 ins_encode %{ 7384 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7385 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7386 %} 7387 ins_pipe(pipe_class_default); 7388 %} 7389 7390 // Add node for expand. 7391 7392 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7393 // The match rule is needed to make it a 'MachTypeNode'! 7394 match(Set dst (DecodeNKlass (Binary base src))); 7395 predicate(false); 7396 7397 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7398 size(4); 7399 ins_encode %{ 7400 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7401 __ add($dst$$Register, $base$$Register, $src$$Register); 7402 %} 7403 ins_pipe(pipe_class_default); 7404 %} 7405 7406 // src != 0, shift != 0, base != 0 7407 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7408 match(Set dst (DecodeNKlass (Binary base src))); 7409 //effect(kill src); // We need a register for the immediate result after shifting. 7410 predicate(false); 7411 7412 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7413 postalloc_expand %{ 7414 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7415 n1->add_req(n_region, n_base, n_src); 7416 n1->_opnds[0] = op_dst; 7417 n1->_opnds[1] = op_base; 7418 n1->_opnds[2] = op_src; 7419 n1->_bottom_type = _bottom_type; 7420 7421 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7422 n2->add_req(n_region, n1); 7423 n2->_opnds[0] = op_dst; 7424 n2->_opnds[1] = op_dst; 7425 n2->_bottom_type = _bottom_type; 7426 7427 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7428 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7429 7430 nodes->push(n1); 7431 nodes->push(n2); 7432 %} 7433 %} 7434 7435 // src != 0, shift != 0, base != 0 7436 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7437 match(Set dst (DecodeNKlass src)); 7438 // predicate(Universe::narrow_klass_shift() != 0 && 7439 // Universe::narrow_klass_base() != 0); 7440 7441 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7442 7443 ins_cost(DEFAULT_COST*2); // Don't count constant. 7444 expand %{ 7445 // We add first, then we shift. Like this, we can get along with one register less. 7446 // But we have to load the base pre-shifted. 7447 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7448 iRegLdst base; 7449 loadConL_Ex(base, baseImm); 7450 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7451 %} 7452 %} 7453 7454 //----------MemBar Instructions----------------------------------------------- 7455 // Memory barrier flavors 7456 7457 instruct membar_acquire() %{ 7458 match(LoadFence); 7459 ins_cost(4*MEMORY_REF_COST); 7460 7461 format %{ "MEMBAR-acquire" %} 7462 size(4); 7463 ins_encode %{ 7464 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7465 __ acquire(); 7466 %} 7467 ins_pipe(pipe_class_default); 7468 %} 7469 7470 instruct unnecessary_membar_acquire() %{ 7471 match(MemBarAcquire); 7472 ins_cost(0); 7473 7474 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7475 size(0); 7476 ins_encode( /*empty*/ ); 7477 ins_pipe(pipe_class_default); 7478 %} 7479 7480 instruct membar_acquire_lock() %{ 7481 match(MemBarAcquireLock); 7482 ins_cost(0); 7483 7484 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7485 size(0); 7486 ins_encode( /*empty*/ ); 7487 ins_pipe(pipe_class_default); 7488 %} 7489 7490 instruct membar_release() %{ 7491 match(MemBarRelease); 7492 match(StoreFence); 7493 ins_cost(4*MEMORY_REF_COST); 7494 7495 format %{ "MEMBAR-release" %} 7496 size(4); 7497 ins_encode %{ 7498 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7499 __ release(); 7500 %} 7501 ins_pipe(pipe_class_default); 7502 %} 7503 7504 instruct membar_storestore() %{ 7505 match(MemBarStoreStore); 7506 ins_cost(4*MEMORY_REF_COST); 7507 7508 format %{ "MEMBAR-store-store" %} 7509 size(4); 7510 ins_encode %{ 7511 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7512 __ membar(Assembler::StoreStore); 7513 %} 7514 ins_pipe(pipe_class_default); 7515 %} 7516 7517 instruct membar_release_lock() %{ 7518 match(MemBarReleaseLock); 7519 ins_cost(0); 7520 7521 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7522 size(0); 7523 ins_encode( /*empty*/ ); 7524 ins_pipe(pipe_class_default); 7525 %} 7526 7527 instruct membar_volatile() %{ 7528 match(MemBarVolatile); 7529 ins_cost(4*MEMORY_REF_COST); 7530 7531 format %{ "MEMBAR-volatile" %} 7532 size(4); 7533 ins_encode %{ 7534 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7535 __ fence(); 7536 %} 7537 ins_pipe(pipe_class_default); 7538 %} 7539 7540 // This optimization is wrong on PPC. The following pattern is not supported: 7541 // MemBarVolatile 7542 // ^ ^ 7543 // | | 7544 // CtrlProj MemProj 7545 // ^ ^ 7546 // | | 7547 // | Load 7548 // | 7549 // MemBarVolatile 7550 // 7551 // The first MemBarVolatile could get optimized out! According to 7552 // Vladimir, this pattern can not occur on Oracle platforms. 7553 // However, it does occur on PPC64 (because of membars in 7554 // inline_unsafe_load_store). 7555 // 7556 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7557 // Don't forget to look at the implementation of post_store_load_barrier again, 7558 // we did other fixes in that method. 7559 //instruct unnecessary_membar_volatile() %{ 7560 // match(MemBarVolatile); 7561 // predicate(Matcher::post_store_load_barrier(n)); 7562 // ins_cost(0); 7563 // 7564 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7565 // size(0); 7566 // ins_encode( /*empty*/ ); 7567 // ins_pipe(pipe_class_default); 7568 //%} 7569 7570 instruct membar_CPUOrder() %{ 7571 match(MemBarCPUOrder); 7572 ins_cost(0); 7573 7574 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7575 size(0); 7576 ins_encode( /*empty*/ ); 7577 ins_pipe(pipe_class_default); 7578 %} 7579 7580 //----------Conditional Move--------------------------------------------------- 7581 7582 // Cmove using isel. 7583 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7584 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7585 predicate(VM_Version::has_isel()); 7586 ins_cost(DEFAULT_COST); 7587 7588 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7589 size(4); 7590 ins_encode %{ 7591 // This is a Power7 instruction for which no machine description 7592 // exists. Anyways, the scheduler should be off on Power7. 7593 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7594 int cc = $cmp$$cmpcode; 7595 __ isel($dst$$Register, $crx$$CondRegister, 7596 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7597 %} 7598 ins_pipe(pipe_class_default); 7599 %} 7600 7601 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7602 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7603 predicate(!VM_Version::has_isel()); 7604 ins_cost(DEFAULT_COST+BRANCH_COST); 7605 7606 ins_variable_size_depending_on_alignment(true); 7607 7608 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7609 // Worst case is branch + move + stop, no stop without scheduler 7610 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7611 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7612 ins_pipe(pipe_class_default); 7613 %} 7614 7615 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7616 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7617 ins_cost(DEFAULT_COST+BRANCH_COST); 7618 7619 ins_variable_size_depending_on_alignment(true); 7620 7621 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7622 // Worst case is branch + move + stop, no stop without scheduler 7623 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7624 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7625 ins_pipe(pipe_class_default); 7626 %} 7627 7628 // Cmove using isel. 7629 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7630 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7631 predicate(VM_Version::has_isel()); 7632 ins_cost(DEFAULT_COST); 7633 7634 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7635 size(4); 7636 ins_encode %{ 7637 // This is a Power7 instruction for which no machine description 7638 // exists. Anyways, the scheduler should be off on Power7. 7639 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7640 int cc = $cmp$$cmpcode; 7641 __ isel($dst$$Register, $crx$$CondRegister, 7642 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7643 %} 7644 ins_pipe(pipe_class_default); 7645 %} 7646 7647 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7648 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7649 predicate(!VM_Version::has_isel()); 7650 ins_cost(DEFAULT_COST+BRANCH_COST); 7651 7652 ins_variable_size_depending_on_alignment(true); 7653 7654 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7655 // Worst case is branch + move + stop, no stop without scheduler. 7656 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7657 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7658 ins_pipe(pipe_class_default); 7659 %} 7660 7661 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7662 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7663 ins_cost(DEFAULT_COST+BRANCH_COST); 7664 7665 ins_variable_size_depending_on_alignment(true); 7666 7667 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7668 // Worst case is branch + move + stop, no stop without scheduler. 7669 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7670 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7671 ins_pipe(pipe_class_default); 7672 %} 7673 7674 // Cmove using isel. 7675 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7676 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7677 predicate(VM_Version::has_isel()); 7678 ins_cost(DEFAULT_COST); 7679 7680 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7681 size(4); 7682 ins_encode %{ 7683 // This is a Power7 instruction for which no machine description 7684 // exists. Anyways, the scheduler should be off on Power7. 7685 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7686 int cc = $cmp$$cmpcode; 7687 __ isel($dst$$Register, $crx$$CondRegister, 7688 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7689 %} 7690 ins_pipe(pipe_class_default); 7691 %} 7692 7693 // Conditional move for RegN. Only cmov(reg, reg). 7694 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7695 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7696 predicate(!VM_Version::has_isel()); 7697 ins_cost(DEFAULT_COST+BRANCH_COST); 7698 7699 ins_variable_size_depending_on_alignment(true); 7700 7701 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7702 // Worst case is branch + move + stop, no stop without scheduler. 7703 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7704 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7705 ins_pipe(pipe_class_default); 7706 %} 7707 7708 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7709 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7710 ins_cost(DEFAULT_COST+BRANCH_COST); 7711 7712 ins_variable_size_depending_on_alignment(true); 7713 7714 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7715 // Worst case is branch + move + stop, no stop without scheduler. 7716 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7717 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7718 ins_pipe(pipe_class_default); 7719 %} 7720 7721 // Cmove using isel. 7722 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7723 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7724 predicate(VM_Version::has_isel()); 7725 ins_cost(DEFAULT_COST); 7726 7727 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7728 size(4); 7729 ins_encode %{ 7730 // This is a Power7 instruction for which no machine description 7731 // exists. Anyways, the scheduler should be off on Power7. 7732 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7733 int cc = $cmp$$cmpcode; 7734 __ isel($dst$$Register, $crx$$CondRegister, 7735 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7736 %} 7737 ins_pipe(pipe_class_default); 7738 %} 7739 7740 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7741 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7742 predicate(!VM_Version::has_isel()); 7743 ins_cost(DEFAULT_COST+BRANCH_COST); 7744 7745 ins_variable_size_depending_on_alignment(true); 7746 7747 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7748 // Worst case is branch + move + stop, no stop without scheduler. 7749 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7750 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7751 ins_pipe(pipe_class_default); 7752 %} 7753 7754 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7755 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7756 ins_cost(DEFAULT_COST+BRANCH_COST); 7757 7758 ins_variable_size_depending_on_alignment(true); 7759 7760 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7761 // Worst case is branch + move + stop, no stop without scheduler. 7762 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7763 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7764 ins_pipe(pipe_class_default); 7765 %} 7766 7767 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7768 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7769 ins_cost(DEFAULT_COST+BRANCH_COST); 7770 7771 ins_variable_size_depending_on_alignment(true); 7772 7773 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7774 // Worst case is branch + move + stop, no stop without scheduler. 7775 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7776 ins_encode %{ 7777 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7778 Label done; 7779 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7780 // Branch if not (cmp crx). 7781 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7782 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7783 // TODO PPC port __ endgroup_if_needed(_size == 12); 7784 __ bind(done); 7785 %} 7786 ins_pipe(pipe_class_default); 7787 %} 7788 7789 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7790 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7791 ins_cost(DEFAULT_COST+BRANCH_COST); 7792 7793 ins_variable_size_depending_on_alignment(true); 7794 7795 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7796 // Worst case is branch + move + stop, no stop without scheduler. 7797 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7798 ins_encode %{ 7799 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7800 Label done; 7801 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7802 // Branch if not (cmp crx). 7803 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7804 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7805 // TODO PPC port __ endgroup_if_needed(_size == 12); 7806 __ bind(done); 7807 %} 7808 ins_pipe(pipe_class_default); 7809 %} 7810 7811 //----------Conditional_store-------------------------------------------------- 7812 // Conditional-store of the updated heap-top. 7813 // Used during allocation of the shared heap. 7814 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7815 7816 // As compareAndSwapL, but return flag register instead of boolean value in 7817 // int register. 7818 // Used by sun/misc/AtomicLongCSImpl.java. 7819 // Mem_ptr must be a memory operand, else this node does not get 7820 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7821 // can be rematerialized which leads to errors. 7822 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7823 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7824 effect(TEMP cr0); 7825 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7826 ins_encode %{ 7827 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7828 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7829 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7830 noreg, NULL, true); 7831 %} 7832 ins_pipe(pipe_class_default); 7833 %} 7834 7835 // As compareAndSwapP, but return flag register instead of boolean value in 7836 // int register. 7837 // This instruction is matched if UseTLAB is off. 7838 // Mem_ptr must be a memory operand, else this node does not get 7839 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7840 // can be rematerialized which leads to errors. 7841 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7842 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7843 ins_cost(2*MEMORY_REF_COST); 7844 7845 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7846 ins_encode %{ 7847 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7848 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7849 %} 7850 ins_pipe(pipe_class_memory); 7851 %} 7852 7853 // Implement LoadPLocked. Must be ordered against changes of the memory location 7854 // by storePConditional. 7855 // Don't know whether this is ever used. 7856 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7857 match(Set dst (LoadPLocked mem)); 7858 ins_cost(2*MEMORY_REF_COST); 7859 7860 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7861 size(4); 7862 ins_encode %{ 7863 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7864 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7865 %} 7866 ins_pipe(pipe_class_memory); 7867 %} 7868 7869 //----------Compare-And-Swap--------------------------------------------------- 7870 7871 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7872 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7873 // matched. 7874 7875 // Strong versions: 7876 7877 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7878 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7879 predicate(VM_Version::has_lqarx()); 7880 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7881 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7882 ins_encode %{ 7883 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7884 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7885 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7886 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7887 $res$$Register, true); 7888 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7889 __ isync(); 7890 } else { 7891 __ sync(); 7892 } 7893 %} 7894 ins_pipe(pipe_class_default); 7895 %} 7896 7897 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7898 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7899 predicate(!VM_Version::has_lqarx()); 7900 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7901 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7902 ins_encode %{ 7903 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7904 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7905 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7906 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7907 $res$$Register, true); 7908 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7909 __ isync(); 7910 } else { 7911 __ sync(); 7912 } 7913 %} 7914 ins_pipe(pipe_class_default); 7915 %} 7916 7917 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7918 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7919 predicate(VM_Version::has_lqarx()); 7920 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7921 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7922 ins_encode %{ 7923 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7924 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7925 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7926 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7927 $res$$Register, true); 7928 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7929 __ isync(); 7930 } else { 7931 __ sync(); 7932 } 7933 %} 7934 ins_pipe(pipe_class_default); 7935 %} 7936 7937 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7938 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7939 predicate(!VM_Version::has_lqarx()); 7940 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7941 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7942 ins_encode %{ 7943 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7944 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7945 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7946 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7947 $res$$Register, true); 7948 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7949 __ isync(); 7950 } else { 7951 __ sync(); 7952 } 7953 %} 7954 ins_pipe(pipe_class_default); 7955 %} 7956 7957 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7958 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7959 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7960 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7961 ins_encode %{ 7962 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7963 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7964 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7965 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7966 $res$$Register, true); 7967 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7968 __ isync(); 7969 } else { 7970 __ sync(); 7971 } 7972 %} 7973 ins_pipe(pipe_class_default); 7974 %} 7975 7976 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7977 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7978 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7979 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7980 ins_encode %{ 7981 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7982 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7983 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7984 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7985 $res$$Register, true); 7986 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7987 __ isync(); 7988 } else { 7989 __ sync(); 7990 } 7991 %} 7992 ins_pipe(pipe_class_default); 7993 %} 7994 7995 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7996 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 7997 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7998 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7999 ins_encode %{ 8000 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8001 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8002 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8003 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8004 $res$$Register, NULL, true); 8005 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8006 __ isync(); 8007 } else { 8008 __ sync(); 8009 } 8010 %} 8011 ins_pipe(pipe_class_default); 8012 %} 8013 8014 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8015 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 8016 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8017 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8018 ins_encode %{ 8019 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8020 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8021 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8022 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8023 $res$$Register, NULL, true); 8024 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8025 __ isync(); 8026 } else { 8027 __ sync(); 8028 } 8029 %} 8030 ins_pipe(pipe_class_default); 8031 %} 8032 8033 // Weak versions: 8034 8035 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8036 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8037 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8038 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8039 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8040 ins_encode %{ 8041 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8042 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8043 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8044 MacroAssembler::MemBarNone, 8045 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8046 %} 8047 ins_pipe(pipe_class_default); 8048 %} 8049 8050 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8051 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8052 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8053 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8054 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8055 ins_encode %{ 8056 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8057 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8058 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8059 MacroAssembler::MemBarNone, 8060 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8061 %} 8062 ins_pipe(pipe_class_default); 8063 %} 8064 8065 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8066 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8067 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8068 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8069 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8070 ins_encode %{ 8071 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8072 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8073 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8074 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8075 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8076 %} 8077 ins_pipe(pipe_class_default); 8078 %} 8079 8080 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8081 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8082 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8083 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8084 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8085 ins_encode %{ 8086 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8087 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8088 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8089 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8090 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8091 %} 8092 ins_pipe(pipe_class_default); 8093 %} 8094 8095 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8096 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8097 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8098 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8099 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8100 ins_encode %{ 8101 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8102 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8103 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8104 MacroAssembler::MemBarNone, 8105 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8106 %} 8107 ins_pipe(pipe_class_default); 8108 %} 8109 8110 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8111 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8112 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8113 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8114 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8115 ins_encode %{ 8116 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8117 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8118 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8119 MacroAssembler::MemBarNone, 8120 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8121 %} 8122 ins_pipe(pipe_class_default); 8123 %} 8124 8125 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8126 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8127 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8128 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8129 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8130 ins_encode %{ 8131 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8132 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8133 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8134 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8135 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8136 %} 8137 ins_pipe(pipe_class_default); 8138 %} 8139 8140 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8141 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8142 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8143 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8144 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8145 ins_encode %{ 8146 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8147 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8148 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8149 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8150 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8151 %} 8152 ins_pipe(pipe_class_default); 8153 %} 8154 8155 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8156 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8157 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8158 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8159 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8160 ins_encode %{ 8161 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8162 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8163 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8164 MacroAssembler::MemBarNone, 8165 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8166 %} 8167 ins_pipe(pipe_class_default); 8168 %} 8169 8170 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8171 match(Set res (WeakCompareAndSwapI 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 CMPXCHGW acq $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 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8179 // value is never passed to caller. 8180 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8181 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8182 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8183 %} 8184 ins_pipe(pipe_class_default); 8185 %} 8186 8187 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8188 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8189 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8190 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8191 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8192 ins_encode %{ 8193 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8194 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8195 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8196 MacroAssembler::MemBarNone, 8197 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8198 %} 8199 ins_pipe(pipe_class_default); 8200 %} 8201 8202 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8203 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8204 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8205 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8206 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8207 ins_encode %{ 8208 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8209 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8210 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8211 // value is never passed to caller. 8212 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8213 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8214 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8215 %} 8216 ins_pipe(pipe_class_default); 8217 %} 8218 8219 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8220 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8221 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8222 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8223 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8224 ins_encode %{ 8225 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8226 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8227 // value is never passed to caller. 8228 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8229 MacroAssembler::MemBarNone, 8230 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8231 %} 8232 ins_pipe(pipe_class_default); 8233 %} 8234 8235 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8236 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8237 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8238 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8239 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 8240 ins_encode %{ 8241 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8242 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8243 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8244 // value is never passed to caller. 8245 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8246 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8247 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8248 %} 8249 ins_pipe(pipe_class_default); 8250 %} 8251 8252 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8253 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8254 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8255 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8256 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8257 ins_encode %{ 8258 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8259 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8260 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8261 MacroAssembler::MemBarNone, 8262 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8263 %} 8264 ins_pipe(pipe_class_default); 8265 %} 8266 8267 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8268 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8269 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8270 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8271 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8272 ins_encode %{ 8273 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8274 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8275 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8276 // value is never passed to caller. 8277 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8278 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8279 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8280 %} 8281 ins_pipe(pipe_class_default); 8282 %} 8283 8284 // CompareAndExchange 8285 8286 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8287 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8288 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8289 effect(TEMP_DEF res, TEMP cr0); 8290 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8291 ins_encode %{ 8292 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8293 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8294 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8295 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8296 noreg, true); 8297 %} 8298 ins_pipe(pipe_class_default); 8299 %} 8300 8301 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8302 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8303 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8304 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8305 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8306 ins_encode %{ 8307 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8308 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8309 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8310 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8311 noreg, true); 8312 %} 8313 ins_pipe(pipe_class_default); 8314 %} 8315 8316 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8317 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8318 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8319 effect(TEMP_DEF res, TEMP cr0); 8320 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8321 ins_encode %{ 8322 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8323 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8324 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8325 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8326 noreg, true); 8327 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8328 __ isync(); 8329 } else { 8330 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8331 __ sync(); 8332 } 8333 %} 8334 ins_pipe(pipe_class_default); 8335 %} 8336 8337 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8338 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8339 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8340 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8341 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8342 ins_encode %{ 8343 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8344 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8345 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8346 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8347 noreg, true); 8348 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8349 __ isync(); 8350 } else { 8351 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8352 __ sync(); 8353 } 8354 %} 8355 ins_pipe(pipe_class_default); 8356 %} 8357 8358 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8359 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8360 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8361 effect(TEMP_DEF res, TEMP cr0); 8362 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8363 ins_encode %{ 8364 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8365 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8366 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8367 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8368 noreg, true); 8369 %} 8370 ins_pipe(pipe_class_default); 8371 %} 8372 8373 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8374 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8375 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8376 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8377 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8378 ins_encode %{ 8379 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8380 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8381 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8382 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8383 noreg, true); 8384 %} 8385 ins_pipe(pipe_class_default); 8386 %} 8387 8388 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8389 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8390 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8391 effect(TEMP_DEF res, TEMP cr0); 8392 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8393 ins_encode %{ 8394 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8395 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8396 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8397 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8398 noreg, true); 8399 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8400 __ isync(); 8401 } else { 8402 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8403 __ sync(); 8404 } 8405 %} 8406 ins_pipe(pipe_class_default); 8407 %} 8408 8409 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8410 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8411 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8412 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8413 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8414 ins_encode %{ 8415 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8416 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8417 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8418 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8419 noreg, true); 8420 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8421 __ isync(); 8422 } else { 8423 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8424 __ sync(); 8425 } 8426 %} 8427 ins_pipe(pipe_class_default); 8428 %} 8429 8430 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8431 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8432 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8433 effect(TEMP_DEF res, TEMP cr0); 8434 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8435 ins_encode %{ 8436 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8437 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8438 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8439 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8440 noreg, true); 8441 %} 8442 ins_pipe(pipe_class_default); 8443 %} 8444 8445 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8446 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8447 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8448 effect(TEMP_DEF res, TEMP cr0); 8449 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8450 ins_encode %{ 8451 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8452 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8453 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8454 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8455 noreg, true); 8456 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8457 __ isync(); 8458 } else { 8459 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8460 __ sync(); 8461 } 8462 %} 8463 ins_pipe(pipe_class_default); 8464 %} 8465 8466 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8467 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8468 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8469 effect(TEMP_DEF res, TEMP cr0); 8470 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8471 ins_encode %{ 8472 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8473 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8474 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8475 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8476 noreg, true); 8477 %} 8478 ins_pipe(pipe_class_default); 8479 %} 8480 8481 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8482 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8483 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8484 effect(TEMP_DEF res, TEMP cr0); 8485 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8486 ins_encode %{ 8487 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8488 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8489 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8490 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8491 noreg, true); 8492 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8493 __ isync(); 8494 } else { 8495 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8496 __ sync(); 8497 } 8498 %} 8499 ins_pipe(pipe_class_default); 8500 %} 8501 8502 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8503 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8504 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8505 effect(TEMP_DEF res, TEMP cr0); 8506 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8507 ins_encode %{ 8508 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8509 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8510 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8511 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8512 noreg, NULL, true); 8513 %} 8514 ins_pipe(pipe_class_default); 8515 %} 8516 8517 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8518 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8519 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8520 effect(TEMP_DEF res, TEMP cr0); 8521 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8522 ins_encode %{ 8523 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8524 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8525 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8526 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8527 noreg, NULL, true); 8528 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8529 __ isync(); 8530 } else { 8531 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8532 __ sync(); 8533 } 8534 %} 8535 ins_pipe(pipe_class_default); 8536 %} 8537 8538 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8539 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8540 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8541 effect(TEMP_DEF res, TEMP cr0); 8542 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8543 ins_encode %{ 8544 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8545 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8546 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8547 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8548 noreg, NULL, true); 8549 %} 8550 ins_pipe(pipe_class_default); 8551 %} 8552 8553 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8554 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8555 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8556 effect(TEMP_DEF res, TEMP cr0); 8557 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8558 ins_encode %{ 8559 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8560 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8561 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8562 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8563 noreg, NULL, true); 8564 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8565 __ isync(); 8566 } else { 8567 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8568 __ sync(); 8569 } 8570 %} 8571 ins_pipe(pipe_class_default); 8572 %} 8573 8574 // Special RMW 8575 8576 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8577 match(Set res (GetAndAddB mem_ptr src)); 8578 predicate(VM_Version::has_lqarx()); 8579 effect(TEMP_DEF res, TEMP cr0); 8580 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8581 ins_encode %{ 8582 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8583 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8584 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8585 __ isync(); 8586 } else { 8587 __ sync(); 8588 } 8589 %} 8590 ins_pipe(pipe_class_default); 8591 %} 8592 8593 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8594 match(Set res (GetAndAddB mem_ptr src)); 8595 predicate(!VM_Version::has_lqarx()); 8596 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8597 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8598 ins_encode %{ 8599 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8600 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8601 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8602 __ isync(); 8603 } else { 8604 __ sync(); 8605 } 8606 %} 8607 ins_pipe(pipe_class_default); 8608 %} 8609 8610 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8611 match(Set res (GetAndAddS mem_ptr src)); 8612 predicate(VM_Version::has_lqarx()); 8613 effect(TEMP_DEF res, TEMP cr0); 8614 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8615 ins_encode %{ 8616 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8617 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8618 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8619 __ isync(); 8620 } else { 8621 __ sync(); 8622 } 8623 %} 8624 ins_pipe(pipe_class_default); 8625 %} 8626 8627 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8628 match(Set res (GetAndAddS mem_ptr src)); 8629 predicate(!VM_Version::has_lqarx()); 8630 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8631 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8632 ins_encode %{ 8633 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8634 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8635 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8636 __ isync(); 8637 } else { 8638 __ sync(); 8639 } 8640 %} 8641 ins_pipe(pipe_class_default); 8642 %} 8643 8644 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8645 match(Set res (GetAndAddI mem_ptr src)); 8646 effect(TEMP_DEF res, TEMP cr0); 8647 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8648 ins_encode %{ 8649 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8650 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8651 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8652 __ isync(); 8653 } else { 8654 __ sync(); 8655 } 8656 %} 8657 ins_pipe(pipe_class_default); 8658 %} 8659 8660 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8661 match(Set res (GetAndAddL mem_ptr src)); 8662 effect(TEMP_DEF res, TEMP cr0); 8663 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8664 ins_encode %{ 8665 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8666 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8667 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8668 __ isync(); 8669 } else { 8670 __ sync(); 8671 } 8672 %} 8673 ins_pipe(pipe_class_default); 8674 %} 8675 8676 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8677 match(Set res (GetAndSetB mem_ptr src)); 8678 predicate(VM_Version::has_lqarx()); 8679 effect(TEMP_DEF res, TEMP cr0); 8680 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8681 ins_encode %{ 8682 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8683 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8684 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8685 __ isync(); 8686 } else { 8687 __ sync(); 8688 } 8689 %} 8690 ins_pipe(pipe_class_default); 8691 %} 8692 8693 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8694 match(Set res (GetAndSetB mem_ptr src)); 8695 predicate(!VM_Version::has_lqarx()); 8696 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8697 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8698 ins_encode %{ 8699 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8700 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8701 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8702 __ isync(); 8703 } else { 8704 __ sync(); 8705 } 8706 %} 8707 ins_pipe(pipe_class_default); 8708 %} 8709 8710 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8711 match(Set res (GetAndSetS mem_ptr src)); 8712 predicate(VM_Version::has_lqarx()); 8713 effect(TEMP_DEF res, TEMP cr0); 8714 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8715 ins_encode %{ 8716 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8717 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8718 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8719 __ isync(); 8720 } else { 8721 __ sync(); 8722 } 8723 %} 8724 ins_pipe(pipe_class_default); 8725 %} 8726 8727 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8728 match(Set res (GetAndSetS mem_ptr src)); 8729 predicate(!VM_Version::has_lqarx()); 8730 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8731 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8732 ins_encode %{ 8733 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8734 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8735 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8736 __ isync(); 8737 } else { 8738 __ sync(); 8739 } 8740 %} 8741 ins_pipe(pipe_class_default); 8742 %} 8743 8744 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8745 match(Set res (GetAndSetI mem_ptr src)); 8746 effect(TEMP_DEF res, TEMP cr0); 8747 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8748 ins_encode %{ 8749 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8750 MacroAssembler::cmpxchgx_hint_atomic_update()); 8751 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8752 __ isync(); 8753 } else { 8754 __ sync(); 8755 } 8756 %} 8757 ins_pipe(pipe_class_default); 8758 %} 8759 8760 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8761 match(Set res (GetAndSetL mem_ptr src)); 8762 effect(TEMP_DEF res, TEMP cr0); 8763 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8764 ins_encode %{ 8765 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8766 MacroAssembler::cmpxchgx_hint_atomic_update()); 8767 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8768 __ isync(); 8769 } else { 8770 __ sync(); 8771 } 8772 %} 8773 ins_pipe(pipe_class_default); 8774 %} 8775 8776 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8777 match(Set res (GetAndSetP mem_ptr src)); 8778 effect(TEMP_DEF res, TEMP cr0); 8779 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8780 ins_encode %{ 8781 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8782 MacroAssembler::cmpxchgx_hint_atomic_update()); 8783 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8784 __ isync(); 8785 } else { 8786 __ sync(); 8787 } 8788 %} 8789 ins_pipe(pipe_class_default); 8790 %} 8791 8792 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8793 match(Set res (GetAndSetN mem_ptr src)); 8794 effect(TEMP_DEF res, TEMP cr0); 8795 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8796 ins_encode %{ 8797 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8798 MacroAssembler::cmpxchgx_hint_atomic_update()); 8799 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8800 __ isync(); 8801 } else { 8802 __ sync(); 8803 } 8804 %} 8805 ins_pipe(pipe_class_default); 8806 %} 8807 8808 //----------Arithmetic Instructions-------------------------------------------- 8809 // Addition Instructions 8810 8811 // Register Addition 8812 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8813 match(Set dst (AddI src1 src2)); 8814 format %{ "ADD $dst, $src1, $src2" %} 8815 size(4); 8816 ins_encode %{ 8817 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8818 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8819 %} 8820 ins_pipe(pipe_class_default); 8821 %} 8822 8823 // Expand does not work with above instruct. (??) 8824 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8825 // no match-rule 8826 effect(DEF dst, USE src1, USE src2); 8827 format %{ "ADD $dst, $src1, $src2" %} 8828 size(4); 8829 ins_encode %{ 8830 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8831 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8832 %} 8833 ins_pipe(pipe_class_default); 8834 %} 8835 8836 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8837 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8838 ins_cost(DEFAULT_COST*3); 8839 8840 expand %{ 8841 // FIXME: we should do this in the ideal world. 8842 iRegIdst tmp1; 8843 iRegIdst tmp2; 8844 addI_reg_reg(tmp1, src1, src2); 8845 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8846 addI_reg_reg(dst, tmp1, tmp2); 8847 %} 8848 %} 8849 8850 // Immediate Addition 8851 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8852 match(Set dst (AddI src1 src2)); 8853 format %{ "ADDI $dst, $src1, $src2" %} 8854 size(4); 8855 ins_encode %{ 8856 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8857 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8858 %} 8859 ins_pipe(pipe_class_default); 8860 %} 8861 8862 // Immediate Addition with 16-bit shifted operand 8863 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8864 match(Set dst (AddI src1 src2)); 8865 format %{ "ADDIS $dst, $src1, $src2" %} 8866 size(4); 8867 ins_encode %{ 8868 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8869 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8870 %} 8871 ins_pipe(pipe_class_default); 8872 %} 8873 8874 // Long Addition 8875 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8876 match(Set dst (AddL src1 src2)); 8877 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8878 size(4); 8879 ins_encode %{ 8880 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8881 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8882 %} 8883 ins_pipe(pipe_class_default); 8884 %} 8885 8886 // Expand does not work with above instruct. (??) 8887 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8888 // no match-rule 8889 effect(DEF dst, USE src1, USE src2); 8890 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8891 size(4); 8892 ins_encode %{ 8893 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8894 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8895 %} 8896 ins_pipe(pipe_class_default); 8897 %} 8898 8899 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8900 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8901 ins_cost(DEFAULT_COST*3); 8902 8903 expand %{ 8904 // FIXME: we should do this in the ideal world. 8905 iRegLdst tmp1; 8906 iRegLdst tmp2; 8907 addL_reg_reg(tmp1, src1, src2); 8908 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8909 addL_reg_reg(dst, tmp1, tmp2); 8910 %} 8911 %} 8912 8913 // AddL + ConvL2I. 8914 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8915 match(Set dst (ConvL2I (AddL src1 src2))); 8916 8917 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8918 size(4); 8919 ins_encode %{ 8920 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8921 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8922 %} 8923 ins_pipe(pipe_class_default); 8924 %} 8925 8926 // No constant pool entries required. 8927 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8928 match(Set dst (AddL src1 src2)); 8929 8930 format %{ "ADDI $dst, $src1, $src2" %} 8931 size(4); 8932 ins_encode %{ 8933 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8934 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8935 %} 8936 ins_pipe(pipe_class_default); 8937 %} 8938 8939 // Long Immediate Addition with 16-bit shifted operand. 8940 // No constant pool entries required. 8941 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8942 match(Set dst (AddL src1 src2)); 8943 8944 format %{ "ADDIS $dst, $src1, $src2" %} 8945 size(4); 8946 ins_encode %{ 8947 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8948 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8949 %} 8950 ins_pipe(pipe_class_default); 8951 %} 8952 8953 // Pointer Register Addition 8954 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8955 match(Set dst (AddP src1 src2)); 8956 format %{ "ADD $dst, $src1, $src2" %} 8957 size(4); 8958 ins_encode %{ 8959 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8960 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8961 %} 8962 ins_pipe(pipe_class_default); 8963 %} 8964 8965 // Pointer Immediate Addition 8966 // No constant pool entries required. 8967 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8968 match(Set dst (AddP src1 src2)); 8969 8970 format %{ "ADDI $dst, $src1, $src2" %} 8971 size(4); 8972 ins_encode %{ 8973 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8974 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8975 %} 8976 ins_pipe(pipe_class_default); 8977 %} 8978 8979 // Pointer Immediate Addition with 16-bit shifted operand. 8980 // No constant pool entries required. 8981 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8982 match(Set dst (AddP src1 src2)); 8983 8984 format %{ "ADDIS $dst, $src1, $src2" %} 8985 size(4); 8986 ins_encode %{ 8987 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8988 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8989 %} 8990 ins_pipe(pipe_class_default); 8991 %} 8992 8993 //--------------------- 8994 // Subtraction Instructions 8995 8996 // Register Subtraction 8997 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8998 match(Set dst (SubI src1 src2)); 8999 format %{ "SUBF $dst, $src2, $src1" %} 9000 size(4); 9001 ins_encode %{ 9002 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9003 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9004 %} 9005 ins_pipe(pipe_class_default); 9006 %} 9007 9008 // Immediate Subtraction 9009 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 9010 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 9011 9012 // SubI from constant (using subfic). 9013 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 9014 match(Set dst (SubI src1 src2)); 9015 format %{ "SUBI $dst, $src1, $src2" %} 9016 9017 size(4); 9018 ins_encode %{ 9019 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 9020 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 9021 %} 9022 ins_pipe(pipe_class_default); 9023 %} 9024 9025 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 9026 // positive integers and 0xF...F for negative ones. 9027 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 9028 // no match-rule, false predicate 9029 effect(DEF dst, USE src); 9030 predicate(false); 9031 9032 format %{ "SRAWI $dst, $src, #31" %} 9033 size(4); 9034 ins_encode %{ 9035 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9036 __ srawi($dst$$Register, $src$$Register, 0x1f); 9037 %} 9038 ins_pipe(pipe_class_default); 9039 %} 9040 9041 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 9042 match(Set dst (AbsI src)); 9043 ins_cost(DEFAULT_COST*3); 9044 9045 expand %{ 9046 iRegIdst tmp1; 9047 iRegIdst tmp2; 9048 signmask32I_regI(tmp1, src); 9049 xorI_reg_reg(tmp2, tmp1, src); 9050 subI_reg_reg(dst, tmp2, tmp1); 9051 %} 9052 %} 9053 9054 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9055 match(Set dst (SubI zero src2)); 9056 format %{ "NEG $dst, $src2" %} 9057 size(4); 9058 ins_encode %{ 9059 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9060 __ neg($dst$$Register, $src2$$Register); 9061 %} 9062 ins_pipe(pipe_class_default); 9063 %} 9064 9065 // Long subtraction 9066 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9067 match(Set dst (SubL src1 src2)); 9068 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9069 size(4); 9070 ins_encode %{ 9071 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9072 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9073 %} 9074 ins_pipe(pipe_class_default); 9075 %} 9076 9077 // SubL + convL2I. 9078 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9079 match(Set dst (ConvL2I (SubL src1 src2))); 9080 9081 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9082 size(4); 9083 ins_encode %{ 9084 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9085 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9086 %} 9087 ins_pipe(pipe_class_default); 9088 %} 9089 9090 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9091 // positive longs and 0xF...F for negative ones. 9092 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9093 // no match-rule, false predicate 9094 effect(DEF dst, USE src); 9095 predicate(false); 9096 9097 format %{ "SRADI $dst, $src, #63" %} 9098 size(4); 9099 ins_encode %{ 9100 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9101 __ sradi($dst$$Register, $src$$Register, 0x3f); 9102 %} 9103 ins_pipe(pipe_class_default); 9104 %} 9105 9106 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9107 // positive longs and 0xF...F for negative ones. 9108 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9109 // no match-rule, false predicate 9110 effect(DEF dst, USE src); 9111 predicate(false); 9112 9113 format %{ "SRADI $dst, $src, #63" %} 9114 size(4); 9115 ins_encode %{ 9116 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9117 __ sradi($dst$$Register, $src$$Register, 0x3f); 9118 %} 9119 ins_pipe(pipe_class_default); 9120 %} 9121 9122 // Long negation 9123 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9124 match(Set dst (SubL zero src2)); 9125 format %{ "NEG $dst, $src2 \t// long" %} 9126 size(4); 9127 ins_encode %{ 9128 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9129 __ neg($dst$$Register, $src2$$Register); 9130 %} 9131 ins_pipe(pipe_class_default); 9132 %} 9133 9134 // NegL + ConvL2I. 9135 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9136 match(Set dst (ConvL2I (SubL zero src2))); 9137 9138 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9139 size(4); 9140 ins_encode %{ 9141 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9142 __ neg($dst$$Register, $src2$$Register); 9143 %} 9144 ins_pipe(pipe_class_default); 9145 %} 9146 9147 // Multiplication Instructions 9148 // Integer Multiplication 9149 9150 // Register Multiplication 9151 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9152 match(Set dst (MulI src1 src2)); 9153 ins_cost(DEFAULT_COST); 9154 9155 format %{ "MULLW $dst, $src1, $src2" %} 9156 size(4); 9157 ins_encode %{ 9158 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9159 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9160 %} 9161 ins_pipe(pipe_class_default); 9162 %} 9163 9164 // Immediate Multiplication 9165 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9166 match(Set dst (MulI src1 src2)); 9167 ins_cost(DEFAULT_COST); 9168 9169 format %{ "MULLI $dst, $src1, $src2" %} 9170 size(4); 9171 ins_encode %{ 9172 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9173 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9174 %} 9175 ins_pipe(pipe_class_default); 9176 %} 9177 9178 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9179 match(Set dst (MulL src1 src2)); 9180 ins_cost(DEFAULT_COST); 9181 9182 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9183 size(4); 9184 ins_encode %{ 9185 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9186 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9187 %} 9188 ins_pipe(pipe_class_default); 9189 %} 9190 9191 // Multiply high for optimized long division by constant. 9192 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9193 match(Set dst (MulHiL src1 src2)); 9194 ins_cost(DEFAULT_COST); 9195 9196 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9197 size(4); 9198 ins_encode %{ 9199 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9200 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9201 %} 9202 ins_pipe(pipe_class_default); 9203 %} 9204 9205 // Immediate Multiplication 9206 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9207 match(Set dst (MulL src1 src2)); 9208 ins_cost(DEFAULT_COST); 9209 9210 format %{ "MULLI $dst, $src1, $src2" %} 9211 size(4); 9212 ins_encode %{ 9213 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9214 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9215 %} 9216 ins_pipe(pipe_class_default); 9217 %} 9218 9219 // Integer Division with Immediate -1: Negate. 9220 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9221 match(Set dst (DivI src1 src2)); 9222 ins_cost(DEFAULT_COST); 9223 9224 format %{ "NEG $dst, $src1 \t// /-1" %} 9225 size(4); 9226 ins_encode %{ 9227 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9228 __ neg($dst$$Register, $src1$$Register); 9229 %} 9230 ins_pipe(pipe_class_default); 9231 %} 9232 9233 // Integer Division with constant, but not -1. 9234 // We should be able to improve this by checking the type of src2. 9235 // It might well be that src2 is known to be positive. 9236 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9237 match(Set dst (DivI src1 src2)); 9238 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9239 ins_cost(2*DEFAULT_COST); 9240 9241 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9242 size(4); 9243 ins_encode %{ 9244 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9245 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9246 %} 9247 ins_pipe(pipe_class_default); 9248 %} 9249 9250 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9251 effect(USE_DEF dst, USE src1, USE crx); 9252 predicate(false); 9253 9254 ins_variable_size_depending_on_alignment(true); 9255 9256 format %{ "CMOVE $dst, neg($src1), $crx" %} 9257 // Worst case is branch + move + stop, no stop without scheduler. 9258 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 9259 ins_encode %{ 9260 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9261 Label done; 9262 __ bne($crx$$CondRegister, done); 9263 __ neg($dst$$Register, $src1$$Register); 9264 // TODO PPC port __ endgroup_if_needed(_size == 12); 9265 __ bind(done); 9266 %} 9267 ins_pipe(pipe_class_default); 9268 %} 9269 9270 // Integer Division with Registers not containing constants. 9271 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9272 match(Set dst (DivI src1 src2)); 9273 ins_cost(10*DEFAULT_COST); 9274 9275 expand %{ 9276 immI16 imm %{ (int)-1 %} 9277 flagsReg tmp1; 9278 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9279 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9280 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9281 %} 9282 %} 9283 9284 // Long Division with Immediate -1: Negate. 9285 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9286 match(Set dst (DivL src1 src2)); 9287 ins_cost(DEFAULT_COST); 9288 9289 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9290 size(4); 9291 ins_encode %{ 9292 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9293 __ neg($dst$$Register, $src1$$Register); 9294 %} 9295 ins_pipe(pipe_class_default); 9296 %} 9297 9298 // Long Division with constant, but not -1. 9299 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9300 match(Set dst (DivL src1 src2)); 9301 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9302 ins_cost(2*DEFAULT_COST); 9303 9304 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9305 size(4); 9306 ins_encode %{ 9307 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9308 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9309 %} 9310 ins_pipe(pipe_class_default); 9311 %} 9312 9313 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9314 effect(USE_DEF dst, USE src1, USE crx); 9315 predicate(false); 9316 9317 ins_variable_size_depending_on_alignment(true); 9318 9319 format %{ "CMOVE $dst, neg($src1), $crx" %} 9320 // Worst case is branch + move + stop, no stop without scheduler. 9321 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 9322 ins_encode %{ 9323 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9324 Label done; 9325 __ bne($crx$$CondRegister, done); 9326 __ neg($dst$$Register, $src1$$Register); 9327 // TODO PPC port __ endgroup_if_needed(_size == 12); 9328 __ bind(done); 9329 %} 9330 ins_pipe(pipe_class_default); 9331 %} 9332 9333 // Long Division with Registers not containing constants. 9334 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9335 match(Set dst (DivL src1 src2)); 9336 ins_cost(10*DEFAULT_COST); 9337 9338 expand %{ 9339 immL16 imm %{ (int)-1 %} 9340 flagsReg tmp1; 9341 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9342 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9343 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9344 %} 9345 %} 9346 9347 // Integer Remainder with registers. 9348 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9349 match(Set dst (ModI src1 src2)); 9350 ins_cost(10*DEFAULT_COST); 9351 9352 expand %{ 9353 immI16 imm %{ (int)-1 %} 9354 flagsReg tmp1; 9355 iRegIdst tmp2; 9356 iRegIdst tmp3; 9357 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9358 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9359 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9360 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9361 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9362 %} 9363 %} 9364 9365 // Long Remainder with registers 9366 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9367 match(Set dst (ModL src1 src2)); 9368 ins_cost(10*DEFAULT_COST); 9369 9370 expand %{ 9371 immL16 imm %{ (int)-1 %} 9372 flagsReg tmp1; 9373 iRegLdst tmp2; 9374 iRegLdst tmp3; 9375 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9376 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9377 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9378 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9379 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9380 %} 9381 %} 9382 9383 // Integer Shift Instructions 9384 9385 // Register Shift Left 9386 9387 // Clear all but the lowest #mask bits. 9388 // Used to normalize shift amounts in registers. 9389 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9390 // no match-rule, false predicate 9391 effect(DEF dst, USE src, USE mask); 9392 predicate(false); 9393 9394 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9395 size(4); 9396 ins_encode %{ 9397 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9398 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9399 %} 9400 ins_pipe(pipe_class_default); 9401 %} 9402 9403 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9404 // no match-rule, false predicate 9405 effect(DEF dst, USE src1, USE src2); 9406 predicate(false); 9407 9408 format %{ "SLW $dst, $src1, $src2" %} 9409 size(4); 9410 ins_encode %{ 9411 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9412 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9413 %} 9414 ins_pipe(pipe_class_default); 9415 %} 9416 9417 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9418 match(Set dst (LShiftI src1 src2)); 9419 ins_cost(DEFAULT_COST*2); 9420 expand %{ 9421 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9422 iRegIdst tmpI; 9423 maskI_reg_imm(tmpI, src2, mask); 9424 lShiftI_reg_reg(dst, src1, tmpI); 9425 %} 9426 %} 9427 9428 // Register Shift Left Immediate 9429 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9430 match(Set dst (LShiftI src1 src2)); 9431 9432 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9433 size(4); 9434 ins_encode %{ 9435 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9436 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9437 %} 9438 ins_pipe(pipe_class_default); 9439 %} 9440 9441 // AndI with negpow2-constant + LShiftI 9442 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9443 match(Set dst (LShiftI (AndI src1 src2) src3)); 9444 predicate(UseRotateAndMaskInstructionsPPC64); 9445 9446 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9447 size(4); 9448 ins_encode %{ 9449 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9450 long src2 = $src2$$constant; 9451 long src3 = $src3$$constant; 9452 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9453 if (maskbits >= 32) { 9454 __ li($dst$$Register, 0); // addi 9455 } else { 9456 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9457 } 9458 %} 9459 ins_pipe(pipe_class_default); 9460 %} 9461 9462 // RShiftI + AndI with negpow2-constant + LShiftI 9463 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9464 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9465 predicate(UseRotateAndMaskInstructionsPPC64); 9466 9467 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9468 size(4); 9469 ins_encode %{ 9470 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9471 long src2 = $src2$$constant; 9472 long src3 = $src3$$constant; 9473 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9474 if (maskbits >= 32) { 9475 __ li($dst$$Register, 0); // addi 9476 } else { 9477 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9478 } 9479 %} 9480 ins_pipe(pipe_class_default); 9481 %} 9482 9483 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9484 // no match-rule, false predicate 9485 effect(DEF dst, USE src1, USE src2); 9486 predicate(false); 9487 9488 format %{ "SLD $dst, $src1, $src2" %} 9489 size(4); 9490 ins_encode %{ 9491 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9492 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9493 %} 9494 ins_pipe(pipe_class_default); 9495 %} 9496 9497 // Register Shift Left 9498 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9499 match(Set dst (LShiftL src1 src2)); 9500 ins_cost(DEFAULT_COST*2); 9501 expand %{ 9502 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9503 iRegIdst tmpI; 9504 maskI_reg_imm(tmpI, src2, mask); 9505 lShiftL_regL_regI(dst, src1, tmpI); 9506 %} 9507 %} 9508 9509 // Register Shift Left Immediate 9510 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9511 match(Set dst (LShiftL src1 src2)); 9512 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9513 size(4); 9514 ins_encode %{ 9515 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9516 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9517 %} 9518 ins_pipe(pipe_class_default); 9519 %} 9520 9521 // If we shift more than 32 bits, we need not convert I2L. 9522 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9523 match(Set dst (LShiftL (ConvI2L src1) src2)); 9524 ins_cost(DEFAULT_COST); 9525 9526 size(4); 9527 format %{ "SLDI $dst, i2l($src1), $src2" %} 9528 ins_encode %{ 9529 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9530 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9531 %} 9532 ins_pipe(pipe_class_default); 9533 %} 9534 9535 // Shift a postivie int to the left. 9536 // Clrlsldi clears the upper 32 bits and shifts. 9537 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9538 match(Set dst (LShiftL (ConvI2L src1) src2)); 9539 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9540 9541 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9542 size(4); 9543 ins_encode %{ 9544 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9545 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9546 %} 9547 ins_pipe(pipe_class_default); 9548 %} 9549 9550 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9551 // no match-rule, false predicate 9552 effect(DEF dst, USE src1, USE src2); 9553 predicate(false); 9554 9555 format %{ "SRAW $dst, $src1, $src2" %} 9556 size(4); 9557 ins_encode %{ 9558 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9559 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9560 %} 9561 ins_pipe(pipe_class_default); 9562 %} 9563 9564 // Register Arithmetic Shift Right 9565 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9566 match(Set dst (RShiftI src1 src2)); 9567 ins_cost(DEFAULT_COST*2); 9568 expand %{ 9569 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9570 iRegIdst tmpI; 9571 maskI_reg_imm(tmpI, src2, mask); 9572 arShiftI_reg_reg(dst, src1, tmpI); 9573 %} 9574 %} 9575 9576 // Register Arithmetic Shift Right Immediate 9577 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9578 match(Set dst (RShiftI src1 src2)); 9579 9580 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9581 size(4); 9582 ins_encode %{ 9583 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9584 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9585 %} 9586 ins_pipe(pipe_class_default); 9587 %} 9588 9589 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9590 // no match-rule, false predicate 9591 effect(DEF dst, USE src1, USE src2); 9592 predicate(false); 9593 9594 format %{ "SRAD $dst, $src1, $src2" %} 9595 size(4); 9596 ins_encode %{ 9597 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9598 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9599 %} 9600 ins_pipe(pipe_class_default); 9601 %} 9602 9603 // Register Shift Right Arithmetic Long 9604 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9605 match(Set dst (RShiftL src1 src2)); 9606 ins_cost(DEFAULT_COST*2); 9607 9608 expand %{ 9609 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9610 iRegIdst tmpI; 9611 maskI_reg_imm(tmpI, src2, mask); 9612 arShiftL_regL_regI(dst, src1, tmpI); 9613 %} 9614 %} 9615 9616 // Register Shift Right Immediate 9617 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9618 match(Set dst (RShiftL src1 src2)); 9619 9620 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9621 size(4); 9622 ins_encode %{ 9623 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9624 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9625 %} 9626 ins_pipe(pipe_class_default); 9627 %} 9628 9629 // RShiftL + ConvL2I 9630 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9631 match(Set dst (ConvL2I (RShiftL src1 src2))); 9632 9633 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9634 size(4); 9635 ins_encode %{ 9636 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9637 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9638 %} 9639 ins_pipe(pipe_class_default); 9640 %} 9641 9642 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9643 // no match-rule, false predicate 9644 effect(DEF dst, USE src1, USE src2); 9645 predicate(false); 9646 9647 format %{ "SRW $dst, $src1, $src2" %} 9648 size(4); 9649 ins_encode %{ 9650 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9651 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9652 %} 9653 ins_pipe(pipe_class_default); 9654 %} 9655 9656 // Register Shift Right 9657 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9658 match(Set dst (URShiftI src1 src2)); 9659 ins_cost(DEFAULT_COST*2); 9660 9661 expand %{ 9662 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9663 iRegIdst tmpI; 9664 maskI_reg_imm(tmpI, src2, mask); 9665 urShiftI_reg_reg(dst, src1, tmpI); 9666 %} 9667 %} 9668 9669 // Register Shift Right Immediate 9670 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9671 match(Set dst (URShiftI src1 src2)); 9672 9673 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9674 size(4); 9675 ins_encode %{ 9676 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9677 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9678 %} 9679 ins_pipe(pipe_class_default); 9680 %} 9681 9682 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9683 // no match-rule, false predicate 9684 effect(DEF dst, USE src1, USE src2); 9685 predicate(false); 9686 9687 format %{ "SRD $dst, $src1, $src2" %} 9688 size(4); 9689 ins_encode %{ 9690 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9691 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9692 %} 9693 ins_pipe(pipe_class_default); 9694 %} 9695 9696 // Register Shift Right 9697 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9698 match(Set dst (URShiftL src1 src2)); 9699 ins_cost(DEFAULT_COST*2); 9700 9701 expand %{ 9702 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9703 iRegIdst tmpI; 9704 maskI_reg_imm(tmpI, src2, mask); 9705 urShiftL_regL_regI(dst, src1, tmpI); 9706 %} 9707 %} 9708 9709 // Register Shift Right Immediate 9710 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9711 match(Set dst (URShiftL src1 src2)); 9712 9713 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9714 size(4); 9715 ins_encode %{ 9716 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9717 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9718 %} 9719 ins_pipe(pipe_class_default); 9720 %} 9721 9722 // URShiftL + ConvL2I. 9723 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9724 match(Set dst (ConvL2I (URShiftL src1 src2))); 9725 9726 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9727 size(4); 9728 ins_encode %{ 9729 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9730 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9731 %} 9732 ins_pipe(pipe_class_default); 9733 %} 9734 9735 // Register Shift Right Immediate with a CastP2X 9736 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9737 match(Set dst (URShiftL (CastP2X src1) src2)); 9738 9739 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9740 size(4); 9741 ins_encode %{ 9742 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9743 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9744 %} 9745 ins_pipe(pipe_class_default); 9746 %} 9747 9748 // Bitfield Extract: URShiftI + AndI 9749 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9750 match(Set dst (AndI (URShiftI src1 src2) src3)); 9751 9752 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9753 size(4); 9754 ins_encode %{ 9755 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9756 int rshift = ($src2$$constant) & 0x1f; 9757 int length = log2_long(((jlong) $src3$$constant) + 1); 9758 if (rshift + length > 32) { 9759 // if necessary, adjust mask to omit rotated bits. 9760 length = 32 - rshift; 9761 } 9762 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9763 %} 9764 ins_pipe(pipe_class_default); 9765 %} 9766 9767 // Bitfield Extract: URShiftL + AndL 9768 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9769 match(Set dst (AndL (URShiftL src1 src2) src3)); 9770 9771 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9772 size(4); 9773 ins_encode %{ 9774 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9775 int rshift = ($src2$$constant) & 0x3f; 9776 int length = log2_long(((jlong) $src3$$constant) + 1); 9777 if (rshift + length > 64) { 9778 // if necessary, adjust mask to omit rotated bits. 9779 length = 64 - rshift; 9780 } 9781 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9782 %} 9783 ins_pipe(pipe_class_default); 9784 %} 9785 9786 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9787 match(Set dst (ConvL2I (ConvI2L src))); 9788 9789 format %{ "EXTSW $dst, $src \t// int->int" %} 9790 size(4); 9791 ins_encode %{ 9792 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9793 __ extsw($dst$$Register, $src$$Register); 9794 %} 9795 ins_pipe(pipe_class_default); 9796 %} 9797 9798 //----------Rotate Instructions------------------------------------------------ 9799 9800 // Rotate Left by 8-bit immediate 9801 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9802 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9803 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9804 9805 format %{ "ROTLWI $dst, $src, $lshift" %} 9806 size(4); 9807 ins_encode %{ 9808 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9809 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9810 %} 9811 ins_pipe(pipe_class_default); 9812 %} 9813 9814 // Rotate Right by 8-bit immediate 9815 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9816 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9817 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9818 9819 format %{ "ROTRWI $dst, $rshift" %} 9820 size(4); 9821 ins_encode %{ 9822 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9823 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9824 %} 9825 ins_pipe(pipe_class_default); 9826 %} 9827 9828 //----------Floating Point Arithmetic Instructions----------------------------- 9829 9830 // Add float single precision 9831 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9832 match(Set dst (AddF src1 src2)); 9833 9834 format %{ "FADDS $dst, $src1, $src2" %} 9835 size(4); 9836 ins_encode %{ 9837 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9838 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9839 %} 9840 ins_pipe(pipe_class_default); 9841 %} 9842 9843 // Add float double precision 9844 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9845 match(Set dst (AddD src1 src2)); 9846 9847 format %{ "FADD $dst, $src1, $src2" %} 9848 size(4); 9849 ins_encode %{ 9850 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9851 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9852 %} 9853 ins_pipe(pipe_class_default); 9854 %} 9855 9856 // Sub float single precision 9857 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9858 match(Set dst (SubF src1 src2)); 9859 9860 format %{ "FSUBS $dst, $src1, $src2" %} 9861 size(4); 9862 ins_encode %{ 9863 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9864 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9865 %} 9866 ins_pipe(pipe_class_default); 9867 %} 9868 9869 // Sub float double precision 9870 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9871 match(Set dst (SubD src1 src2)); 9872 format %{ "FSUB $dst, $src1, $src2" %} 9873 size(4); 9874 ins_encode %{ 9875 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9876 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9877 %} 9878 ins_pipe(pipe_class_default); 9879 %} 9880 9881 // Mul float single precision 9882 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9883 match(Set dst (MulF src1 src2)); 9884 format %{ "FMULS $dst, $src1, $src2" %} 9885 size(4); 9886 ins_encode %{ 9887 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9888 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9889 %} 9890 ins_pipe(pipe_class_default); 9891 %} 9892 9893 // Mul float double precision 9894 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9895 match(Set dst (MulD src1 src2)); 9896 format %{ "FMUL $dst, $src1, $src2" %} 9897 size(4); 9898 ins_encode %{ 9899 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9900 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9901 %} 9902 ins_pipe(pipe_class_default); 9903 %} 9904 9905 // Div float single precision 9906 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9907 match(Set dst (DivF src1 src2)); 9908 format %{ "FDIVS $dst, $src1, $src2" %} 9909 size(4); 9910 ins_encode %{ 9911 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9912 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9913 %} 9914 ins_pipe(pipe_class_default); 9915 %} 9916 9917 // Div float double precision 9918 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9919 match(Set dst (DivD src1 src2)); 9920 format %{ "FDIV $dst, $src1, $src2" %} 9921 size(4); 9922 ins_encode %{ 9923 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9924 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9925 %} 9926 ins_pipe(pipe_class_default); 9927 %} 9928 9929 // Absolute float single precision 9930 instruct absF_reg(regF dst, regF src) %{ 9931 match(Set dst (AbsF src)); 9932 format %{ "FABS $dst, $src \t// float" %} 9933 size(4); 9934 ins_encode %{ 9935 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9936 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9937 %} 9938 ins_pipe(pipe_class_default); 9939 %} 9940 9941 // Absolute float double precision 9942 instruct absD_reg(regD dst, regD src) %{ 9943 match(Set dst (AbsD src)); 9944 format %{ "FABS $dst, $src \t// double" %} 9945 size(4); 9946 ins_encode %{ 9947 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9948 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9949 %} 9950 ins_pipe(pipe_class_default); 9951 %} 9952 9953 instruct negF_reg(regF dst, regF src) %{ 9954 match(Set dst (NegF src)); 9955 format %{ "FNEG $dst, $src \t// float" %} 9956 size(4); 9957 ins_encode %{ 9958 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9959 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9960 %} 9961 ins_pipe(pipe_class_default); 9962 %} 9963 9964 instruct negD_reg(regD dst, regD src) %{ 9965 match(Set dst (NegD src)); 9966 format %{ "FNEG $dst, $src \t// double" %} 9967 size(4); 9968 ins_encode %{ 9969 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9970 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9971 %} 9972 ins_pipe(pipe_class_default); 9973 %} 9974 9975 // AbsF + NegF. 9976 instruct negF_absF_reg(regF dst, regF src) %{ 9977 match(Set dst (NegF (AbsF src))); 9978 format %{ "FNABS $dst, $src \t// float" %} 9979 size(4); 9980 ins_encode %{ 9981 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9982 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9983 %} 9984 ins_pipe(pipe_class_default); 9985 %} 9986 9987 // AbsD + NegD. 9988 instruct negD_absD_reg(regD dst, regD src) %{ 9989 match(Set dst (NegD (AbsD src))); 9990 format %{ "FNABS $dst, $src \t// double" %} 9991 size(4); 9992 ins_encode %{ 9993 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9994 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9995 %} 9996 ins_pipe(pipe_class_default); 9997 %} 9998 9999 // VM_Version::has_fsqrt() decides if this node will be used. 10000 // Sqrt float double precision 10001 instruct sqrtD_reg(regD dst, regD src) %{ 10002 match(Set dst (SqrtD src)); 10003 format %{ "FSQRT $dst, $src" %} 10004 size(4); 10005 ins_encode %{ 10006 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 10007 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 10008 %} 10009 ins_pipe(pipe_class_default); 10010 %} 10011 10012 // Single-precision sqrt. 10013 instruct sqrtF_reg(regF dst, regF src) %{ 10014 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 10015 predicate(VM_Version::has_fsqrts()); 10016 ins_cost(DEFAULT_COST); 10017 10018 format %{ "FSQRTS $dst, $src" %} 10019 size(4); 10020 ins_encode %{ 10021 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 10022 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 10023 %} 10024 ins_pipe(pipe_class_default); 10025 %} 10026 10027 instruct roundDouble_nop(regD dst) %{ 10028 match(Set dst (RoundDouble dst)); 10029 ins_cost(0); 10030 10031 format %{ " -- \t// RoundDouble not needed - empty" %} 10032 size(0); 10033 // PPC results are already "rounded" (i.e., normal-format IEEE). 10034 ins_encode( /*empty*/ ); 10035 ins_pipe(pipe_class_default); 10036 %} 10037 10038 instruct roundFloat_nop(regF dst) %{ 10039 match(Set dst (RoundFloat dst)); 10040 ins_cost(0); 10041 10042 format %{ " -- \t// RoundFloat not needed - empty" %} 10043 size(0); 10044 // PPC results are already "rounded" (i.e., normal-format IEEE). 10045 ins_encode( /*empty*/ ); 10046 ins_pipe(pipe_class_default); 10047 %} 10048 10049 10050 // Multiply-Accumulate 10051 // src1 * src2 + src3 10052 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10053 match(Set dst (FmaF src3 (Binary src1 src2))); 10054 10055 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10056 size(4); 10057 ins_encode %{ 10058 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10059 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10060 %} 10061 ins_pipe(pipe_class_default); 10062 %} 10063 10064 // src1 * src2 + src3 10065 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10066 match(Set dst (FmaD src3 (Binary src1 src2))); 10067 10068 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10069 size(4); 10070 ins_encode %{ 10071 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10072 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10073 %} 10074 ins_pipe(pipe_class_default); 10075 %} 10076 10077 // -src1 * src2 + src3 = -(src1*src2-src3) 10078 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10079 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10080 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10081 10082 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10083 size(4); 10084 ins_encode %{ 10085 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10086 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10087 %} 10088 ins_pipe(pipe_class_default); 10089 %} 10090 10091 // -src1 * src2 + src3 = -(src1*src2-src3) 10092 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10093 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10094 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10095 10096 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10097 size(4); 10098 ins_encode %{ 10099 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10100 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10101 %} 10102 ins_pipe(pipe_class_default); 10103 %} 10104 10105 // -src1 * src2 - src3 = -(src1*src2+src3) 10106 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10107 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10108 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10109 10110 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10111 size(4); 10112 ins_encode %{ 10113 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10114 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10115 %} 10116 ins_pipe(pipe_class_default); 10117 %} 10118 10119 // -src1 * src2 - src3 = -(src1*src2+src3) 10120 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10121 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10122 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10123 10124 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10125 size(4); 10126 ins_encode %{ 10127 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10128 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10129 %} 10130 ins_pipe(pipe_class_default); 10131 %} 10132 10133 // src1 * src2 - src3 10134 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10135 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10136 10137 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10138 size(4); 10139 ins_encode %{ 10140 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10141 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10142 %} 10143 ins_pipe(pipe_class_default); 10144 %} 10145 10146 // src1 * src2 - src3 10147 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10148 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10149 10150 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10151 size(4); 10152 ins_encode %{ 10153 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10154 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10155 %} 10156 ins_pipe(pipe_class_default); 10157 %} 10158 10159 10160 //----------Logical Instructions----------------------------------------------- 10161 10162 // And Instructions 10163 10164 // Register And 10165 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10166 match(Set dst (AndI src1 src2)); 10167 format %{ "AND $dst, $src1, $src2" %} 10168 size(4); 10169 ins_encode %{ 10170 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10171 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10172 %} 10173 ins_pipe(pipe_class_default); 10174 %} 10175 10176 // Left shifted Immediate And 10177 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10178 match(Set dst (AndI src1 src2)); 10179 effect(KILL cr0); 10180 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10181 size(4); 10182 ins_encode %{ 10183 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10184 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10185 %} 10186 ins_pipe(pipe_class_default); 10187 %} 10188 10189 // Immediate And 10190 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10191 match(Set dst (AndI src1 src2)); 10192 effect(KILL cr0); 10193 10194 format %{ "ANDI $dst, $src1, $src2" %} 10195 size(4); 10196 ins_encode %{ 10197 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10198 // FIXME: avoid andi_ ? 10199 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10200 %} 10201 ins_pipe(pipe_class_default); 10202 %} 10203 10204 // Immediate And where the immediate is a negative power of 2. 10205 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10206 match(Set dst (AndI src1 src2)); 10207 format %{ "ANDWI $dst, $src1, $src2" %} 10208 size(4); 10209 ins_encode %{ 10210 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10211 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10212 %} 10213 ins_pipe(pipe_class_default); 10214 %} 10215 10216 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10217 match(Set dst (AndI src1 src2)); 10218 format %{ "ANDWI $dst, $src1, $src2" %} 10219 size(4); 10220 ins_encode %{ 10221 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10222 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10223 %} 10224 ins_pipe(pipe_class_default); 10225 %} 10226 10227 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10228 match(Set dst (AndI src1 src2)); 10229 predicate(UseRotateAndMaskInstructionsPPC64); 10230 format %{ "ANDWI $dst, $src1, $src2" %} 10231 size(4); 10232 ins_encode %{ 10233 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10234 __ rlwinm($dst$$Register, $src1$$Register, 0, 10235 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10236 %} 10237 ins_pipe(pipe_class_default); 10238 %} 10239 10240 // Register And Long 10241 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10242 match(Set dst (AndL src1 src2)); 10243 ins_cost(DEFAULT_COST); 10244 10245 format %{ "AND $dst, $src1, $src2 \t// long" %} 10246 size(4); 10247 ins_encode %{ 10248 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10249 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10250 %} 10251 ins_pipe(pipe_class_default); 10252 %} 10253 10254 // Immediate And long 10255 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10256 match(Set dst (AndL src1 src2)); 10257 effect(KILL cr0); 10258 10259 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10260 size(4); 10261 ins_encode %{ 10262 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10263 // FIXME: avoid andi_ ? 10264 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10265 %} 10266 ins_pipe(pipe_class_default); 10267 %} 10268 10269 // Immediate And Long where the immediate is a negative power of 2. 10270 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10271 match(Set dst (AndL src1 src2)); 10272 format %{ "ANDDI $dst, $src1, $src2" %} 10273 size(4); 10274 ins_encode %{ 10275 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10276 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10277 %} 10278 ins_pipe(pipe_class_default); 10279 %} 10280 10281 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10282 match(Set dst (AndL src1 src2)); 10283 format %{ "ANDDI $dst, $src1, $src2" %} 10284 size(4); 10285 ins_encode %{ 10286 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10287 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10288 %} 10289 ins_pipe(pipe_class_default); 10290 %} 10291 10292 // AndL + ConvL2I. 10293 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10294 match(Set dst (ConvL2I (AndL src1 src2))); 10295 ins_cost(DEFAULT_COST); 10296 10297 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10298 size(4); 10299 ins_encode %{ 10300 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10301 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10302 %} 10303 ins_pipe(pipe_class_default); 10304 %} 10305 10306 // Or Instructions 10307 10308 // Register Or 10309 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10310 match(Set dst (OrI src1 src2)); 10311 format %{ "OR $dst, $src1, $src2" %} 10312 size(4); 10313 ins_encode %{ 10314 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10315 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10316 %} 10317 ins_pipe(pipe_class_default); 10318 %} 10319 10320 // Expand does not work with above instruct. (??) 10321 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10322 // no match-rule 10323 effect(DEF dst, USE src1, USE src2); 10324 format %{ "OR $dst, $src1, $src2" %} 10325 size(4); 10326 ins_encode %{ 10327 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10328 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10329 %} 10330 ins_pipe(pipe_class_default); 10331 %} 10332 10333 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10334 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10335 ins_cost(DEFAULT_COST*3); 10336 10337 expand %{ 10338 // FIXME: we should do this in the ideal world. 10339 iRegIdst tmp1; 10340 iRegIdst tmp2; 10341 orI_reg_reg(tmp1, src1, src2); 10342 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10343 orI_reg_reg(dst, tmp1, tmp2); 10344 %} 10345 %} 10346 10347 // Immediate Or 10348 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10349 match(Set dst (OrI src1 src2)); 10350 format %{ "ORI $dst, $src1, $src2" %} 10351 size(4); 10352 ins_encode %{ 10353 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10354 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10355 %} 10356 ins_pipe(pipe_class_default); 10357 %} 10358 10359 // Register Or Long 10360 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10361 match(Set dst (OrL src1 src2)); 10362 ins_cost(DEFAULT_COST); 10363 10364 size(4); 10365 format %{ "OR $dst, $src1, $src2 \t// long" %} 10366 ins_encode %{ 10367 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10368 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10369 %} 10370 ins_pipe(pipe_class_default); 10371 %} 10372 10373 // OrL + ConvL2I. 10374 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10375 match(Set dst (ConvL2I (OrL src1 src2))); 10376 ins_cost(DEFAULT_COST); 10377 10378 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10379 size(4); 10380 ins_encode %{ 10381 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10382 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10383 %} 10384 ins_pipe(pipe_class_default); 10385 %} 10386 10387 // Immediate Or long 10388 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10389 match(Set dst (OrL src1 con)); 10390 ins_cost(DEFAULT_COST); 10391 10392 format %{ "ORI $dst, $src1, $con \t// long" %} 10393 size(4); 10394 ins_encode %{ 10395 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10396 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10397 %} 10398 ins_pipe(pipe_class_default); 10399 %} 10400 10401 // Xor Instructions 10402 10403 // Register Xor 10404 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10405 match(Set dst (XorI src1 src2)); 10406 format %{ "XOR $dst, $src1, $src2" %} 10407 size(4); 10408 ins_encode %{ 10409 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10410 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10411 %} 10412 ins_pipe(pipe_class_default); 10413 %} 10414 10415 // Expand does not work with above instruct. (??) 10416 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10417 // no match-rule 10418 effect(DEF dst, USE src1, USE src2); 10419 format %{ "XOR $dst, $src1, $src2" %} 10420 size(4); 10421 ins_encode %{ 10422 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10423 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10424 %} 10425 ins_pipe(pipe_class_default); 10426 %} 10427 10428 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10429 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10430 ins_cost(DEFAULT_COST*3); 10431 10432 expand %{ 10433 // FIXME: we should do this in the ideal world. 10434 iRegIdst tmp1; 10435 iRegIdst tmp2; 10436 xorI_reg_reg(tmp1, src1, src2); 10437 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10438 xorI_reg_reg(dst, tmp1, tmp2); 10439 %} 10440 %} 10441 10442 // Immediate Xor 10443 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10444 match(Set dst (XorI src1 src2)); 10445 format %{ "XORI $dst, $src1, $src2" %} 10446 size(4); 10447 ins_encode %{ 10448 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10449 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10450 %} 10451 ins_pipe(pipe_class_default); 10452 %} 10453 10454 // Register Xor Long 10455 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10456 match(Set dst (XorL src1 src2)); 10457 ins_cost(DEFAULT_COST); 10458 10459 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10460 size(4); 10461 ins_encode %{ 10462 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10463 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10464 %} 10465 ins_pipe(pipe_class_default); 10466 %} 10467 10468 // XorL + ConvL2I. 10469 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10470 match(Set dst (ConvL2I (XorL src1 src2))); 10471 ins_cost(DEFAULT_COST); 10472 10473 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10474 size(4); 10475 ins_encode %{ 10476 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10477 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10478 %} 10479 ins_pipe(pipe_class_default); 10480 %} 10481 10482 // Immediate Xor Long 10483 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10484 match(Set dst (XorL src1 src2)); 10485 ins_cost(DEFAULT_COST); 10486 10487 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10488 size(4); 10489 ins_encode %{ 10490 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10491 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10492 %} 10493 ins_pipe(pipe_class_default); 10494 %} 10495 10496 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10497 match(Set dst (XorI src1 src2)); 10498 ins_cost(DEFAULT_COST); 10499 10500 format %{ "NOT $dst, $src1 ($src2)" %} 10501 size(4); 10502 ins_encode %{ 10503 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10504 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10505 %} 10506 ins_pipe(pipe_class_default); 10507 %} 10508 10509 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10510 match(Set dst (XorL src1 src2)); 10511 ins_cost(DEFAULT_COST); 10512 10513 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10514 size(4); 10515 ins_encode %{ 10516 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10517 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10518 %} 10519 ins_pipe(pipe_class_default); 10520 %} 10521 10522 // And-complement 10523 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10524 match(Set dst (AndI (XorI src1 src2) src3)); 10525 ins_cost(DEFAULT_COST); 10526 10527 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10528 size(4); 10529 ins_encode( enc_andc(dst, src3, src1) ); 10530 ins_pipe(pipe_class_default); 10531 %} 10532 10533 // And-complement 10534 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10535 // no match-rule, false predicate 10536 effect(DEF dst, USE src1, USE src2); 10537 predicate(false); 10538 10539 format %{ "ANDC $dst, $src1, $src2" %} 10540 size(4); 10541 ins_encode %{ 10542 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10543 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10544 %} 10545 ins_pipe(pipe_class_default); 10546 %} 10547 10548 //----------Moves between int/long and float/double---------------------------- 10549 // 10550 // The following rules move values from int/long registers/stack-locations 10551 // to float/double registers/stack-locations and vice versa, without doing any 10552 // conversions. These rules are used to implement the bit-conversion methods 10553 // of java.lang.Float etc., e.g. 10554 // int floatToIntBits(float value) 10555 // float intBitsToFloat(int bits) 10556 // 10557 // Notes on the implementation on ppc64: 10558 // For Power7 and earlier, the rules are limited to those which move between a 10559 // register and a stack-location, because we always have to go through memory 10560 // when moving between a float register and an integer register. 10561 // This restriction is removed in Power8 with the introduction of the mtfprd 10562 // and mffprd instructions. 10563 10564 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10565 match(Set dst (MoveL2D src)); 10566 predicate(VM_Version::has_mtfprd()); 10567 10568 format %{ "MTFPRD $dst, $src" %} 10569 size(4); 10570 ins_encode %{ 10571 __ mtfprd($dst$$FloatRegister, $src$$Register); 10572 %} 10573 ins_pipe(pipe_class_default); 10574 %} 10575 10576 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10577 // no match-rule, false predicate 10578 effect(DEF dst, USE src); 10579 predicate(false); 10580 10581 format %{ "MTFPRWA $dst, $src" %} 10582 size(4); 10583 ins_encode %{ 10584 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10585 %} 10586 ins_pipe(pipe_class_default); 10587 %} 10588 10589 //---------- Chain stack slots between similar types -------- 10590 10591 // These are needed so that the rules below can match. 10592 10593 // Load integer from stack slot 10594 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10595 match(Set dst src); 10596 ins_cost(MEMORY_REF_COST); 10597 10598 format %{ "LWZ $dst, $src" %} 10599 size(4); 10600 ins_encode( enc_lwz(dst, src) ); 10601 ins_pipe(pipe_class_memory); 10602 %} 10603 10604 // Store integer to stack slot 10605 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10606 match(Set dst src); 10607 ins_cost(MEMORY_REF_COST); 10608 10609 format %{ "STW $src, $dst \t// stk" %} 10610 size(4); 10611 ins_encode( enc_stw(src, dst) ); // rs=rt 10612 ins_pipe(pipe_class_memory); 10613 %} 10614 10615 // Load long from stack slot 10616 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10617 match(Set dst src); 10618 ins_cost(MEMORY_REF_COST); 10619 10620 format %{ "LD $dst, $src \t// long" %} 10621 size(4); 10622 ins_encode( enc_ld(dst, src) ); 10623 ins_pipe(pipe_class_memory); 10624 %} 10625 10626 // Store long to stack slot 10627 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10628 match(Set dst src); 10629 ins_cost(MEMORY_REF_COST); 10630 10631 format %{ "STD $src, $dst \t// long" %} 10632 size(4); 10633 ins_encode( enc_std(src, dst) ); // rs=rt 10634 ins_pipe(pipe_class_memory); 10635 %} 10636 10637 //----------Moves between int and float 10638 10639 // Move float value from float stack-location to integer register. 10640 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10641 match(Set dst (MoveF2I src)); 10642 ins_cost(MEMORY_REF_COST); 10643 10644 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10645 size(4); 10646 ins_encode( enc_lwz(dst, src) ); 10647 ins_pipe(pipe_class_memory); 10648 %} 10649 10650 // Move float value from float register to integer stack-location. 10651 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10652 match(Set dst (MoveF2I src)); 10653 ins_cost(MEMORY_REF_COST); 10654 10655 format %{ "STFS $src, $dst \t// MoveF2I" %} 10656 size(4); 10657 ins_encode( enc_stfs(src, dst) ); 10658 ins_pipe(pipe_class_memory); 10659 %} 10660 10661 // Move integer value from integer stack-location to float register. 10662 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10663 match(Set dst (MoveI2F src)); 10664 ins_cost(MEMORY_REF_COST); 10665 10666 format %{ "LFS $dst, $src \t// MoveI2F" %} 10667 size(4); 10668 ins_encode %{ 10669 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10670 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10671 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10672 %} 10673 ins_pipe(pipe_class_memory); 10674 %} 10675 10676 // Move integer value from integer register to float stack-location. 10677 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10678 match(Set dst (MoveI2F src)); 10679 ins_cost(MEMORY_REF_COST); 10680 10681 format %{ "STW $src, $dst \t// MoveI2F" %} 10682 size(4); 10683 ins_encode( enc_stw(src, dst) ); 10684 ins_pipe(pipe_class_memory); 10685 %} 10686 10687 //----------Moves between long and float 10688 10689 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10690 // no match-rule, false predicate 10691 effect(DEF dst, USE src); 10692 predicate(false); 10693 10694 format %{ "storeD $src, $dst \t// STACK" %} 10695 size(4); 10696 ins_encode( enc_stfd(src, dst) ); 10697 ins_pipe(pipe_class_default); 10698 %} 10699 10700 //----------Moves between long and double 10701 10702 // Move double value from double stack-location to long register. 10703 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10704 match(Set dst (MoveD2L src)); 10705 ins_cost(MEMORY_REF_COST); 10706 size(4); 10707 format %{ "LD $dst, $src \t// MoveD2L" %} 10708 ins_encode( enc_ld(dst, src) ); 10709 ins_pipe(pipe_class_memory); 10710 %} 10711 10712 // Move double value from double register to long stack-location. 10713 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10714 match(Set dst (MoveD2L src)); 10715 effect(DEF dst, USE src); 10716 ins_cost(MEMORY_REF_COST); 10717 10718 format %{ "STFD $src, $dst \t// MoveD2L" %} 10719 size(4); 10720 ins_encode( enc_stfd(src, dst) ); 10721 ins_pipe(pipe_class_memory); 10722 %} 10723 10724 // Move long value from long stack-location to double register. 10725 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10726 match(Set dst (MoveL2D src)); 10727 ins_cost(MEMORY_REF_COST); 10728 10729 format %{ "LFD $dst, $src \t// MoveL2D" %} 10730 size(4); 10731 ins_encode( enc_lfd(dst, src) ); 10732 ins_pipe(pipe_class_memory); 10733 %} 10734 10735 // Move long value from long register to double stack-location. 10736 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10737 match(Set dst (MoveL2D src)); 10738 ins_cost(MEMORY_REF_COST); 10739 10740 format %{ "STD $src, $dst \t// MoveL2D" %} 10741 size(4); 10742 ins_encode( enc_std(src, dst) ); 10743 ins_pipe(pipe_class_memory); 10744 %} 10745 10746 //----------Register Move Instructions----------------------------------------- 10747 10748 // Replicate for Superword 10749 10750 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10751 predicate(false); 10752 effect(DEF dst, USE src); 10753 10754 format %{ "MR $dst, $src \t// replicate " %} 10755 // variable size, 0 or 4. 10756 ins_encode %{ 10757 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10758 __ mr_if_needed($dst$$Register, $src$$Register); 10759 %} 10760 ins_pipe(pipe_class_default); 10761 %} 10762 10763 //----------Cast instructions (Java-level type cast)--------------------------- 10764 10765 // Cast Long to Pointer for unsafe natives. 10766 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10767 match(Set dst (CastX2P src)); 10768 10769 format %{ "MR $dst, $src \t// Long->Ptr" %} 10770 // variable size, 0 or 4. 10771 ins_encode %{ 10772 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10773 __ mr_if_needed($dst$$Register, $src$$Register); 10774 %} 10775 ins_pipe(pipe_class_default); 10776 %} 10777 10778 // Cast Pointer to Long for unsafe natives. 10779 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10780 match(Set dst (CastP2X src)); 10781 10782 format %{ "MR $dst, $src \t// Ptr->Long" %} 10783 // variable size, 0 or 4. 10784 ins_encode %{ 10785 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10786 __ mr_if_needed($dst$$Register, $src$$Register); 10787 %} 10788 ins_pipe(pipe_class_default); 10789 %} 10790 10791 instruct castPP(iRegPdst dst) %{ 10792 match(Set dst (CastPP dst)); 10793 format %{ " -- \t// castPP of $dst" %} 10794 size(0); 10795 ins_encode( /*empty*/ ); 10796 ins_pipe(pipe_class_default); 10797 %} 10798 10799 instruct castII(iRegIdst dst) %{ 10800 match(Set dst (CastII dst)); 10801 format %{ " -- \t// castII of $dst" %} 10802 size(0); 10803 ins_encode( /*empty*/ ); 10804 ins_pipe(pipe_class_default); 10805 %} 10806 10807 instruct checkCastPP(iRegPdst dst) %{ 10808 match(Set dst (CheckCastPP dst)); 10809 format %{ " -- \t// checkcastPP of $dst" %} 10810 size(0); 10811 ins_encode( /*empty*/ ); 10812 ins_pipe(pipe_class_default); 10813 %} 10814 10815 //----------Convert instructions----------------------------------------------- 10816 10817 // Convert to boolean. 10818 10819 // int_to_bool(src) : { 1 if src != 0 10820 // { 0 else 10821 // 10822 // strategy: 10823 // 1) Count leading zeros of 32 bit-value src, 10824 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10825 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10826 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10827 10828 // convI2Bool 10829 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10830 match(Set dst (Conv2B src)); 10831 predicate(UseCountLeadingZerosInstructionsPPC64); 10832 ins_cost(DEFAULT_COST); 10833 10834 expand %{ 10835 immI shiftAmount %{ 0x5 %} 10836 uimmI16 mask %{ 0x1 %} 10837 iRegIdst tmp1; 10838 iRegIdst tmp2; 10839 countLeadingZerosI(tmp1, src); 10840 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10841 xorI_reg_uimm16(dst, tmp2, mask); 10842 %} 10843 %} 10844 10845 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10846 match(Set dst (Conv2B src)); 10847 effect(TEMP crx); 10848 predicate(!UseCountLeadingZerosInstructionsPPC64); 10849 ins_cost(DEFAULT_COST); 10850 10851 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10852 "LI $dst, #0\n\t" 10853 "BEQ $crx, done\n\t" 10854 "LI $dst, #1\n" 10855 "done:" %} 10856 size(16); 10857 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10858 ins_pipe(pipe_class_compare); 10859 %} 10860 10861 // ConvI2B + XorI 10862 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10863 match(Set dst (XorI (Conv2B src) mask)); 10864 predicate(UseCountLeadingZerosInstructionsPPC64); 10865 ins_cost(DEFAULT_COST); 10866 10867 expand %{ 10868 immI shiftAmount %{ 0x5 %} 10869 iRegIdst tmp1; 10870 countLeadingZerosI(tmp1, src); 10871 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10872 %} 10873 %} 10874 10875 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10876 match(Set dst (XorI (Conv2B src) mask)); 10877 effect(TEMP crx); 10878 predicate(!UseCountLeadingZerosInstructionsPPC64); 10879 ins_cost(DEFAULT_COST); 10880 10881 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10882 "LI $dst, #1\n\t" 10883 "BEQ $crx, done\n\t" 10884 "LI $dst, #0\n" 10885 "done:" %} 10886 size(16); 10887 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10888 ins_pipe(pipe_class_compare); 10889 %} 10890 10891 // AndI 0b0..010..0 + ConvI2B 10892 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10893 match(Set dst (Conv2B (AndI src mask))); 10894 predicate(UseRotateAndMaskInstructionsPPC64); 10895 ins_cost(DEFAULT_COST); 10896 10897 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10898 size(4); 10899 ins_encode %{ 10900 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10901 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10902 %} 10903 ins_pipe(pipe_class_default); 10904 %} 10905 10906 // Convert pointer to boolean. 10907 // 10908 // ptr_to_bool(src) : { 1 if src != 0 10909 // { 0 else 10910 // 10911 // strategy: 10912 // 1) Count leading zeros of 64 bit-value src, 10913 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10914 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10915 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10916 10917 // ConvP2B 10918 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10919 match(Set dst (Conv2B src)); 10920 predicate(UseCountLeadingZerosInstructionsPPC64); 10921 ins_cost(DEFAULT_COST); 10922 10923 expand %{ 10924 immI shiftAmount %{ 0x6 %} 10925 uimmI16 mask %{ 0x1 %} 10926 iRegIdst tmp1; 10927 iRegIdst tmp2; 10928 countLeadingZerosP(tmp1, src); 10929 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10930 xorI_reg_uimm16(dst, tmp2, mask); 10931 %} 10932 %} 10933 10934 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10935 match(Set dst (Conv2B src)); 10936 effect(TEMP crx); 10937 predicate(!UseCountLeadingZerosInstructionsPPC64); 10938 ins_cost(DEFAULT_COST); 10939 10940 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10941 "LI $dst, #0\n\t" 10942 "BEQ $crx, done\n\t" 10943 "LI $dst, #1\n" 10944 "done:" %} 10945 size(16); 10946 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10947 ins_pipe(pipe_class_compare); 10948 %} 10949 10950 // ConvP2B + XorI 10951 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10952 match(Set dst (XorI (Conv2B src) mask)); 10953 predicate(UseCountLeadingZerosInstructionsPPC64); 10954 ins_cost(DEFAULT_COST); 10955 10956 expand %{ 10957 immI shiftAmount %{ 0x6 %} 10958 iRegIdst tmp1; 10959 countLeadingZerosP(tmp1, src); 10960 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10961 %} 10962 %} 10963 10964 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10965 match(Set dst (XorI (Conv2B src) mask)); 10966 effect(TEMP crx); 10967 predicate(!UseCountLeadingZerosInstructionsPPC64); 10968 ins_cost(DEFAULT_COST); 10969 10970 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10971 "LI $dst, #1\n\t" 10972 "BEQ $crx, done\n\t" 10973 "LI $dst, #0\n" 10974 "done:" %} 10975 size(16); 10976 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10977 ins_pipe(pipe_class_compare); 10978 %} 10979 10980 // if src1 < src2, return -1 else return 0 10981 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10982 match(Set dst (CmpLTMask src1 src2)); 10983 ins_cost(DEFAULT_COST*4); 10984 10985 expand %{ 10986 iRegLdst src1s; 10987 iRegLdst src2s; 10988 iRegLdst diff; 10989 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10990 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10991 subL_reg_reg(diff, src1s, src2s); 10992 // Need to consider >=33 bit result, therefore we need signmaskL. 10993 signmask64I_regL(dst, diff); 10994 %} 10995 %} 10996 10997 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 10998 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 10999 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 11000 size(4); 11001 ins_encode %{ 11002 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 11003 __ srawi($dst$$Register, $src1$$Register, 0x1f); 11004 %} 11005 ins_pipe(pipe_class_default); 11006 %} 11007 11008 //----------Arithmetic Conversion Instructions--------------------------------- 11009 11010 // Convert to Byte -- nop 11011 // Convert to Short -- nop 11012 11013 // Convert to Int 11014 11015 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 11016 match(Set dst (RShiftI (LShiftI src amount) amount)); 11017 format %{ "EXTSB $dst, $src \t// byte->int" %} 11018 size(4); 11019 ins_encode %{ 11020 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 11021 __ extsb($dst$$Register, $src$$Register); 11022 %} 11023 ins_pipe(pipe_class_default); 11024 %} 11025 11026 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 11027 effect(DEF dst, USE src); 11028 11029 size(4); 11030 ins_encode %{ 11031 __ extsh($dst$$Register, $src$$Register); 11032 %} 11033 ins_pipe(pipe_class_default); 11034 %} 11035 11036 // LShiftI 16 + RShiftI 16 converts short to int. 11037 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 11038 match(Set dst (RShiftI (LShiftI src amount) amount)); 11039 format %{ "EXTSH $dst, $src \t// short->int" %} 11040 size(4); 11041 ins_encode %{ 11042 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 11043 __ extsh($dst$$Register, $src$$Register); 11044 %} 11045 ins_pipe(pipe_class_default); 11046 %} 11047 11048 // ConvL2I + ConvI2L: Sign extend int in long register. 11049 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11050 match(Set dst (ConvI2L (ConvL2I src))); 11051 11052 format %{ "EXTSW $dst, $src \t// long->long" %} 11053 size(4); 11054 ins_encode %{ 11055 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11056 __ extsw($dst$$Register, $src$$Register); 11057 %} 11058 ins_pipe(pipe_class_default); 11059 %} 11060 11061 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11062 match(Set dst (ConvL2I src)); 11063 format %{ "MR $dst, $src \t// long->int" %} 11064 // variable size, 0 or 4 11065 ins_encode %{ 11066 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11067 __ mr_if_needed($dst$$Register, $src$$Register); 11068 %} 11069 ins_pipe(pipe_class_default); 11070 %} 11071 11072 instruct convD2IRaw_regD(regD dst, regD src) %{ 11073 // no match-rule, false predicate 11074 effect(DEF dst, USE src); 11075 predicate(false); 11076 11077 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11078 size(4); 11079 ins_encode %{ 11080 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11081 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11082 %} 11083 ins_pipe(pipe_class_default); 11084 %} 11085 11086 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 11087 // no match-rule, false predicate 11088 effect(DEF dst, USE crx, USE src); 11089 predicate(false); 11090 11091 ins_variable_size_depending_on_alignment(true); 11092 11093 format %{ "cmovI $crx, $dst, $src" %} 11094 // Worst case is branch + move + stop, no stop without scheduler. 11095 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 11096 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11097 ins_pipe(pipe_class_default); 11098 %} 11099 11100 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11101 // no match-rule, false predicate 11102 effect(DEF dst, USE crx, USE src); 11103 predicate(false); 11104 11105 ins_variable_size_depending_on_alignment(true); 11106 11107 format %{ "cmovI $crx, $dst, $src" %} 11108 // Worst case is branch + move + stop, no stop without scheduler. 11109 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 11110 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11111 ins_pipe(pipe_class_default); 11112 %} 11113 11114 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11115 // no match-rule, false predicate 11116 effect(DEF dst, USE crx, USE mem); 11117 predicate(false); 11118 11119 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11120 postalloc_expand %{ 11121 // 11122 // replaces 11123 // 11124 // region dst crx mem 11125 // \ | | / 11126 // dst=cmovI_bso_stackSlotL_conLvalue0 11127 // 11128 // with 11129 // 11130 // region dst 11131 // \ / 11132 // dst=loadConI16(0) 11133 // | 11134 // ^ region dst crx mem 11135 // | \ | | / 11136 // dst=cmovI_bso_stackSlotL 11137 // 11138 11139 // Create new nodes. 11140 MachNode *m1 = new loadConI16Node(); 11141 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11142 11143 // inputs for new nodes 11144 m1->add_req(n_region); 11145 m2->add_req(n_region, n_crx, n_mem); 11146 11147 // precedences for new nodes 11148 m2->add_prec(m1); 11149 11150 // operands for new nodes 11151 m1->_opnds[0] = op_dst; 11152 m1->_opnds[1] = new immI16Oper(0); 11153 11154 m2->_opnds[0] = op_dst; 11155 m2->_opnds[1] = op_crx; 11156 m2->_opnds[2] = op_mem; 11157 11158 // registers for new nodes 11159 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11160 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11161 11162 // Insert new nodes. 11163 nodes->push(m1); 11164 nodes->push(m2); 11165 %} 11166 %} 11167 11168 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11169 // no match-rule, false predicate 11170 effect(DEF dst, USE crx, USE src); 11171 predicate(false); 11172 11173 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11174 postalloc_expand %{ 11175 // 11176 // replaces 11177 // 11178 // region dst crx src 11179 // \ | | / 11180 // dst=cmovI_bso_reg_conLvalue0 11181 // 11182 // with 11183 // 11184 // region dst 11185 // \ / 11186 // dst=loadConI16(0) 11187 // | 11188 // ^ region dst crx src 11189 // | \ | | / 11190 // dst=cmovI_bso_reg 11191 // 11192 11193 // Create new nodes. 11194 MachNode *m1 = new loadConI16Node(); 11195 MachNode *m2 = new cmovI_bso_regNode(); 11196 11197 // inputs for new nodes 11198 m1->add_req(n_region); 11199 m2->add_req(n_region, n_crx, n_src); 11200 11201 // precedences for new nodes 11202 m2->add_prec(m1); 11203 11204 // operands for new nodes 11205 m1->_opnds[0] = op_dst; 11206 m1->_opnds[1] = new immI16Oper(0); 11207 11208 m2->_opnds[0] = op_dst; 11209 m2->_opnds[1] = op_crx; 11210 m2->_opnds[2] = op_src; 11211 11212 // registers for new nodes 11213 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11214 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11215 11216 // Insert new nodes. 11217 nodes->push(m1); 11218 nodes->push(m2); 11219 %} 11220 %} 11221 11222 // Double to Int conversion, NaN is mapped to 0. 11223 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11224 match(Set dst (ConvD2I src)); 11225 predicate(!VM_Version::has_mtfprd()); 11226 ins_cost(DEFAULT_COST); 11227 11228 expand %{ 11229 regD tmpD; 11230 stackSlotL tmpS; 11231 flagsReg crx; 11232 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11233 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11234 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11235 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11236 %} 11237 %} 11238 11239 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11240 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11241 match(Set dst (ConvD2I src)); 11242 predicate(VM_Version::has_mtfprd()); 11243 ins_cost(DEFAULT_COST); 11244 11245 expand %{ 11246 regD tmpD; 11247 flagsReg crx; 11248 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11249 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11250 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11251 %} 11252 %} 11253 11254 instruct convF2IRaw_regF(regF dst, regF src) %{ 11255 // no match-rule, false predicate 11256 effect(DEF dst, USE src); 11257 predicate(false); 11258 11259 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11260 size(4); 11261 ins_encode %{ 11262 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11263 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11264 %} 11265 ins_pipe(pipe_class_default); 11266 %} 11267 11268 // Float to Int conversion, NaN is mapped to 0. 11269 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11270 match(Set dst (ConvF2I src)); 11271 predicate(!VM_Version::has_mtfprd()); 11272 ins_cost(DEFAULT_COST); 11273 11274 expand %{ 11275 regF tmpF; 11276 stackSlotL tmpS; 11277 flagsReg crx; 11278 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11279 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11280 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11281 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11282 %} 11283 %} 11284 11285 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11286 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11287 match(Set dst (ConvF2I src)); 11288 predicate(VM_Version::has_mtfprd()); 11289 ins_cost(DEFAULT_COST); 11290 11291 expand %{ 11292 regF tmpF; 11293 flagsReg crx; 11294 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11295 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11296 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11297 %} 11298 %} 11299 11300 // Convert to Long 11301 11302 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11303 match(Set dst (ConvI2L src)); 11304 format %{ "EXTSW $dst, $src \t// int->long" %} 11305 size(4); 11306 ins_encode %{ 11307 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11308 __ extsw($dst$$Register, $src$$Register); 11309 %} 11310 ins_pipe(pipe_class_default); 11311 %} 11312 11313 // Zero-extend: convert unsigned int to long (convUI2L). 11314 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11315 match(Set dst (AndL (ConvI2L src) mask)); 11316 ins_cost(DEFAULT_COST); 11317 11318 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11319 size(4); 11320 ins_encode %{ 11321 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11322 __ clrldi($dst$$Register, $src$$Register, 32); 11323 %} 11324 ins_pipe(pipe_class_default); 11325 %} 11326 11327 // Zero-extend: convert unsigned int to long in long register. 11328 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11329 match(Set dst (AndL src mask)); 11330 ins_cost(DEFAULT_COST); 11331 11332 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11333 size(4); 11334 ins_encode %{ 11335 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11336 __ clrldi($dst$$Register, $src$$Register, 32); 11337 %} 11338 ins_pipe(pipe_class_default); 11339 %} 11340 11341 instruct convF2LRaw_regF(regF dst, regF src) %{ 11342 // no match-rule, false predicate 11343 effect(DEF dst, USE src); 11344 predicate(false); 11345 11346 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11347 size(4); 11348 ins_encode %{ 11349 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11350 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11351 %} 11352 ins_pipe(pipe_class_default); 11353 %} 11354 11355 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 11356 // no match-rule, false predicate 11357 effect(DEF dst, USE crx, USE src); 11358 predicate(false); 11359 11360 ins_variable_size_depending_on_alignment(true); 11361 11362 format %{ "cmovL $crx, $dst, $src" %} 11363 // Worst case is branch + move + stop, no stop without scheduler. 11364 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 11365 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11366 ins_pipe(pipe_class_default); 11367 %} 11368 11369 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11370 // no match-rule, false predicate 11371 effect(DEF dst, USE crx, USE src); 11372 predicate(false); 11373 11374 ins_variable_size_depending_on_alignment(true); 11375 11376 format %{ "cmovL $crx, $dst, $src" %} 11377 // Worst case is branch + move + stop, no stop without scheduler. 11378 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 11379 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11380 ins_pipe(pipe_class_default); 11381 %} 11382 11383 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11384 // no match-rule, false predicate 11385 effect(DEF dst, USE crx, USE mem); 11386 predicate(false); 11387 11388 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11389 postalloc_expand %{ 11390 // 11391 // replaces 11392 // 11393 // region dst crx mem 11394 // \ | | / 11395 // dst=cmovL_bso_stackSlotL_conLvalue0 11396 // 11397 // with 11398 // 11399 // region dst 11400 // \ / 11401 // dst=loadConL16(0) 11402 // | 11403 // ^ region dst crx mem 11404 // | \ | | / 11405 // dst=cmovL_bso_stackSlotL 11406 // 11407 11408 // Create new nodes. 11409 MachNode *m1 = new loadConL16Node(); 11410 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11411 11412 // inputs for new nodes 11413 m1->add_req(n_region); 11414 m2->add_req(n_region, n_crx, n_mem); 11415 m2->add_prec(m1); 11416 11417 // operands for new nodes 11418 m1->_opnds[0] = op_dst; 11419 m1->_opnds[1] = new immL16Oper(0); 11420 m2->_opnds[0] = op_dst; 11421 m2->_opnds[1] = op_crx; 11422 m2->_opnds[2] = op_mem; 11423 11424 // registers for new nodes 11425 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11426 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11427 11428 // Insert new nodes. 11429 nodes->push(m1); 11430 nodes->push(m2); 11431 %} 11432 %} 11433 11434 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11435 // no match-rule, false predicate 11436 effect(DEF dst, USE crx, USE src); 11437 predicate(false); 11438 11439 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11440 postalloc_expand %{ 11441 // 11442 // replaces 11443 // 11444 // region dst crx src 11445 // \ | | / 11446 // dst=cmovL_bso_reg_conLvalue0 11447 // 11448 // with 11449 // 11450 // region dst 11451 // \ / 11452 // dst=loadConL16(0) 11453 // | 11454 // ^ region dst crx src 11455 // | \ | | / 11456 // dst=cmovL_bso_reg 11457 // 11458 11459 // Create new nodes. 11460 MachNode *m1 = new loadConL16Node(); 11461 MachNode *m2 = new cmovL_bso_regNode(); 11462 11463 // inputs for new nodes 11464 m1->add_req(n_region); 11465 m2->add_req(n_region, n_crx, n_src); 11466 m2->add_prec(m1); 11467 11468 // operands for new nodes 11469 m1->_opnds[0] = op_dst; 11470 m1->_opnds[1] = new immL16Oper(0); 11471 m2->_opnds[0] = op_dst; 11472 m2->_opnds[1] = op_crx; 11473 m2->_opnds[2] = op_src; 11474 11475 // registers for new nodes 11476 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11477 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11478 11479 // Insert new nodes. 11480 nodes->push(m1); 11481 nodes->push(m2); 11482 %} 11483 %} 11484 11485 // Float to Long conversion, NaN is mapped to 0. 11486 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11487 match(Set dst (ConvF2L src)); 11488 predicate(!VM_Version::has_mtfprd()); 11489 ins_cost(DEFAULT_COST); 11490 11491 expand %{ 11492 regF tmpF; 11493 stackSlotL tmpS; 11494 flagsReg crx; 11495 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11496 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11497 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11498 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11499 %} 11500 %} 11501 11502 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11503 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11504 match(Set dst (ConvF2L src)); 11505 predicate(VM_Version::has_mtfprd()); 11506 ins_cost(DEFAULT_COST); 11507 11508 expand %{ 11509 regF tmpF; 11510 flagsReg crx; 11511 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11512 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11513 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11514 %} 11515 %} 11516 11517 instruct convD2LRaw_regD(regD dst, regD src) %{ 11518 // no match-rule, false predicate 11519 effect(DEF dst, USE src); 11520 predicate(false); 11521 11522 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11523 size(4); 11524 ins_encode %{ 11525 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11526 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11527 %} 11528 ins_pipe(pipe_class_default); 11529 %} 11530 11531 // Double to Long conversion, NaN is mapped to 0. 11532 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11533 match(Set dst (ConvD2L src)); 11534 predicate(!VM_Version::has_mtfprd()); 11535 ins_cost(DEFAULT_COST); 11536 11537 expand %{ 11538 regD tmpD; 11539 stackSlotL tmpS; 11540 flagsReg crx; 11541 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11542 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11543 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11544 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11545 %} 11546 %} 11547 11548 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11549 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11550 match(Set dst (ConvD2L src)); 11551 predicate(VM_Version::has_mtfprd()); 11552 ins_cost(DEFAULT_COST); 11553 11554 expand %{ 11555 regD tmpD; 11556 flagsReg crx; 11557 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11558 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11559 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11560 %} 11561 %} 11562 11563 // Convert to Float 11564 11565 // Placed here as needed in expand. 11566 instruct convL2DRaw_regD(regD dst, regD src) %{ 11567 // no match-rule, false predicate 11568 effect(DEF dst, USE src); 11569 predicate(false); 11570 11571 format %{ "FCFID $dst, $src \t// convL2D" %} 11572 size(4); 11573 ins_encode %{ 11574 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11575 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11576 %} 11577 ins_pipe(pipe_class_default); 11578 %} 11579 11580 // Placed here as needed in expand. 11581 instruct convD2F_reg(regF dst, regD src) %{ 11582 match(Set dst (ConvD2F src)); 11583 format %{ "FRSP $dst, $src \t// convD2F" %} 11584 size(4); 11585 ins_encode %{ 11586 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11587 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11588 %} 11589 ins_pipe(pipe_class_default); 11590 %} 11591 11592 // Integer to Float conversion. 11593 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11594 match(Set dst (ConvI2F src)); 11595 predicate(!VM_Version::has_fcfids()); 11596 ins_cost(DEFAULT_COST); 11597 11598 expand %{ 11599 iRegLdst tmpL; 11600 stackSlotL tmpS; 11601 regD tmpD; 11602 regD tmpD2; 11603 convI2L_reg(tmpL, src); // Sign-extension int to long. 11604 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11605 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11606 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11607 convD2F_reg(dst, tmpD2); // Convert double to float. 11608 %} 11609 %} 11610 11611 instruct convL2FRaw_regF(regF dst, regD src) %{ 11612 // no match-rule, false predicate 11613 effect(DEF dst, USE src); 11614 predicate(false); 11615 11616 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11617 size(4); 11618 ins_encode %{ 11619 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11620 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11621 %} 11622 ins_pipe(pipe_class_default); 11623 %} 11624 11625 // Integer to Float conversion. Special version for Power7. 11626 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11627 match(Set dst (ConvI2F src)); 11628 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11629 ins_cost(DEFAULT_COST); 11630 11631 expand %{ 11632 iRegLdst tmpL; 11633 stackSlotL tmpS; 11634 regD tmpD; 11635 convI2L_reg(tmpL, src); // Sign-extension int to long. 11636 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11637 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11638 convL2FRaw_regF(dst, tmpD); // Convert to float. 11639 %} 11640 %} 11641 11642 // Integer to Float conversion. Special version for Power8. 11643 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11644 match(Set dst (ConvI2F src)); 11645 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11646 ins_cost(DEFAULT_COST); 11647 11648 expand %{ 11649 regD tmpD; 11650 moveI2D_reg(tmpD, src); 11651 convL2FRaw_regF(dst, tmpD); // Convert to float. 11652 %} 11653 %} 11654 11655 // L2F to avoid runtime call. 11656 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11657 match(Set dst (ConvL2F src)); 11658 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11659 ins_cost(DEFAULT_COST); 11660 11661 expand %{ 11662 stackSlotL tmpS; 11663 regD tmpD; 11664 regL_to_stkL(tmpS, src); // Store long to stack. 11665 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11666 convL2FRaw_regF(dst, tmpD); // Convert to float. 11667 %} 11668 %} 11669 11670 // L2F to avoid runtime call. Special version for Power8. 11671 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11672 match(Set dst (ConvL2F src)); 11673 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11674 ins_cost(DEFAULT_COST); 11675 11676 expand %{ 11677 regD tmpD; 11678 moveL2D_reg(tmpD, src); 11679 convL2FRaw_regF(dst, tmpD); // Convert to float. 11680 %} 11681 %} 11682 11683 // Moved up as used in expand. 11684 //instruct convD2F_reg(regF dst, regD src) %{%} 11685 11686 // Convert to Double 11687 11688 // Integer to Double conversion. 11689 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11690 match(Set dst (ConvI2D src)); 11691 predicate(!VM_Version::has_mtfprd()); 11692 ins_cost(DEFAULT_COST); 11693 11694 expand %{ 11695 iRegLdst tmpL; 11696 stackSlotL tmpS; 11697 regD tmpD; 11698 convI2L_reg(tmpL, src); // Sign-extension int to long. 11699 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11700 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11701 convL2DRaw_regD(dst, tmpD); // Convert to double. 11702 %} 11703 %} 11704 11705 // Integer to Double conversion. Special version for Power8. 11706 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11707 match(Set dst (ConvI2D src)); 11708 predicate(VM_Version::has_mtfprd()); 11709 ins_cost(DEFAULT_COST); 11710 11711 expand %{ 11712 regD tmpD; 11713 moveI2D_reg(tmpD, src); 11714 convL2DRaw_regD(dst, tmpD); // Convert to double. 11715 %} 11716 %} 11717 11718 // Long to Double conversion 11719 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11720 match(Set dst (ConvL2D src)); 11721 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11722 11723 expand %{ 11724 regD tmpD; 11725 moveL2D_stack_reg(tmpD, src); 11726 convL2DRaw_regD(dst, tmpD); 11727 %} 11728 %} 11729 11730 // Long to Double conversion. Special version for Power8. 11731 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11732 match(Set dst (ConvL2D src)); 11733 predicate(VM_Version::has_mtfprd()); 11734 ins_cost(DEFAULT_COST); 11735 11736 expand %{ 11737 regD tmpD; 11738 moveL2D_reg(tmpD, src); 11739 convL2DRaw_regD(dst, tmpD); // Convert to double. 11740 %} 11741 %} 11742 11743 instruct convF2D_reg(regD dst, regF src) %{ 11744 match(Set dst (ConvF2D src)); 11745 format %{ "FMR $dst, $src \t// float->double" %} 11746 // variable size, 0 or 4 11747 ins_encode %{ 11748 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11749 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11750 %} 11751 ins_pipe(pipe_class_default); 11752 %} 11753 11754 //----------Control Flow Instructions------------------------------------------ 11755 // Compare Instructions 11756 11757 // Compare Integers 11758 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11759 match(Set crx (CmpI src1 src2)); 11760 size(4); 11761 format %{ "CMPW $crx, $src1, $src2" %} 11762 ins_encode %{ 11763 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11764 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11765 %} 11766 ins_pipe(pipe_class_compare); 11767 %} 11768 11769 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11770 match(Set crx (CmpI src1 src2)); 11771 format %{ "CMPWI $crx, $src1, $src2" %} 11772 size(4); 11773 ins_encode %{ 11774 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11775 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11776 %} 11777 ins_pipe(pipe_class_compare); 11778 %} 11779 11780 // (src1 & src2) == 0? 11781 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11782 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11783 // r0 is killed 11784 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11785 size(4); 11786 ins_encode %{ 11787 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11788 __ andi_(R0, $src1$$Register, $src2$$constant); 11789 %} 11790 ins_pipe(pipe_class_compare); 11791 %} 11792 11793 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11794 match(Set crx (CmpL src1 src2)); 11795 format %{ "CMPD $crx, $src1, $src2" %} 11796 size(4); 11797 ins_encode %{ 11798 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11799 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11800 %} 11801 ins_pipe(pipe_class_compare); 11802 %} 11803 11804 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11805 match(Set crx (CmpL src1 src2)); 11806 format %{ "CMPDI $crx, $src1, $src2" %} 11807 size(4); 11808 ins_encode %{ 11809 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11810 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11811 %} 11812 ins_pipe(pipe_class_compare); 11813 %} 11814 11815 // Added CmpUL for LoopPredicate. 11816 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11817 match(Set crx (CmpUL src1 src2)); 11818 format %{ "CMPLD $crx, $src1, $src2" %} 11819 size(4); 11820 ins_encode %{ 11821 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11822 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11823 %} 11824 ins_pipe(pipe_class_compare); 11825 %} 11826 11827 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11828 match(Set crx (CmpUL src1 src2)); 11829 format %{ "CMPLDI $crx, $src1, $src2" %} 11830 size(4); 11831 ins_encode %{ 11832 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11833 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11834 %} 11835 ins_pipe(pipe_class_compare); 11836 %} 11837 11838 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11839 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11840 // r0 is killed 11841 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11842 size(4); 11843 ins_encode %{ 11844 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11845 __ and_(R0, $src1$$Register, $src2$$Register); 11846 %} 11847 ins_pipe(pipe_class_compare); 11848 %} 11849 11850 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11851 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11852 // r0 is killed 11853 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11854 size(4); 11855 ins_encode %{ 11856 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11857 __ andi_(R0, $src1$$Register, $src2$$constant); 11858 %} 11859 ins_pipe(pipe_class_compare); 11860 %} 11861 11862 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11863 // no match-rule, false predicate 11864 effect(DEF dst, USE crx); 11865 predicate(false); 11866 11867 ins_variable_size_depending_on_alignment(true); 11868 11869 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11870 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11871 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16); 11872 ins_encode %{ 11873 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11874 Label done; 11875 // li(Rdst, 0); // equal -> 0 11876 __ beq($crx$$CondRegister, done); 11877 __ li($dst$$Register, 1); // greater -> +1 11878 __ bgt($crx$$CondRegister, done); 11879 __ li($dst$$Register, -1); // unordered or less -> -1 11880 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11881 __ bind(done); 11882 %} 11883 ins_pipe(pipe_class_compare); 11884 %} 11885 11886 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11887 // no match-rule, false predicate 11888 effect(DEF dst, USE crx); 11889 predicate(false); 11890 11891 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11892 postalloc_expand %{ 11893 // 11894 // replaces 11895 // 11896 // region crx 11897 // \ | 11898 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11899 // 11900 // with 11901 // 11902 // region 11903 // \ 11904 // dst=loadConI16(0) 11905 // | 11906 // ^ region crx 11907 // | \ | 11908 // dst=cmovI_conIvalueMinus1_conIvalue1 11909 // 11910 11911 // Create new nodes. 11912 MachNode *m1 = new loadConI16Node(); 11913 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11914 11915 // inputs for new nodes 11916 m1->add_req(n_region); 11917 m2->add_req(n_region, n_crx); 11918 m2->add_prec(m1); 11919 11920 // operands for new nodes 11921 m1->_opnds[0] = op_dst; 11922 m1->_opnds[1] = new immI16Oper(0); 11923 m2->_opnds[0] = op_dst; 11924 m2->_opnds[1] = op_crx; 11925 11926 // registers for new nodes 11927 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11928 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11929 11930 // Insert new nodes. 11931 nodes->push(m1); 11932 nodes->push(m2); 11933 %} 11934 %} 11935 11936 // Manifest a CmpL3 result in an integer register. Very painful. 11937 // This is the test to avoid. 11938 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11939 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11940 match(Set dst (CmpL3 src1 src2)); 11941 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11942 11943 expand %{ 11944 flagsReg tmp1; 11945 cmpL_reg_reg(tmp1, src1, src2); 11946 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11947 %} 11948 %} 11949 11950 // Implicit range checks. 11951 // A range check in the ideal world has one of the following shapes: 11952 // - (If le (CmpU length index)), (IfTrue throw exception) 11953 // - (If lt (CmpU index length)), (IfFalse throw exception) 11954 // 11955 // Match range check 'If le (CmpU length index)'. 11956 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11957 match(If cmp (CmpU src_length index)); 11958 effect(USE labl); 11959 predicate(TrapBasedRangeChecks && 11960 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11961 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11962 (Matcher::branches_to_uncommon_trap(_leaf))); 11963 11964 ins_is_TrapBasedCheckNode(true); 11965 11966 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11967 size(4); 11968 ins_encode %{ 11969 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11970 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11971 __ trap_range_check_le($src_length$$Register, $index$$constant); 11972 } else { 11973 // Both successors are uncommon traps, probability is 0. 11974 // Node got flipped during fixup flow. 11975 assert($cmp$$cmpcode == 0x9, "must be greater"); 11976 __ trap_range_check_g($src_length$$Register, $index$$constant); 11977 } 11978 %} 11979 ins_pipe(pipe_class_trap); 11980 %} 11981 11982 // Match range check 'If lt (CmpU index length)'. 11983 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11984 match(If cmp (CmpU src_index src_length)); 11985 effect(USE labl); 11986 predicate(TrapBasedRangeChecks && 11987 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11988 _leaf->as_If()->_prob >= PROB_ALWAYS && 11989 (Matcher::branches_to_uncommon_trap(_leaf))); 11990 11991 ins_is_TrapBasedCheckNode(true); 11992 11993 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 11994 size(4); 11995 ins_encode %{ 11996 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 11997 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11998 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 11999 } else { 12000 // Both successors are uncommon traps, probability is 0. 12001 // Node got flipped during fixup flow. 12002 assert($cmp$$cmpcode == 0x8, "must be less"); 12003 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 12004 } 12005 %} 12006 ins_pipe(pipe_class_trap); 12007 %} 12008 12009 // Match range check 'If lt (CmpU index length)'. 12010 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 12011 match(If cmp (CmpU src_index length)); 12012 effect(USE labl); 12013 predicate(TrapBasedRangeChecks && 12014 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12015 _leaf->as_If()->_prob >= PROB_ALWAYS && 12016 (Matcher::branches_to_uncommon_trap(_leaf))); 12017 12018 ins_is_TrapBasedCheckNode(true); 12019 12020 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 12021 size(4); 12022 ins_encode %{ 12023 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12024 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12025 __ trap_range_check_ge($src_index$$Register, $length$$constant); 12026 } else { 12027 // Both successors are uncommon traps, probability is 0. 12028 // Node got flipped during fixup flow. 12029 assert($cmp$$cmpcode == 0x8, "must be less"); 12030 __ trap_range_check_l($src_index$$Register, $length$$constant); 12031 } 12032 %} 12033 ins_pipe(pipe_class_trap); 12034 %} 12035 12036 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 12037 match(Set crx (CmpU src1 src2)); 12038 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 12039 size(4); 12040 ins_encode %{ 12041 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12042 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12043 %} 12044 ins_pipe(pipe_class_compare); 12045 %} 12046 12047 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 12048 match(Set crx (CmpU src1 src2)); 12049 size(4); 12050 format %{ "CMPLWI $crx, $src1, $src2" %} 12051 ins_encode %{ 12052 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12053 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12054 %} 12055 ins_pipe(pipe_class_compare); 12056 %} 12057 12058 // Implicit zero checks (more implicit null checks). 12059 // No constant pool entries required. 12060 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12061 match(If cmp (CmpN value zero)); 12062 effect(USE labl); 12063 predicate(TrapBasedNullChecks && 12064 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12065 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12066 Matcher::branches_to_uncommon_trap(_leaf)); 12067 ins_cost(1); 12068 12069 ins_is_TrapBasedCheckNode(true); 12070 12071 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12072 size(4); 12073 ins_encode %{ 12074 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12075 if ($cmp$$cmpcode == 0xA) { 12076 __ trap_null_check($value$$Register); 12077 } else { 12078 // Both successors are uncommon traps, probability is 0. 12079 // Node got flipped during fixup flow. 12080 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12081 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12082 } 12083 %} 12084 ins_pipe(pipe_class_trap); 12085 %} 12086 12087 // Compare narrow oops. 12088 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12089 match(Set crx (CmpN src1 src2)); 12090 12091 size(4); 12092 ins_cost(2); 12093 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12094 ins_encode %{ 12095 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12096 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12097 %} 12098 ins_pipe(pipe_class_compare); 12099 %} 12100 12101 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12102 match(Set crx (CmpN src1 src2)); 12103 // Make this more expensive than zeroCheckN_iReg_imm0. 12104 ins_cost(2); 12105 12106 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12107 size(4); 12108 ins_encode %{ 12109 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12110 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12111 %} 12112 ins_pipe(pipe_class_compare); 12113 %} 12114 12115 // Implicit zero checks (more implicit null checks). 12116 // No constant pool entries required. 12117 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12118 match(If cmp (CmpP value zero)); 12119 effect(USE labl); 12120 predicate(TrapBasedNullChecks && 12121 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12122 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12123 Matcher::branches_to_uncommon_trap(_leaf)); 12124 ins_cost(1); // Should not be cheaper than zeroCheckN. 12125 12126 ins_is_TrapBasedCheckNode(true); 12127 12128 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12129 size(4); 12130 ins_encode %{ 12131 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12132 if ($cmp$$cmpcode == 0xA) { 12133 __ trap_null_check($value$$Register); 12134 } else { 12135 // Both successors are uncommon traps, probability is 0. 12136 // Node got flipped during fixup flow. 12137 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12138 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12139 } 12140 %} 12141 ins_pipe(pipe_class_trap); 12142 %} 12143 12144 // Compare Pointers 12145 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12146 match(Set crx (CmpP src1 src2)); 12147 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12148 size(4); 12149 ins_encode %{ 12150 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12151 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12152 %} 12153 ins_pipe(pipe_class_compare); 12154 %} 12155 12156 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12157 match(Set crx (CmpP src1 src2)); 12158 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12159 size(4); 12160 ins_encode %{ 12161 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12162 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12163 %} 12164 ins_pipe(pipe_class_compare); 12165 %} 12166 12167 // Used in postalloc expand. 12168 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12169 // This match rule prevents reordering of node before a safepoint. 12170 // This only makes sense if this instructions is used exclusively 12171 // for the expansion of EncodeP! 12172 match(Set crx (CmpP src1 src2)); 12173 predicate(false); 12174 12175 format %{ "CMPDI $crx, $src1, $src2" %} 12176 size(4); 12177 ins_encode %{ 12178 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12179 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12180 %} 12181 ins_pipe(pipe_class_compare); 12182 %} 12183 12184 //----------Float Compares---------------------------------------------------- 12185 12186 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12187 // Needs matchrule, see cmpDUnordered. 12188 match(Set crx (CmpF src1 src2)); 12189 // no match-rule, false predicate 12190 predicate(false); 12191 12192 format %{ "cmpFUrd $crx, $src1, $src2" %} 12193 size(4); 12194 ins_encode %{ 12195 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12196 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12197 %} 12198 ins_pipe(pipe_class_default); 12199 %} 12200 12201 instruct cmov_bns_less(flagsReg crx) %{ 12202 // no match-rule, false predicate 12203 effect(DEF crx); 12204 predicate(false); 12205 12206 ins_variable_size_depending_on_alignment(true); 12207 12208 format %{ "cmov $crx" %} 12209 // Worst case is branch + move + stop, no stop without scheduler. 12210 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12); 12211 ins_encode %{ 12212 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12213 Label done; 12214 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12215 __ li(R0, 0); 12216 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12217 // TODO PPC port __ endgroup_if_needed(_size == 16); 12218 __ bind(done); 12219 %} 12220 ins_pipe(pipe_class_default); 12221 %} 12222 12223 // Compare floating, generate condition code. 12224 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12225 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12226 // 12227 // The following code sequence occurs a lot in mpegaudio: 12228 // 12229 // block BXX: 12230 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12231 // cmpFUrd CCR6, F11, F9 12232 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12233 // cmov CCR6 12234 // 8: instruct branchConSched: 12235 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12236 match(Set crx (CmpF src1 src2)); 12237 ins_cost(DEFAULT_COST+BRANCH_COST); 12238 12239 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12240 postalloc_expand %{ 12241 // 12242 // replaces 12243 // 12244 // region src1 src2 12245 // \ | | 12246 // crx=cmpF_reg_reg 12247 // 12248 // with 12249 // 12250 // region src1 src2 12251 // \ | | 12252 // crx=cmpFUnordered_reg_reg 12253 // | 12254 // ^ region 12255 // | \ 12256 // crx=cmov_bns_less 12257 // 12258 12259 // Create new nodes. 12260 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12261 MachNode *m2 = new cmov_bns_lessNode(); 12262 12263 // inputs for new nodes 12264 m1->add_req(n_region, n_src1, n_src2); 12265 m2->add_req(n_region); 12266 m2->add_prec(m1); 12267 12268 // operands for new nodes 12269 m1->_opnds[0] = op_crx; 12270 m1->_opnds[1] = op_src1; 12271 m1->_opnds[2] = op_src2; 12272 m2->_opnds[0] = op_crx; 12273 12274 // registers for new nodes 12275 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12276 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12277 12278 // Insert new nodes. 12279 nodes->push(m1); 12280 nodes->push(m2); 12281 %} 12282 %} 12283 12284 // Compare float, generate -1,0,1 12285 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12286 match(Set dst (CmpF3 src1 src2)); 12287 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12288 12289 expand %{ 12290 flagsReg tmp1; 12291 cmpFUnordered_reg_reg(tmp1, src1, src2); 12292 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12293 %} 12294 %} 12295 12296 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12297 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12298 // node right before the conditional move using it. 12299 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12300 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12301 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12302 // conditional move was supposed to be spilled. 12303 match(Set crx (CmpD src1 src2)); 12304 // False predicate, shall not be matched. 12305 predicate(false); 12306 12307 format %{ "cmpFUrd $crx, $src1, $src2" %} 12308 size(4); 12309 ins_encode %{ 12310 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12311 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12312 %} 12313 ins_pipe(pipe_class_default); 12314 %} 12315 12316 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12317 match(Set crx (CmpD src1 src2)); 12318 ins_cost(DEFAULT_COST+BRANCH_COST); 12319 12320 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12321 postalloc_expand %{ 12322 // 12323 // replaces 12324 // 12325 // region src1 src2 12326 // \ | | 12327 // crx=cmpD_reg_reg 12328 // 12329 // with 12330 // 12331 // region src1 src2 12332 // \ | | 12333 // crx=cmpDUnordered_reg_reg 12334 // | 12335 // ^ region 12336 // | \ 12337 // crx=cmov_bns_less 12338 // 12339 12340 // create new nodes 12341 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12342 MachNode *m2 = new cmov_bns_lessNode(); 12343 12344 // inputs for new nodes 12345 m1->add_req(n_region, n_src1, n_src2); 12346 m2->add_req(n_region); 12347 m2->add_prec(m1); 12348 12349 // operands for new nodes 12350 m1->_opnds[0] = op_crx; 12351 m1->_opnds[1] = op_src1; 12352 m1->_opnds[2] = op_src2; 12353 m2->_opnds[0] = op_crx; 12354 12355 // registers for new nodes 12356 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12357 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12358 12359 // Insert new nodes. 12360 nodes->push(m1); 12361 nodes->push(m2); 12362 %} 12363 %} 12364 12365 // Compare double, generate -1,0,1 12366 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12367 match(Set dst (CmpD3 src1 src2)); 12368 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12369 12370 expand %{ 12371 flagsReg tmp1; 12372 cmpDUnordered_reg_reg(tmp1, src1, src2); 12373 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12374 %} 12375 %} 12376 12377 //----------Branches--------------------------------------------------------- 12378 // Jump 12379 12380 // Direct Branch. 12381 instruct branch(label labl) %{ 12382 match(Goto); 12383 effect(USE labl); 12384 ins_cost(BRANCH_COST); 12385 12386 format %{ "B $labl" %} 12387 size(4); 12388 ins_encode %{ 12389 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12390 Label d; // dummy 12391 __ bind(d); 12392 Label* p = $labl$$label; 12393 // `p' is `NULL' when this encoding class is used only to 12394 // determine the size of the encoded instruction. 12395 Label& l = (NULL == p)? d : *(p); 12396 __ b(l); 12397 %} 12398 ins_pipe(pipe_class_default); 12399 %} 12400 12401 // Conditional Near Branch 12402 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12403 // Same match rule as `branchConFar'. 12404 match(If cmp crx); 12405 effect(USE lbl); 12406 ins_cost(BRANCH_COST); 12407 12408 // If set to 1 this indicates that the current instruction is a 12409 // short variant of a long branch. This avoids using this 12410 // instruction in first-pass matching. It will then only be used in 12411 // the `Shorten_branches' pass. 12412 ins_short_branch(1); 12413 12414 format %{ "B$cmp $crx, $lbl" %} 12415 size(4); 12416 ins_encode( enc_bc(crx, cmp, lbl) ); 12417 ins_pipe(pipe_class_default); 12418 %} 12419 12420 // This is for cases when the ppc64 `bc' instruction does not 12421 // reach far enough. So we emit a far branch here, which is more 12422 // expensive. 12423 // 12424 // Conditional Far Branch 12425 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12426 // Same match rule as `branchCon'. 12427 match(If cmp crx); 12428 effect(USE crx, USE lbl); 12429 predicate(!false /* TODO: PPC port HB_Schedule*/); 12430 // Higher cost than `branchCon'. 12431 ins_cost(5*BRANCH_COST); 12432 12433 // This is not a short variant of a branch, but the long variant. 12434 ins_short_branch(0); 12435 12436 format %{ "B_FAR$cmp $crx, $lbl" %} 12437 size(8); 12438 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12439 ins_pipe(pipe_class_default); 12440 %} 12441 12442 // Conditional Branch used with Power6 scheduler (can be far or short). 12443 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12444 // Same match rule as `branchCon'. 12445 match(If cmp crx); 12446 effect(USE crx, USE lbl); 12447 predicate(false /* TODO: PPC port HB_Schedule*/); 12448 // Higher cost than `branchCon'. 12449 ins_cost(5*BRANCH_COST); 12450 12451 // Actually size doesn't depend on alignment but on shortening. 12452 ins_variable_size_depending_on_alignment(true); 12453 // long variant. 12454 ins_short_branch(0); 12455 12456 format %{ "B_FAR$cmp $crx, $lbl" %} 12457 size(8); // worst case 12458 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12459 ins_pipe(pipe_class_default); 12460 %} 12461 12462 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12463 match(CountedLoopEnd cmp crx); 12464 effect(USE labl); 12465 ins_cost(BRANCH_COST); 12466 12467 // short variant. 12468 ins_short_branch(1); 12469 12470 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12471 size(4); 12472 ins_encode( enc_bc(crx, cmp, labl) ); 12473 ins_pipe(pipe_class_default); 12474 %} 12475 12476 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12477 match(CountedLoopEnd cmp crx); 12478 effect(USE labl); 12479 predicate(!false /* TODO: PPC port HB_Schedule */); 12480 ins_cost(BRANCH_COST); 12481 12482 // Long variant. 12483 ins_short_branch(0); 12484 12485 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12486 size(8); 12487 ins_encode( enc_bc_far(crx, cmp, labl) ); 12488 ins_pipe(pipe_class_default); 12489 %} 12490 12491 // Conditional Branch used with Power6 scheduler (can be far or short). 12492 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12493 match(CountedLoopEnd cmp crx); 12494 effect(USE labl); 12495 predicate(false /* TODO: PPC port HB_Schedule */); 12496 // Higher cost than `branchCon'. 12497 ins_cost(5*BRANCH_COST); 12498 12499 // Actually size doesn't depend on alignment but on shortening. 12500 ins_variable_size_depending_on_alignment(true); 12501 // Long variant. 12502 ins_short_branch(0); 12503 12504 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12505 size(8); // worst case 12506 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12507 ins_pipe(pipe_class_default); 12508 %} 12509 12510 // ============================================================================ 12511 // Java runtime operations, intrinsics and other complex operations. 12512 12513 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12514 // array for an instance of the superklass. Set a hidden internal cache on a 12515 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12516 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12517 // 12518 // GL TODO: Improve this. 12519 // - result should not be a TEMP 12520 // - Add match rule as on sparc avoiding additional Cmp. 12521 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12522 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12523 match(Set result (PartialSubtypeCheck subklass superklass)); 12524 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12525 ins_cost(DEFAULT_COST*10); 12526 12527 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12528 ins_encode %{ 12529 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12530 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12531 $tmp_klass$$Register, NULL, $result$$Register); 12532 %} 12533 ins_pipe(pipe_class_default); 12534 %} 12535 12536 // inlined locking and unlocking 12537 12538 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12539 match(Set crx (FastLock oop box)); 12540 effect(TEMP tmp1, TEMP tmp2); 12541 predicate(!Compile::current()->use_rtm()); 12542 12543 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12544 ins_encode %{ 12545 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12546 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12547 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12548 UseBiasedLocking && !UseOptoBiasInlining); 12549 // If locking was successfull, crx should indicate 'EQ'. 12550 // The compiler generates a branch to the runtime call to 12551 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12552 %} 12553 ins_pipe(pipe_class_compare); 12554 %} 12555 12556 // Separate version for TM. Use bound register for box to enable USE_KILL. 12557 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12558 match(Set crx (FastLock oop box)); 12559 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12560 predicate(Compile::current()->use_rtm()); 12561 12562 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12563 ins_encode %{ 12564 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12565 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12566 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12567 /*Biased Locking*/ false, 12568 _rtm_counters, _stack_rtm_counters, 12569 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12570 /*TM*/ true, ra_->C->profile_rtm()); 12571 // If locking was successfull, crx should indicate 'EQ'. 12572 // The compiler generates a branch to the runtime call to 12573 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12574 %} 12575 ins_pipe(pipe_class_compare); 12576 %} 12577 12578 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12579 match(Set crx (FastUnlock oop box)); 12580 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12581 predicate(!Compile::current()->use_rtm()); 12582 12583 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12584 ins_encode %{ 12585 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12586 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12587 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12588 UseBiasedLocking && !UseOptoBiasInlining, 12589 false); 12590 // If unlocking was successfull, crx should indicate 'EQ'. 12591 // The compiler generates a branch to the runtime call to 12592 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12593 %} 12594 ins_pipe(pipe_class_compare); 12595 %} 12596 12597 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12598 match(Set crx (FastUnlock oop box)); 12599 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12600 predicate(Compile::current()->use_rtm()); 12601 12602 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12603 ins_encode %{ 12604 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12605 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12606 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12607 /*Biased Locking*/ false, /*TM*/ true); 12608 // If unlocking was successfull, crx should indicate 'EQ'. 12609 // The compiler generates a branch to the runtime call to 12610 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12611 %} 12612 ins_pipe(pipe_class_compare); 12613 %} 12614 12615 // Align address. 12616 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12617 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12618 12619 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12620 size(4); 12621 ins_encode %{ 12622 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12623 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12624 %} 12625 ins_pipe(pipe_class_default); 12626 %} 12627 12628 // Array size computation. 12629 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12630 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12631 12632 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12633 size(4); 12634 ins_encode %{ 12635 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12636 __ subf($dst$$Register, $start$$Register, $end$$Register); 12637 %} 12638 ins_pipe(pipe_class_default); 12639 %} 12640 12641 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12642 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12643 match(Set dummy (ClearArray cnt base)); 12644 effect(USE_KILL base, KILL ctr); 12645 ins_cost(2 * MEMORY_REF_COST); 12646 12647 format %{ "ClearArray $cnt, $base" %} 12648 ins_encode %{ 12649 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12650 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12651 %} 12652 ins_pipe(pipe_class_default); 12653 %} 12654 12655 // Clear-array with constant large array length. 12656 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12657 match(Set dummy (ClearArray cnt base)); 12658 effect(USE_KILL base, TEMP tmp, KILL ctr); 12659 ins_cost(3 * MEMORY_REF_COST); 12660 12661 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12662 ins_encode %{ 12663 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12664 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12665 %} 12666 ins_pipe(pipe_class_default); 12667 %} 12668 12669 // Clear-array with dynamic array length. 12670 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12671 match(Set dummy (ClearArray cnt base)); 12672 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12673 ins_cost(4 * MEMORY_REF_COST); 12674 12675 format %{ "ClearArray $cnt, $base" %} 12676 ins_encode %{ 12677 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12678 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12679 %} 12680 ins_pipe(pipe_class_default); 12681 %} 12682 12683 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12684 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12685 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12686 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12687 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12688 ins_cost(300); 12689 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12690 ins_encode %{ 12691 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12692 __ string_compare($str1$$Register, $str2$$Register, 12693 $cnt1$$Register, $cnt2$$Register, 12694 $tmp$$Register, 12695 $result$$Register, StrIntrinsicNode::LL); 12696 %} 12697 ins_pipe(pipe_class_default); 12698 %} 12699 12700 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12701 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12702 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12703 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12704 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12705 ins_cost(300); 12706 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12707 ins_encode %{ 12708 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12709 __ string_compare($str1$$Register, $str2$$Register, 12710 $cnt1$$Register, $cnt2$$Register, 12711 $tmp$$Register, 12712 $result$$Register, StrIntrinsicNode::UU); 12713 %} 12714 ins_pipe(pipe_class_default); 12715 %} 12716 12717 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12718 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12719 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12720 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12721 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12722 ins_cost(300); 12723 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12724 ins_encode %{ 12725 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12726 __ string_compare($str1$$Register, $str2$$Register, 12727 $cnt1$$Register, $cnt2$$Register, 12728 $tmp$$Register, 12729 $result$$Register, StrIntrinsicNode::LU); 12730 %} 12731 ins_pipe(pipe_class_default); 12732 %} 12733 12734 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12735 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12736 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12737 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12738 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12739 ins_cost(300); 12740 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12741 ins_encode %{ 12742 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12743 __ string_compare($str2$$Register, $str1$$Register, 12744 $cnt2$$Register, $cnt1$$Register, 12745 $tmp$$Register, 12746 $result$$Register, StrIntrinsicNode::UL); 12747 %} 12748 ins_pipe(pipe_class_default); 12749 %} 12750 12751 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12752 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12753 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12754 match(Set result (StrEquals (Binary str1 str2) cnt)); 12755 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12756 ins_cost(300); 12757 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12758 ins_encode %{ 12759 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12760 __ array_equals(false, $str1$$Register, $str2$$Register, 12761 $cnt$$Register, $tmp$$Register, 12762 $result$$Register, true /* byte */); 12763 %} 12764 ins_pipe(pipe_class_default); 12765 %} 12766 12767 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12768 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12769 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12770 match(Set result (StrEquals (Binary str1 str2) cnt)); 12771 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12772 ins_cost(300); 12773 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12774 ins_encode %{ 12775 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12776 __ array_equals(false, $str1$$Register, $str2$$Register, 12777 $cnt$$Register, $tmp$$Register, 12778 $result$$Register, false /* byte */); 12779 %} 12780 ins_pipe(pipe_class_default); 12781 %} 12782 12783 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12784 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12785 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12786 match(Set result (AryEq ary1 ary2)); 12787 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12788 ins_cost(300); 12789 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12790 ins_encode %{ 12791 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12792 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12793 $tmp1$$Register, $tmp2$$Register, 12794 $result$$Register, true /* byte */); 12795 %} 12796 ins_pipe(pipe_class_default); 12797 %} 12798 12799 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12800 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12801 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12802 match(Set result (AryEq ary1 ary2)); 12803 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12804 ins_cost(300); 12805 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12806 ins_encode %{ 12807 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12808 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12809 $tmp1$$Register, $tmp2$$Register, 12810 $result$$Register, false /* byte */); 12811 %} 12812 ins_pipe(pipe_class_default); 12813 %} 12814 12815 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12816 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12817 iRegIdst tmp1, iRegIdst tmp2, 12818 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12819 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12820 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12821 // Required for EA: check if it is still a type_array. 12822 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12823 ins_cost(150); 12824 12825 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12826 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12827 12828 ins_encode %{ 12829 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12830 immPOper *needleOper = (immPOper *)$needleImm; 12831 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12832 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12833 jchar chr; 12834 #ifdef VM_LITTLE_ENDIAN 12835 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12836 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12837 #else 12838 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12839 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12840 #endif 12841 __ string_indexof_char($result$$Register, 12842 $haystack$$Register, $haycnt$$Register, 12843 R0, chr, 12844 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12845 %} 12846 ins_pipe(pipe_class_compare); 12847 %} 12848 12849 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12850 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12851 iRegIdst tmp1, iRegIdst tmp2, 12852 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12853 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12854 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12855 // Required for EA: check if it is still a type_array. 12856 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12857 ins_cost(150); 12858 12859 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12860 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12861 12862 ins_encode %{ 12863 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12864 immPOper *needleOper = (immPOper *)$needleImm; 12865 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12866 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12867 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12868 __ string_indexof_char($result$$Register, 12869 $haystack$$Register, $haycnt$$Register, 12870 R0, chr, 12871 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12872 %} 12873 ins_pipe(pipe_class_compare); 12874 %} 12875 12876 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12877 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12878 iRegIdst tmp1, iRegIdst tmp2, 12879 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12880 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12881 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12882 // Required for EA: check if it is still a type_array. 12883 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12884 ins_cost(150); 12885 12886 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12887 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12888 12889 ins_encode %{ 12890 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12891 immPOper *needleOper = (immPOper *)$needleImm; 12892 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12893 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12894 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12895 __ string_indexof_char($result$$Register, 12896 $haystack$$Register, $haycnt$$Register, 12897 R0, chr, 12898 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12899 %} 12900 ins_pipe(pipe_class_compare); 12901 %} 12902 12903 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12904 rscratch2RegP needle, immI_1 needlecntImm, 12905 iRegIdst tmp1, iRegIdst tmp2, 12906 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12907 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12908 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12909 // Required for EA: check if it is still a type_array. 12910 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12911 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12912 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12913 ins_cost(180); 12914 12915 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12916 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12917 ins_encode %{ 12918 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12919 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12920 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12921 guarantee(needle_values, "sanity"); 12922 jchar chr; 12923 #ifdef VM_LITTLE_ENDIAN 12924 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12925 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12926 #else 12927 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12928 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12929 #endif 12930 __ string_indexof_char($result$$Register, 12931 $haystack$$Register, $haycnt$$Register, 12932 R0, chr, 12933 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12934 %} 12935 ins_pipe(pipe_class_compare); 12936 %} 12937 12938 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12939 rscratch2RegP needle, immI_1 needlecntImm, 12940 iRegIdst tmp1, iRegIdst tmp2, 12941 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12942 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12943 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12944 // Required for EA: check if it is still a type_array. 12945 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12946 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12947 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12948 ins_cost(180); 12949 12950 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12951 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12952 ins_encode %{ 12953 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12954 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12955 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12956 guarantee(needle_values, "sanity"); 12957 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12958 __ string_indexof_char($result$$Register, 12959 $haystack$$Register, $haycnt$$Register, 12960 R0, chr, 12961 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12962 %} 12963 ins_pipe(pipe_class_compare); 12964 %} 12965 12966 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12967 rscratch2RegP needle, immI_1 needlecntImm, 12968 iRegIdst tmp1, iRegIdst tmp2, 12969 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12970 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12971 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12972 // Required for EA: check if it is still a type_array. 12973 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12974 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12975 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12976 ins_cost(180); 12977 12978 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12979 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12980 ins_encode %{ 12981 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12982 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12983 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12984 guarantee(needle_values, "sanity"); 12985 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12986 __ string_indexof_char($result$$Register, 12987 $haystack$$Register, $haycnt$$Register, 12988 R0, chr, 12989 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12990 %} 12991 ins_pipe(pipe_class_compare); 12992 %} 12993 12994 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12995 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12996 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12997 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12998 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12999 ins_cost(180); 13000 13001 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 13002 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13003 ins_encode %{ 13004 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13005 __ string_indexof_char($result$$Register, 13006 $haystack$$Register, $haycnt$$Register, 13007 $ch$$Register, 0 /* this is not used if the character is already in a register */, 13008 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13009 %} 13010 ins_pipe(pipe_class_compare); 13011 %} 13012 13013 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13014 iRegPsrc needle, uimmI15 needlecntImm, 13015 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13016 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13017 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13018 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13019 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13020 // Required for EA: check if it is still a type_array. 13021 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13022 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13023 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13024 ins_cost(250); 13025 13026 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13027 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13028 ins_encode %{ 13029 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13030 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13031 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13032 13033 __ string_indexof($result$$Register, 13034 $haystack$$Register, $haycnt$$Register, 13035 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13036 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13037 %} 13038 ins_pipe(pipe_class_compare); 13039 %} 13040 13041 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13042 iRegPsrc needle, uimmI15 needlecntImm, 13043 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13044 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13045 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13046 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13047 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13048 // Required for EA: check if it is still a type_array. 13049 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13050 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13051 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13052 ins_cost(250); 13053 13054 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13055 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13056 ins_encode %{ 13057 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13058 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13059 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13060 13061 __ string_indexof($result$$Register, 13062 $haystack$$Register, $haycnt$$Register, 13063 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13064 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13065 %} 13066 ins_pipe(pipe_class_compare); 13067 %} 13068 13069 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13070 iRegPsrc needle, uimmI15 needlecntImm, 13071 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13072 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13073 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13074 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13075 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13076 // Required for EA: check if it is still a type_array. 13077 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13078 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13079 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13080 ins_cost(250); 13081 13082 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13083 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13084 ins_encode %{ 13085 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13086 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13087 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13088 13089 __ string_indexof($result$$Register, 13090 $haystack$$Register, $haycnt$$Register, 13091 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13092 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13093 %} 13094 ins_pipe(pipe_class_compare); 13095 %} 13096 13097 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13098 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13099 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13100 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13101 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13102 TEMP_DEF result, 13103 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13104 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13105 ins_cost(300); 13106 13107 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13108 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13109 ins_encode %{ 13110 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13111 __ string_indexof($result$$Register, 13112 $haystack$$Register, $haycnt$$Register, 13113 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13114 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13115 %} 13116 ins_pipe(pipe_class_compare); 13117 %} 13118 13119 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13120 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13121 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13122 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13123 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13124 TEMP_DEF result, 13125 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13126 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13127 ins_cost(300); 13128 13129 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13130 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13131 ins_encode %{ 13132 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13133 __ string_indexof($result$$Register, 13134 $haystack$$Register, $haycnt$$Register, 13135 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13136 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13137 %} 13138 ins_pipe(pipe_class_compare); 13139 %} 13140 13141 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13142 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13143 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13144 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13145 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13146 TEMP_DEF result, 13147 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13148 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13149 ins_cost(300); 13150 13151 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13152 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13153 ins_encode %{ 13154 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13155 __ string_indexof($result$$Register, 13156 $haystack$$Register, $haycnt$$Register, 13157 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13158 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13159 %} 13160 ins_pipe(pipe_class_compare); 13161 %} 13162 13163 // char[] to byte[] compression 13164 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13165 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13166 match(Set result (StrCompressedCopy src (Binary dst len))); 13167 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13168 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13169 ins_cost(300); 13170 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13171 ins_encode %{ 13172 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13173 Label Lskip, Ldone; 13174 __ li($result$$Register, 0); 13175 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13176 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13177 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13178 __ beq(CCR0, Lskip); 13179 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13180 __ bind(Lskip); 13181 __ mr($result$$Register, $len$$Register); 13182 __ bind(Ldone); 13183 %} 13184 ins_pipe(pipe_class_default); 13185 %} 13186 13187 // byte[] to char[] inflation 13188 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13189 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13190 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13191 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13192 ins_cost(300); 13193 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13194 ins_encode %{ 13195 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13196 Label Ldone; 13197 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13198 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13199 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13200 __ beq(CCR0, Ldone); 13201 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13202 __ bind(Ldone); 13203 %} 13204 ins_pipe(pipe_class_default); 13205 %} 13206 13207 // StringCoding.java intrinsics 13208 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13209 regCTR ctr, flagsRegCR0 cr0) 13210 %{ 13211 match(Set result (HasNegatives ary1 len)); 13212 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13213 ins_cost(300); 13214 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13215 ins_encode %{ 13216 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13217 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13218 $tmp1$$Register, $tmp2$$Register); 13219 %} 13220 ins_pipe(pipe_class_default); 13221 %} 13222 13223 // encode char[] to byte[] in ISO_8859_1 13224 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13225 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13226 match(Set result (EncodeISOArray src (Binary dst len))); 13227 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13228 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13229 ins_cost(300); 13230 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13231 ins_encode %{ 13232 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13233 Label Lslow, Lfailure1, Lfailure2, Ldone; 13234 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13235 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13236 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13237 __ beq(CCR0, Ldone); 13238 __ bind(Lslow); 13239 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13240 __ li($result$$Register, 0); 13241 __ b(Ldone); 13242 13243 __ bind(Lfailure1); 13244 __ mr($result$$Register, $len$$Register); 13245 __ mfctr($tmp1$$Register); 13246 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13247 __ beq(CCR0, Ldone); 13248 __ b(Lslow); 13249 13250 __ bind(Lfailure2); 13251 __ mfctr($result$$Register); // Remaining characters. 13252 13253 __ bind(Ldone); 13254 __ subf($result$$Register, $result$$Register, $len$$Register); 13255 %} 13256 ins_pipe(pipe_class_default); 13257 %} 13258 13259 13260 //---------- Min/Max Instructions --------------------------------------------- 13261 13262 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13263 match(Set dst (MinI src1 src2)); 13264 ins_cost(DEFAULT_COST*6); 13265 13266 expand %{ 13267 iRegLdst src1s; 13268 iRegLdst src2s; 13269 iRegLdst diff; 13270 iRegLdst sm; 13271 iRegLdst doz; // difference or zero 13272 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13273 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13274 subL_reg_reg(diff, src2s, src1s); 13275 // Need to consider >=33 bit result, therefore we need signmaskL. 13276 signmask64L_regL(sm, diff); 13277 andL_reg_reg(doz, diff, sm); // <=0 13278 addI_regL_regL(dst, doz, src1s); 13279 %} 13280 %} 13281 13282 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13283 match(Set dst (MinI src1 src2)); 13284 effect(KILL cr0); 13285 predicate(VM_Version::has_isel()); 13286 ins_cost(DEFAULT_COST*2); 13287 13288 ins_encode %{ 13289 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13290 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13291 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13292 %} 13293 ins_pipe(pipe_class_default); 13294 %} 13295 13296 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13297 match(Set dst (MaxI src1 src2)); 13298 ins_cost(DEFAULT_COST*6); 13299 13300 expand %{ 13301 iRegLdst src1s; 13302 iRegLdst src2s; 13303 iRegLdst diff; 13304 iRegLdst sm; 13305 iRegLdst doz; // difference or zero 13306 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13307 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13308 subL_reg_reg(diff, src2s, src1s); 13309 // Need to consider >=33 bit result, therefore we need signmaskL. 13310 signmask64L_regL(sm, diff); 13311 andcL_reg_reg(doz, diff, sm); // >=0 13312 addI_regL_regL(dst, doz, src1s); 13313 %} 13314 %} 13315 13316 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13317 match(Set dst (MaxI src1 src2)); 13318 effect(KILL cr0); 13319 predicate(VM_Version::has_isel()); 13320 ins_cost(DEFAULT_COST*2); 13321 13322 ins_encode %{ 13323 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13324 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13325 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13326 %} 13327 ins_pipe(pipe_class_default); 13328 %} 13329 13330 //---------- Population Count Instructions ------------------------------------ 13331 13332 // Popcnt for Power7. 13333 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13334 match(Set dst (PopCountI src)); 13335 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13336 ins_cost(DEFAULT_COST); 13337 13338 format %{ "POPCNTW $dst, $src" %} 13339 size(4); 13340 ins_encode %{ 13341 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13342 __ popcntw($dst$$Register, $src$$Register); 13343 %} 13344 ins_pipe(pipe_class_default); 13345 %} 13346 13347 // Popcnt for Power7. 13348 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13349 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13350 match(Set dst (PopCountL src)); 13351 ins_cost(DEFAULT_COST); 13352 13353 format %{ "POPCNTD $dst, $src" %} 13354 size(4); 13355 ins_encode %{ 13356 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13357 __ popcntd($dst$$Register, $src$$Register); 13358 %} 13359 ins_pipe(pipe_class_default); 13360 %} 13361 13362 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13363 match(Set dst (CountLeadingZerosI src)); 13364 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13365 ins_cost(DEFAULT_COST); 13366 13367 format %{ "CNTLZW $dst, $src" %} 13368 size(4); 13369 ins_encode %{ 13370 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13371 __ cntlzw($dst$$Register, $src$$Register); 13372 %} 13373 ins_pipe(pipe_class_default); 13374 %} 13375 13376 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13377 match(Set dst (CountLeadingZerosL src)); 13378 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13379 ins_cost(DEFAULT_COST); 13380 13381 format %{ "CNTLZD $dst, $src" %} 13382 size(4); 13383 ins_encode %{ 13384 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13385 __ cntlzd($dst$$Register, $src$$Register); 13386 %} 13387 ins_pipe(pipe_class_default); 13388 %} 13389 13390 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13391 // no match-rule, false predicate 13392 effect(DEF dst, USE src); 13393 predicate(false); 13394 13395 format %{ "CNTLZD $dst, $src" %} 13396 size(4); 13397 ins_encode %{ 13398 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13399 __ cntlzd($dst$$Register, $src$$Register); 13400 %} 13401 ins_pipe(pipe_class_default); 13402 %} 13403 13404 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13405 match(Set dst (CountTrailingZerosI src)); 13406 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13407 ins_cost(DEFAULT_COST); 13408 13409 expand %{ 13410 immI16 imm1 %{ (int)-1 %} 13411 immI16 imm2 %{ (int)32 %} 13412 immI_minus1 m1 %{ -1 %} 13413 iRegIdst tmpI1; 13414 iRegIdst tmpI2; 13415 iRegIdst tmpI3; 13416 addI_reg_imm16(tmpI1, src, imm1); 13417 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13418 countLeadingZerosI(tmpI3, tmpI2); 13419 subI_imm16_reg(dst, imm2, tmpI3); 13420 %} 13421 %} 13422 13423 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{ 13424 match(Set dst (CountTrailingZerosI src)); 13425 predicate(UseCountTrailingZerosInstructionsPPC64); 13426 ins_cost(DEFAULT_COST); 13427 13428 format %{ "CNTTZW $dst, $src" %} 13429 size(4); 13430 ins_encode %{ 13431 __ cnttzw($dst$$Register, $src$$Register); 13432 %} 13433 ins_pipe(pipe_class_default); 13434 %} 13435 13436 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13437 match(Set dst (CountTrailingZerosL src)); 13438 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13439 ins_cost(DEFAULT_COST); 13440 13441 expand %{ 13442 immL16 imm1 %{ (long)-1 %} 13443 immI16 imm2 %{ (int)64 %} 13444 iRegLdst tmpL1; 13445 iRegLdst tmpL2; 13446 iRegIdst tmpL3; 13447 addL_reg_imm16(tmpL1, src, imm1); 13448 andcL_reg_reg(tmpL2, tmpL1, src); 13449 countLeadingZerosL(tmpL3, tmpL2); 13450 subI_imm16_reg(dst, imm2, tmpL3); 13451 %} 13452 %} 13453 13454 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{ 13455 match(Set dst (CountTrailingZerosL src)); 13456 predicate(UseCountTrailingZerosInstructionsPPC64); 13457 ins_cost(DEFAULT_COST); 13458 13459 format %{ "CNTTZD $dst, $src" %} 13460 size(4); 13461 ins_encode %{ 13462 __ cnttzd($dst$$Register, $src$$Register); 13463 %} 13464 ins_pipe(pipe_class_default); 13465 %} 13466 13467 // Expand nodes for byte_reverse_int. 13468 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13469 effect(DEF dst, USE src, USE pos, USE shift); 13470 predicate(false); 13471 13472 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13473 size(4); 13474 ins_encode %{ 13475 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13476 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13477 %} 13478 ins_pipe(pipe_class_default); 13479 %} 13480 13481 // As insrwi_a, but with USE_DEF. 13482 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13483 effect(USE_DEF dst, USE src, USE pos, USE shift); 13484 predicate(false); 13485 13486 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13487 size(4); 13488 ins_encode %{ 13489 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13490 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13491 %} 13492 ins_pipe(pipe_class_default); 13493 %} 13494 13495 // Just slightly faster than java implementation. 13496 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13497 match(Set dst (ReverseBytesI src)); 13498 ins_cost(7*DEFAULT_COST); 13499 13500 expand %{ 13501 immI16 imm24 %{ (int) 24 %} 13502 immI16 imm16 %{ (int) 16 %} 13503 immI16 imm8 %{ (int) 8 %} 13504 immI16 imm4 %{ (int) 4 %} 13505 immI16 imm0 %{ (int) 0 %} 13506 iRegLdst tmpI1; 13507 iRegLdst tmpI2; 13508 iRegLdst tmpI3; 13509 13510 urShiftI_reg_imm(tmpI1, src, imm24); 13511 insrwi_a(dst, tmpI1, imm24, imm8); 13512 urShiftI_reg_imm(tmpI2, src, imm16); 13513 insrwi(dst, tmpI2, imm8, imm16); 13514 urShiftI_reg_imm(tmpI3, src, imm8); 13515 insrwi(dst, tmpI3, imm8, imm8); 13516 insrwi(dst, src, imm0, imm8); 13517 %} 13518 %} 13519 13520 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13521 match(Set dst (ReverseBytesL src)); 13522 ins_cost(15*DEFAULT_COST); 13523 13524 expand %{ 13525 immI16 imm56 %{ (int) 56 %} 13526 immI16 imm48 %{ (int) 48 %} 13527 immI16 imm40 %{ (int) 40 %} 13528 immI16 imm32 %{ (int) 32 %} 13529 immI16 imm24 %{ (int) 24 %} 13530 immI16 imm16 %{ (int) 16 %} 13531 immI16 imm8 %{ (int) 8 %} 13532 immI16 imm0 %{ (int) 0 %} 13533 iRegLdst tmpL1; 13534 iRegLdst tmpL2; 13535 iRegLdst tmpL3; 13536 iRegLdst tmpL4; 13537 iRegLdst tmpL5; 13538 iRegLdst tmpL6; 13539 13540 // src : |a|b|c|d|e|f|g|h| 13541 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13542 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13543 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13544 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13545 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13546 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13547 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13548 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13549 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13550 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13551 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13552 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13553 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13554 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13555 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13556 %} 13557 %} 13558 13559 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13560 match(Set dst (ReverseBytesUS src)); 13561 ins_cost(2*DEFAULT_COST); 13562 13563 expand %{ 13564 immI16 imm16 %{ (int) 16 %} 13565 immI16 imm8 %{ (int) 8 %} 13566 13567 urShiftI_reg_imm(dst, src, imm8); 13568 insrwi(dst, src, imm16, imm8); 13569 %} 13570 %} 13571 13572 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13573 match(Set dst (ReverseBytesS src)); 13574 ins_cost(3*DEFAULT_COST); 13575 13576 expand %{ 13577 immI16 imm16 %{ (int) 16 %} 13578 immI16 imm8 %{ (int) 8 %} 13579 iRegLdst tmpI1; 13580 13581 urShiftI_reg_imm(tmpI1, src, imm8); 13582 insrwi(tmpI1, src, imm16, imm8); 13583 extsh(dst, tmpI1); 13584 %} 13585 %} 13586 13587 // Load Integer reversed byte order 13588 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13589 match(Set dst (ReverseBytesI (LoadI mem))); 13590 ins_cost(MEMORY_REF_COST); 13591 13592 size(4); 13593 ins_encode %{ 13594 __ lwbrx($dst$$Register, $mem$$Register); 13595 %} 13596 ins_pipe(pipe_class_default); 13597 %} 13598 13599 // Load Long - aligned and reversed 13600 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13601 match(Set dst (ReverseBytesL (LoadL mem))); 13602 predicate(VM_Version::has_ldbrx()); 13603 ins_cost(MEMORY_REF_COST); 13604 13605 size(4); 13606 ins_encode %{ 13607 __ ldbrx($dst$$Register, $mem$$Register); 13608 %} 13609 ins_pipe(pipe_class_default); 13610 %} 13611 13612 // Load unsigned short / char reversed byte order 13613 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13614 match(Set dst (ReverseBytesUS (LoadUS mem))); 13615 ins_cost(MEMORY_REF_COST); 13616 13617 size(4); 13618 ins_encode %{ 13619 __ lhbrx($dst$$Register, $mem$$Register); 13620 %} 13621 ins_pipe(pipe_class_default); 13622 %} 13623 13624 // Load short reversed byte order 13625 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13626 match(Set dst (ReverseBytesS (LoadS mem))); 13627 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13628 13629 size(8); 13630 ins_encode %{ 13631 __ lhbrx($dst$$Register, $mem$$Register); 13632 __ extsh($dst$$Register, $dst$$Register); 13633 %} 13634 ins_pipe(pipe_class_default); 13635 %} 13636 13637 // Store Integer reversed byte order 13638 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13639 match(Set mem (StoreI mem (ReverseBytesI src))); 13640 ins_cost(MEMORY_REF_COST); 13641 13642 size(4); 13643 ins_encode %{ 13644 __ stwbrx($src$$Register, $mem$$Register); 13645 %} 13646 ins_pipe(pipe_class_default); 13647 %} 13648 13649 // Store Long reversed byte order 13650 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13651 match(Set mem (StoreL mem (ReverseBytesL src))); 13652 predicate(VM_Version::has_stdbrx()); 13653 ins_cost(MEMORY_REF_COST); 13654 13655 size(4); 13656 ins_encode %{ 13657 __ stdbrx($src$$Register, $mem$$Register); 13658 %} 13659 ins_pipe(pipe_class_default); 13660 %} 13661 13662 // Store unsigned short / char reversed byte order 13663 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13664 match(Set mem (StoreC mem (ReverseBytesUS src))); 13665 ins_cost(MEMORY_REF_COST); 13666 13667 size(4); 13668 ins_encode %{ 13669 __ sthbrx($src$$Register, $mem$$Register); 13670 %} 13671 ins_pipe(pipe_class_default); 13672 %} 13673 13674 // Store short reversed byte order 13675 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13676 match(Set mem (StoreC mem (ReverseBytesS src))); 13677 ins_cost(MEMORY_REF_COST); 13678 13679 size(4); 13680 ins_encode %{ 13681 __ sthbrx($src$$Register, $mem$$Register); 13682 %} 13683 ins_pipe(pipe_class_default); 13684 %} 13685 13686 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13687 effect(DEF temp1, USE src); 13688 13689 size(4); 13690 ins_encode %{ 13691 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13692 %} 13693 ins_pipe(pipe_class_default); 13694 %} 13695 13696 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13697 effect(DEF dst, USE src, USE imm1); 13698 13699 size(4); 13700 ins_encode %{ 13701 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13702 %} 13703 ins_pipe(pipe_class_default); 13704 %} 13705 13706 //---------- Replicate Vector Instructions ------------------------------------ 13707 13708 // Insrdi does replicate if src == dst. 13709 instruct repl32(iRegLdst dst) %{ 13710 predicate(false); 13711 effect(USE_DEF dst); 13712 13713 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13714 size(4); 13715 ins_encode %{ 13716 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13717 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13718 %} 13719 ins_pipe(pipe_class_default); 13720 %} 13721 13722 // Insrdi does replicate if src == dst. 13723 instruct repl48(iRegLdst dst) %{ 13724 predicate(false); 13725 effect(USE_DEF dst); 13726 13727 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13728 size(4); 13729 ins_encode %{ 13730 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13731 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13732 %} 13733 ins_pipe(pipe_class_default); 13734 %} 13735 13736 // Insrdi does replicate if src == dst. 13737 instruct repl56(iRegLdst dst) %{ 13738 predicate(false); 13739 effect(USE_DEF dst); 13740 13741 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13742 size(4); 13743 ins_encode %{ 13744 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13745 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 13746 %} 13747 ins_pipe(pipe_class_default); 13748 %} 13749 13750 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13751 match(Set dst (ReplicateB src)); 13752 predicate(n->as_Vector()->length() == 8); 13753 expand %{ 13754 moveReg(dst, src); 13755 repl56(dst); 13756 repl48(dst); 13757 repl32(dst); 13758 %} 13759 %} 13760 13761 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 13762 match(Set dst (ReplicateB zero)); 13763 predicate(n->as_Vector()->length() == 8); 13764 format %{ "LI $dst, #0 \t// replicate8B" %} 13765 size(4); 13766 ins_encode %{ 13767 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13768 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13769 %} 13770 ins_pipe(pipe_class_default); 13771 %} 13772 13773 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13774 match(Set dst (ReplicateB src)); 13775 predicate(n->as_Vector()->length() == 8); 13776 format %{ "LI $dst, #-1 \t// replicate8B" %} 13777 size(4); 13778 ins_encode %{ 13779 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13780 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13781 %} 13782 ins_pipe(pipe_class_default); 13783 %} 13784 13785 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 13786 match(Set dst (ReplicateB src)); 13787 predicate(n->as_Vector()->length() == 16); 13788 13789 expand %{ 13790 iRegLdst tmpL; 13791 vecX tmpV; 13792 immI8 imm1 %{ (int) 1 %} 13793 moveReg(tmpL, src); 13794 repl56(tmpL); 13795 repl48(tmpL); 13796 mtvsrwz(tmpV, tmpL); 13797 xxspltw(dst, tmpV, imm1); 13798 %} 13799 %} 13800 13801 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 13802 match(Set dst (ReplicateB zero)); 13803 predicate(n->as_Vector()->length() == 16); 13804 13805 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 13806 size(4); 13807 ins_encode %{ 13808 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13809 %} 13810 ins_pipe(pipe_class_default); 13811 %} 13812 13813 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 13814 match(Set dst (ReplicateB src)); 13815 predicate(n->as_Vector()->length() == 16); 13816 13817 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13818 size(4); 13819 ins_encode %{ 13820 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13821 %} 13822 ins_pipe(pipe_class_default); 13823 %} 13824 13825 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13826 match(Set dst (ReplicateS src)); 13827 predicate(n->as_Vector()->length() == 4); 13828 expand %{ 13829 moveReg(dst, src); 13830 repl48(dst); 13831 repl32(dst); 13832 %} 13833 %} 13834 13835 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 13836 match(Set dst (ReplicateS zero)); 13837 predicate(n->as_Vector()->length() == 4); 13838 format %{ "LI $dst, #0 \t// replicate4C" %} 13839 size(4); 13840 ins_encode %{ 13841 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13842 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13843 %} 13844 ins_pipe(pipe_class_default); 13845 %} 13846 13847 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13848 match(Set dst (ReplicateS src)); 13849 predicate(n->as_Vector()->length() == 4); 13850 format %{ "LI $dst, -1 \t// replicate4C" %} 13851 size(4); 13852 ins_encode %{ 13853 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13854 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13855 %} 13856 ins_pipe(pipe_class_default); 13857 %} 13858 13859 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 13860 match(Set dst (ReplicateS src)); 13861 predicate(n->as_Vector()->length() == 8); 13862 13863 expand %{ 13864 iRegLdst tmpL; 13865 vecX tmpV; 13866 immI8 zero %{ (int) 0 %} 13867 moveReg(tmpL, src); 13868 repl48(tmpL); 13869 repl32(tmpL); 13870 mtvsrd(tmpV, tmpL); 13871 xxpermdi(dst, tmpV, tmpV, zero); 13872 %} 13873 %} 13874 13875 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 13876 match(Set dst (ReplicateS zero)); 13877 predicate(n->as_Vector()->length() == 8); 13878 13879 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 13880 size(4); 13881 ins_encode %{ 13882 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13883 %} 13884 ins_pipe(pipe_class_default); 13885 %} 13886 13887 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 13888 match(Set dst (ReplicateS src)); 13889 predicate(n->as_Vector()->length() == 8); 13890 13891 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13892 size(4); 13893 ins_encode %{ 13894 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13895 %} 13896 ins_pipe(pipe_class_default); 13897 %} 13898 13899 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13900 match(Set dst (ReplicateI src)); 13901 predicate(n->as_Vector()->length() == 2); 13902 ins_cost(2 * DEFAULT_COST); 13903 expand %{ 13904 moveReg(dst, src); 13905 repl32(dst); 13906 %} 13907 %} 13908 13909 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 13910 match(Set dst (ReplicateI zero)); 13911 predicate(n->as_Vector()->length() == 2); 13912 format %{ "LI $dst, #0 \t// replicate4C" %} 13913 size(4); 13914 ins_encode %{ 13915 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13916 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13917 %} 13918 ins_pipe(pipe_class_default); 13919 %} 13920 13921 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13922 match(Set dst (ReplicateI src)); 13923 predicate(n->as_Vector()->length() == 2); 13924 format %{ "LI $dst, -1 \t// replicate4C" %} 13925 size(4); 13926 ins_encode %{ 13927 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13928 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13929 %} 13930 ins_pipe(pipe_class_default); 13931 %} 13932 13933 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 13934 match(Set dst (ReplicateI src)); 13935 predicate(n->as_Vector()->length() == 4); 13936 ins_cost(2 * DEFAULT_COST); 13937 13938 expand %{ 13939 iRegLdst tmpL; 13940 vecX tmpV; 13941 immI8 zero %{ (int) 0 %} 13942 moveReg(tmpL, src); 13943 repl32(tmpL); 13944 mtvsrd(tmpV, tmpL); 13945 xxpermdi(dst, tmpV, tmpV, zero); 13946 %} 13947 %} 13948 13949 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 13950 match(Set dst (ReplicateI zero)); 13951 predicate(n->as_Vector()->length() == 4); 13952 13953 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 13954 size(4); 13955 ins_encode %{ 13956 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13957 %} 13958 ins_pipe(pipe_class_default); 13959 %} 13960 13961 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 13962 match(Set dst (ReplicateI src)); 13963 predicate(n->as_Vector()->length() == 4); 13964 13965 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 13966 size(4); 13967 ins_encode %{ 13968 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13969 %} 13970 ins_pipe(pipe_class_default); 13971 %} 13972 13973 // Move float to int register via stack, replicate. 13974 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 13975 match(Set dst (ReplicateF src)); 13976 predicate(n->as_Vector()->length() == 2); 13977 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13978 expand %{ 13979 stackSlotL tmpS; 13980 iRegIdst tmpI; 13981 moveF2I_reg_stack(tmpS, src); // Move float to stack. 13982 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 13983 moveReg(dst, tmpI); // Move int to long reg. 13984 repl32(dst); // Replicate bitpattern. 13985 %} 13986 %} 13987 13988 // Replicate scalar constant to packed float values in Double register 13989 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 13990 match(Set dst (ReplicateF src)); 13991 predicate(n->as_Vector()->length() == 2); 13992 ins_cost(5 * DEFAULT_COST); 13993 13994 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 13995 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 13996 %} 13997 13998 // Replicate scalar zero constant to packed float values in Double register 13999 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 14000 match(Set dst (ReplicateF zero)); 14001 predicate(n->as_Vector()->length() == 2); 14002 14003 format %{ "LI $dst, #0 \t// replicate2F" %} 14004 ins_encode %{ 14005 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14006 __ li($dst$$Register, 0x0); 14007 %} 14008 ins_pipe(pipe_class_default); 14009 %} 14010 14011 14012 //----------Overflow Math Instructions----------------------------------------- 14013 14014 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 14015 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14016 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14017 14018 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14019 match(Set cr0 (OverflowAddL op1 op2)); 14020 14021 format %{ "add_ $op1, $op2\t# overflow check long" %} 14022 ins_encode %{ 14023 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14024 __ li(R0, 0); 14025 __ mtxer(R0); // clear XER.SO 14026 __ addo_(R0, $op1$$Register, $op2$$Register); 14027 %} 14028 ins_pipe(pipe_class_default); 14029 %} 14030 14031 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14032 match(Set cr0 (OverflowSubL op1 op2)); 14033 14034 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14035 ins_encode %{ 14036 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14037 __ li(R0, 0); 14038 __ mtxer(R0); // clear XER.SO 14039 __ subfo_(R0, $op2$$Register, $op1$$Register); 14040 %} 14041 ins_pipe(pipe_class_default); 14042 %} 14043 14044 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14045 match(Set cr0 (OverflowSubL zero op2)); 14046 14047 format %{ "nego_ R0, $op2\t# overflow check long" %} 14048 ins_encode %{ 14049 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14050 __ li(R0, 0); 14051 __ mtxer(R0); // clear XER.SO 14052 __ nego_(R0, $op2$$Register); 14053 %} 14054 ins_pipe(pipe_class_default); 14055 %} 14056 14057 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14058 match(Set cr0 (OverflowMulL op1 op2)); 14059 14060 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14061 ins_encode %{ 14062 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14063 __ li(R0, 0); 14064 __ mtxer(R0); // clear XER.SO 14065 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14066 %} 14067 ins_pipe(pipe_class_default); 14068 %} 14069 14070 14071 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14072 match(Set dst (ReplicateF src)); 14073 predicate(n->as_Vector()->length() == 4); 14074 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14075 expand %{ 14076 stackSlotL tmpS; 14077 iRegIdst tmpI; 14078 iRegLdst tmpL; 14079 vecX tmpV; 14080 immI8 zero %{ (int) 0 %} 14081 14082 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14083 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14084 moveReg(tmpL, tmpI); // Move int to long reg. 14085 repl32(tmpL); // Replicate bitpattern. 14086 mtvsrd(tmpV, tmpL); 14087 xxpermdi(dst, tmpV, tmpV, zero); 14088 %} 14089 %} 14090 14091 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14092 match(Set dst (ReplicateF src)); 14093 predicate(n->as_Vector()->length() == 4); 14094 effect(TEMP tmp); 14095 ins_cost(10 * DEFAULT_COST); 14096 14097 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14098 %} 14099 14100 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14101 match(Set dst (ReplicateF zero)); 14102 predicate(n->as_Vector()->length() == 4); 14103 14104 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14105 ins_encode %{ 14106 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14107 %} 14108 ins_pipe(pipe_class_default); 14109 %} 14110 14111 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14112 match(Set dst (ReplicateD src)); 14113 predicate(n->as_Vector()->length() == 2); 14114 expand %{ 14115 stackSlotL tmpS; 14116 iRegLdst tmpL; 14117 iRegLdst tmp; 14118 vecX tmpV; 14119 immI8 zero %{ (int) 0 %} 14120 moveD2L_reg_stack(tmpS, src); 14121 moveD2L_stack_reg(tmpL, tmpS); 14122 mtvsrd(tmpV, tmpL); 14123 xxpermdi(dst, tmpV, tmpV, zero); 14124 %} 14125 %} 14126 14127 instruct repl2D_immI0(vecX dst, immI_0 zero) %{ 14128 match(Set dst (ReplicateD zero)); 14129 predicate(n->as_Vector()->length() == 2); 14130 14131 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14132 size(4); 14133 ins_encode %{ 14134 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14135 %} 14136 ins_pipe(pipe_class_default); 14137 %} 14138 14139 instruct repl2D_immIminus1(vecX dst, immI_minus1 src) %{ 14140 match(Set dst (ReplicateD src)); 14141 predicate(n->as_Vector()->length() == 2); 14142 14143 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14144 size(4); 14145 ins_encode %{ 14146 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14147 %} 14148 ins_pipe(pipe_class_default); 14149 %} 14150 14151 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14152 predicate(false); 14153 effect(DEF dst, USE src); 14154 14155 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register"%} 14156 size(4); 14157 ins_encode %{ 14158 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14159 %} 14160 ins_pipe(pipe_class_default); 14161 %} 14162 14163 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14164 effect(DEF dst, USE src, USE zero); 14165 14166 format %{ "XXSPLATD $dst, $src, $zero \t// Permute 16-byte register"%} 14167 size(4); 14168 ins_encode %{ 14169 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14170 %} 14171 ins_pipe(pipe_class_default); 14172 %} 14173 14174 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14175 effect(DEF dst, USE src1, USE src2, USE zero); 14176 14177 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Permute 16-byte register"%} 14178 size(4); 14179 ins_encode %{ 14180 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14181 %} 14182 ins_pipe(pipe_class_default); 14183 %} 14184 14185 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14186 match(Set dst (ReplicateL src)); 14187 predicate(n->as_Vector()->length() == 2); 14188 expand %{ 14189 vecX tmpV; 14190 immI8 zero %{ (int) 0 %} 14191 mtvsrd(tmpV, src); 14192 xxpermdi(dst, tmpV, tmpV, zero); 14193 %} 14194 %} 14195 14196 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14197 match(Set dst (ReplicateL zero)); 14198 predicate(n->as_Vector()->length() == 2); 14199 14200 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14201 size(4); 14202 ins_encode %{ 14203 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14204 %} 14205 ins_pipe(pipe_class_default); 14206 %} 14207 14208 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14209 match(Set dst (ReplicateL src)); 14210 predicate(n->as_Vector()->length() == 2); 14211 14212 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14213 size(4); 14214 ins_encode %{ 14215 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14216 %} 14217 ins_pipe(pipe_class_default); 14218 %} 14219 14220 // ============================================================================ 14221 // Safepoint Instruction 14222 14223 instruct safePoint_poll(iRegPdst poll) %{ 14224 match(SafePoint poll); 14225 14226 // It caused problems to add the effect that r0 is killed, but this 14227 // effect no longer needs to be mentioned, since r0 is not contained 14228 // in a reg_class. 14229 14230 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14231 size(4); 14232 ins_encode( enc_poll(0x0, poll) ); 14233 ins_pipe(pipe_class_default); 14234 %} 14235 14236 // ============================================================================ 14237 // Call Instructions 14238 14239 // Call Java Static Instruction 14240 14241 // Schedulable version of call static node. 14242 instruct CallStaticJavaDirect(method meth) %{ 14243 match(CallStaticJava); 14244 effect(USE meth); 14245 ins_cost(CALL_COST); 14246 14247 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14248 14249 format %{ "CALL,static $meth \t// ==> " %} 14250 size(4); 14251 ins_encode( enc_java_static_call(meth) ); 14252 ins_pipe(pipe_class_call); 14253 %} 14254 14255 // Call Java Dynamic Instruction 14256 14257 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14258 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14259 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14260 // The call destination must still be placed in the constant pool. 14261 instruct CallDynamicJavaDirectSched(method meth) %{ 14262 match(CallDynamicJava); // To get all the data fields we need ... 14263 effect(USE meth); 14264 predicate(false); // ... but never match. 14265 14266 ins_field_load_ic_hi_node(loadConL_hiNode*); 14267 ins_field_load_ic_node(loadConLNode*); 14268 ins_num_consts(1 /* 1 patchable constant: call destination */); 14269 14270 format %{ "BL \t// dynamic $meth ==> " %} 14271 size(4); 14272 ins_encode( enc_java_dynamic_call_sched(meth) ); 14273 ins_pipe(pipe_class_call); 14274 %} 14275 14276 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14277 // We use postalloc expanded calls if we use inline caches 14278 // and do not update method data. 14279 // 14280 // This instruction has two constants: inline cache (IC) and call destination. 14281 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14282 // one constant. 14283 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14284 match(CallDynamicJava); 14285 effect(USE meth); 14286 predicate(UseInlineCaches); 14287 ins_cost(CALL_COST); 14288 14289 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14290 14291 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14292 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14293 %} 14294 14295 // Compound version of call dynamic java 14296 // We use postalloc expanded calls if we use inline caches 14297 // and do not update method data. 14298 instruct CallDynamicJavaDirect(method meth) %{ 14299 match(CallDynamicJava); 14300 effect(USE meth); 14301 predicate(!UseInlineCaches); 14302 ins_cost(CALL_COST); 14303 14304 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14305 ins_num_consts(4); 14306 14307 format %{ "CALL,dynamic $meth \t// ==> " %} 14308 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14309 ins_pipe(pipe_class_call); 14310 %} 14311 14312 // Call Runtime Instruction 14313 14314 instruct CallRuntimeDirect(method meth) %{ 14315 match(CallRuntime); 14316 effect(USE meth); 14317 ins_cost(CALL_COST); 14318 14319 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14320 // env for callee, C-toc. 14321 ins_num_consts(3); 14322 14323 format %{ "CALL,runtime" %} 14324 ins_encode( enc_java_to_runtime_call(meth) ); 14325 ins_pipe(pipe_class_call); 14326 %} 14327 14328 // Call Leaf 14329 14330 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14331 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14332 effect(DEF dst, USE src); 14333 14334 ins_num_consts(1); 14335 14336 format %{ "MTCTR $src" %} 14337 size(4); 14338 ins_encode( enc_leaf_call_mtctr(src) ); 14339 ins_pipe(pipe_class_default); 14340 %} 14341 14342 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 14343 instruct CallLeafDirect(method meth) %{ 14344 match(CallLeaf); // To get the data all the data fields we need ... 14345 effect(USE meth); 14346 predicate(false); // but never match. 14347 14348 format %{ "BCTRL \t// leaf call $meth ==> " %} 14349 size(4); 14350 ins_encode %{ 14351 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 14352 __ bctrl(); 14353 %} 14354 ins_pipe(pipe_class_call); 14355 %} 14356 14357 // postalloc expand of CallLeafDirect. 14358 // Load adress to call from TOC, then bl to it. 14359 instruct CallLeafDirect_Ex(method meth) %{ 14360 match(CallLeaf); 14361 effect(USE meth); 14362 ins_cost(CALL_COST); 14363 14364 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14365 // env for callee, C-toc. 14366 ins_num_consts(3); 14367 14368 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14369 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14370 %} 14371 14372 // Call runtime without safepoint - same as CallLeaf. 14373 // postalloc expand of CallLeafNoFPDirect. 14374 // Load adress to call from TOC, then bl to it. 14375 instruct CallLeafNoFPDirect_Ex(method meth) %{ 14376 match(CallLeafNoFP); 14377 effect(USE meth); 14378 ins_cost(CALL_COST); 14379 14380 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14381 // env for callee, C-toc. 14382 ins_num_consts(3); 14383 14384 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14385 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14386 %} 14387 14388 // Tail Call; Jump from runtime stub to Java code. 14389 // Also known as an 'interprocedural jump'. 14390 // Target of jump will eventually return to caller. 14391 // TailJump below removes the return address. 14392 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 14393 match(TailCall jump_target method_oop); 14394 ins_cost(CALL_COST); 14395 14396 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 14397 "BCTR \t// tail call" %} 14398 size(8); 14399 ins_encode %{ 14400 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14401 __ mtctr($jump_target$$Register); 14402 __ bctr(); 14403 %} 14404 ins_pipe(pipe_class_call); 14405 %} 14406 14407 // Return Instruction 14408 instruct Ret() %{ 14409 match(Return); 14410 format %{ "BLR \t// branch to link register" %} 14411 size(4); 14412 ins_encode %{ 14413 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 14414 // LR is restored in MachEpilogNode. Just do the RET here. 14415 __ blr(); 14416 %} 14417 ins_pipe(pipe_class_default); 14418 %} 14419 14420 // Tail Jump; remove the return address; jump to target. 14421 // TailCall above leaves the return address around. 14422 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14423 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14424 // "restore" before this instruction (in Epilogue), we need to materialize it 14425 // in %i0. 14426 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14427 match(TailJump jump_target ex_oop); 14428 ins_cost(CALL_COST); 14429 14430 format %{ "LD R4_ARG2 = LR\n\t" 14431 "MTCTR $jump_target\n\t" 14432 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14433 size(12); 14434 ins_encode %{ 14435 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14436 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 14437 __ mtctr($jump_target$$Register); 14438 __ bctr(); 14439 %} 14440 ins_pipe(pipe_class_call); 14441 %} 14442 14443 // Create exception oop: created by stack-crawling runtime code. 14444 // Created exception is now available to this handler, and is setup 14445 // just prior to jumping to this handler. No code emitted. 14446 instruct CreateException(rarg1RegP ex_oop) %{ 14447 match(Set ex_oop (CreateEx)); 14448 ins_cost(0); 14449 14450 format %{ " -- \t// exception oop; no code emitted" %} 14451 size(0); 14452 ins_encode( /*empty*/ ); 14453 ins_pipe(pipe_class_default); 14454 %} 14455 14456 // Rethrow exception: The exception oop will come in the first 14457 // argument position. Then JUMP (not call) to the rethrow stub code. 14458 instruct RethrowException() %{ 14459 match(Rethrow); 14460 ins_cost(CALL_COST); 14461 14462 format %{ "Jmp rethrow_stub" %} 14463 ins_encode %{ 14464 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14465 cbuf.set_insts_mark(); 14466 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 14467 %} 14468 ins_pipe(pipe_class_call); 14469 %} 14470 14471 // Die now. 14472 instruct ShouldNotReachHere() %{ 14473 match(Halt); 14474 ins_cost(CALL_COST); 14475 14476 format %{ "ShouldNotReachHere" %} 14477 size(4); 14478 ins_encode %{ 14479 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 14480 __ trap_should_not_reach_here(); 14481 %} 14482 ins_pipe(pipe_class_default); 14483 %} 14484 14485 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 14486 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 14487 // Get a DEF on threadRegP, no costs, no encoding, use 14488 // 'ins_should_rematerialize(true)' to avoid spilling. 14489 instruct tlsLoadP(threadRegP dst) %{ 14490 match(Set dst (ThreadLocal)); 14491 ins_cost(0); 14492 14493 ins_should_rematerialize(true); 14494 14495 format %{ " -- \t// $dst=Thread::current(), empty" %} 14496 size(0); 14497 ins_encode( /*empty*/ ); 14498 ins_pipe(pipe_class_empty); 14499 %} 14500 14501 //---Some PPC specific nodes--------------------------------------------------- 14502 14503 // Stop a group. 14504 instruct endGroup() %{ 14505 ins_cost(0); 14506 14507 ins_is_nop(true); 14508 14509 format %{ "End Bundle (ori r1, r1, 0)" %} 14510 size(4); 14511 ins_encode %{ 14512 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 14513 __ endgroup(); 14514 %} 14515 ins_pipe(pipe_class_default); 14516 %} 14517 14518 // Nop instructions 14519 14520 instruct fxNop() %{ 14521 ins_cost(0); 14522 14523 ins_is_nop(true); 14524 14525 format %{ "fxNop" %} 14526 size(4); 14527 ins_encode %{ 14528 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14529 __ nop(); 14530 %} 14531 ins_pipe(pipe_class_default); 14532 %} 14533 14534 instruct fpNop0() %{ 14535 ins_cost(0); 14536 14537 ins_is_nop(true); 14538 14539 format %{ "fpNop0" %} 14540 size(4); 14541 ins_encode %{ 14542 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14543 __ fpnop0(); 14544 %} 14545 ins_pipe(pipe_class_default); 14546 %} 14547 14548 instruct fpNop1() %{ 14549 ins_cost(0); 14550 14551 ins_is_nop(true); 14552 14553 format %{ "fpNop1" %} 14554 size(4); 14555 ins_encode %{ 14556 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14557 __ fpnop1(); 14558 %} 14559 ins_pipe(pipe_class_default); 14560 %} 14561 14562 instruct brNop0() %{ 14563 ins_cost(0); 14564 size(4); 14565 format %{ "brNop0" %} 14566 ins_encode %{ 14567 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14568 __ brnop0(); 14569 %} 14570 ins_is_nop(true); 14571 ins_pipe(pipe_class_default); 14572 %} 14573 14574 instruct brNop1() %{ 14575 ins_cost(0); 14576 14577 ins_is_nop(true); 14578 14579 format %{ "brNop1" %} 14580 size(4); 14581 ins_encode %{ 14582 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14583 __ brnop1(); 14584 %} 14585 ins_pipe(pipe_class_default); 14586 %} 14587 14588 instruct brNop2() %{ 14589 ins_cost(0); 14590 14591 ins_is_nop(true); 14592 14593 format %{ "brNop2" %} 14594 size(4); 14595 ins_encode %{ 14596 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14597 __ brnop2(); 14598 %} 14599 ins_pipe(pipe_class_default); 14600 %} 14601 14602 //----------PEEPHOLE RULES----------------------------------------------------- 14603 // These must follow all instruction definitions as they use the names 14604 // defined in the instructions definitions. 14605 // 14606 // peepmatch ( root_instr_name [preceeding_instruction]* ); 14607 // 14608 // peepconstraint %{ 14609 // (instruction_number.operand_name relational_op instruction_number.operand_name 14610 // [, ...] ); 14611 // // instruction numbers are zero-based using left to right order in peepmatch 14612 // 14613 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14614 // // provide an instruction_number.operand_name for each operand that appears 14615 // // in the replacement instruction's match rule 14616 // 14617 // ---------VM FLAGS--------------------------------------------------------- 14618 // 14619 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14620 // 14621 // Each peephole rule is given an identifying number starting with zero and 14622 // increasing by one in the order seen by the parser. An individual peephole 14623 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14624 // on the command-line. 14625 // 14626 // ---------CURRENT LIMITATIONS---------------------------------------------- 14627 // 14628 // Only match adjacent instructions in same basic block 14629 // Only equality constraints 14630 // Only constraints between operands, not (0.dest_reg == EAX_enc) 14631 // Only one replacement instruction 14632 // 14633 // ---------EXAMPLE---------------------------------------------------------- 14634 // 14635 // // pertinent parts of existing instructions in architecture description 14636 // instruct movI(eRegI dst, eRegI src) %{ 14637 // match(Set dst (CopyI src)); 14638 // %} 14639 // 14640 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 14641 // match(Set dst (AddI dst src)); 14642 // effect(KILL cr); 14643 // %} 14644 // 14645 // // Change (inc mov) to lea 14646 // peephole %{ 14647 // // increment preceeded by register-register move 14648 // peepmatch ( incI_eReg movI ); 14649 // // require that the destination register of the increment 14650 // // match the destination register of the move 14651 // peepconstraint ( 0.dst == 1.dst ); 14652 // // construct a replacement instruction that sets 14653 // // the destination to ( move's source register + one ) 14654 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14655 // %} 14656 // 14657 // Implementation no longer uses movX instructions since 14658 // machine-independent system no longer uses CopyX nodes. 14659 // 14660 // peephole %{ 14661 // peepmatch ( incI_eReg movI ); 14662 // peepconstraint ( 0.dst == 1.dst ); 14663 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14664 // %} 14665 // 14666 // peephole %{ 14667 // peepmatch ( decI_eReg movI ); 14668 // peepconstraint ( 0.dst == 1.dst ); 14669 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14670 // %} 14671 // 14672 // peephole %{ 14673 // peepmatch ( addI_eReg_imm movI ); 14674 // peepconstraint ( 0.dst == 1.dst ); 14675 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14676 // %} 14677 // 14678 // peephole %{ 14679 // peepmatch ( addP_eReg_imm movP ); 14680 // peepconstraint ( 0.dst == 1.dst ); 14681 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 14682 // %} 14683 14684 // // Change load of spilled value to only a spill 14685 // instruct storeI(memory mem, eRegI src) %{ 14686 // match(Set mem (StoreI mem src)); 14687 // %} 14688 // 14689 // instruct loadI(eRegI dst, memory mem) %{ 14690 // match(Set dst (LoadI mem)); 14691 // %} 14692 // 14693 peephole %{ 14694 peepmatch ( loadI storeI ); 14695 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14696 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 14697 %} 14698 14699 peephole %{ 14700 peepmatch ( loadL storeL ); 14701 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14702 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 14703 %} 14704 14705 peephole %{ 14706 peepmatch ( loadP storeP ); 14707 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 14708 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 14709 %} 14710 14711 //----------SMARTSPILL RULES--------------------------------------------------- 14712 // These must follow all instruction definitions as they use the names 14713 // defined in the instructions definitions.