1 // 2 // Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2017 SAP SE. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // 27 // PPC64 Architecture Description File 28 // 29 30 //----------REGISTER DEFINITION BLOCK------------------------------------------ 31 // This information is used by the matcher and the register allocator to 32 // describe individual registers and classes of registers within the target 33 // architecture. 34 register %{ 35 //----------Architecture Description Register Definitions---------------------- 36 // General Registers 37 // "reg_def" name (register save type, C convention save type, 38 // ideal register type, encoding); 39 // 40 // Register Save Types: 41 // 42 // NS = No-Save: The register allocator assumes that these registers 43 // can be used without saving upon entry to the method, & 44 // that they do not need to be saved at call sites. 45 // 46 // SOC = Save-On-Call: The register allocator assumes that these registers 47 // can be used without saving upon entry to the method, 48 // but that they must be saved at call sites. 49 // These are called "volatiles" on ppc. 50 // 51 // SOE = Save-On-Entry: The register allocator assumes that these registers 52 // must be saved before using them upon entry to the 53 // method, but they do not need to be saved at call 54 // sites. 55 // These are called "nonvolatiles" on ppc. 56 // 57 // AS = Always-Save: The register allocator assumes that these registers 58 // must be saved before using them upon entry to the 59 // method, & that they must be saved at call sites. 60 // 61 // Ideal Register Type is used to determine how to save & restore a 62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 64 // 65 // The encoding number is the actual bit-pattern placed into the opcodes. 66 // 67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI 68 // Supplement Version 1.7 as of 2003-10-29. 69 // 70 // For each 64-bit register we must define two registers: the register 71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half', 72 // e.g. R3_H, which is needed by the allocator, but is not used 73 // for stores, loads, etc. 74 75 // ---------------------------- 76 // Integer/Long Registers 77 // ---------------------------- 78 79 // PPC64 has 32 64-bit integer registers. 80 81 // types: v = volatile, nv = non-volatile, s = system 82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs 83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() ); 84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP 85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() ); 86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC 87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() ); 88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret 89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() ); 90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2 91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() ); 92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3 93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() ); 94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4 95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() ); 96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5 97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() ); 98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6 99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() ); 100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7 101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() ); 102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8 103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next()); 104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch 105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next()); 106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch 107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next()); 108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id 109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next()); 110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv 111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next()); 112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv 113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next()); 114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv 115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next()); 116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv 117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next()); 118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv 119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next()); 120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv 121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next()); 122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv 123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next()); 124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv 125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next()); 126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv 127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next()); 128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv 129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next()); 130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv 131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next()); 132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv 133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next()); 134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv 135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next()); 136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv 137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next()); 138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv 139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next()); 140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv 141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next()); 142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv 143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next()); 144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv 145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next()); 146 147 148 // ---------------------------- 149 // Float/Double Registers 150 // ---------------------------- 151 152 // Double Registers 153 // The rules of ADL require that double registers be defined in pairs. 154 // Each pair must be two 32-bit values, but not necessarily a pair of 155 // single float registers. In each pair, ADLC-assigned register numbers 156 // must be adjacent, with the lower number even. Finally, when the 157 // CPU stores such a register pair to memory, the word associated with 158 // the lower ADLC-assigned number must be stored to the lower address. 159 160 // PPC64 has 32 64-bit floating-point registers. Each can store a single 161 // or double precision floating-point value. 162 163 // types: v = volatile, nv = non-volatile, s = system 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch 165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret 167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2 169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3 171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4 173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5 175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6 177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7 179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8 181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9 183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10 185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next()); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11 187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next()); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12 189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next()); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13 191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next()); 192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv 193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next()); 194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv 195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next()); 196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv 197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next()); 198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv 199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next()); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv 201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next()); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv 203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next()); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv 205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next()); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv 207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next()); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv 209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next()); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv 211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next()); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv 213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next()); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv 215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next()); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv 217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next()); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv 219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next()); 220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv 221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next()); 222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv 223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next()); 224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv 225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next()); 226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv 227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next()); 228 229 // ---------------------------- 230 // Special Registers 231 // ---------------------------- 232 233 // Condition Codes Flag Registers 234 235 // PPC64 has 8 condition code "registers" which are all contained 236 // in the CR register. 237 238 // types: v = volatile, nv = non-volatile, s = system 239 reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v 240 reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v 241 reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv 242 reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv 243 reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv 244 reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v 245 reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v 246 reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg()); // v 247 248 // Special registers of PPC64 249 250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v 251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v 252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v 253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v 254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v 255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v 256 257 // ---------------------------- 258 // Vector-Scalar Registers 259 // ---------------------------- 260 reg_def VSR0 ( SOC, SOC, Op_VecX, 0, NULL); 261 reg_def VSR1 ( SOC, SOC, Op_VecX, 1, NULL); 262 reg_def VSR2 ( SOC, SOC, Op_VecX, 2, NULL); 263 reg_def VSR3 ( SOC, SOC, Op_VecX, 3, NULL); 264 reg_def VSR4 ( SOC, SOC, Op_VecX, 4, NULL); 265 reg_def VSR5 ( SOC, SOC, Op_VecX, 5, NULL); 266 reg_def VSR6 ( SOC, SOC, Op_VecX, 6, NULL); 267 reg_def VSR7 ( SOC, SOC, Op_VecX, 7, NULL); 268 reg_def VSR8 ( SOC, SOC, Op_VecX, 8, NULL); 269 reg_def VSR9 ( SOC, SOC, Op_VecX, 9, NULL); 270 reg_def VSR10 ( SOC, SOC, Op_VecX, 10, NULL); 271 reg_def VSR11 ( SOC, SOC, Op_VecX, 11, NULL); 272 reg_def VSR12 ( SOC, SOC, Op_VecX, 12, NULL); 273 reg_def VSR13 ( SOC, SOC, Op_VecX, 13, NULL); 274 reg_def VSR14 ( SOC, SOC, Op_VecX, 14, NULL); 275 reg_def VSR15 ( SOC, SOC, Op_VecX, 15, NULL); 276 reg_def VSR16 ( SOC, SOC, Op_VecX, 16, NULL); 277 reg_def VSR17 ( SOC, SOC, Op_VecX, 17, NULL); 278 reg_def VSR18 ( SOC, SOC, Op_VecX, 18, NULL); 279 reg_def VSR19 ( SOC, SOC, Op_VecX, 19, NULL); 280 reg_def VSR20 ( SOC, SOC, Op_VecX, 20, NULL); 281 reg_def VSR21 ( SOC, SOC, Op_VecX, 21, NULL); 282 reg_def VSR22 ( SOC, SOC, Op_VecX, 22, NULL); 283 reg_def VSR23 ( SOC, SOC, Op_VecX, 23, NULL); 284 reg_def VSR24 ( SOC, SOC, Op_VecX, 24, NULL); 285 reg_def VSR25 ( SOC, SOC, Op_VecX, 25, NULL); 286 reg_def VSR26 ( SOC, SOC, Op_VecX, 26, NULL); 287 reg_def VSR27 ( SOC, SOC, Op_VecX, 27, NULL); 288 reg_def VSR28 ( SOC, SOC, Op_VecX, 28, NULL); 289 reg_def VSR29 ( SOC, SOC, Op_VecX, 29, NULL); 290 reg_def VSR30 ( SOC, SOC, Op_VecX, 30, NULL); 291 reg_def VSR31 ( SOC, SOC, Op_VecX, 31, NULL); 292 reg_def VSR32 ( SOC, SOC, Op_VecX, 32, NULL); 293 reg_def VSR33 ( SOC, SOC, Op_VecX, 33, NULL); 294 reg_def VSR34 ( SOC, SOC, Op_VecX, 34, NULL); 295 reg_def VSR35 ( SOC, SOC, Op_VecX, 35, NULL); 296 reg_def VSR36 ( SOC, SOC, Op_VecX, 36, NULL); 297 reg_def VSR37 ( SOC, SOC, Op_VecX, 37, NULL); 298 reg_def VSR38 ( SOC, SOC, Op_VecX, 38, NULL); 299 reg_def VSR39 ( SOC, SOC, Op_VecX, 39, NULL); 300 reg_def VSR40 ( SOC, SOC, Op_VecX, 40, NULL); 301 reg_def VSR41 ( SOC, SOC, Op_VecX, 41, NULL); 302 reg_def VSR42 ( SOC, SOC, Op_VecX, 42, NULL); 303 reg_def VSR43 ( SOC, SOC, Op_VecX, 43, NULL); 304 reg_def VSR44 ( SOC, SOC, Op_VecX, 44, NULL); 305 reg_def VSR45 ( SOC, SOC, Op_VecX, 45, NULL); 306 reg_def VSR46 ( SOC, SOC, Op_VecX, 46, NULL); 307 reg_def VSR47 ( SOC, SOC, Op_VecX, 47, NULL); 308 reg_def VSR48 ( SOC, SOC, Op_VecX, 48, NULL); 309 reg_def VSR49 ( SOC, SOC, Op_VecX, 49, NULL); 310 reg_def VSR50 ( SOC, SOC, Op_VecX, 50, NULL); 311 reg_def VSR51 ( SOC, SOC, Op_VecX, 51, NULL); 312 reg_def VSR52 ( SOC, SOC, Op_VecX, 52, NULL); 313 reg_def VSR53 ( SOC, SOC, Op_VecX, 53, NULL); 314 reg_def VSR54 ( SOC, SOC, Op_VecX, 54, NULL); 315 reg_def VSR55 ( SOC, SOC, Op_VecX, 55, NULL); 316 reg_def VSR56 ( SOC, SOC, Op_VecX, 56, NULL); 317 reg_def VSR57 ( SOC, SOC, Op_VecX, 57, NULL); 318 reg_def VSR58 ( SOC, SOC, Op_VecX, 58, NULL); 319 reg_def VSR59 ( SOC, SOC, Op_VecX, 59, NULL); 320 reg_def VSR60 ( SOC, SOC, Op_VecX, 60, NULL); 321 reg_def VSR61 ( SOC, SOC, Op_VecX, 61, NULL); 322 reg_def VSR62 ( SOC, SOC, Op_VecX, 62, NULL); 323 reg_def VSR63 ( SOC, SOC, Op_VecX, 63, NULL); 324 325 // ---------------------------- 326 // Specify priority of register selection within phases of register 327 // allocation. Highest priority is first. A useful heuristic is to 328 // give registers a low priority when they are required by machine 329 // instructions, like EAX and EDX on I486, and choose no-save registers 330 // before save-on-call, & save-on-call before save-on-entry. Registers 331 // which participate in fixed calling sequences should come last. 332 // Registers which are used as pairs must fall on an even boundary. 333 334 // It's worth about 1% on SPEC geomean to get this right. 335 336 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 337 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 338 // R3_num. Therefore, R3_num may not be (and in reality is not) 339 // the same as R3->encoding()! Furthermore, we cannot make any 340 // assumptions on ordering, e.g. R3_num may be less than R2_num. 341 // Additionally, the function 342 // static enum RC rc_class(OptoReg::Name reg ) 343 // maps a given <register>_num value to its chunk type (except for flags) 344 // and its current implementation relies on chunk0 and chunk1 having a 345 // size of 64 each. 346 347 // If you change this allocation class, please have a look at the 348 // default values for the parameters RoundRobinIntegerRegIntervalStart 349 // and RoundRobinFloatRegIntervalStart 350 351 alloc_class chunk0 ( 352 // Chunk0 contains *all* 64 integer registers halves. 353 354 // "non-volatile" registers 355 R14, R14_H, 356 R15, R15_H, 357 R17, R17_H, 358 R18, R18_H, 359 R19, R19_H, 360 R20, R20_H, 361 R21, R21_H, 362 R22, R22_H, 363 R23, R23_H, 364 R24, R24_H, 365 R25, R25_H, 366 R26, R26_H, 367 R27, R27_H, 368 R28, R28_H, 369 R29, R29_H, 370 R30, R30_H, 371 R31, R31_H, 372 373 // scratch/special registers 374 R11, R11_H, 375 R12, R12_H, 376 377 // argument registers 378 R10, R10_H, 379 R9, R9_H, 380 R8, R8_H, 381 R7, R7_H, 382 R6, R6_H, 383 R5, R5_H, 384 R4, R4_H, 385 R3, R3_H, 386 387 // special registers, not available for allocation 388 R16, R16_H, // R16_thread 389 R13, R13_H, // system thread id 390 R2, R2_H, // may be used for TOC 391 R1, R1_H, // SP 392 R0, R0_H // R0 (scratch) 393 ); 394 395 // If you change this allocation class, please have a look at the 396 // default values for the parameters RoundRobinIntegerRegIntervalStart 397 // and RoundRobinFloatRegIntervalStart 398 399 alloc_class chunk1 ( 400 // Chunk1 contains *all* 64 floating-point registers halves. 401 402 // scratch register 403 F0, F0_H, 404 405 // argument registers 406 F13, F13_H, 407 F12, F12_H, 408 F11, F11_H, 409 F10, F10_H, 410 F9, F9_H, 411 F8, F8_H, 412 F7, F7_H, 413 F6, F6_H, 414 F5, F5_H, 415 F4, F4_H, 416 F3, F3_H, 417 F2, F2_H, 418 F1, F1_H, 419 420 // non-volatile registers 421 F14, F14_H, 422 F15, F15_H, 423 F16, F16_H, 424 F17, F17_H, 425 F18, F18_H, 426 F19, F19_H, 427 F20, F20_H, 428 F21, F21_H, 429 F22, F22_H, 430 F23, F23_H, 431 F24, F24_H, 432 F25, F25_H, 433 F26, F26_H, 434 F27, F27_H, 435 F28, F28_H, 436 F29, F29_H, 437 F30, F30_H, 438 F31, F31_H 439 ); 440 441 alloc_class chunk2 ( 442 // Chunk2 contains *all* 8 condition code registers. 443 444 CCR0, 445 CCR1, 446 CCR2, 447 CCR3, 448 CCR4, 449 CCR5, 450 CCR6, 451 CCR7 452 ); 453 454 alloc_class chunk3 ( 455 VSR0, 456 VSR1, 457 VSR2, 458 VSR3, 459 VSR4, 460 VSR5, 461 VSR6, 462 VSR7, 463 VSR8, 464 VSR9, 465 VSR10, 466 VSR11, 467 VSR12, 468 VSR13, 469 VSR14, 470 VSR15, 471 VSR16, 472 VSR17, 473 VSR18, 474 VSR19, 475 VSR20, 476 VSR21, 477 VSR22, 478 VSR23, 479 VSR24, 480 VSR25, 481 VSR26, 482 VSR27, 483 VSR28, 484 VSR29, 485 VSR30, 486 VSR31, 487 VSR32, 488 VSR33, 489 VSR34, 490 VSR35, 491 VSR36, 492 VSR37, 493 VSR38, 494 VSR39, 495 VSR40, 496 VSR41, 497 VSR42, 498 VSR43, 499 VSR44, 500 VSR45, 501 VSR46, 502 VSR47, 503 VSR48, 504 VSR49, 505 VSR50, 506 VSR51, 507 VSR52, 508 VSR53, 509 VSR54, 510 VSR55, 511 VSR56, 512 VSR57, 513 VSR58, 514 VSR59, 515 VSR60, 516 VSR61, 517 VSR62, 518 VSR63 519 ); 520 521 alloc_class chunk4 ( 522 // special registers 523 // These registers are not allocated, but used for nodes generated by postalloc expand. 524 SR_XER, 525 SR_LR, 526 SR_CTR, 527 SR_VRSAVE, 528 SR_SPEFSCR, 529 SR_PPR 530 ); 531 532 //-------Architecture Description Register Classes----------------------- 533 534 // Several register classes are automatically defined based upon 535 // information in this architecture description. 536 537 // 1) reg_class inline_cache_reg ( as defined in frame section ) 538 // 2) reg_class compiler_method_oop_reg ( as defined in frame section ) 539 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 540 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 541 // 542 543 // ---------------------------- 544 // 32 Bit Register Classes 545 // ---------------------------- 546 547 // We specify registers twice, once as read/write, and once read-only. 548 // We use the read-only registers for source operands. With this, we 549 // can include preset read only registers in this class, as a hard-coded 550 // '0'-register. (We used to simulate this on ppc.) 551 552 // 32 bit registers that can be read and written i.e. these registers 553 // can be dest (or src) of normal instructions. 554 reg_class bits32_reg_rw( 555 /*R0*/ // R0 556 /*R1*/ // SP 557 R2, // TOC 558 R3, 559 R4, 560 R5, 561 R6, 562 R7, 563 R8, 564 R9, 565 R10, 566 R11, 567 R12, 568 /*R13*/ // system thread id 569 R14, 570 R15, 571 /*R16*/ // R16_thread 572 R17, 573 R18, 574 R19, 575 R20, 576 R21, 577 R22, 578 R23, 579 R24, 580 R25, 581 R26, 582 R27, 583 R28, 584 /*R29,*/ // global TOC 585 R30, 586 R31 587 ); 588 589 // 32 bit registers that can only be read i.e. these registers can 590 // only be src of all instructions. 591 reg_class bits32_reg_ro( 592 /*R0*/ // R0 593 /*R1*/ // SP 594 R2 // TOC 595 R3, 596 R4, 597 R5, 598 R6, 599 R7, 600 R8, 601 R9, 602 R10, 603 R11, 604 R12, 605 /*R13*/ // system thread id 606 R14, 607 R15, 608 /*R16*/ // R16_thread 609 R17, 610 R18, 611 R19, 612 R20, 613 R21, 614 R22, 615 R23, 616 R24, 617 R25, 618 R26, 619 R27, 620 R28, 621 /*R29,*/ 622 R30, 623 R31 624 ); 625 626 reg_class rscratch1_bits32_reg(R11); 627 reg_class rscratch2_bits32_reg(R12); 628 reg_class rarg1_bits32_reg(R3); 629 reg_class rarg2_bits32_reg(R4); 630 reg_class rarg3_bits32_reg(R5); 631 reg_class rarg4_bits32_reg(R6); 632 633 // ---------------------------- 634 // 64 Bit Register Classes 635 // ---------------------------- 636 // 64-bit build means 64-bit pointers means hi/lo pairs 637 638 reg_class rscratch1_bits64_reg(R11_H, R11); 639 reg_class rscratch2_bits64_reg(R12_H, R12); 640 reg_class rarg1_bits64_reg(R3_H, R3); 641 reg_class rarg2_bits64_reg(R4_H, R4); 642 reg_class rarg3_bits64_reg(R5_H, R5); 643 reg_class rarg4_bits64_reg(R6_H, R6); 644 // Thread register, 'written' by tlsLoadP, see there. 645 reg_class thread_bits64_reg(R16_H, R16); 646 647 reg_class r19_bits64_reg(R19_H, R19); 648 649 // 64 bit registers that can be read and written i.e. these registers 650 // can be dest (or src) of normal instructions. 651 reg_class bits64_reg_rw( 652 /*R0_H, R0*/ // R0 653 /*R1_H, R1*/ // SP 654 R2_H, R2, // TOC 655 R3_H, R3, 656 R4_H, R4, 657 R5_H, R5, 658 R6_H, R6, 659 R7_H, R7, 660 R8_H, R8, 661 R9_H, R9, 662 R10_H, R10, 663 R11_H, R11, 664 R12_H, R12, 665 /*R13_H, R13*/ // system thread id 666 R14_H, R14, 667 R15_H, R15, 668 /*R16_H, R16*/ // R16_thread 669 R17_H, R17, 670 R18_H, R18, 671 R19_H, R19, 672 R20_H, R20, 673 R21_H, R21, 674 R22_H, R22, 675 R23_H, R23, 676 R24_H, R24, 677 R25_H, R25, 678 R26_H, R26, 679 R27_H, R27, 680 R28_H, R28, 681 /*R29_H, R29,*/ 682 R30_H, R30, 683 R31_H, R31 684 ); 685 686 // 64 bit registers used excluding r2, r11 and r12 687 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses 688 // r2, r11 and r12 internally. 689 reg_class bits64_reg_leaf_call( 690 /*R0_H, R0*/ // R0 691 /*R1_H, R1*/ // SP 692 /*R2_H, R2*/ // TOC 693 R3_H, R3, 694 R4_H, R4, 695 R5_H, R5, 696 R6_H, R6, 697 R7_H, R7, 698 R8_H, R8, 699 R9_H, R9, 700 R10_H, R10, 701 /*R11_H, R11*/ 702 /*R12_H, R12*/ 703 /*R13_H, R13*/ // system thread id 704 R14_H, R14, 705 R15_H, R15, 706 /*R16_H, R16*/ // R16_thread 707 R17_H, R17, 708 R18_H, R18, 709 R19_H, R19, 710 R20_H, R20, 711 R21_H, R21, 712 R22_H, R22, 713 R23_H, R23, 714 R24_H, R24, 715 R25_H, R25, 716 R26_H, R26, 717 R27_H, R27, 718 R28_H, R28, 719 /*R29_H, R29,*/ 720 R30_H, R30, 721 R31_H, R31 722 ); 723 724 // Used to hold the TOC to avoid collisions with expanded DynamicCall 725 // which uses r19 as inline cache internally and expanded LeafCall which uses 726 // r2, r11 and r12 internally. 727 reg_class bits64_constant_table_base( 728 /*R0_H, R0*/ // R0 729 /*R1_H, R1*/ // SP 730 /*R2_H, R2*/ // TOC 731 R3_H, R3, 732 R4_H, R4, 733 R5_H, R5, 734 R6_H, R6, 735 R7_H, R7, 736 R8_H, R8, 737 R9_H, R9, 738 R10_H, R10, 739 /*R11_H, R11*/ 740 /*R12_H, R12*/ 741 /*R13_H, R13*/ // system thread id 742 R14_H, R14, 743 R15_H, R15, 744 /*R16_H, R16*/ // R16_thread 745 R17_H, R17, 746 R18_H, R18, 747 /*R19_H, R19*/ 748 R20_H, R20, 749 R21_H, R21, 750 R22_H, R22, 751 R23_H, R23, 752 R24_H, R24, 753 R25_H, R25, 754 R26_H, R26, 755 R27_H, R27, 756 R28_H, R28, 757 /*R29_H, R29,*/ 758 R30_H, R30, 759 R31_H, R31 760 ); 761 762 // 64 bit registers that can only be read i.e. these registers can 763 // only be src of all instructions. 764 reg_class bits64_reg_ro( 765 /*R0_H, R0*/ // R0 766 R1_H, R1, 767 R2_H, R2, // TOC 768 R3_H, R3, 769 R4_H, R4, 770 R5_H, R5, 771 R6_H, R6, 772 R7_H, R7, 773 R8_H, R8, 774 R9_H, R9, 775 R10_H, R10, 776 R11_H, R11, 777 R12_H, R12, 778 /*R13_H, R13*/ // system thread id 779 R14_H, R14, 780 R15_H, R15, 781 R16_H, R16, // R16_thread 782 R17_H, R17, 783 R18_H, R18, 784 R19_H, R19, 785 R20_H, R20, 786 R21_H, R21, 787 R22_H, R22, 788 R23_H, R23, 789 R24_H, R24, 790 R25_H, R25, 791 R26_H, R26, 792 R27_H, R27, 793 R28_H, R28, 794 /*R29_H, R29,*/ // TODO: let allocator handle TOC!! 795 R30_H, R30, 796 R31_H, R31 797 ); 798 799 800 // ---------------------------- 801 // Special Class for Condition Code Flags Register 802 803 reg_class int_flags( 804 /*CCR0*/ // scratch 805 /*CCR1*/ // scratch 806 /*CCR2*/ // nv! 807 /*CCR3*/ // nv! 808 /*CCR4*/ // nv! 809 CCR5, 810 CCR6, 811 CCR7 812 ); 813 814 reg_class int_flags_ro( 815 CCR0, 816 CCR1, 817 CCR2, 818 CCR3, 819 CCR4, 820 CCR5, 821 CCR6, 822 CCR7 823 ); 824 825 reg_class int_flags_CR0(CCR0); 826 reg_class int_flags_CR1(CCR1); 827 reg_class int_flags_CR6(CCR6); 828 reg_class ctr_reg(SR_CTR); 829 830 // ---------------------------- 831 // Float Register Classes 832 // ---------------------------- 833 834 reg_class flt_reg( 835 F0, 836 F1, 837 F2, 838 F3, 839 F4, 840 F5, 841 F6, 842 F7, 843 F8, 844 F9, 845 F10, 846 F11, 847 F12, 848 F13, 849 F14, // nv! 850 F15, // nv! 851 F16, // nv! 852 F17, // nv! 853 F18, // nv! 854 F19, // nv! 855 F20, // nv! 856 F21, // nv! 857 F22, // nv! 858 F23, // nv! 859 F24, // nv! 860 F25, // nv! 861 F26, // nv! 862 F27, // nv! 863 F28, // nv! 864 F29, // nv! 865 F30, // nv! 866 F31 // nv! 867 ); 868 869 // Double precision float registers have virtual `high halves' that 870 // are needed by the allocator. 871 reg_class dbl_reg( 872 F0, F0_H, 873 F1, F1_H, 874 F2, F2_H, 875 F3, F3_H, 876 F4, F4_H, 877 F5, F5_H, 878 F6, F6_H, 879 F7, F7_H, 880 F8, F8_H, 881 F9, F9_H, 882 F10, F10_H, 883 F11, F11_H, 884 F12, F12_H, 885 F13, F13_H, 886 F14, F14_H, // nv! 887 F15, F15_H, // nv! 888 F16, F16_H, // nv! 889 F17, F17_H, // nv! 890 F18, F18_H, // nv! 891 F19, F19_H, // nv! 892 F20, F20_H, // nv! 893 F21, F21_H, // nv! 894 F22, F22_H, // nv! 895 F23, F23_H, // nv! 896 F24, F24_H, // nv! 897 F25, F25_H, // nv! 898 F26, F26_H, // nv! 899 F27, F27_H, // nv! 900 F28, F28_H, // nv! 901 F29, F29_H, // nv! 902 F30, F30_H, // nv! 903 F31, F31_H // nv! 904 ); 905 906 // ---------------------------- 907 // Vector-Scalar Register Class 908 // ---------------------------- 909 910 reg_class vs_reg( 911 VSR32, 912 VSR33, 913 VSR34, 914 VSR35, 915 VSR36, 916 VSR37, 917 VSR38, 918 VSR39, 919 VSR40, 920 VSR41, 921 VSR42, 922 VSR43, 923 VSR44, 924 VSR45, 925 VSR46, 926 VSR47, 927 VSR48, 928 VSR49, 929 VSR50, 930 VSR51 931 // VSR52, // nv! 932 // VSR53, // nv! 933 // VSR54, // nv! 934 // VSR55, // nv! 935 // VSR56, // nv! 936 // VSR57, // nv! 937 // VSR58, // nv! 938 // VSR59, // nv! 939 // VSR60, // nv! 940 // VSR61, // nv! 941 // VSR62, // nv! 942 // VSR63 // nv! 943 ); 944 945 %} 946 947 //----------DEFINITION BLOCK--------------------------------------------------- 948 // Define name --> value mappings to inform the ADLC of an integer valued name 949 // Current support includes integer values in the range [0, 0x7FFFFFFF] 950 // Format: 951 // int_def <name> ( <int_value>, <expression>); 952 // Generated Code in ad_<arch>.hpp 953 // #define <name> (<expression>) 954 // // value == <int_value> 955 // Generated code in ad_<arch>.cpp adlc_verification() 956 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 957 // 958 definitions %{ 959 // The default cost (of an ALU instruction). 960 int_def DEFAULT_COST_LOW ( 30, 30); 961 int_def DEFAULT_COST ( 100, 100); 962 int_def HUGE_COST (1000000, 1000000); 963 964 // Memory refs 965 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 966 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 967 968 // Branches are even more expensive. 969 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 970 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 971 %} 972 973 974 //----------SOURCE BLOCK------------------------------------------------------- 975 // This is a block of C++ code which provides values, functions, and 976 // definitions necessary in the rest of the architecture description. 977 source_hpp %{ 978 // Header information of the source block. 979 // Method declarations/definitions which are used outside 980 // the ad-scope can conveniently be defined here. 981 // 982 // To keep related declarations/definitions/uses close together, 983 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 984 985 // Returns true if Node n is followed by a MemBar node that 986 // will do an acquire. If so, this node must not do the acquire 987 // operation. 988 bool followed_by_acquire(const Node *n); 989 %} 990 991 source %{ 992 993 // Should the Matcher clone shifts on addressing modes, expecting them 994 // to be subsumed into complex addressing expressions or compute them 995 // into registers? 996 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 997 return clone_base_plus_offset_address(m, mstack, address_visited); 998 } 999 1000 void Compile::reshape_address(AddPNode* addp) { 1001 } 1002 1003 // Optimize load-acquire. 1004 // 1005 // Check if acquire is unnecessary due to following operation that does 1006 // acquire anyways. 1007 // Walk the pattern: 1008 // 1009 // n: Load.acq 1010 // | 1011 // MemBarAcquire 1012 // | | 1013 // Proj(ctrl) Proj(mem) 1014 // | | 1015 // MemBarRelease/Volatile 1016 // 1017 bool followed_by_acquire(const Node *load) { 1018 assert(load->is_Load(), "So far implemented only for loads."); 1019 1020 // Find MemBarAcquire. 1021 const Node *mba = NULL; 1022 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 1023 const Node *out = load->fast_out(i); 1024 if (out->Opcode() == Op_MemBarAcquire) { 1025 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 1026 mba = out; 1027 break; 1028 } 1029 } 1030 if (!mba) return false; 1031 1032 // Find following MemBar node. 1033 // 1034 // The following node must be reachable by control AND memory 1035 // edge to assure no other operations are in between the two nodes. 1036 // 1037 // So first get the Proj node, mem_proj, to use it to iterate forward. 1038 Node *mem_proj = NULL; 1039 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 1040 mem_proj = mba->fast_out(i); // Runs out of bounds and asserts if Proj not found. 1041 assert(mem_proj->is_Proj(), "only projections here"); 1042 ProjNode *proj = mem_proj->as_Proj(); 1043 if (proj->_con == TypeFunc::Memory && 1044 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 1045 break; 1046 } 1047 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 1048 1049 // Search MemBar behind Proj. If there are other memory operations 1050 // behind the Proj we lost. 1051 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 1052 Node *x = mem_proj->fast_out(j); 1053 // Proj might have an edge to a store or load node which precedes the membar. 1054 if (x->is_Mem()) return false; 1055 1056 // On PPC64 release and volatile are implemented by an instruction 1057 // that also has acquire semantics. I.e. there is no need for an 1058 // acquire before these. 1059 int xop = x->Opcode(); 1060 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 1061 // Make sure we're not missing Call/Phi/MergeMem by checking 1062 // control edges. The control edge must directly lead back 1063 // to the MemBarAcquire 1064 Node *ctrl_proj = x->in(0); 1065 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 1066 return true; 1067 } 1068 } 1069 } 1070 1071 return false; 1072 } 1073 1074 #define __ _masm. 1075 1076 // Tertiary op of a LoadP or StoreP encoding. 1077 #define REGP_OP true 1078 1079 // **************************************************************************** 1080 1081 // REQUIRED FUNCTIONALITY 1082 1083 // !!!!! Special hack to get all type of calls to specify the byte offset 1084 // from the start of the call to the point where the return address 1085 // will point. 1086 1087 // PPC port: Removed use of lazy constant construct. 1088 1089 int MachCallStaticJavaNode::ret_addr_offset() { 1090 // It's only a single branch-and-link instruction. 1091 return 4; 1092 } 1093 1094 int MachCallDynamicJavaNode::ret_addr_offset() { 1095 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 1096 // postalloc expanded calls if we use inline caches and do not update method data. 1097 if (UseInlineCaches) 1098 return 4; 1099 1100 int vtable_index = this->_vtable_index; 1101 if (vtable_index < 0) { 1102 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 1103 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 1104 return 12; 1105 } else { 1106 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 1107 return 24; 1108 } 1109 } 1110 1111 int MachCallRuntimeNode::ret_addr_offset() { 1112 #if defined(ABI_ELFv2) 1113 return 28; 1114 #else 1115 return 40; 1116 #endif 1117 } 1118 1119 //============================================================================= 1120 1121 // condition code conversions 1122 1123 static int cc_to_boint(int cc) { 1124 return Assembler::bcondCRbiIs0 | (cc & 8); 1125 } 1126 1127 static int cc_to_inverse_boint(int cc) { 1128 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 1129 } 1130 1131 static int cc_to_biint(int cc, int flags_reg) { 1132 return (flags_reg << 2) | (cc & 3); 1133 } 1134 1135 //============================================================================= 1136 1137 // Compute padding required for nodes which need alignment. The padding 1138 // is the number of bytes (not instructions) which will be inserted before 1139 // the instruction. The padding must match the size of a NOP instruction. 1140 1141 // Currently not used on this platform. 1142 1143 //============================================================================= 1144 1145 // Indicate if the safepoint node needs the polling page as an input. 1146 bool SafePointNode::needs_polling_address_input() { 1147 // The address is loaded from thread by a seperate node. 1148 return true; 1149 } 1150 1151 //============================================================================= 1152 1153 // Emit an interrupt that is caught by the debugger (for debugging compiler). 1154 void emit_break(CodeBuffer &cbuf) { 1155 MacroAssembler _masm(&cbuf); 1156 __ illtrap(); 1157 } 1158 1159 #ifndef PRODUCT 1160 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1161 st->print("BREAKPOINT"); 1162 } 1163 #endif 1164 1165 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1166 emit_break(cbuf); 1167 } 1168 1169 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1170 return MachNode::size(ra_); 1171 } 1172 1173 //============================================================================= 1174 1175 void emit_nop(CodeBuffer &cbuf) { 1176 MacroAssembler _masm(&cbuf); 1177 __ nop(); 1178 } 1179 1180 static inline void emit_long(CodeBuffer &cbuf, int value) { 1181 *((int*)(cbuf.insts_end())) = value; 1182 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1183 } 1184 1185 //============================================================================= 1186 1187 %} // interrupt source 1188 1189 source_hpp %{ // Header information of the source block. 1190 1191 //-------------------------------------------------------------- 1192 //---< Used for optimization in Compile::Shorten_branches >--- 1193 //-------------------------------------------------------------- 1194 1195 class CallStubImpl { 1196 1197 public: 1198 1199 // Emit call stub, compiled java to interpreter. 1200 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1201 1202 // Size of call trampoline stub. 1203 // This doesn't need to be accurate to the byte, but it 1204 // must be larger than or equal to the real size of the stub. 1205 static uint size_call_trampoline() { 1206 return MacroAssembler::trampoline_stub_size; 1207 } 1208 1209 // number of relocations needed by a call trampoline stub 1210 static uint reloc_call_trampoline() { 1211 return 5; 1212 } 1213 1214 }; 1215 1216 %} // end source_hpp 1217 1218 source %{ 1219 1220 // Emit a trampoline stub for a call to a target which is too far away. 1221 // 1222 // code sequences: 1223 // 1224 // call-site: 1225 // branch-and-link to <destination> or <trampoline stub> 1226 // 1227 // Related trampoline stub for this call-site in the stub section: 1228 // load the call target from the constant pool 1229 // branch via CTR (LR/link still points to the call-site above) 1230 1231 void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1232 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1233 if (stub == NULL) { 1234 ciEnv::current()->record_out_of_memory_failure(); 1235 } 1236 } 1237 1238 //============================================================================= 1239 1240 // Emit an inline branch-and-link call and a related trampoline stub. 1241 // 1242 // code sequences: 1243 // 1244 // call-site: 1245 // branch-and-link to <destination> or <trampoline stub> 1246 // 1247 // Related trampoline stub for this call-site in the stub section: 1248 // load the call target from the constant pool 1249 // branch via CTR (LR/link still points to the call-site above) 1250 // 1251 1252 typedef struct { 1253 int insts_call_instruction_offset; 1254 int ret_addr_offset; 1255 } EmitCallOffsets; 1256 1257 // Emit a branch-and-link instruction that branches to a trampoline. 1258 // - Remember the offset of the branch-and-link instruction. 1259 // - Add a relocation at the branch-and-link instruction. 1260 // - Emit a branch-and-link. 1261 // - Remember the return pc offset. 1262 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1263 EmitCallOffsets offsets = { -1, -1 }; 1264 const int start_offset = __ offset(); 1265 offsets.insts_call_instruction_offset = __ offset(); 1266 1267 // No entry point given, use the current pc. 1268 if (entry_point == NULL) entry_point = __ pc(); 1269 1270 // Put the entry point as a constant into the constant pool. 1271 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1272 if (entry_point_toc_addr == NULL) { 1273 ciEnv::current()->record_out_of_memory_failure(); 1274 return offsets; 1275 } 1276 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1277 1278 // Emit the trampoline stub which will be related to the branch-and-link below. 1279 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1280 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1281 __ relocate(rtype); 1282 1283 // Note: At this point we do not have the address of the trampoline 1284 // stub, and the entry point might be too far away for bl, so __ pc() 1285 // serves as dummy and the bl will be patched later. 1286 __ bl((address) __ pc()); 1287 1288 offsets.ret_addr_offset = __ offset() - start_offset; 1289 1290 return offsets; 1291 } 1292 1293 //============================================================================= 1294 1295 // Factory for creating loadConL* nodes for large/small constant pool. 1296 1297 static inline jlong replicate_immF(float con) { 1298 // Replicate float con 2 times and pack into vector. 1299 int val = *((int*)&con); 1300 jlong lval = val; 1301 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1302 return lval; 1303 } 1304 1305 //============================================================================= 1306 1307 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1308 int Compile::ConstantTable::calculate_table_base_offset() const { 1309 return 0; // absolute addressing, no offset 1310 } 1311 1312 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1313 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1314 iRegPdstOper *op_dst = new iRegPdstOper(); 1315 MachNode *m1 = new loadToc_hiNode(); 1316 MachNode *m2 = new loadToc_loNode(); 1317 1318 m1->add_req(NULL); 1319 m2->add_req(NULL, m1); 1320 m1->_opnds[0] = op_dst; 1321 m2->_opnds[0] = op_dst; 1322 m2->_opnds[1] = op_dst; 1323 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1324 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1325 nodes->push(m1); 1326 nodes->push(m2); 1327 } 1328 1329 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1330 // Is postalloc expanded. 1331 ShouldNotReachHere(); 1332 } 1333 1334 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1335 return 0; 1336 } 1337 1338 #ifndef PRODUCT 1339 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1340 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1341 } 1342 #endif 1343 1344 //============================================================================= 1345 1346 #ifndef PRODUCT 1347 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1348 Compile* C = ra_->C; 1349 const long framesize = C->frame_slots() << LogBytesPerInt; 1350 1351 st->print("PROLOG\n\t"); 1352 if (C->need_stack_bang(framesize)) { 1353 st->print("stack_overflow_check\n\t"); 1354 } 1355 1356 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1357 st->print("save return pc\n\t"); 1358 st->print("push frame %ld\n\t", -framesize); 1359 } 1360 } 1361 #endif 1362 1363 // Macro used instead of the common __ to emulate the pipes of PPC. 1364 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1365 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1366 // still no scheduling of this code is possible, the micro scheduler is aware of the 1367 // code and can update its internal data. The following mechanism is used to achieve this: 1368 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1369 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1370 #if 0 // TODO: PPC port 1371 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1372 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1373 _masm. 1374 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1375 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1376 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1377 C->hb_scheduling()->_pdScheduling->advance_offset 1378 #else 1379 #define ___(op) if (UsePower6SchedulerPPC64) \ 1380 Unimplemented(); \ 1381 _masm. 1382 #define ___stop if (UsePower6SchedulerPPC64) \ 1383 Unimplemented() 1384 #define ___advance if (UsePower6SchedulerPPC64) \ 1385 Unimplemented() 1386 #endif 1387 1388 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1389 Compile* C = ra_->C; 1390 MacroAssembler _masm(&cbuf); 1391 1392 const long framesize = C->frame_size_in_bytes(); 1393 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1394 1395 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1396 1397 const Register return_pc = R20; // Must match return_addr() in frame section. 1398 const Register callers_sp = R21; 1399 const Register push_frame_temp = R22; 1400 const Register toc_temp = R23; 1401 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1402 1403 if (method_is_frameless) { 1404 // Add nop at beginning of all frameless methods to prevent any 1405 // oop instructions from getting overwritten by make_not_entrant 1406 // (patching attempt would fail). 1407 ___(nop) nop(); 1408 } else { 1409 // Get return pc. 1410 ___(mflr) mflr(return_pc); 1411 } 1412 1413 // Calls to C2R adapters often do not accept exceptional returns. 1414 // We require that their callers must bang for them. But be 1415 // careful, because some VM calls (such as call site linkage) can 1416 // use several kilobytes of stack. But the stack safety zone should 1417 // account for that. See bugs 4446381, 4468289, 4497237. 1418 1419 int bangsize = C->bang_size_in_bytes(); 1420 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1421 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1422 // Unfortunately we cannot use the function provided in 1423 // assembler.cpp as we have to emulate the pipes. So I had to 1424 // insert the code of generate_stack_overflow_check(), see 1425 // assembler.cpp for some illuminative comments. 1426 const int page_size = os::vm_page_size(); 1427 int bang_end = JavaThread::stack_shadow_zone_size(); 1428 1429 // This is how far the previous frame's stack banging extended. 1430 const int bang_end_safe = bang_end; 1431 1432 if (bangsize > page_size) { 1433 bang_end += bangsize; 1434 } 1435 1436 int bang_offset = bang_end_safe; 1437 1438 while (bang_offset <= bang_end) { 1439 // Need at least one stack bang at end of shadow zone. 1440 1441 // Again I had to copy code, this time from assembler_ppc.cpp, 1442 // bang_stack_with_offset - see there for comments. 1443 1444 // Stack grows down, caller passes positive offset. 1445 assert(bang_offset > 0, "must bang with positive offset"); 1446 1447 long stdoffset = -bang_offset; 1448 1449 if (Assembler::is_simm(stdoffset, 16)) { 1450 // Signed 16 bit offset, a simple std is ok. 1451 if (UseLoadInstructionsForStackBangingPPC64) { 1452 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1453 } else { 1454 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1455 } 1456 } else if (Assembler::is_simm(stdoffset, 31)) { 1457 // Use largeoffset calculations for addis & ld/std. 1458 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1459 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1460 1461 Register tmp = R11; 1462 ___(addis) addis(tmp, R1_SP, hi); 1463 if (UseLoadInstructionsForStackBangingPPC64) { 1464 ___(ld) ld(R0, lo, tmp); 1465 } else { 1466 ___(std) std(R0, lo, tmp); 1467 } 1468 } else { 1469 ShouldNotReachHere(); 1470 } 1471 1472 bang_offset += page_size; 1473 } 1474 // R11 trashed 1475 } // C->need_stack_bang(framesize) && UseStackBanging 1476 1477 unsigned int bytes = (unsigned int)framesize; 1478 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1479 ciMethod *currMethod = C->method(); 1480 1481 // Optimized version for most common case. 1482 if (UsePower6SchedulerPPC64 && 1483 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1484 !(false /* ConstantsALot TODO: PPC port*/)) { 1485 ___(or) mr(callers_sp, R1_SP); 1486 ___(std) std(return_pc, _abi(lr), R1_SP); 1487 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1488 return; 1489 } 1490 1491 if (!method_is_frameless) { 1492 // Get callers sp. 1493 ___(or) mr(callers_sp, R1_SP); 1494 1495 // Push method's frame, modifies SP. 1496 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1497 // The ABI is already accounted for in 'framesize' via the 1498 // 'out_preserve' area. 1499 Register tmp = push_frame_temp; 1500 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1501 if (Assembler::is_simm(-offset, 16)) { 1502 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1503 } else { 1504 long x = -offset; 1505 // Had to insert load_const(tmp, -offset). 1506 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1507 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1508 ___(rldicr) sldi(tmp, tmp, 32); 1509 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1510 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1511 1512 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1513 } 1514 } 1515 #if 0 // TODO: PPC port 1516 // For testing large constant pools, emit a lot of constants to constant pool. 1517 // "Randomize" const_size. 1518 if (ConstantsALot) { 1519 const int num_consts = const_size(); 1520 for (int i = 0; i < num_consts; i++) { 1521 __ long_constant(0xB0B5B00BBABE); 1522 } 1523 } 1524 #endif 1525 if (!method_is_frameless) { 1526 // Save return pc. 1527 ___(std) std(return_pc, _abi(lr), callers_sp); 1528 } 1529 1530 C->set_frame_complete(cbuf.insts_size()); 1531 } 1532 #undef ___ 1533 #undef ___stop 1534 #undef ___advance 1535 1536 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1537 // Variable size. determine dynamically. 1538 return MachNode::size(ra_); 1539 } 1540 1541 int MachPrologNode::reloc() const { 1542 // Return number of relocatable values contained in this instruction. 1543 return 1; // 1 reloc entry for load_const(toc). 1544 } 1545 1546 //============================================================================= 1547 1548 #ifndef PRODUCT 1549 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1550 Compile* C = ra_->C; 1551 1552 st->print("EPILOG\n\t"); 1553 st->print("restore return pc\n\t"); 1554 st->print("pop frame\n\t"); 1555 1556 if (do_polling() && C->is_method_compilation()) { 1557 st->print("touch polling page\n\t"); 1558 } 1559 } 1560 #endif 1561 1562 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1563 Compile* C = ra_->C; 1564 MacroAssembler _masm(&cbuf); 1565 1566 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1567 assert(framesize >= 0, "negative frame-size?"); 1568 1569 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1570 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1571 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1572 const Register polling_page = R12; 1573 1574 if (!method_is_frameless) { 1575 // Restore return pc relative to callers' sp. 1576 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1577 } 1578 1579 if (method_needs_polling) { 1580 if (SafepointMechanism::uses_thread_local_poll()) { 1581 __ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread); 1582 } else { 1583 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); 1584 } 1585 } 1586 1587 if (!method_is_frameless) { 1588 // Move return pc to LR. 1589 __ mtlr(return_pc); 1590 // Pop frame (fixed frame-size). 1591 __ addi(R1_SP, R1_SP, (int)framesize); 1592 } 1593 1594 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1595 __ reserved_stack_check(return_pc); 1596 } 1597 1598 if (method_needs_polling) { 1599 // We need to mark the code position where the load from the safepoint 1600 // polling page was emitted as relocInfo::poll_return_type here. 1601 __ relocate(relocInfo::poll_return_type); 1602 __ load_from_polling_page(polling_page); 1603 } 1604 } 1605 1606 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1607 // Variable size. Determine dynamically. 1608 return MachNode::size(ra_); 1609 } 1610 1611 int MachEpilogNode::reloc() const { 1612 // Return number of relocatable values contained in this instruction. 1613 return 1; // 1 for load_from_polling_page. 1614 } 1615 1616 const Pipeline * MachEpilogNode::pipeline() const { 1617 return MachNode::pipeline_class(); 1618 } 1619 1620 // This method seems to be obsolete. It is declared in machnode.hpp 1621 // and defined in all *.ad files, but it is never called. Should we 1622 // get rid of it? 1623 int MachEpilogNode::safepoint_offset() const { 1624 assert(do_polling(), "no return for this epilog node"); 1625 return 0; 1626 } 1627 1628 #if 0 // TODO: PPC port 1629 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1630 MacroAssembler _masm(&cbuf); 1631 if (LoadPollAddressFromThread) { 1632 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1633 } else { 1634 _masm.nop(); 1635 } 1636 } 1637 1638 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1639 if (LoadPollAddressFromThread) { 1640 return 4; 1641 } else { 1642 return 4; 1643 } 1644 } 1645 1646 #ifndef PRODUCT 1647 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1648 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1649 } 1650 #endif 1651 1652 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1653 return RSCRATCH1_BITS64_REG_mask(); 1654 } 1655 #endif // PPC port 1656 1657 // ============================================================================= 1658 1659 // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or 1660 // rc_stack. 1661 enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack }; 1662 1663 static enum RC rc_class(OptoReg::Name reg) { 1664 // Return the register class for the given register. The given register 1665 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1666 // enumeration in adGlobals_ppc.hpp. 1667 1668 if (reg == OptoReg::Bad) return rc_bad; 1669 1670 // We have 64 integer register halves, starting at index 0. 1671 if (reg < 64) return rc_int; 1672 1673 // We have 64 floating-point register halves, starting at index 64. 1674 if (reg < 64+64) return rc_float; 1675 1676 // We have 64 vector-scalar registers, starting at index 128. 1677 if (reg < 64+64+64) return rc_vs; 1678 1679 // Between float regs & stack are the flags regs. 1680 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1681 1682 return rc_stack; 1683 } 1684 1685 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1686 bool do_print, Compile* C, outputStream *st) { 1687 1688 assert(opcode == Assembler::LD_OPCODE || 1689 opcode == Assembler::STD_OPCODE || 1690 opcode == Assembler::LWZ_OPCODE || 1691 opcode == Assembler::STW_OPCODE || 1692 opcode == Assembler::LFD_OPCODE || 1693 opcode == Assembler::STFD_OPCODE || 1694 opcode == Assembler::LFS_OPCODE || 1695 opcode == Assembler::STFS_OPCODE, 1696 "opcode not supported"); 1697 1698 if (cbuf) { 1699 int d = 1700 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1701 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1702 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1703 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1704 } 1705 #ifndef PRODUCT 1706 else if (do_print) { 1707 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1708 op_str, 1709 Matcher::regName[reg], 1710 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1711 } 1712 #endif 1713 return 4; // size 1714 } 1715 1716 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1717 Compile* C = ra_->C; 1718 1719 // Get registers to move. 1720 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1721 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1722 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1723 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1724 1725 enum RC src_hi_rc = rc_class(src_hi); 1726 enum RC src_lo_rc = rc_class(src_lo); 1727 enum RC dst_hi_rc = rc_class(dst_hi); 1728 enum RC dst_lo_rc = rc_class(dst_lo); 1729 1730 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1731 if (src_hi != OptoReg::Bad) 1732 assert((src_lo&1)==0 && src_lo+1==src_hi && 1733 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1734 "expected aligned-adjacent pairs"); 1735 // Generate spill code! 1736 int size = 0; 1737 1738 if (src_lo == dst_lo && src_hi == dst_hi) 1739 return size; // Self copy, no move. 1740 1741 if (bottom_type()->isa_vect() != NULL && ideal_reg() == Op_VecX) { 1742 // Memory->Memory Spill. 1743 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1744 int src_offset = ra_->reg2offset(src_lo); 1745 int dst_offset = ra_->reg2offset(dst_lo); 1746 if (cbuf) { 1747 MacroAssembler _masm(cbuf); 1748 __ ld(R0, src_offset, R1_SP); 1749 __ std(R0, dst_offset, R1_SP); 1750 __ ld(R0, src_offset+8, R1_SP); 1751 __ std(R0, dst_offset+8, R1_SP); 1752 } 1753 size += 16; 1754 } 1755 // VectorSRegister->Memory Spill. 1756 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) { 1757 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1758 int dst_offset = ra_->reg2offset(dst_lo); 1759 if (cbuf) { 1760 MacroAssembler _masm(cbuf); 1761 __ addi(R0, R1_SP, dst_offset); 1762 __ stxvd2x(Rsrc, R0); 1763 } 1764 size += 8; 1765 } 1766 // Memory->VectorSRegister Spill. 1767 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) { 1768 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1769 int src_offset = ra_->reg2offset(src_lo); 1770 if (cbuf) { 1771 MacroAssembler _masm(cbuf); 1772 __ addi(R0, R1_SP, src_offset); 1773 __ lxvd2x(Rdst, R0); 1774 } 1775 size += 8; 1776 } 1777 // VectorSRegister->VectorSRegister. 1778 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) { 1779 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1780 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1781 if (cbuf) { 1782 MacroAssembler _masm(cbuf); 1783 __ xxlor(Rdst, Rsrc, Rsrc); 1784 } 1785 size += 4; 1786 } 1787 else { 1788 ShouldNotReachHere(); // No VSR spill. 1789 } 1790 return size; 1791 } 1792 1793 // -------------------------------------- 1794 // Memory->Memory Spill. Use R0 to hold the value. 1795 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1796 int src_offset = ra_->reg2offset(src_lo); 1797 int dst_offset = ra_->reg2offset(dst_lo); 1798 if (src_hi != OptoReg::Bad) { 1799 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1800 "expected same type of move for high parts"); 1801 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1802 if (!cbuf && !do_size) st->print("\n\t"); 1803 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1804 } else { 1805 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1806 if (!cbuf && !do_size) st->print("\n\t"); 1807 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1808 } 1809 return size; 1810 } 1811 1812 // -------------------------------------- 1813 // Check for float->int copy; requires a trip through memory. 1814 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1815 Unimplemented(); 1816 } 1817 1818 // -------------------------------------- 1819 // Check for integer reg-reg copy. 1820 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1821 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1822 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1823 size = (Rsrc != Rdst) ? 4 : 0; 1824 1825 if (cbuf) { 1826 MacroAssembler _masm(cbuf); 1827 if (size) { 1828 __ mr(Rdst, Rsrc); 1829 } 1830 } 1831 #ifndef PRODUCT 1832 else if (!do_size) { 1833 if (size) { 1834 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1835 } else { 1836 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1837 } 1838 } 1839 #endif 1840 return size; 1841 } 1842 1843 // Check for integer store. 1844 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1845 int dst_offset = ra_->reg2offset(dst_lo); 1846 if (src_hi != OptoReg::Bad) { 1847 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1848 "expected same type of move for high parts"); 1849 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1850 } else { 1851 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1852 } 1853 return size; 1854 } 1855 1856 // Check for integer load. 1857 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1858 int src_offset = ra_->reg2offset(src_lo); 1859 if (src_hi != OptoReg::Bad) { 1860 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1861 "expected same type of move for high parts"); 1862 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1863 } else { 1864 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1865 } 1866 return size; 1867 } 1868 1869 // Check for float reg-reg copy. 1870 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1871 if (cbuf) { 1872 MacroAssembler _masm(cbuf); 1873 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1874 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1875 __ fmr(Rdst, Rsrc); 1876 } 1877 #ifndef PRODUCT 1878 else if (!do_size) { 1879 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1880 } 1881 #endif 1882 return 4; 1883 } 1884 1885 // Check for float store. 1886 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1887 int dst_offset = ra_->reg2offset(dst_lo); 1888 if (src_hi != OptoReg::Bad) { 1889 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1890 "expected same type of move for high parts"); 1891 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1892 } else { 1893 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1894 } 1895 return size; 1896 } 1897 1898 // Check for float load. 1899 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1900 int src_offset = ra_->reg2offset(src_lo); 1901 if (src_hi != OptoReg::Bad) { 1902 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1903 "expected same type of move for high parts"); 1904 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1905 } else { 1906 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1907 } 1908 return size; 1909 } 1910 1911 // -------------------------------------------------------------------- 1912 // Check for hi bits still needing moving. Only happens for misaligned 1913 // arguments to native calls. 1914 if (src_hi == dst_hi) 1915 return size; // Self copy; no move. 1916 1917 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1918 ShouldNotReachHere(); // Unimplemented 1919 return 0; 1920 } 1921 1922 #ifndef PRODUCT 1923 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1924 if (!ra_) 1925 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1926 else 1927 implementation(NULL, ra_, false, st); 1928 } 1929 #endif 1930 1931 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1932 implementation(&cbuf, ra_, false, NULL); 1933 } 1934 1935 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1936 return implementation(NULL, ra_, true, NULL); 1937 } 1938 1939 #if 0 // TODO: PPC port 1940 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1941 #ifndef PRODUCT 1942 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1943 #endif 1944 assert(ra_->node_regs_max_index() != 0, ""); 1945 1946 // Get registers to move. 1947 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1948 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1949 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1950 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1951 1952 enum RC src_lo_rc = rc_class(src_lo); 1953 enum RC dst_lo_rc = rc_class(dst_lo); 1954 1955 if (src_lo == dst_lo && src_hi == dst_hi) 1956 return ppc64Opcode_none; // Self copy, no move. 1957 1958 // -------------------------------------- 1959 // Memory->Memory Spill. Use R0 to hold the value. 1960 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1961 return ppc64Opcode_compound; 1962 } 1963 1964 // -------------------------------------- 1965 // Check for float->int copy; requires a trip through memory. 1966 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1967 Unimplemented(); 1968 } 1969 1970 // -------------------------------------- 1971 // Check for integer reg-reg copy. 1972 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1973 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1974 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1975 if (Rsrc == Rdst) { 1976 return ppc64Opcode_none; 1977 } else { 1978 return ppc64Opcode_or; 1979 } 1980 } 1981 1982 // Check for integer store. 1983 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1984 if (src_hi != OptoReg::Bad) { 1985 return ppc64Opcode_std; 1986 } else { 1987 return ppc64Opcode_stw; 1988 } 1989 } 1990 1991 // Check for integer load. 1992 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1993 if (src_hi != OptoReg::Bad) { 1994 return ppc64Opcode_ld; 1995 } else { 1996 return ppc64Opcode_lwz; 1997 } 1998 } 1999 2000 // Check for float reg-reg copy. 2001 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 2002 return ppc64Opcode_fmr; 2003 } 2004 2005 // Check for float store. 2006 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 2007 if (src_hi != OptoReg::Bad) { 2008 return ppc64Opcode_stfd; 2009 } else { 2010 return ppc64Opcode_stfs; 2011 } 2012 } 2013 2014 // Check for float load. 2015 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 2016 if (src_hi != OptoReg::Bad) { 2017 return ppc64Opcode_lfd; 2018 } else { 2019 return ppc64Opcode_lfs; 2020 } 2021 } 2022 2023 // -------------------------------------------------------------------- 2024 // Check for hi bits still needing moving. Only happens for misaligned 2025 // arguments to native calls. 2026 if (src_hi == dst_hi) { 2027 return ppc64Opcode_none; // Self copy; no move. 2028 } 2029 2030 ShouldNotReachHere(); 2031 return ppc64Opcode_undefined; 2032 } 2033 #endif // PPC port 2034 2035 #ifndef PRODUCT 2036 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2037 st->print("NOP \t// %d nops to pad for loops.", _count); 2038 } 2039 #endif 2040 2041 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 2042 MacroAssembler _masm(&cbuf); 2043 // _count contains the number of nops needed for padding. 2044 for (int i = 0; i < _count; i++) { 2045 __ nop(); 2046 } 2047 } 2048 2049 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 2050 return _count * 4; 2051 } 2052 2053 #ifndef PRODUCT 2054 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2055 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2056 char reg_str[128]; 2057 ra_->dump_register(this, reg_str); 2058 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 2059 } 2060 #endif 2061 2062 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2063 MacroAssembler _masm(&cbuf); 2064 2065 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2066 int reg = ra_->get_encode(this); 2067 2068 if (Assembler::is_simm(offset, 16)) { 2069 __ addi(as_Register(reg), R1, offset); 2070 } else { 2071 ShouldNotReachHere(); 2072 } 2073 } 2074 2075 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2076 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2077 return 4; 2078 } 2079 2080 #ifndef PRODUCT 2081 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2082 st->print_cr("---- MachUEPNode ----"); 2083 st->print_cr("..."); 2084 } 2085 #endif 2086 2087 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2088 // This is the unverified entry point. 2089 MacroAssembler _masm(&cbuf); 2090 2091 // Inline_cache contains a klass. 2092 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 2093 Register receiver_klass = R12_scratch2; // tmp 2094 2095 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 2096 assert(R11_scratch1 == R11, "need prologue scratch register"); 2097 2098 // Check for NULL argument if we don't have implicit null checks. 2099 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 2100 if (TrapBasedNullChecks) { 2101 __ trap_null_check(R3_ARG1); 2102 } else { 2103 Label valid; 2104 __ cmpdi(CCR0, R3_ARG1, 0); 2105 __ bne_predict_taken(CCR0, valid); 2106 // We have a null argument, branch to ic_miss_stub. 2107 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2108 relocInfo::runtime_call_type); 2109 __ bind(valid); 2110 } 2111 } 2112 // Assume argument is not NULL, load klass from receiver. 2113 __ load_klass(receiver_klass, R3_ARG1); 2114 2115 if (TrapBasedICMissChecks) { 2116 __ trap_ic_miss_check(receiver_klass, ic_klass); 2117 } else { 2118 Label valid; 2119 __ cmpd(CCR0, receiver_klass, ic_klass); 2120 __ beq_predict_taken(CCR0, valid); 2121 // We have an unexpected klass, branch to ic_miss_stub. 2122 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2123 relocInfo::runtime_call_type); 2124 __ bind(valid); 2125 } 2126 2127 // Argument is valid and klass is as expected, continue. 2128 } 2129 2130 #if 0 // TODO: PPC port 2131 // Optimize UEP code on z (save a load_const() call in main path). 2132 int MachUEPNode::ep_offset() { 2133 return 0; 2134 } 2135 #endif 2136 2137 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2138 // Variable size. Determine dynamically. 2139 return MachNode::size(ra_); 2140 } 2141 2142 //============================================================================= 2143 2144 %} // interrupt source 2145 2146 source_hpp %{ // Header information of the source block. 2147 2148 class HandlerImpl { 2149 2150 public: 2151 2152 static int emit_exception_handler(CodeBuffer &cbuf); 2153 static int emit_deopt_handler(CodeBuffer& cbuf); 2154 2155 static uint size_exception_handler() { 2156 // The exception_handler is a b64_patchable. 2157 return MacroAssembler::b64_patchable_size; 2158 } 2159 2160 static uint size_deopt_handler() { 2161 // The deopt_handler is a bl64_patchable. 2162 return MacroAssembler::bl64_patchable_size; 2163 } 2164 2165 }; 2166 2167 %} // end source_hpp 2168 2169 source %{ 2170 2171 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2172 MacroAssembler _masm(&cbuf); 2173 2174 address base = __ start_a_stub(size_exception_handler()); 2175 if (base == NULL) return 0; // CodeBuffer::expand failed 2176 2177 int offset = __ offset(); 2178 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2179 relocInfo::runtime_call_type); 2180 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2181 __ end_a_stub(); 2182 2183 return offset; 2184 } 2185 2186 // The deopt_handler is like the exception handler, but it calls to 2187 // the deoptimization blob instead of jumping to the exception blob. 2188 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2189 MacroAssembler _masm(&cbuf); 2190 2191 address base = __ start_a_stub(size_deopt_handler()); 2192 if (base == NULL) return 0; // CodeBuffer::expand failed 2193 2194 int offset = __ offset(); 2195 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2196 relocInfo::runtime_call_type); 2197 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2198 __ end_a_stub(); 2199 2200 return offset; 2201 } 2202 2203 //============================================================================= 2204 2205 // Use a frame slots bias for frameless methods if accessing the stack. 2206 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2207 if (as_Register(reg_enc) == R1_SP) { 2208 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2209 } 2210 return 0; 2211 } 2212 2213 const bool Matcher::match_rule_supported(int opcode) { 2214 if (!has_match_rule(opcode)) 2215 return false; 2216 2217 switch (opcode) { 2218 case Op_SqrtD: 2219 return VM_Version::has_fsqrt(); 2220 case Op_CountLeadingZerosI: 2221 case Op_CountLeadingZerosL: 2222 case Op_CountTrailingZerosI: 2223 case Op_CountTrailingZerosL: 2224 if (!UseCountLeadingZerosInstructionsPPC64) 2225 return false; 2226 break; 2227 2228 case Op_PopCountI: 2229 case Op_PopCountL: 2230 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2231 2232 case Op_StrComp: 2233 return SpecialStringCompareTo; 2234 case Op_StrEquals: 2235 return SpecialStringEquals; 2236 case Op_StrIndexOf: 2237 return SpecialStringIndexOf; 2238 case Op_StrIndexOfChar: 2239 return SpecialStringIndexOf; 2240 } 2241 2242 return true; // Per default match rules are supported. 2243 } 2244 2245 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2246 2247 // TODO 2248 // identify extra cases that we might want to provide match rules for 2249 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2250 bool ret_value = match_rule_supported(opcode); 2251 // Add rules here. 2252 2253 return ret_value; // Per default match rules are supported. 2254 } 2255 2256 const bool Matcher::has_predicated_vectors(void) { 2257 return false; 2258 } 2259 2260 const int Matcher::float_pressure(int default_pressure_threshold) { 2261 return default_pressure_threshold; 2262 } 2263 2264 int Matcher::regnum_to_fpu_offset(int regnum) { 2265 // No user for this method? 2266 Unimplemented(); 2267 return 999; 2268 } 2269 2270 const bool Matcher::convL2FSupported(void) { 2271 // fcfids can do the conversion (>= Power7). 2272 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2273 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2274 } 2275 2276 // Vector width in bytes. 2277 const int Matcher::vector_width_in_bytes(BasicType bt) { 2278 if (SuperwordUseVSX) { 2279 assert(MaxVectorSize == 16, ""); 2280 return 16; 2281 } else { 2282 assert(MaxVectorSize == 8, ""); 2283 return 8; 2284 } 2285 } 2286 2287 // Vector ideal reg. 2288 const uint Matcher::vector_ideal_reg(int size) { 2289 if (SuperwordUseVSX) { 2290 assert(MaxVectorSize == 16 && size == 16, ""); 2291 return Op_VecX; 2292 } else { 2293 assert(MaxVectorSize == 8 && size == 8, ""); 2294 return Op_RegL; 2295 } 2296 } 2297 2298 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2299 fatal("vector shift is not supported"); 2300 return Node::NotAMachineReg; 2301 } 2302 2303 // Limits on vector size (number of elements) loaded into vector. 2304 const int Matcher::max_vector_size(const BasicType bt) { 2305 assert(is_java_primitive(bt), "only primitive type vectors"); 2306 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2307 } 2308 2309 const int Matcher::min_vector_size(const BasicType bt) { 2310 return max_vector_size(bt); // Same as max. 2311 } 2312 2313 // PPC doesn't support misaligned vectors store/load. 2314 const bool Matcher::misaligned_vectors_ok() { 2315 return !AlignVector; // can be changed by flag 2316 } 2317 2318 // PPC AES support not yet implemented 2319 const bool Matcher::pass_original_key_for_aes() { 2320 return false; 2321 } 2322 2323 // RETURNS: whether this branch offset is short enough that a short 2324 // branch can be used. 2325 // 2326 // If the platform does not provide any short branch variants, then 2327 // this method should return `false' for offset 0. 2328 // 2329 // `Compile::Fill_buffer' will decide on basis of this information 2330 // whether to do the pass `Compile::Shorten_branches' at all. 2331 // 2332 // And `Compile::Shorten_branches' will decide on basis of this 2333 // information whether to replace particular branch sites by short 2334 // ones. 2335 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2336 // Is the offset within the range of a ppc64 pc relative branch? 2337 bool b; 2338 2339 const int safety_zone = 3 * BytesPerInstWord; 2340 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2341 29 - 16 + 1 + 2); 2342 return b; 2343 } 2344 2345 const bool Matcher::isSimpleConstant64(jlong value) { 2346 // Probably always true, even if a temp register is required. 2347 return true; 2348 } 2349 /* TODO: PPC port 2350 // Make a new machine dependent decode node (with its operands). 2351 MachTypeNode *Matcher::make_decode_node() { 2352 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2353 "This method is only implemented for unscaled cOops mode so far"); 2354 MachTypeNode *decode = new decodeN_unscaledNode(); 2355 decode->set_opnd_array(0, new iRegPdstOper()); 2356 decode->set_opnd_array(1, new iRegNsrcOper()); 2357 return decode; 2358 } 2359 */ 2360 2361 // false => size gets scaled to BytesPerLong, ok. 2362 const bool Matcher::init_array_count_is_in_bytes = false; 2363 2364 // Use conditional move (CMOVL) on Power7. 2365 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2366 2367 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2368 // fsel doesn't accept a condition register as input, so this would be slightly different. 2369 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2370 2371 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2372 const bool Matcher::require_postalloc_expand = true; 2373 2374 // Do we need to mask the count passed to shift instructions or does 2375 // the cpu only look at the lower 5/6 bits anyway? 2376 // PowerPC requires masked shift counts. 2377 const bool Matcher::need_masked_shift_count = true; 2378 2379 // This affects two different things: 2380 // - how Decode nodes are matched 2381 // - how ImplicitNullCheck opportunities are recognized 2382 // If true, the matcher will try to remove all Decodes and match them 2383 // (as operands) into nodes. NullChecks are not prepared to deal with 2384 // Decodes by final_graph_reshaping(). 2385 // If false, final_graph_reshaping() forces the decode behind the Cmp 2386 // for a NullCheck. The matcher matches the Decode node into a register. 2387 // Implicit_null_check optimization moves the Decode along with the 2388 // memory operation back up before the NullCheck. 2389 bool Matcher::narrow_oop_use_complex_address() { 2390 // TODO: PPC port if (MatchDecodeNodes) return true; 2391 return false; 2392 } 2393 2394 bool Matcher::narrow_klass_use_complex_address() { 2395 NOT_LP64(ShouldNotCallThis()); 2396 assert(UseCompressedClassPointers, "only for compressed klass code"); 2397 // TODO: PPC port if (MatchDecodeNodes) return true; 2398 return false; 2399 } 2400 2401 bool Matcher::const_oop_prefer_decode() { 2402 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2403 return Universe::narrow_oop_base() == NULL; 2404 } 2405 2406 bool Matcher::const_klass_prefer_decode() { 2407 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2408 return Universe::narrow_klass_base() == NULL; 2409 } 2410 2411 // Is it better to copy float constants, or load them directly from memory? 2412 // Intel can load a float constant from a direct address, requiring no 2413 // extra registers. Most RISCs will have to materialize an address into a 2414 // register first, so they would do better to copy the constant from stack. 2415 const bool Matcher::rematerialize_float_constants = false; 2416 2417 // If CPU can load and store mis-aligned doubles directly then no fixup is 2418 // needed. Else we split the double into 2 integer pieces and move it 2419 // piece-by-piece. Only happens when passing doubles into C code as the 2420 // Java calling convention forces doubles to be aligned. 2421 const bool Matcher::misaligned_doubles_ok = true; 2422 2423 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2424 Unimplemented(); 2425 } 2426 2427 // Advertise here if the CPU requires explicit rounding operations 2428 // to implement the UseStrictFP mode. 2429 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2430 2431 // Do floats take an entire double register or just half? 2432 // 2433 // A float occupies a ppc64 double register. For the allocator, a 2434 // ppc64 double register appears as a pair of float registers. 2435 bool Matcher::float_in_double() { return true; } 2436 2437 // Do ints take an entire long register or just half? 2438 // The relevant question is how the int is callee-saved: 2439 // the whole long is written but de-opt'ing will have to extract 2440 // the relevant 32 bits. 2441 const bool Matcher::int_in_long = true; 2442 2443 // Constants for c2c and c calling conventions. 2444 2445 const MachRegisterNumbers iarg_reg[8] = { 2446 R3_num, R4_num, R5_num, R6_num, 2447 R7_num, R8_num, R9_num, R10_num 2448 }; 2449 2450 const MachRegisterNumbers farg_reg[13] = { 2451 F1_num, F2_num, F3_num, F4_num, 2452 F5_num, F6_num, F7_num, F8_num, 2453 F9_num, F10_num, F11_num, F12_num, 2454 F13_num 2455 }; 2456 2457 const MachRegisterNumbers vsarg_reg[64] = { 2458 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2459 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2460 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2461 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2462 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2463 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2464 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2465 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2466 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2467 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2468 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2469 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2470 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2471 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2472 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2473 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2474 }; 2475 2476 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2477 2478 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2479 2480 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2481 2482 // Return whether or not this register is ever used as an argument. This 2483 // function is used on startup to build the trampoline stubs in generateOptoStub. 2484 // Registers not mentioned will be killed by the VM call in the trampoline, and 2485 // arguments in those registers not be available to the callee. 2486 bool Matcher::can_be_java_arg(int reg) { 2487 // We return true for all registers contained in iarg_reg[] and 2488 // farg_reg[] and their virtual halves. 2489 // We must include the virtual halves in order to get STDs and LDs 2490 // instead of STWs and LWs in the trampoline stubs. 2491 2492 if ( reg == R3_num || reg == R3_H_num 2493 || reg == R4_num || reg == R4_H_num 2494 || reg == R5_num || reg == R5_H_num 2495 || reg == R6_num || reg == R6_H_num 2496 || reg == R7_num || reg == R7_H_num 2497 || reg == R8_num || reg == R8_H_num 2498 || reg == R9_num || reg == R9_H_num 2499 || reg == R10_num || reg == R10_H_num) 2500 return true; 2501 2502 if ( reg == F1_num || reg == F1_H_num 2503 || reg == F2_num || reg == F2_H_num 2504 || reg == F3_num || reg == F3_H_num 2505 || reg == F4_num || reg == F4_H_num 2506 || reg == F5_num || reg == F5_H_num 2507 || reg == F6_num || reg == F6_H_num 2508 || reg == F7_num || reg == F7_H_num 2509 || reg == F8_num || reg == F8_H_num 2510 || reg == F9_num || reg == F9_H_num 2511 || reg == F10_num || reg == F10_H_num 2512 || reg == F11_num || reg == F11_H_num 2513 || reg == F12_num || reg == F12_H_num 2514 || reg == F13_num || reg == F13_H_num) 2515 return true; 2516 2517 return false; 2518 } 2519 2520 bool Matcher::is_spillable_arg(int reg) { 2521 return can_be_java_arg(reg); 2522 } 2523 2524 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2525 return false; 2526 } 2527 2528 // Register for DIVI projection of divmodI. 2529 RegMask Matcher::divI_proj_mask() { 2530 ShouldNotReachHere(); 2531 return RegMask(); 2532 } 2533 2534 // Register for MODI projection of divmodI. 2535 RegMask Matcher::modI_proj_mask() { 2536 ShouldNotReachHere(); 2537 return RegMask(); 2538 } 2539 2540 // Register for DIVL projection of divmodL. 2541 RegMask Matcher::divL_proj_mask() { 2542 ShouldNotReachHere(); 2543 return RegMask(); 2544 } 2545 2546 // Register for MODL projection of divmodL. 2547 RegMask Matcher::modL_proj_mask() { 2548 ShouldNotReachHere(); 2549 return RegMask(); 2550 } 2551 2552 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2553 return RegMask(); 2554 } 2555 2556 const bool Matcher::convi2l_type_required = true; 2557 2558 %} 2559 2560 //----------ENCODING BLOCK----------------------------------------------------- 2561 // This block specifies the encoding classes used by the compiler to output 2562 // byte streams. Encoding classes are parameterized macros used by 2563 // Machine Instruction Nodes in order to generate the bit encoding of the 2564 // instruction. Operands specify their base encoding interface with the 2565 // interface keyword. There are currently supported four interfaces, 2566 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2567 // operand to generate a function which returns its register number when 2568 // queried. CONST_INTER causes an operand to generate a function which 2569 // returns the value of the constant when queried. MEMORY_INTER causes an 2570 // operand to generate four functions which return the Base Register, the 2571 // Index Register, the Scale Value, and the Offset Value of the operand when 2572 // queried. COND_INTER causes an operand to generate six functions which 2573 // return the encoding code (ie - encoding bits for the instruction) 2574 // associated with each basic boolean condition for a conditional instruction. 2575 // 2576 // Instructions specify two basic values for encoding. Again, a function 2577 // is available to check if the constant displacement is an oop. They use the 2578 // ins_encode keyword to specify their encoding classes (which must be 2579 // a sequence of enc_class names, and their parameters, specified in 2580 // the encoding block), and they use the 2581 // opcode keyword to specify, in order, their primary, secondary, and 2582 // tertiary opcode. Only the opcode sections which a particular instruction 2583 // needs for encoding need to be specified. 2584 encode %{ 2585 enc_class enc_unimplemented %{ 2586 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2587 MacroAssembler _masm(&cbuf); 2588 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2589 %} 2590 2591 enc_class enc_untested %{ 2592 #ifdef ASSERT 2593 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2594 MacroAssembler _masm(&cbuf); 2595 __ untested("Untested mach node encoding in AD file."); 2596 #else 2597 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2598 #endif 2599 %} 2600 2601 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2602 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2603 MacroAssembler _masm(&cbuf); 2604 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2605 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2606 %} 2607 2608 // Load acquire. 2609 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2610 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2611 MacroAssembler _masm(&cbuf); 2612 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2613 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2614 __ twi_0($dst$$Register); 2615 __ isync(); 2616 %} 2617 2618 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2619 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2620 2621 MacroAssembler _masm(&cbuf); 2622 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2623 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2624 %} 2625 2626 // Load acquire. 2627 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2628 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2629 2630 MacroAssembler _masm(&cbuf); 2631 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2632 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2633 __ twi_0($dst$$Register); 2634 __ isync(); 2635 %} 2636 2637 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2638 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2639 2640 MacroAssembler _masm(&cbuf); 2641 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2642 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2643 %} 2644 2645 // Load acquire. 2646 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2647 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2648 2649 MacroAssembler _masm(&cbuf); 2650 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2651 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2652 __ twi_0($dst$$Register); 2653 __ isync(); 2654 %} 2655 2656 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2657 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2658 MacroAssembler _masm(&cbuf); 2659 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2660 // Operand 'ds' requires 4-alignment. 2661 assert((Idisp & 0x3) == 0, "unaligned offset"); 2662 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2663 %} 2664 2665 // Load acquire. 2666 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2667 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2668 MacroAssembler _masm(&cbuf); 2669 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2670 // Operand 'ds' requires 4-alignment. 2671 assert((Idisp & 0x3) == 0, "unaligned offset"); 2672 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2673 __ twi_0($dst$$Register); 2674 __ isync(); 2675 %} 2676 2677 enc_class enc_lfd(RegF dst, memory mem) %{ 2678 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2679 MacroAssembler _masm(&cbuf); 2680 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2681 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2682 %} 2683 2684 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2685 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2686 2687 MacroAssembler _masm(&cbuf); 2688 int toc_offset = 0; 2689 2690 address const_toc_addr; 2691 // Create a non-oop constant, no relocation needed. 2692 // If it is an IC, it has a virtual_call_Relocation. 2693 const_toc_addr = __ long_constant((jlong)$src$$constant); 2694 if (const_toc_addr == NULL) { 2695 ciEnv::current()->record_out_of_memory_failure(); 2696 return; 2697 } 2698 2699 // Get the constant's TOC offset. 2700 toc_offset = __ offset_to_method_toc(const_toc_addr); 2701 2702 // Keep the current instruction offset in mind. 2703 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2704 2705 __ ld($dst$$Register, toc_offset, $toc$$Register); 2706 %} 2707 2708 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2709 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2710 2711 MacroAssembler _masm(&cbuf); 2712 2713 if (!ra_->C->in_scratch_emit_size()) { 2714 address const_toc_addr; 2715 // Create a non-oop constant, no relocation needed. 2716 // If it is an IC, it has a virtual_call_Relocation. 2717 const_toc_addr = __ long_constant((jlong)$src$$constant); 2718 if (const_toc_addr == NULL) { 2719 ciEnv::current()->record_out_of_memory_failure(); 2720 return; 2721 } 2722 2723 // Get the constant's TOC offset. 2724 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2725 // Store the toc offset of the constant. 2726 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2727 2728 // Also keep the current instruction offset in mind. 2729 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2730 } 2731 2732 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2733 %} 2734 2735 %} // encode 2736 2737 source %{ 2738 2739 typedef struct { 2740 loadConL_hiNode *_large_hi; 2741 loadConL_loNode *_large_lo; 2742 loadConLNode *_small; 2743 MachNode *_last; 2744 } loadConLNodesTuple; 2745 2746 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2747 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2748 loadConLNodesTuple nodes; 2749 2750 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2751 if (large_constant_pool) { 2752 // Create new nodes. 2753 loadConL_hiNode *m1 = new loadConL_hiNode(); 2754 loadConL_loNode *m2 = new loadConL_loNode(); 2755 2756 // inputs for new nodes 2757 m1->add_req(NULL, toc); 2758 m2->add_req(NULL, m1); 2759 2760 // operands for new nodes 2761 m1->_opnds[0] = new iRegLdstOper(); // dst 2762 m1->_opnds[1] = immSrc; // src 2763 m1->_opnds[2] = new iRegPdstOper(); // toc 2764 m2->_opnds[0] = new iRegLdstOper(); // dst 2765 m2->_opnds[1] = immSrc; // src 2766 m2->_opnds[2] = new iRegLdstOper(); // base 2767 2768 // Initialize ins_attrib TOC fields. 2769 m1->_const_toc_offset = -1; 2770 m2->_const_toc_offset_hi_node = m1; 2771 2772 // Initialize ins_attrib instruction offset. 2773 m1->_cbuf_insts_offset = -1; 2774 2775 // register allocation for new nodes 2776 ra_->set_pair(m1->_idx, reg_second, reg_first); 2777 ra_->set_pair(m2->_idx, reg_second, reg_first); 2778 2779 // Create result. 2780 nodes._large_hi = m1; 2781 nodes._large_lo = m2; 2782 nodes._small = NULL; 2783 nodes._last = nodes._large_lo; 2784 assert(m2->bottom_type()->isa_long(), "must be long"); 2785 } else { 2786 loadConLNode *m2 = new loadConLNode(); 2787 2788 // inputs for new nodes 2789 m2->add_req(NULL, toc); 2790 2791 // operands for new nodes 2792 m2->_opnds[0] = new iRegLdstOper(); // dst 2793 m2->_opnds[1] = immSrc; // src 2794 m2->_opnds[2] = new iRegPdstOper(); // toc 2795 2796 // Initialize ins_attrib instruction offset. 2797 m2->_cbuf_insts_offset = -1; 2798 2799 // register allocation for new nodes 2800 ra_->set_pair(m2->_idx, reg_second, reg_first); 2801 2802 // Create result. 2803 nodes._large_hi = NULL; 2804 nodes._large_lo = NULL; 2805 nodes._small = m2; 2806 nodes._last = nodes._small; 2807 assert(m2->bottom_type()->isa_long(), "must be long"); 2808 } 2809 2810 return nodes; 2811 } 2812 2813 typedef struct { 2814 loadConL_hiNode *_large_hi; 2815 loadConL_loNode *_large_lo; 2816 mtvsrdNode *_moved; 2817 xxspltdNode *_replicated; 2818 loadConLNode *_small; 2819 MachNode *_last; 2820 } loadConLReplicatedNodesTuple; 2821 2822 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2823 vecXOper *dst, immI_0Oper *zero, 2824 OptoReg::Name reg_second, OptoReg::Name reg_first, 2825 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2826 loadConLReplicatedNodesTuple nodes; 2827 2828 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2829 if (large_constant_pool) { 2830 // Create new nodes. 2831 loadConL_hiNode *m1 = new loadConL_hiNode(); 2832 loadConL_loNode *m2 = new loadConL_loNode(); 2833 mtvsrdNode *m3 = new mtvsrdNode(); 2834 xxspltdNode *m4 = new xxspltdNode(); 2835 2836 // inputs for new nodes 2837 m1->add_req(NULL, toc); 2838 m2->add_req(NULL, m1); 2839 m3->add_req(NULL, m2); 2840 m4->add_req(NULL, m3); 2841 2842 // operands for new nodes 2843 m1->_opnds[0] = new iRegLdstOper(); // dst 2844 m1->_opnds[1] = immSrc; // src 2845 m1->_opnds[2] = new iRegPdstOper(); // toc 2846 2847 m2->_opnds[0] = new iRegLdstOper(); // dst 2848 m2->_opnds[1] = immSrc; // src 2849 m2->_opnds[2] = new iRegLdstOper(); // base 2850 2851 m3->_opnds[0] = new vecXOper(); // dst 2852 m3->_opnds[1] = new iRegLdstOper(); // src 2853 2854 m4->_opnds[0] = new vecXOper(); // dst 2855 m4->_opnds[1] = new vecXOper(); // src 2856 m4->_opnds[2] = zero; 2857 2858 // Initialize ins_attrib TOC fields. 2859 m1->_const_toc_offset = -1; 2860 m2->_const_toc_offset_hi_node = m1; 2861 2862 // Initialize ins_attrib instruction offset. 2863 m1->_cbuf_insts_offset = -1; 2864 2865 // register allocation for new nodes 2866 ra_->set_pair(m1->_idx, reg_second, reg_first); 2867 ra_->set_pair(m2->_idx, reg_second, reg_first); 2868 ra_->set1(m3->_idx, reg_second); 2869 ra_->set2(m3->_idx, reg_vec_first); 2870 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2871 2872 // Create result. 2873 nodes._large_hi = m1; 2874 nodes._large_lo = m2; 2875 nodes._moved = m3; 2876 nodes._replicated = m4; 2877 nodes._small = NULL; 2878 nodes._last = nodes._replicated; 2879 assert(m2->bottom_type()->isa_long(), "must be long"); 2880 } else { 2881 loadConLNode *m2 = new loadConLNode(); 2882 mtvsrdNode *m3 = new mtvsrdNode(); 2883 xxspltdNode *m4 = new xxspltdNode(); 2884 2885 // inputs for new nodes 2886 m2->add_req(NULL, toc); 2887 2888 // operands for new nodes 2889 m2->_opnds[0] = new iRegLdstOper(); // dst 2890 m2->_opnds[1] = immSrc; // src 2891 m2->_opnds[2] = new iRegPdstOper(); // toc 2892 2893 m3->_opnds[0] = new vecXOper(); // dst 2894 m3->_opnds[1] = new iRegLdstOper(); // src 2895 2896 m4->_opnds[0] = new vecXOper(); // dst 2897 m4->_opnds[1] = new vecXOper(); // src 2898 m4->_opnds[2] = zero; 2899 2900 // Initialize ins_attrib instruction offset. 2901 m2->_cbuf_insts_offset = -1; 2902 ra_->set1(m3->_idx, reg_second); 2903 ra_->set2(m3->_idx, reg_vec_first); 2904 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2905 2906 // register allocation for new nodes 2907 ra_->set_pair(m2->_idx, reg_second, reg_first); 2908 2909 // Create result. 2910 nodes._large_hi = NULL; 2911 nodes._large_lo = NULL; 2912 nodes._small = m2; 2913 nodes._moved = m3; 2914 nodes._replicated = m4; 2915 nodes._last = nodes._replicated; 2916 assert(m2->bottom_type()->isa_long(), "must be long"); 2917 } 2918 2919 return nodes; 2920 } 2921 2922 %} // source 2923 2924 encode %{ 2925 // Postalloc expand emitter for loading a long constant from the method's TOC. 2926 // Enc_class needed as consttanttablebase is not supported by postalloc 2927 // expand. 2928 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2929 // Create new nodes. 2930 loadConLNodesTuple loadConLNodes = 2931 loadConLNodesTuple_create(ra_, n_toc, op_src, 2932 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2933 2934 // Push new nodes. 2935 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2936 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2937 2938 // some asserts 2939 assert(nodes->length() >= 1, "must have created at least 1 node"); 2940 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2941 %} 2942 2943 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2944 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2945 2946 MacroAssembler _masm(&cbuf); 2947 int toc_offset = 0; 2948 2949 intptr_t val = $src$$constant; 2950 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2951 address const_toc_addr; 2952 if (constant_reloc == relocInfo::oop_type) { 2953 // Create an oop constant and a corresponding relocation. 2954 AddressLiteral a = __ allocate_oop_address((jobject)val); 2955 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2956 __ relocate(a.rspec()); 2957 } else if (constant_reloc == relocInfo::metadata_type) { 2958 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2959 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2960 __ relocate(a.rspec()); 2961 } else { 2962 // Create a non-oop constant, no relocation needed. 2963 const_toc_addr = __ long_constant((jlong)$src$$constant); 2964 } 2965 2966 if (const_toc_addr == NULL) { 2967 ciEnv::current()->record_out_of_memory_failure(); 2968 return; 2969 } 2970 // Get the constant's TOC offset. 2971 toc_offset = __ offset_to_method_toc(const_toc_addr); 2972 2973 __ ld($dst$$Register, toc_offset, $toc$$Register); 2974 %} 2975 2976 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2977 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2978 2979 MacroAssembler _masm(&cbuf); 2980 if (!ra_->C->in_scratch_emit_size()) { 2981 intptr_t val = $src$$constant; 2982 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2983 address const_toc_addr; 2984 if (constant_reloc == relocInfo::oop_type) { 2985 // Create an oop constant and a corresponding relocation. 2986 AddressLiteral a = __ allocate_oop_address((jobject)val); 2987 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2988 __ relocate(a.rspec()); 2989 } else if (constant_reloc == relocInfo::metadata_type) { 2990 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2991 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2992 __ relocate(a.rspec()); 2993 } else { // non-oop pointers, e.g. card mark base, heap top 2994 // Create a non-oop constant, no relocation needed. 2995 const_toc_addr = __ long_constant((jlong)$src$$constant); 2996 } 2997 2998 if (const_toc_addr == NULL) { 2999 ciEnv::current()->record_out_of_memory_failure(); 3000 return; 3001 } 3002 // Get the constant's TOC offset. 3003 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 3004 // Store the toc offset of the constant. 3005 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 3006 } 3007 3008 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 3009 %} 3010 3011 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 3012 // Enc_class needed as consttanttablebase is not supported by postalloc 3013 // expand. 3014 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 3015 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3016 if (large_constant_pool) { 3017 // Create new nodes. 3018 loadConP_hiNode *m1 = new loadConP_hiNode(); 3019 loadConP_loNode *m2 = new loadConP_loNode(); 3020 3021 // inputs for new nodes 3022 m1->add_req(NULL, n_toc); 3023 m2->add_req(NULL, m1); 3024 3025 // operands for new nodes 3026 m1->_opnds[0] = new iRegPdstOper(); // dst 3027 m1->_opnds[1] = op_src; // src 3028 m1->_opnds[2] = new iRegPdstOper(); // toc 3029 m2->_opnds[0] = new iRegPdstOper(); // dst 3030 m2->_opnds[1] = op_src; // src 3031 m2->_opnds[2] = new iRegLdstOper(); // base 3032 3033 // Initialize ins_attrib TOC fields. 3034 m1->_const_toc_offset = -1; 3035 m2->_const_toc_offset_hi_node = m1; 3036 3037 // Register allocation for new nodes. 3038 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3039 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3040 3041 nodes->push(m1); 3042 nodes->push(m2); 3043 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3044 } else { 3045 loadConPNode *m2 = new loadConPNode(); 3046 3047 // inputs for new nodes 3048 m2->add_req(NULL, n_toc); 3049 3050 // operands for new nodes 3051 m2->_opnds[0] = new iRegPdstOper(); // dst 3052 m2->_opnds[1] = op_src; // src 3053 m2->_opnds[2] = new iRegPdstOper(); // toc 3054 3055 // Register allocation for new nodes. 3056 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3057 3058 nodes->push(m2); 3059 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3060 } 3061 %} 3062 3063 // Enc_class needed as consttanttablebase is not supported by postalloc 3064 // expand. 3065 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3066 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3067 3068 MachNode *m2; 3069 if (large_constant_pool) { 3070 m2 = new loadConFCompNode(); 3071 } else { 3072 m2 = new loadConFNode(); 3073 } 3074 // inputs for new nodes 3075 m2->add_req(NULL, n_toc); 3076 3077 // operands for new nodes 3078 m2->_opnds[0] = op_dst; 3079 m2->_opnds[1] = op_src; 3080 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3081 3082 // register allocation for new nodes 3083 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3084 nodes->push(m2); 3085 %} 3086 3087 // Enc_class needed as consttanttablebase is not supported by postalloc 3088 // expand. 3089 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3090 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3091 3092 MachNode *m2; 3093 if (large_constant_pool) { 3094 m2 = new loadConDCompNode(); 3095 } else { 3096 m2 = new loadConDNode(); 3097 } 3098 // inputs for new nodes 3099 m2->add_req(NULL, n_toc); 3100 3101 // operands for new nodes 3102 m2->_opnds[0] = op_dst; 3103 m2->_opnds[1] = op_src; 3104 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3105 3106 // register allocation for new nodes 3107 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3108 nodes->push(m2); 3109 %} 3110 3111 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3112 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3113 MacroAssembler _masm(&cbuf); 3114 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3115 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3116 %} 3117 3118 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3119 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3120 MacroAssembler _masm(&cbuf); 3121 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3122 // Operand 'ds' requires 4-alignment. 3123 assert((Idisp & 0x3) == 0, "unaligned offset"); 3124 __ std($src$$Register, Idisp, $mem$$base$$Register); 3125 %} 3126 3127 enc_class enc_stfs(RegF src, memory mem) %{ 3128 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3129 MacroAssembler _masm(&cbuf); 3130 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3131 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3132 %} 3133 3134 enc_class enc_stfd(RegF src, memory mem) %{ 3135 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3136 MacroAssembler _masm(&cbuf); 3137 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3138 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3139 %} 3140 3141 // Use release_store for card-marking to ensure that previous 3142 // oop-stores are visible before the card-mark change. 3143 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3144 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3145 // FIXME: Implement this as a cmove and use a fixed condition code 3146 // register which is written on every transition to compiled code, 3147 // e.g. in call-stub and when returning from runtime stubs. 3148 // 3149 // Proposed code sequence for the cmove implementation: 3150 // 3151 // Label skip_release; 3152 // __ beq(CCRfixed, skip_release); 3153 // __ release(); 3154 // __ bind(skip_release); 3155 // __ stb(card mark); 3156 3157 MacroAssembler _masm(&cbuf); 3158 Label skip_storestore; 3159 3160 #if 0 // TODO: PPC port 3161 // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the 3162 // StoreStore barrier conditionally. 3163 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3164 __ cmpwi($crx$$CondRegister, R0, 0); 3165 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3166 #endif 3167 __ li(R0, 0); 3168 __ membar(Assembler::StoreStore); 3169 #if 0 // TODO: PPC port 3170 __ bind(skip_storestore); 3171 #endif 3172 3173 // Do the store. 3174 if ($mem$$index == 0) { 3175 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3176 } else { 3177 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3178 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3179 } 3180 %} 3181 3182 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3183 3184 if (VM_Version::has_isel()) { 3185 // use isel instruction with Power 7 3186 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3187 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3188 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3189 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3190 3191 n_compare->add_req(n_region, n_src); 3192 n_compare->_opnds[0] = op_crx; 3193 n_compare->_opnds[1] = op_src; 3194 n_compare->_opnds[2] = new immL16Oper(0); 3195 3196 n_sub_base->add_req(n_region, n_src); 3197 n_sub_base->_opnds[0] = op_dst; 3198 n_sub_base->_opnds[1] = op_src; 3199 n_sub_base->_bottom_type = _bottom_type; 3200 3201 n_shift->add_req(n_region, n_sub_base); 3202 n_shift->_opnds[0] = op_dst; 3203 n_shift->_opnds[1] = op_dst; 3204 n_shift->_bottom_type = _bottom_type; 3205 3206 n_cond_set->add_req(n_region, n_compare, n_shift); 3207 n_cond_set->_opnds[0] = op_dst; 3208 n_cond_set->_opnds[1] = op_crx; 3209 n_cond_set->_opnds[2] = op_dst; 3210 n_cond_set->_bottom_type = _bottom_type; 3211 3212 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3213 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3214 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3215 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3216 3217 nodes->push(n_compare); 3218 nodes->push(n_sub_base); 3219 nodes->push(n_shift); 3220 nodes->push(n_cond_set); 3221 3222 } else { 3223 // before Power 7 3224 moveRegNode *n_move = new moveRegNode(); 3225 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3226 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3227 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3228 3229 n_move->add_req(n_region, n_src); 3230 n_move->_opnds[0] = op_dst; 3231 n_move->_opnds[1] = op_src; 3232 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3233 3234 n_compare->add_req(n_region, n_src); 3235 n_compare->add_prec(n_move); 3236 3237 n_compare->_opnds[0] = op_crx; 3238 n_compare->_opnds[1] = op_src; 3239 n_compare->_opnds[2] = new immL16Oper(0); 3240 3241 n_sub_base->add_req(n_region, n_compare, n_src); 3242 n_sub_base->_opnds[0] = op_dst; 3243 n_sub_base->_opnds[1] = op_crx; 3244 n_sub_base->_opnds[2] = op_src; 3245 n_sub_base->_bottom_type = _bottom_type; 3246 3247 n_shift->add_req(n_region, n_sub_base); 3248 n_shift->_opnds[0] = op_dst; 3249 n_shift->_opnds[1] = op_dst; 3250 n_shift->_bottom_type = _bottom_type; 3251 3252 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3253 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3254 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3255 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3256 3257 nodes->push(n_move); 3258 nodes->push(n_compare); 3259 nodes->push(n_sub_base); 3260 nodes->push(n_shift); 3261 } 3262 3263 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3264 %} 3265 3266 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3267 3268 encodeP_subNode *n1 = new encodeP_subNode(); 3269 n1->add_req(n_region, n_src); 3270 n1->_opnds[0] = op_dst; 3271 n1->_opnds[1] = op_src; 3272 n1->_bottom_type = _bottom_type; 3273 3274 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3275 n2->add_req(n_region, n1); 3276 n2->_opnds[0] = op_dst; 3277 n2->_opnds[1] = op_dst; 3278 n2->_bottom_type = _bottom_type; 3279 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3280 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3281 3282 nodes->push(n1); 3283 nodes->push(n2); 3284 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3285 %} 3286 3287 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3288 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3289 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3290 3291 n_compare->add_req(n_region, n_src); 3292 n_compare->_opnds[0] = op_crx; 3293 n_compare->_opnds[1] = op_src; 3294 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3295 3296 n_shift->add_req(n_region, n_src); 3297 n_shift->_opnds[0] = op_dst; 3298 n_shift->_opnds[1] = op_src; 3299 n_shift->_bottom_type = _bottom_type; 3300 3301 if (VM_Version::has_isel()) { 3302 // use isel instruction with Power 7 3303 3304 decodeN_addNode *n_add_base = new decodeN_addNode(); 3305 n_add_base->add_req(n_region, n_shift); 3306 n_add_base->_opnds[0] = op_dst; 3307 n_add_base->_opnds[1] = op_dst; 3308 n_add_base->_bottom_type = _bottom_type; 3309 3310 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3311 n_cond_set->add_req(n_region, n_compare, n_add_base); 3312 n_cond_set->_opnds[0] = op_dst; 3313 n_cond_set->_opnds[1] = op_crx; 3314 n_cond_set->_opnds[2] = op_dst; 3315 n_cond_set->_bottom_type = _bottom_type; 3316 3317 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3318 ra_->set_oop(n_cond_set, true); 3319 3320 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3321 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3322 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3323 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3324 3325 nodes->push(n_compare); 3326 nodes->push(n_shift); 3327 nodes->push(n_add_base); 3328 nodes->push(n_cond_set); 3329 3330 } else { 3331 // before Power 7 3332 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3333 3334 n_add_base->add_req(n_region, n_compare, n_shift); 3335 n_add_base->_opnds[0] = op_dst; 3336 n_add_base->_opnds[1] = op_crx; 3337 n_add_base->_opnds[2] = op_dst; 3338 n_add_base->_bottom_type = _bottom_type; 3339 3340 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3341 ra_->set_oop(n_add_base, true); 3342 3343 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3344 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3345 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3346 3347 nodes->push(n_compare); 3348 nodes->push(n_shift); 3349 nodes->push(n_add_base); 3350 } 3351 %} 3352 3353 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3354 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3355 n1->add_req(n_region, n_src); 3356 n1->_opnds[0] = op_dst; 3357 n1->_opnds[1] = op_src; 3358 n1->_bottom_type = _bottom_type; 3359 3360 decodeN_addNode *n2 = new decodeN_addNode(); 3361 n2->add_req(n_region, n1); 3362 n2->_opnds[0] = op_dst; 3363 n2->_opnds[1] = op_dst; 3364 n2->_bottom_type = _bottom_type; 3365 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3366 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3367 3368 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3369 ra_->set_oop(n2, true); 3370 3371 nodes->push(n1); 3372 nodes->push(n2); 3373 %} 3374 3375 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3376 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3377 3378 MacroAssembler _masm(&cbuf); 3379 int cc = $cmp$$cmpcode; 3380 int flags_reg = $crx$$reg; 3381 Label done; 3382 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3383 // Branch if not (cmp crx). 3384 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3385 __ mr($dst$$Register, $src$$Register); 3386 // TODO PPC port __ endgroup_if_needed(_size == 12); 3387 __ bind(done); 3388 %} 3389 3390 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3391 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3392 3393 MacroAssembler _masm(&cbuf); 3394 Label done; 3395 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3396 // Branch if not (cmp crx). 3397 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3398 __ li($dst$$Register, $src$$constant); 3399 // TODO PPC port __ endgroup_if_needed(_size == 12); 3400 __ bind(done); 3401 %} 3402 3403 // This enc_class is needed so that scheduler gets proper 3404 // input mapping for latency computation. 3405 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3406 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3407 MacroAssembler _masm(&cbuf); 3408 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3409 %} 3410 3411 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3412 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3413 3414 MacroAssembler _masm(&cbuf); 3415 3416 Label done; 3417 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3418 __ li($dst$$Register, $zero$$constant); 3419 __ beq($crx$$CondRegister, done); 3420 __ li($dst$$Register, $notzero$$constant); 3421 __ bind(done); 3422 %} 3423 3424 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3425 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3426 3427 MacroAssembler _masm(&cbuf); 3428 3429 Label done; 3430 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3431 __ li($dst$$Register, $zero$$constant); 3432 __ beq($crx$$CondRegister, done); 3433 __ li($dst$$Register, $notzero$$constant); 3434 __ bind(done); 3435 %} 3436 3437 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3438 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3439 3440 MacroAssembler _masm(&cbuf); 3441 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3442 Label done; 3443 __ bso($crx$$CondRegister, done); 3444 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3445 // TODO PPC port __ endgroup_if_needed(_size == 12); 3446 __ bind(done); 3447 %} 3448 3449 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3450 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3451 3452 MacroAssembler _masm(&cbuf); 3453 Label done; 3454 __ bso($crx$$CondRegister, done); 3455 __ mffprd($dst$$Register, $src$$FloatRegister); 3456 // TODO PPC port __ endgroup_if_needed(_size == 12); 3457 __ bind(done); 3458 %} 3459 3460 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3461 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3462 3463 MacroAssembler _masm(&cbuf); 3464 Label d; // dummy 3465 __ bind(d); 3466 Label* p = ($lbl$$label); 3467 // `p' is `NULL' when this encoding class is used only to 3468 // determine the size of the encoded instruction. 3469 Label& l = (NULL == p)? d : *(p); 3470 int cc = $cmp$$cmpcode; 3471 int flags_reg = $crx$$reg; 3472 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3473 int bhint = Assembler::bhintNoHint; 3474 3475 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3476 if (_prob <= PROB_NEVER) { 3477 bhint = Assembler::bhintIsNotTaken; 3478 } else if (_prob >= PROB_ALWAYS) { 3479 bhint = Assembler::bhintIsTaken; 3480 } 3481 } 3482 3483 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3484 cc_to_biint(cc, flags_reg), 3485 l); 3486 %} 3487 3488 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3489 // The scheduler doesn't know about branch shortening, so we set the opcode 3490 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3491 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3492 3493 MacroAssembler _masm(&cbuf); 3494 Label d; // dummy 3495 __ bind(d); 3496 Label* p = ($lbl$$label); 3497 // `p' is `NULL' when this encoding class is used only to 3498 // determine the size of the encoded instruction. 3499 Label& l = (NULL == p)? d : *(p); 3500 int cc = $cmp$$cmpcode; 3501 int flags_reg = $crx$$reg; 3502 int bhint = Assembler::bhintNoHint; 3503 3504 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3505 if (_prob <= PROB_NEVER) { 3506 bhint = Assembler::bhintIsNotTaken; 3507 } else if (_prob >= PROB_ALWAYS) { 3508 bhint = Assembler::bhintIsTaken; 3509 } 3510 } 3511 3512 // Tell the conditional far branch to optimize itself when being relocated. 3513 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3514 cc_to_biint(cc, flags_reg), 3515 l, 3516 MacroAssembler::bc_far_optimize_on_relocate); 3517 %} 3518 3519 // Branch used with Power6 scheduling (can be shortened without changing the node). 3520 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3521 // The scheduler doesn't know about branch shortening, so we set the opcode 3522 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3523 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3524 3525 MacroAssembler _masm(&cbuf); 3526 Label d; // dummy 3527 __ bind(d); 3528 Label* p = ($lbl$$label); 3529 // `p' is `NULL' when this encoding class is used only to 3530 // determine the size of the encoded instruction. 3531 Label& l = (NULL == p)? d : *(p); 3532 int cc = $cmp$$cmpcode; 3533 int flags_reg = $crx$$reg; 3534 int bhint = Assembler::bhintNoHint; 3535 3536 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3537 if (_prob <= PROB_NEVER) { 3538 bhint = Assembler::bhintIsNotTaken; 3539 } else if (_prob >= PROB_ALWAYS) { 3540 bhint = Assembler::bhintIsTaken; 3541 } 3542 } 3543 3544 #if 0 // TODO: PPC port 3545 if (_size == 8) { 3546 // Tell the conditional far branch to optimize itself when being relocated. 3547 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3548 cc_to_biint(cc, flags_reg), 3549 l, 3550 MacroAssembler::bc_far_optimize_on_relocate); 3551 } else { 3552 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3553 cc_to_biint(cc, flags_reg), 3554 l); 3555 } 3556 #endif 3557 Unimplemented(); 3558 %} 3559 3560 // Postalloc expand emitter for loading a replicatef float constant from 3561 // the method's TOC. 3562 // Enc_class needed as consttanttablebase is not supported by postalloc 3563 // expand. 3564 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3565 // Create new nodes. 3566 3567 // Make an operand with the bit pattern to load as float. 3568 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3569 3570 loadConLNodesTuple loadConLNodes = 3571 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3572 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3573 3574 // Push new nodes. 3575 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3576 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3577 3578 assert(nodes->length() >= 1, "must have created at least 1 node"); 3579 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3580 %} 3581 3582 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3583 // Create new nodes. 3584 3585 // Make an operand with the bit pattern to load as float. 3586 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3587 immI_0Oper *op_zero = new immI_0Oper(0); 3588 3589 loadConLReplicatedNodesTuple loadConLNodes = 3590 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3591 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3592 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3593 3594 // Push new nodes. 3595 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3596 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3597 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3598 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3599 3600 assert(nodes->length() >= 1, "must have created at least 1 node"); 3601 %} 3602 3603 // This enc_class is needed so that scheduler gets proper 3604 // input mapping for latency computation. 3605 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3606 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3607 // Fake operand dst needed for PPC scheduler. 3608 assert($dst$$constant == 0x0, "dst must be 0x0"); 3609 3610 MacroAssembler _masm(&cbuf); 3611 // Mark the code position where the load from the safepoint 3612 // polling page was emitted as relocInfo::poll_type. 3613 __ relocate(relocInfo::poll_type); 3614 __ load_from_polling_page($poll$$Register); 3615 %} 3616 3617 // A Java static call or a runtime call. 3618 // 3619 // Branch-and-link relative to a trampoline. 3620 // The trampoline loads the target address and does a long branch to there. 3621 // In case we call java, the trampoline branches to a interpreter_stub 3622 // which loads the inline cache and the real call target from the constant pool. 3623 // 3624 // This basically looks like this: 3625 // 3626 // >>>> consts -+ -+ 3627 // | |- offset1 3628 // [call target1] | <-+ 3629 // [IC cache] |- offset2 3630 // [call target2] <--+ 3631 // 3632 // <<<< consts 3633 // >>>> insts 3634 // 3635 // bl offset16 -+ -+ ??? // How many bits available? 3636 // | | 3637 // <<<< insts | | 3638 // >>>> stubs | | 3639 // | |- trampoline_stub_Reloc 3640 // trampoline stub: | <-+ 3641 // r2 = toc | 3642 // r2 = [r2 + offset1] | // Load call target1 from const section 3643 // mtctr r2 | 3644 // bctr |- static_stub_Reloc 3645 // comp_to_interp_stub: <---+ 3646 // r1 = toc 3647 // ICreg = [r1 + IC_offset] // Load IC from const section 3648 // r1 = [r1 + offset2] // Load call target2 from const section 3649 // mtctr r1 3650 // bctr 3651 // 3652 // <<<< stubs 3653 // 3654 // The call instruction in the code either 3655 // - Branches directly to a compiled method if the offset is encodable in instruction. 3656 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3657 // - Branches to the compiled_to_interp stub if the target is interpreted. 3658 // 3659 // Further there are three relocations from the loads to the constants in 3660 // the constant section. 3661 // 3662 // Usage of r1 and r2 in the stubs allows to distinguish them. 3663 enc_class enc_java_static_call(method meth) %{ 3664 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3665 3666 MacroAssembler _masm(&cbuf); 3667 address entry_point = (address)$meth$$method; 3668 3669 if (!_method) { 3670 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3671 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3672 } else { 3673 // Remember the offset not the address. 3674 const int start_offset = __ offset(); 3675 3676 // The trampoline stub. 3677 // No entry point given, use the current pc. 3678 // Make sure branch fits into 3679 if (entry_point == 0) entry_point = __ pc(); 3680 3681 // Put the entry point as a constant into the constant pool. 3682 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3683 if (entry_point_toc_addr == NULL) { 3684 ciEnv::current()->record_out_of_memory_failure(); 3685 return; 3686 } 3687 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3688 3689 // Emit the trampoline stub which will be related to the branch-and-link below. 3690 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3691 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3692 int method_index = resolved_method_index(cbuf); 3693 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3694 : static_call_Relocation::spec(method_index)); 3695 3696 // The real call. 3697 // Note: At this point we do not have the address of the trampoline 3698 // stub, and the entry point might be too far away for bl, so __ pc() 3699 // serves as dummy and the bl will be patched later. 3700 cbuf.set_insts_mark(); 3701 __ bl(__ pc()); // Emits a relocation. 3702 3703 // The stub for call to interpreter. 3704 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3705 if (stub == NULL) { 3706 ciEnv::current()->record_failure("CodeCache is full"); 3707 return; 3708 } 3709 } 3710 %} 3711 3712 // Second node of expanded dynamic call - the call. 3713 enc_class enc_java_dynamic_call_sched(method meth) %{ 3714 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3715 3716 MacroAssembler _masm(&cbuf); 3717 3718 if (!ra_->C->in_scratch_emit_size()) { 3719 // Create a call trampoline stub for the given method. 3720 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3721 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3722 if (entry_point_const == NULL) { 3723 ciEnv::current()->record_out_of_memory_failure(); 3724 return; 3725 } 3726 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3727 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3728 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3729 3730 // Build relocation at call site with ic position as data. 3731 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3732 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3733 "must have one, but can't have both"); 3734 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3735 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3736 "must contain instruction offset"); 3737 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3738 ? _load_ic_hi_node->_cbuf_insts_offset 3739 : _load_ic_node->_cbuf_insts_offset; 3740 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3741 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3742 "should be load from TOC"); 3743 int method_index = resolved_method_index(cbuf); 3744 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3745 } 3746 3747 // At this point I do not have the address of the trampoline stub, 3748 // and the entry point might be too far away for bl. Pc() serves 3749 // as dummy and bl will be patched later. 3750 __ bl((address) __ pc()); 3751 %} 3752 3753 // postalloc expand emitter for virtual calls. 3754 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3755 3756 // Create the nodes for loading the IC from the TOC. 3757 loadConLNodesTuple loadConLNodes_IC = 3758 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3759 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3760 3761 // Create the call node. 3762 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3763 call->_method_handle_invoke = _method_handle_invoke; 3764 call->_vtable_index = _vtable_index; 3765 call->_method = _method; 3766 call->_bci = _bci; 3767 call->_optimized_virtual = _optimized_virtual; 3768 call->_tf = _tf; 3769 call->_entry_point = _entry_point; 3770 call->_cnt = _cnt; 3771 call->_argsize = _argsize; 3772 call->_oop_map = _oop_map; 3773 call->_jvms = _jvms; 3774 call->_jvmadj = _jvmadj; 3775 call->_in_rms = _in_rms; 3776 call->_nesting = _nesting; 3777 call->_override_symbolic_info = _override_symbolic_info; 3778 3779 // New call needs all inputs of old call. 3780 // Req... 3781 for (uint i = 0; i < req(); ++i) { 3782 // The expanded node does not need toc any more. 3783 // Add the inline cache constant here instead. This expresses the 3784 // register of the inline cache must be live at the call. 3785 // Else we would have to adapt JVMState by -1. 3786 if (i == mach_constant_base_node_input()) { 3787 call->add_req(loadConLNodes_IC._last); 3788 } else { 3789 call->add_req(in(i)); 3790 } 3791 } 3792 // ...as well as prec 3793 for (uint i = req(); i < len(); ++i) { 3794 call->add_prec(in(i)); 3795 } 3796 3797 // Remember nodes loading the inline cache into r19. 3798 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3799 call->_load_ic_node = loadConLNodes_IC._small; 3800 3801 // Operands for new nodes. 3802 call->_opnds[0] = _opnds[0]; 3803 call->_opnds[1] = _opnds[1]; 3804 3805 // Only the inline cache is associated with a register. 3806 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3807 3808 // Push new nodes. 3809 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3810 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3811 nodes->push(call); 3812 %} 3813 3814 // Compound version of call dynamic 3815 // Toc is only passed so that it can be used in ins_encode statement. 3816 // In the code we have to use $constanttablebase. 3817 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3818 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3819 MacroAssembler _masm(&cbuf); 3820 int start_offset = __ offset(); 3821 3822 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3823 #if 0 3824 int vtable_index = this->_vtable_index; 3825 if (_vtable_index < 0) { 3826 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3827 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3828 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3829 3830 // Virtual call relocation will point to ic load. 3831 address virtual_call_meta_addr = __ pc(); 3832 // Load a clear inline cache. 3833 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3834 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3835 if (!success) { 3836 ciEnv::current()->record_out_of_memory_failure(); 3837 return; 3838 } 3839 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3840 // to determine who we intended to call. 3841 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3842 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3843 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3844 "Fix constant in ret_addr_offset()"); 3845 } else { 3846 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3847 // Go thru the vtable. Get receiver klass. Receiver already 3848 // checked for non-null. If we'll go thru a C2I adapter, the 3849 // interpreter expects method in R19_method. 3850 3851 __ load_klass(R11_scratch1, R3); 3852 3853 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3854 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3855 __ li(R19_method, v_off); 3856 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3857 // NOTE: for vtable dispatches, the vtable entry will never be 3858 // null. However it may very well end up in handle_wrong_method 3859 // if the method is abstract for the particular class. 3860 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3861 // Call target. Either compiled code or C2I adapter. 3862 __ mtctr(R11_scratch1); 3863 __ bctrl(); 3864 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3865 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3866 } 3867 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3868 "Fix constant in ret_addr_offset()"); 3869 } 3870 #endif 3871 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3872 %} 3873 3874 // a runtime call 3875 enc_class enc_java_to_runtime_call (method meth) %{ 3876 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3877 3878 MacroAssembler _masm(&cbuf); 3879 const address start_pc = __ pc(); 3880 3881 #if defined(ABI_ELFv2) 3882 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3883 __ call_c(entry, relocInfo::runtime_call_type); 3884 #else 3885 // The function we're going to call. 3886 FunctionDescriptor fdtemp; 3887 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3888 3889 Register Rtoc = R12_scratch2; 3890 // Calculate the method's TOC. 3891 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3892 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3893 // pool entries; call_c_using_toc will optimize the call. 3894 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3895 if (!success) { 3896 ciEnv::current()->record_out_of_memory_failure(); 3897 return; 3898 } 3899 #endif 3900 3901 // Check the ret_addr_offset. 3902 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3903 "Fix constant in ret_addr_offset()"); 3904 %} 3905 3906 // Move to ctr for leaf call. 3907 // This enc_class is needed so that scheduler gets proper 3908 // input mapping for latency computation. 3909 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3910 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3911 MacroAssembler _masm(&cbuf); 3912 __ mtctr($src$$Register); 3913 %} 3914 3915 // Postalloc expand emitter for runtime leaf calls. 3916 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3917 loadConLNodesTuple loadConLNodes_Entry; 3918 #if defined(ABI_ELFv2) 3919 jlong entry_address = (jlong) this->entry_point(); 3920 assert(entry_address, "need address here"); 3921 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3922 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3923 #else 3924 // Get the struct that describes the function we are about to call. 3925 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3926 assert(fd, "need fd here"); 3927 jlong entry_address = (jlong) fd->entry(); 3928 // new nodes 3929 loadConLNodesTuple loadConLNodes_Env; 3930 loadConLNodesTuple loadConLNodes_Toc; 3931 3932 // Create nodes and operands for loading the entry point. 3933 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3934 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3935 3936 3937 // Create nodes and operands for loading the env pointer. 3938 if (fd->env() != NULL) { 3939 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3940 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3941 } else { 3942 loadConLNodes_Env._large_hi = NULL; 3943 loadConLNodes_Env._large_lo = NULL; 3944 loadConLNodes_Env._small = NULL; 3945 loadConLNodes_Env._last = new loadConL16Node(); 3946 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3947 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3948 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3949 } 3950 3951 // Create nodes and operands for loading the Toc point. 3952 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3953 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3954 #endif // ABI_ELFv2 3955 // mtctr node 3956 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3957 3958 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3959 mtctr->add_req(0, loadConLNodes_Entry._last); 3960 3961 mtctr->_opnds[0] = new iRegLdstOper(); 3962 mtctr->_opnds[1] = new iRegLdstOper(); 3963 3964 // call node 3965 MachCallLeafNode *call = new CallLeafDirectNode(); 3966 3967 call->_opnds[0] = _opnds[0]; 3968 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3969 3970 // Make the new call node look like the old one. 3971 call->_name = _name; 3972 call->_tf = _tf; 3973 call->_entry_point = _entry_point; 3974 call->_cnt = _cnt; 3975 call->_argsize = _argsize; 3976 call->_oop_map = _oop_map; 3977 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3978 call->_jvms = NULL; 3979 call->_jvmadj = _jvmadj; 3980 call->_in_rms = _in_rms; 3981 call->_nesting = _nesting; 3982 3983 3984 // New call needs all inputs of old call. 3985 // Req... 3986 for (uint i = 0; i < req(); ++i) { 3987 if (i != mach_constant_base_node_input()) { 3988 call->add_req(in(i)); 3989 } 3990 } 3991 3992 // These must be reqired edges, as the registers are live up to 3993 // the call. Else the constants are handled as kills. 3994 call->add_req(mtctr); 3995 #if !defined(ABI_ELFv2) 3996 call->add_req(loadConLNodes_Env._last); 3997 call->add_req(loadConLNodes_Toc._last); 3998 #endif 3999 4000 // ...as well as prec 4001 for (uint i = req(); i < len(); ++i) { 4002 call->add_prec(in(i)); 4003 } 4004 4005 // registers 4006 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 4007 4008 // Insert the new nodes. 4009 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 4010 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 4011 #if !defined(ABI_ELFv2) 4012 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 4013 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 4014 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 4015 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 4016 #endif 4017 nodes->push(mtctr); 4018 nodes->push(call); 4019 %} 4020 %} 4021 4022 //----------FRAME-------------------------------------------------------------- 4023 // Definition of frame structure and management information. 4024 4025 frame %{ 4026 // What direction does stack grow in (assumed to be same for native & Java). 4027 stack_direction(TOWARDS_LOW); 4028 4029 // These two registers define part of the calling convention between 4030 // compiled code and the interpreter. 4031 4032 // Inline Cache Register or method for I2C. 4033 inline_cache_reg(R19); // R19_method 4034 4035 // Method Oop Register when calling interpreter. 4036 interpreter_method_oop_reg(R19); // R19_method 4037 4038 // Optional: name the operand used by cisc-spilling to access 4039 // [stack_pointer + offset]. 4040 cisc_spilling_operand_name(indOffset); 4041 4042 // Number of stack slots consumed by a Monitor enter. 4043 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 4044 4045 // Compiled code's Frame Pointer. 4046 frame_pointer(R1); // R1_SP 4047 4048 // Interpreter stores its frame pointer in a register which is 4049 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 4050 // interpreted java to compiled java. 4051 // 4052 // R14_state holds pointer to caller's cInterpreter. 4053 interpreter_frame_pointer(R14); // R14_state 4054 4055 stack_alignment(frame::alignment_in_bytes); 4056 4057 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4058 4059 // Number of outgoing stack slots killed above the 4060 // out_preserve_stack_slots for calls to C. Supports the var-args 4061 // backing area for register parms. 4062 // 4063 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4064 4065 // The after-PROLOG location of the return address. Location of 4066 // return address specifies a type (REG or STACK) and a number 4067 // representing the register number (i.e. - use a register name) or 4068 // stack slot. 4069 // 4070 // A: Link register is stored in stack slot ... 4071 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4072 // J: Therefore, we make sure that the link register is also in R11_scratch1 4073 // at the end of the prolog. 4074 // B: We use R20, now. 4075 //return_addr(REG R20); 4076 4077 // G: After reading the comments made by all the luminaries on their 4078 // failure to tell the compiler where the return address really is, 4079 // I hardly dare to try myself. However, I'm convinced it's in slot 4080 // 4 what apparently works and saves us some spills. 4081 return_addr(STACK 4); 4082 4083 // This is the body of the function 4084 // 4085 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4086 // uint length, // length of array 4087 // bool is_outgoing) 4088 // 4089 // The `sig' array is to be updated. sig[j] represents the location 4090 // of the j-th argument, either a register or a stack slot. 4091 4092 // Comment taken from i486.ad: 4093 // Body of function which returns an integer array locating 4094 // arguments either in registers or in stack slots. Passed an array 4095 // of ideal registers called "sig" and a "length" count. Stack-slot 4096 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4097 // arguments for a CALLEE. Incoming stack arguments are 4098 // automatically biased by the preserve_stack_slots field above. 4099 calling_convention %{ 4100 // No difference between ingoing/outgoing. Just pass false. 4101 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4102 %} 4103 4104 // Comment taken from i486.ad: 4105 // Body of function which returns an integer array locating 4106 // arguments either in registers or in stack slots. Passed an array 4107 // of ideal registers called "sig" and a "length" count. Stack-slot 4108 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4109 // arguments for a CALLEE. Incoming stack arguments are 4110 // automatically biased by the preserve_stack_slots field above. 4111 c_calling_convention %{ 4112 // This is obviously always outgoing. 4113 // C argument in register AND stack slot. 4114 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4115 %} 4116 4117 // Location of native (C/C++) and interpreter return values. This 4118 // is specified to be the same as Java. In the 32-bit VM, long 4119 // values are actually returned from native calls in O0:O1 and 4120 // returned to the interpreter in I0:I1. The copying to and from 4121 // the register pairs is done by the appropriate call and epilog 4122 // opcodes. This simplifies the register allocator. 4123 c_return_value %{ 4124 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4125 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4126 "only return normal values"); 4127 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4128 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4129 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4130 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4131 %} 4132 4133 // Location of compiled Java return values. Same as C 4134 return_value %{ 4135 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4136 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4137 "only return normal values"); 4138 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4139 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4140 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4141 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4142 %} 4143 %} 4144 4145 4146 //----------ATTRIBUTES--------------------------------------------------------- 4147 4148 //----------Operand Attributes------------------------------------------------- 4149 op_attrib op_cost(1); // Required cost attribute. 4150 4151 //----------Instruction Attributes--------------------------------------------- 4152 4153 // Cost attribute. required. 4154 ins_attrib ins_cost(DEFAULT_COST); 4155 4156 // Is this instruction a non-matching short branch variant of some 4157 // long branch? Not required. 4158 ins_attrib ins_short_branch(0); 4159 4160 ins_attrib ins_is_TrapBasedCheckNode(true); 4161 4162 // Number of constants. 4163 // This instruction uses the given number of constants 4164 // (optional attribute). 4165 // This is needed to determine in time whether the constant pool will 4166 // exceed 4000 entries. Before postalloc_expand the overall number of constants 4167 // is determined. It's also used to compute the constant pool size 4168 // in Output(). 4169 ins_attrib ins_num_consts(0); 4170 4171 // Required alignment attribute (must be a power of 2) specifies the 4172 // alignment that some part of the instruction (not necessarily the 4173 // start) requires. If > 1, a compute_padding() function must be 4174 // provided for the instruction. 4175 ins_attrib ins_alignment(1); 4176 4177 // Enforce/prohibit rematerializations. 4178 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4179 // then rematerialization of that instruction is prohibited and the 4180 // instruction's value will be spilled if necessary. 4181 // Causes that MachNode::rematerialize() returns false. 4182 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 4183 // then rematerialization should be enforced and a copy of the instruction 4184 // should be inserted if possible; rematerialization is not guaranteed. 4185 // Note: this may result in rematerializations in front of every use. 4186 // Causes that MachNode::rematerialize() can return true. 4187 // (optional attribute) 4188 ins_attrib ins_cannot_rematerialize(false); 4189 ins_attrib ins_should_rematerialize(false); 4190 4191 // Instruction has variable size depending on alignment. 4192 ins_attrib ins_variable_size_depending_on_alignment(false); 4193 4194 // Instruction is a nop. 4195 ins_attrib ins_is_nop(false); 4196 4197 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4198 ins_attrib ins_use_mach_if_fast_lock_node(false); 4199 4200 // Field for the toc offset of a constant. 4201 // 4202 // This is needed if the toc offset is not encodable as an immediate in 4203 // the PPC load instruction. If so, the upper (hi) bits of the offset are 4204 // added to the toc, and from this a load with immediate is performed. 4205 // With postalloc expand, we get two nodes that require the same offset 4206 // but which don't know about each other. The offset is only known 4207 // when the constant is added to the constant pool during emitting. 4208 // It is generated in the 'hi'-node adding the upper bits, and saved 4209 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 4210 // the offset from there when it gets encoded. 4211 ins_attrib ins_field_const_toc_offset(0); 4212 ins_attrib ins_field_const_toc_offset_hi_node(0); 4213 4214 // A field that can hold the instructions offset in the code buffer. 4215 // Set in the nodes emitter. 4216 ins_attrib ins_field_cbuf_insts_offset(-1); 4217 4218 // Fields for referencing a call's load-IC-node. 4219 // If the toc offset can not be encoded as an immediate in a load, we 4220 // use two nodes. 4221 ins_attrib ins_field_load_ic_hi_node(0); 4222 ins_attrib ins_field_load_ic_node(0); 4223 4224 //----------OPERANDS----------------------------------------------------------- 4225 // Operand definitions must precede instruction definitions for correct 4226 // parsing in the ADLC because operands constitute user defined types 4227 // which are used in instruction definitions. 4228 // 4229 // Formats are generated automatically for constants and base registers. 4230 4231 operand vecX() %{ 4232 constraint(ALLOC_IN_RC(vs_reg)); 4233 match(VecX); 4234 4235 format %{ %} 4236 interface(REG_INTER); 4237 %} 4238 4239 //----------Simple Operands---------------------------------------------------- 4240 // Immediate Operands 4241 4242 // Integer Immediate: 32-bit 4243 operand immI() %{ 4244 match(ConI); 4245 op_cost(40); 4246 format %{ %} 4247 interface(CONST_INTER); 4248 %} 4249 4250 operand immI8() %{ 4251 predicate(Assembler::is_simm(n->get_int(), 8)); 4252 op_cost(0); 4253 match(ConI); 4254 format %{ %} 4255 interface(CONST_INTER); 4256 %} 4257 4258 // Integer Immediate: 16-bit 4259 operand immI16() %{ 4260 predicate(Assembler::is_simm(n->get_int(), 16)); 4261 op_cost(0); 4262 match(ConI); 4263 format %{ %} 4264 interface(CONST_INTER); 4265 %} 4266 4267 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4268 operand immIhi16() %{ 4269 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4270 match(ConI); 4271 op_cost(0); 4272 format %{ %} 4273 interface(CONST_INTER); 4274 %} 4275 4276 operand immInegpow2() %{ 4277 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 4278 match(ConI); 4279 op_cost(0); 4280 format %{ %} 4281 interface(CONST_INTER); 4282 %} 4283 4284 operand immIpow2minus1() %{ 4285 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 4286 match(ConI); 4287 op_cost(0); 4288 format %{ %} 4289 interface(CONST_INTER); 4290 %} 4291 4292 operand immIpowerOf2() %{ 4293 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 4294 match(ConI); 4295 op_cost(0); 4296 format %{ %} 4297 interface(CONST_INTER); 4298 %} 4299 4300 // Unsigned Integer Immediate: the values 0-31 4301 operand uimmI5() %{ 4302 predicate(Assembler::is_uimm(n->get_int(), 5)); 4303 match(ConI); 4304 op_cost(0); 4305 format %{ %} 4306 interface(CONST_INTER); 4307 %} 4308 4309 // Unsigned Integer Immediate: 6-bit 4310 operand uimmI6() %{ 4311 predicate(Assembler::is_uimm(n->get_int(), 6)); 4312 match(ConI); 4313 op_cost(0); 4314 format %{ %} 4315 interface(CONST_INTER); 4316 %} 4317 4318 // Unsigned Integer Immediate: 6-bit int, greater than 32 4319 operand uimmI6_ge32() %{ 4320 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4321 match(ConI); 4322 op_cost(0); 4323 format %{ %} 4324 interface(CONST_INTER); 4325 %} 4326 4327 // Unsigned Integer Immediate: 15-bit 4328 operand uimmI15() %{ 4329 predicate(Assembler::is_uimm(n->get_int(), 15)); 4330 match(ConI); 4331 op_cost(0); 4332 format %{ %} 4333 interface(CONST_INTER); 4334 %} 4335 4336 // Unsigned Integer Immediate: 16-bit 4337 operand uimmI16() %{ 4338 predicate(Assembler::is_uimm(n->get_int(), 16)); 4339 match(ConI); 4340 op_cost(0); 4341 format %{ %} 4342 interface(CONST_INTER); 4343 %} 4344 4345 // constant 'int 0'. 4346 operand immI_0() %{ 4347 predicate(n->get_int() == 0); 4348 match(ConI); 4349 op_cost(0); 4350 format %{ %} 4351 interface(CONST_INTER); 4352 %} 4353 4354 // constant 'int 1'. 4355 operand immI_1() %{ 4356 predicate(n->get_int() == 1); 4357 match(ConI); 4358 op_cost(0); 4359 format %{ %} 4360 interface(CONST_INTER); 4361 %} 4362 4363 // constant 'int -1'. 4364 operand immI_minus1() %{ 4365 predicate(n->get_int() == -1); 4366 match(ConI); 4367 op_cost(0); 4368 format %{ %} 4369 interface(CONST_INTER); 4370 %} 4371 4372 // int value 16. 4373 operand immI_16() %{ 4374 predicate(n->get_int() == 16); 4375 match(ConI); 4376 op_cost(0); 4377 format %{ %} 4378 interface(CONST_INTER); 4379 %} 4380 4381 // int value 24. 4382 operand immI_24() %{ 4383 predicate(n->get_int() == 24); 4384 match(ConI); 4385 op_cost(0); 4386 format %{ %} 4387 interface(CONST_INTER); 4388 %} 4389 4390 // Compressed oops constants 4391 // Pointer Immediate 4392 operand immN() %{ 4393 match(ConN); 4394 4395 op_cost(10); 4396 format %{ %} 4397 interface(CONST_INTER); 4398 %} 4399 4400 // NULL Pointer Immediate 4401 operand immN_0() %{ 4402 predicate(n->get_narrowcon() == 0); 4403 match(ConN); 4404 4405 op_cost(0); 4406 format %{ %} 4407 interface(CONST_INTER); 4408 %} 4409 4410 // Compressed klass constants 4411 operand immNKlass() %{ 4412 match(ConNKlass); 4413 4414 op_cost(0); 4415 format %{ %} 4416 interface(CONST_INTER); 4417 %} 4418 4419 // This operand can be used to avoid matching of an instruct 4420 // with chain rule. 4421 operand immNKlass_NM() %{ 4422 match(ConNKlass); 4423 predicate(false); 4424 op_cost(0); 4425 format %{ %} 4426 interface(CONST_INTER); 4427 %} 4428 4429 // Pointer Immediate: 64-bit 4430 operand immP() %{ 4431 match(ConP); 4432 op_cost(0); 4433 format %{ %} 4434 interface(CONST_INTER); 4435 %} 4436 4437 // Operand to avoid match of loadConP. 4438 // This operand can be used to avoid matching of an instruct 4439 // with chain rule. 4440 operand immP_NM() %{ 4441 match(ConP); 4442 predicate(false); 4443 op_cost(0); 4444 format %{ %} 4445 interface(CONST_INTER); 4446 %} 4447 4448 // costant 'pointer 0'. 4449 operand immP_0() %{ 4450 predicate(n->get_ptr() == 0); 4451 match(ConP); 4452 op_cost(0); 4453 format %{ %} 4454 interface(CONST_INTER); 4455 %} 4456 4457 // pointer 0x0 or 0x1 4458 operand immP_0or1() %{ 4459 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4460 match(ConP); 4461 op_cost(0); 4462 format %{ %} 4463 interface(CONST_INTER); 4464 %} 4465 4466 operand immL() %{ 4467 match(ConL); 4468 op_cost(40); 4469 format %{ %} 4470 interface(CONST_INTER); 4471 %} 4472 4473 operand immLmax30() %{ 4474 predicate((n->get_long() <= 30)); 4475 match(ConL); 4476 op_cost(0); 4477 format %{ %} 4478 interface(CONST_INTER); 4479 %} 4480 4481 // Long Immediate: 16-bit 4482 operand immL16() %{ 4483 predicate(Assembler::is_simm(n->get_long(), 16)); 4484 match(ConL); 4485 op_cost(0); 4486 format %{ %} 4487 interface(CONST_INTER); 4488 %} 4489 4490 // Long Immediate: 16-bit, 4-aligned 4491 operand immL16Alg4() %{ 4492 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4493 match(ConL); 4494 op_cost(0); 4495 format %{ %} 4496 interface(CONST_INTER); 4497 %} 4498 4499 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4500 operand immL32hi16() %{ 4501 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4502 match(ConL); 4503 op_cost(0); 4504 format %{ %} 4505 interface(CONST_INTER); 4506 %} 4507 4508 // Long Immediate: 32-bit 4509 operand immL32() %{ 4510 predicate(Assembler::is_simm(n->get_long(), 32)); 4511 match(ConL); 4512 op_cost(0); 4513 format %{ %} 4514 interface(CONST_INTER); 4515 %} 4516 4517 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4518 operand immLhighest16() %{ 4519 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4520 match(ConL); 4521 op_cost(0); 4522 format %{ %} 4523 interface(CONST_INTER); 4524 %} 4525 4526 operand immLnegpow2() %{ 4527 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4528 match(ConL); 4529 op_cost(0); 4530 format %{ %} 4531 interface(CONST_INTER); 4532 %} 4533 4534 operand immLpow2minus1() %{ 4535 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4536 (n->get_long() != (jlong)0xffffffffffffffffL)); 4537 match(ConL); 4538 op_cost(0); 4539 format %{ %} 4540 interface(CONST_INTER); 4541 %} 4542 4543 // constant 'long 0'. 4544 operand immL_0() %{ 4545 predicate(n->get_long() == 0L); 4546 match(ConL); 4547 op_cost(0); 4548 format %{ %} 4549 interface(CONST_INTER); 4550 %} 4551 4552 // constat ' long -1'. 4553 operand immL_minus1() %{ 4554 predicate(n->get_long() == -1L); 4555 match(ConL); 4556 op_cost(0); 4557 format %{ %} 4558 interface(CONST_INTER); 4559 %} 4560 4561 // Long Immediate: low 32-bit mask 4562 operand immL_32bits() %{ 4563 predicate(n->get_long() == 0xFFFFFFFFL); 4564 match(ConL); 4565 op_cost(0); 4566 format %{ %} 4567 interface(CONST_INTER); 4568 %} 4569 4570 // Unsigned Long Immediate: 16-bit 4571 operand uimmL16() %{ 4572 predicate(Assembler::is_uimm(n->get_long(), 16)); 4573 match(ConL); 4574 op_cost(0); 4575 format %{ %} 4576 interface(CONST_INTER); 4577 %} 4578 4579 // Float Immediate 4580 operand immF() %{ 4581 match(ConF); 4582 op_cost(40); 4583 format %{ %} 4584 interface(CONST_INTER); 4585 %} 4586 4587 // Float Immediate: +0.0f. 4588 operand immF_0() %{ 4589 predicate(jint_cast(n->getf()) == 0); 4590 match(ConF); 4591 4592 op_cost(0); 4593 format %{ %} 4594 interface(CONST_INTER); 4595 %} 4596 4597 // Double Immediate 4598 operand immD() %{ 4599 match(ConD); 4600 op_cost(40); 4601 format %{ %} 4602 interface(CONST_INTER); 4603 %} 4604 4605 // Integer Register Operands 4606 // Integer Destination Register 4607 // See definition of reg_class bits32_reg_rw. 4608 operand iRegIdst() %{ 4609 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4610 match(RegI); 4611 match(rscratch1RegI); 4612 match(rscratch2RegI); 4613 match(rarg1RegI); 4614 match(rarg2RegI); 4615 match(rarg3RegI); 4616 match(rarg4RegI); 4617 format %{ %} 4618 interface(REG_INTER); 4619 %} 4620 4621 // Integer Source Register 4622 // See definition of reg_class bits32_reg_ro. 4623 operand iRegIsrc() %{ 4624 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4625 match(RegI); 4626 match(rscratch1RegI); 4627 match(rscratch2RegI); 4628 match(rarg1RegI); 4629 match(rarg2RegI); 4630 match(rarg3RegI); 4631 match(rarg4RegI); 4632 format %{ %} 4633 interface(REG_INTER); 4634 %} 4635 4636 operand rscratch1RegI() %{ 4637 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4638 match(iRegIdst); 4639 format %{ %} 4640 interface(REG_INTER); 4641 %} 4642 4643 operand rscratch2RegI() %{ 4644 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4645 match(iRegIdst); 4646 format %{ %} 4647 interface(REG_INTER); 4648 %} 4649 4650 operand rarg1RegI() %{ 4651 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4652 match(iRegIdst); 4653 format %{ %} 4654 interface(REG_INTER); 4655 %} 4656 4657 operand rarg2RegI() %{ 4658 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4659 match(iRegIdst); 4660 format %{ %} 4661 interface(REG_INTER); 4662 %} 4663 4664 operand rarg3RegI() %{ 4665 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4666 match(iRegIdst); 4667 format %{ %} 4668 interface(REG_INTER); 4669 %} 4670 4671 operand rarg4RegI() %{ 4672 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4673 match(iRegIdst); 4674 format %{ %} 4675 interface(REG_INTER); 4676 %} 4677 4678 operand rarg1RegL() %{ 4679 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4680 match(iRegLdst); 4681 format %{ %} 4682 interface(REG_INTER); 4683 %} 4684 4685 operand rarg2RegL() %{ 4686 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4687 match(iRegLdst); 4688 format %{ %} 4689 interface(REG_INTER); 4690 %} 4691 4692 operand rarg3RegL() %{ 4693 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4694 match(iRegLdst); 4695 format %{ %} 4696 interface(REG_INTER); 4697 %} 4698 4699 operand rarg4RegL() %{ 4700 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4701 match(iRegLdst); 4702 format %{ %} 4703 interface(REG_INTER); 4704 %} 4705 4706 // Pointer Destination Register 4707 // See definition of reg_class bits64_reg_rw. 4708 operand iRegPdst() %{ 4709 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4710 match(RegP); 4711 match(rscratch1RegP); 4712 match(rscratch2RegP); 4713 match(rarg1RegP); 4714 match(rarg2RegP); 4715 match(rarg3RegP); 4716 match(rarg4RegP); 4717 format %{ %} 4718 interface(REG_INTER); 4719 %} 4720 4721 // Pointer Destination Register 4722 // Operand not using r11 and r12 (killed in epilog). 4723 operand iRegPdstNoScratch() %{ 4724 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4725 match(RegP); 4726 match(rarg1RegP); 4727 match(rarg2RegP); 4728 match(rarg3RegP); 4729 match(rarg4RegP); 4730 format %{ %} 4731 interface(REG_INTER); 4732 %} 4733 4734 // Pointer Source Register 4735 // See definition of reg_class bits64_reg_ro. 4736 operand iRegPsrc() %{ 4737 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4738 match(RegP); 4739 match(iRegPdst); 4740 match(rscratch1RegP); 4741 match(rscratch2RegP); 4742 match(rarg1RegP); 4743 match(rarg2RegP); 4744 match(rarg3RegP); 4745 match(rarg4RegP); 4746 match(threadRegP); 4747 format %{ %} 4748 interface(REG_INTER); 4749 %} 4750 4751 // Thread operand. 4752 operand threadRegP() %{ 4753 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4754 match(iRegPdst); 4755 format %{ "R16" %} 4756 interface(REG_INTER); 4757 %} 4758 4759 operand rscratch1RegP() %{ 4760 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4761 match(iRegPdst); 4762 format %{ "R11" %} 4763 interface(REG_INTER); 4764 %} 4765 4766 operand rscratch2RegP() %{ 4767 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4768 match(iRegPdst); 4769 format %{ %} 4770 interface(REG_INTER); 4771 %} 4772 4773 operand rarg1RegP() %{ 4774 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4775 match(iRegPdst); 4776 format %{ %} 4777 interface(REG_INTER); 4778 %} 4779 4780 operand rarg2RegP() %{ 4781 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4782 match(iRegPdst); 4783 format %{ %} 4784 interface(REG_INTER); 4785 %} 4786 4787 operand rarg3RegP() %{ 4788 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4789 match(iRegPdst); 4790 format %{ %} 4791 interface(REG_INTER); 4792 %} 4793 4794 operand rarg4RegP() %{ 4795 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4796 match(iRegPdst); 4797 format %{ %} 4798 interface(REG_INTER); 4799 %} 4800 4801 operand iRegNsrc() %{ 4802 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4803 match(RegN); 4804 match(iRegNdst); 4805 4806 format %{ %} 4807 interface(REG_INTER); 4808 %} 4809 4810 operand iRegNdst() %{ 4811 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4812 match(RegN); 4813 4814 format %{ %} 4815 interface(REG_INTER); 4816 %} 4817 4818 // Long Destination Register 4819 // See definition of reg_class bits64_reg_rw. 4820 operand iRegLdst() %{ 4821 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4822 match(RegL); 4823 match(rscratch1RegL); 4824 match(rscratch2RegL); 4825 format %{ %} 4826 interface(REG_INTER); 4827 %} 4828 4829 // Long Source Register 4830 // See definition of reg_class bits64_reg_ro. 4831 operand iRegLsrc() %{ 4832 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4833 match(RegL); 4834 match(iRegLdst); 4835 match(rscratch1RegL); 4836 match(rscratch2RegL); 4837 format %{ %} 4838 interface(REG_INTER); 4839 %} 4840 4841 // Special operand for ConvL2I. 4842 operand iRegL2Isrc(iRegLsrc reg) %{ 4843 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4844 match(ConvL2I reg); 4845 format %{ "ConvL2I($reg)" %} 4846 interface(REG_INTER) 4847 %} 4848 4849 operand rscratch1RegL() %{ 4850 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4851 match(RegL); 4852 format %{ %} 4853 interface(REG_INTER); 4854 %} 4855 4856 operand rscratch2RegL() %{ 4857 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4858 match(RegL); 4859 format %{ %} 4860 interface(REG_INTER); 4861 %} 4862 4863 // Condition Code Flag Registers 4864 operand flagsReg() %{ 4865 constraint(ALLOC_IN_RC(int_flags)); 4866 match(RegFlags); 4867 format %{ %} 4868 interface(REG_INTER); 4869 %} 4870 4871 operand flagsRegSrc() %{ 4872 constraint(ALLOC_IN_RC(int_flags_ro)); 4873 match(RegFlags); 4874 match(flagsReg); 4875 match(flagsRegCR0); 4876 format %{ %} 4877 interface(REG_INTER); 4878 %} 4879 4880 // Condition Code Flag Register CR0 4881 operand flagsRegCR0() %{ 4882 constraint(ALLOC_IN_RC(int_flags_CR0)); 4883 match(RegFlags); 4884 format %{ "CR0" %} 4885 interface(REG_INTER); 4886 %} 4887 4888 operand flagsRegCR1() %{ 4889 constraint(ALLOC_IN_RC(int_flags_CR1)); 4890 match(RegFlags); 4891 format %{ "CR1" %} 4892 interface(REG_INTER); 4893 %} 4894 4895 operand flagsRegCR6() %{ 4896 constraint(ALLOC_IN_RC(int_flags_CR6)); 4897 match(RegFlags); 4898 format %{ "CR6" %} 4899 interface(REG_INTER); 4900 %} 4901 4902 operand regCTR() %{ 4903 constraint(ALLOC_IN_RC(ctr_reg)); 4904 // RegFlags should work. Introducing a RegSpecial type would cause a 4905 // lot of changes. 4906 match(RegFlags); 4907 format %{"SR_CTR" %} 4908 interface(REG_INTER); 4909 %} 4910 4911 operand regD() %{ 4912 constraint(ALLOC_IN_RC(dbl_reg)); 4913 match(RegD); 4914 format %{ %} 4915 interface(REG_INTER); 4916 %} 4917 4918 operand regF() %{ 4919 constraint(ALLOC_IN_RC(flt_reg)); 4920 match(RegF); 4921 format %{ %} 4922 interface(REG_INTER); 4923 %} 4924 4925 // Special Registers 4926 4927 // Method Register 4928 operand inline_cache_regP(iRegPdst reg) %{ 4929 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4930 match(reg); 4931 format %{ %} 4932 interface(REG_INTER); 4933 %} 4934 4935 operand compiler_method_oop_regP(iRegPdst reg) %{ 4936 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4937 match(reg); 4938 format %{ %} 4939 interface(REG_INTER); 4940 %} 4941 4942 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4943 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4944 match(reg); 4945 format %{ %} 4946 interface(REG_INTER); 4947 %} 4948 4949 // Operands to remove register moves in unscaled mode. 4950 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4951 operand iRegP2N(iRegPsrc reg) %{ 4952 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4953 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4954 match(EncodeP reg); 4955 format %{ "$reg" %} 4956 interface(REG_INTER) 4957 %} 4958 4959 operand iRegN2P(iRegNsrc reg) %{ 4960 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4961 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4962 match(DecodeN reg); 4963 format %{ "$reg" %} 4964 interface(REG_INTER) 4965 %} 4966 4967 operand iRegN2P_klass(iRegNsrc reg) %{ 4968 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4969 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4970 match(DecodeNKlass reg); 4971 format %{ "$reg" %} 4972 interface(REG_INTER) 4973 %} 4974 4975 //----------Complex Operands--------------------------------------------------- 4976 // Indirect Memory Reference 4977 operand indirect(iRegPsrc reg) %{ 4978 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4979 match(reg); 4980 op_cost(100); 4981 format %{ "[$reg]" %} 4982 interface(MEMORY_INTER) %{ 4983 base($reg); 4984 index(0x0); 4985 scale(0x0); 4986 disp(0x0); 4987 %} 4988 %} 4989 4990 // Indirect with Offset 4991 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 4992 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4993 match(AddP reg offset); 4994 op_cost(100); 4995 format %{ "[$reg + $offset]" %} 4996 interface(MEMORY_INTER) %{ 4997 base($reg); 4998 index(0x0); 4999 scale(0x0); 5000 disp($offset); 5001 %} 5002 %} 5003 5004 // Indirect with 4-aligned Offset 5005 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 5006 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5007 match(AddP reg offset); 5008 op_cost(100); 5009 format %{ "[$reg + $offset]" %} 5010 interface(MEMORY_INTER) %{ 5011 base($reg); 5012 index(0x0); 5013 scale(0x0); 5014 disp($offset); 5015 %} 5016 %} 5017 5018 //----------Complex Operands for Compressed OOPs------------------------------- 5019 // Compressed OOPs with narrow_oop_shift == 0. 5020 5021 // Indirect Memory Reference, compressed OOP 5022 operand indirectNarrow(iRegNsrc reg) %{ 5023 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5024 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5025 match(DecodeN reg); 5026 op_cost(100); 5027 format %{ "[$reg]" %} 5028 interface(MEMORY_INTER) %{ 5029 base($reg); 5030 index(0x0); 5031 scale(0x0); 5032 disp(0x0); 5033 %} 5034 %} 5035 5036 operand indirectNarrow_klass(iRegNsrc reg) %{ 5037 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5038 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5039 match(DecodeNKlass reg); 5040 op_cost(100); 5041 format %{ "[$reg]" %} 5042 interface(MEMORY_INTER) %{ 5043 base($reg); 5044 index(0x0); 5045 scale(0x0); 5046 disp(0x0); 5047 %} 5048 %} 5049 5050 // Indirect with Offset, compressed OOP 5051 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 5052 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5053 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5054 match(AddP (DecodeN reg) offset); 5055 op_cost(100); 5056 format %{ "[$reg + $offset]" %} 5057 interface(MEMORY_INTER) %{ 5058 base($reg); 5059 index(0x0); 5060 scale(0x0); 5061 disp($offset); 5062 %} 5063 %} 5064 5065 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5066 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5067 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5068 match(AddP (DecodeNKlass reg) offset); 5069 op_cost(100); 5070 format %{ "[$reg + $offset]" %} 5071 interface(MEMORY_INTER) %{ 5072 base($reg); 5073 index(0x0); 5074 scale(0x0); 5075 disp($offset); 5076 %} 5077 %} 5078 5079 // Indirect with 4-aligned Offset, compressed OOP 5080 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 5081 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5082 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5083 match(AddP (DecodeN reg) offset); 5084 op_cost(100); 5085 format %{ "[$reg + $offset]" %} 5086 interface(MEMORY_INTER) %{ 5087 base($reg); 5088 index(0x0); 5089 scale(0x0); 5090 disp($offset); 5091 %} 5092 %} 5093 5094 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5095 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5096 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5097 match(AddP (DecodeNKlass reg) offset); 5098 op_cost(100); 5099 format %{ "[$reg + $offset]" %} 5100 interface(MEMORY_INTER) %{ 5101 base($reg); 5102 index(0x0); 5103 scale(0x0); 5104 disp($offset); 5105 %} 5106 %} 5107 5108 //----------Special Memory Operands-------------------------------------------- 5109 // Stack Slot Operand 5110 // 5111 // This operand is used for loading and storing temporary values on 5112 // the stack where a match requires a value to flow through memory. 5113 operand stackSlotI(sRegI reg) %{ 5114 constraint(ALLOC_IN_RC(stack_slots)); 5115 op_cost(100); 5116 //match(RegI); 5117 format %{ "[sp+$reg]" %} 5118 interface(MEMORY_INTER) %{ 5119 base(0x1); // R1_SP 5120 index(0x0); 5121 scale(0x0); 5122 disp($reg); // Stack Offset 5123 %} 5124 %} 5125 5126 operand stackSlotL(sRegL reg) %{ 5127 constraint(ALLOC_IN_RC(stack_slots)); 5128 op_cost(100); 5129 //match(RegL); 5130 format %{ "[sp+$reg]" %} 5131 interface(MEMORY_INTER) %{ 5132 base(0x1); // R1_SP 5133 index(0x0); 5134 scale(0x0); 5135 disp($reg); // Stack Offset 5136 %} 5137 %} 5138 5139 operand stackSlotP(sRegP reg) %{ 5140 constraint(ALLOC_IN_RC(stack_slots)); 5141 op_cost(100); 5142 //match(RegP); 5143 format %{ "[sp+$reg]" %} 5144 interface(MEMORY_INTER) %{ 5145 base(0x1); // R1_SP 5146 index(0x0); 5147 scale(0x0); 5148 disp($reg); // Stack Offset 5149 %} 5150 %} 5151 5152 operand stackSlotF(sRegF reg) %{ 5153 constraint(ALLOC_IN_RC(stack_slots)); 5154 op_cost(100); 5155 //match(RegF); 5156 format %{ "[sp+$reg]" %} 5157 interface(MEMORY_INTER) %{ 5158 base(0x1); // R1_SP 5159 index(0x0); 5160 scale(0x0); 5161 disp($reg); // Stack Offset 5162 %} 5163 %} 5164 5165 operand stackSlotD(sRegD reg) %{ 5166 constraint(ALLOC_IN_RC(stack_slots)); 5167 op_cost(100); 5168 //match(RegD); 5169 format %{ "[sp+$reg]" %} 5170 interface(MEMORY_INTER) %{ 5171 base(0x1); // R1_SP 5172 index(0x0); 5173 scale(0x0); 5174 disp($reg); // Stack Offset 5175 %} 5176 %} 5177 5178 // Operands for expressing Control Flow 5179 // NOTE: Label is a predefined operand which should not be redefined in 5180 // the AD file. It is generically handled within the ADLC. 5181 5182 //----------Conditional Branch Operands---------------------------------------- 5183 // Comparison Op 5184 // 5185 // This is the operation of the comparison, and is limited to the 5186 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5187 // (!=). 5188 // 5189 // Other attributes of the comparison, such as unsignedness, are specified 5190 // by the comparison instruction that sets a condition code flags register. 5191 // That result is represented by a flags operand whose subtype is appropriate 5192 // to the unsignedness (etc.) of the comparison. 5193 // 5194 // Later, the instruction which matches both the Comparison Op (a Bool) and 5195 // the flags (produced by the Cmp) specifies the coding of the comparison op 5196 // by matching a specific subtype of Bool operand below. 5197 5198 // When used for floating point comparisons: unordered same as less. 5199 operand cmpOp() %{ 5200 match(Bool); 5201 format %{ "" %} 5202 interface(COND_INTER) %{ 5203 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5204 // BO & BI 5205 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5206 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5207 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5208 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5209 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5210 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5211 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5212 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5213 %} 5214 %} 5215 5216 //----------OPERAND CLASSES---------------------------------------------------- 5217 // Operand Classes are groups of operands that are used to simplify 5218 // instruction definitions by not requiring the AD writer to specify 5219 // seperate instructions for every form of operand when the 5220 // instruction accepts multiple operand types with the same basic 5221 // encoding and format. The classic case of this is memory operands. 5222 // Indirect is not included since its use is limited to Compare & Swap. 5223 5224 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5225 // Memory operand where offsets are 4-aligned. Required for ld, std. 5226 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5227 opclass indirectMemory(indirect, indirectNarrow); 5228 5229 // Special opclass for I and ConvL2I. 5230 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5231 5232 // Operand classes to match encode and decode. iRegN_P2N is only used 5233 // for storeN. I have never seen an encode node elsewhere. 5234 opclass iRegN_P2N(iRegNsrc, iRegP2N); 5235 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5236 5237 //----------PIPELINE----------------------------------------------------------- 5238 5239 pipeline %{ 5240 5241 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5242 // J. Res. & Dev., No. 1, Jan. 2002. 5243 5244 //----------ATTRIBUTES--------------------------------------------------------- 5245 attributes %{ 5246 5247 // Power4 instructions are of fixed length. 5248 fixed_size_instructions; 5249 5250 // TODO: if `bundle' means number of instructions fetched 5251 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5252 // max instructions issued per cycle, this is 5. 5253 max_instructions_per_bundle = 8; 5254 5255 // A Power4 instruction is 4 bytes long. 5256 instruction_unit_size = 4; 5257 5258 // The Power4 processor fetches 64 bytes... 5259 instruction_fetch_unit_size = 64; 5260 5261 // ...in one line 5262 instruction_fetch_units = 1 5263 5264 // Unused, list one so that array generated by adlc is not empty. 5265 // Aix compiler chokes if _nop_count = 0. 5266 nops(fxNop); 5267 %} 5268 5269 //----------RESOURCES---------------------------------------------------------- 5270 // Resources are the functional units available to the machine 5271 resources( 5272 PPC_BR, // branch unit 5273 PPC_CR, // condition unit 5274 PPC_FX1, // integer arithmetic unit 1 5275 PPC_FX2, // integer arithmetic unit 2 5276 PPC_LDST1, // load/store unit 1 5277 PPC_LDST2, // load/store unit 2 5278 PPC_FP1, // float arithmetic unit 1 5279 PPC_FP2, // float arithmetic unit 2 5280 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5281 PPC_FX = PPC_FX1 | PPC_FX2, 5282 PPC_FP = PPC_FP1 | PPC_FP2 5283 ); 5284 5285 //----------PIPELINE DESCRIPTION----------------------------------------------- 5286 // Pipeline Description specifies the stages in the machine's pipeline 5287 pipe_desc( 5288 // Power4 longest pipeline path 5289 PPC_IF, // instruction fetch 5290 PPC_IC, 5291 //PPC_BP, // branch prediction 5292 PPC_D0, // decode 5293 PPC_D1, // decode 5294 PPC_D2, // decode 5295 PPC_D3, // decode 5296 PPC_Xfer1, 5297 PPC_GD, // group definition 5298 PPC_MP, // map 5299 PPC_ISS, // issue 5300 PPC_RF, // resource fetch 5301 PPC_EX1, // execute (all units) 5302 PPC_EX2, // execute (FP, LDST) 5303 PPC_EX3, // execute (FP, LDST) 5304 PPC_EX4, // execute (FP) 5305 PPC_EX5, // execute (FP) 5306 PPC_EX6, // execute (FP) 5307 PPC_WB, // write back 5308 PPC_Xfer2, 5309 PPC_CP 5310 ); 5311 5312 //----------PIPELINE CLASSES--------------------------------------------------- 5313 // Pipeline Classes describe the stages in which input and output are 5314 // referenced by the hardware pipeline. 5315 5316 // Simple pipeline classes. 5317 5318 // Default pipeline class. 5319 pipe_class pipe_class_default() %{ 5320 single_instruction; 5321 fixed_latency(2); 5322 %} 5323 5324 // Pipeline class for empty instructions. 5325 pipe_class pipe_class_empty() %{ 5326 single_instruction; 5327 fixed_latency(0); 5328 %} 5329 5330 // Pipeline class for compares. 5331 pipe_class pipe_class_compare() %{ 5332 single_instruction; 5333 fixed_latency(16); 5334 %} 5335 5336 // Pipeline class for traps. 5337 pipe_class pipe_class_trap() %{ 5338 single_instruction; 5339 fixed_latency(100); 5340 %} 5341 5342 // Pipeline class for memory operations. 5343 pipe_class pipe_class_memory() %{ 5344 single_instruction; 5345 fixed_latency(16); 5346 %} 5347 5348 // Pipeline class for call. 5349 pipe_class pipe_class_call() %{ 5350 single_instruction; 5351 fixed_latency(100); 5352 %} 5353 5354 // Define the class for the Nop node. 5355 define %{ 5356 MachNop = pipe_class_default; 5357 %} 5358 5359 %} 5360 5361 //----------INSTRUCTIONS------------------------------------------------------- 5362 5363 // Naming of instructions: 5364 // opA_operB / opA_operB_operC: 5365 // Operation 'op' with one or two source operands 'oper'. Result 5366 // type is A, source operand types are B and C. 5367 // Iff A == B == C, B and C are left out. 5368 // 5369 // The instructions are ordered according to the following scheme: 5370 // - loads 5371 // - load constants 5372 // - prefetch 5373 // - store 5374 // - encode/decode 5375 // - membar 5376 // - conditional moves 5377 // - compare & swap 5378 // - arithmetic and logic operations 5379 // * int: Add, Sub, Mul, Div, Mod 5380 // * int: lShift, arShift, urShift, rot 5381 // * float: Add, Sub, Mul, Div 5382 // * and, or, xor ... 5383 // - register moves: float <-> int, reg <-> stack, repl 5384 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5385 // - conv (low level type cast requiring bit changes (sign extend etc) 5386 // - compares, range & zero checks. 5387 // - branches 5388 // - complex operations, intrinsics, min, max, replicate 5389 // - lock 5390 // - Calls 5391 // 5392 // If there are similar instructions with different types they are sorted: 5393 // int before float 5394 // small before big 5395 // signed before unsigned 5396 // e.g., loadS before loadUS before loadI before loadF. 5397 5398 5399 //----------Load/Store Instructions-------------------------------------------- 5400 5401 //----------Load Instructions-------------------------------------------------- 5402 5403 // Converts byte to int. 5404 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5405 // reuses the 'amount' operand, but adlc expects that operand specification 5406 // and operands in match rule are equivalent. 5407 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5408 effect(DEF dst, USE src); 5409 format %{ "EXTSB $dst, $src \t// byte->int" %} 5410 size(4); 5411 ins_encode %{ 5412 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5413 __ extsb($dst$$Register, $src$$Register); 5414 %} 5415 ins_pipe(pipe_class_default); 5416 %} 5417 5418 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5419 // match-rule, false predicate 5420 match(Set dst (LoadB mem)); 5421 predicate(false); 5422 5423 format %{ "LBZ $dst, $mem" %} 5424 size(4); 5425 ins_encode( enc_lbz(dst, mem) ); 5426 ins_pipe(pipe_class_memory); 5427 %} 5428 5429 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5430 // match-rule, false predicate 5431 match(Set dst (LoadB mem)); 5432 predicate(false); 5433 5434 format %{ "LBZ $dst, $mem\n\t" 5435 "TWI $dst\n\t" 5436 "ISYNC" %} 5437 size(12); 5438 ins_encode( enc_lbz_ac(dst, mem) ); 5439 ins_pipe(pipe_class_memory); 5440 %} 5441 5442 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5443 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5444 match(Set dst (LoadB mem)); 5445 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5446 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5447 expand %{ 5448 iRegIdst tmp; 5449 loadUB_indirect(tmp, mem); 5450 convB2I_reg_2(dst, tmp); 5451 %} 5452 %} 5453 5454 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5455 match(Set dst (LoadB mem)); 5456 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5457 expand %{ 5458 iRegIdst tmp; 5459 loadUB_indirect_ac(tmp, mem); 5460 convB2I_reg_2(dst, tmp); 5461 %} 5462 %} 5463 5464 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5465 // match-rule, false predicate 5466 match(Set dst (LoadB mem)); 5467 predicate(false); 5468 5469 format %{ "LBZ $dst, $mem" %} 5470 size(4); 5471 ins_encode( enc_lbz(dst, mem) ); 5472 ins_pipe(pipe_class_memory); 5473 %} 5474 5475 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5476 // match-rule, false predicate 5477 match(Set dst (LoadB mem)); 5478 predicate(false); 5479 5480 format %{ "LBZ $dst, $mem\n\t" 5481 "TWI $dst\n\t" 5482 "ISYNC" %} 5483 size(12); 5484 ins_encode( enc_lbz_ac(dst, mem) ); 5485 ins_pipe(pipe_class_memory); 5486 %} 5487 5488 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5489 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5490 match(Set dst (LoadB mem)); 5491 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5492 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5493 5494 expand %{ 5495 iRegIdst tmp; 5496 loadUB_indOffset16(tmp, mem); 5497 convB2I_reg_2(dst, tmp); 5498 %} 5499 %} 5500 5501 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5502 match(Set dst (LoadB mem)); 5503 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5504 5505 expand %{ 5506 iRegIdst tmp; 5507 loadUB_indOffset16_ac(tmp, mem); 5508 convB2I_reg_2(dst, tmp); 5509 %} 5510 %} 5511 5512 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5513 instruct loadUB(iRegIdst dst, memory mem) %{ 5514 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5515 match(Set dst (LoadUB mem)); 5516 ins_cost(MEMORY_REF_COST); 5517 5518 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5519 size(4); 5520 ins_encode( enc_lbz(dst, mem) ); 5521 ins_pipe(pipe_class_memory); 5522 %} 5523 5524 // Load Unsigned Byte (8bit UNsigned) acquire. 5525 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5526 match(Set dst (LoadUB mem)); 5527 ins_cost(3*MEMORY_REF_COST); 5528 5529 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5530 "TWI $dst\n\t" 5531 "ISYNC" %} 5532 size(12); 5533 ins_encode( enc_lbz_ac(dst, mem) ); 5534 ins_pipe(pipe_class_memory); 5535 %} 5536 5537 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5538 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5539 match(Set dst (ConvI2L (LoadUB mem))); 5540 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5541 ins_cost(MEMORY_REF_COST); 5542 5543 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5544 size(4); 5545 ins_encode( enc_lbz(dst, mem) ); 5546 ins_pipe(pipe_class_memory); 5547 %} 5548 5549 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5550 match(Set dst (ConvI2L (LoadUB mem))); 5551 ins_cost(3*MEMORY_REF_COST); 5552 5553 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5554 "TWI $dst\n\t" 5555 "ISYNC" %} 5556 size(12); 5557 ins_encode( enc_lbz_ac(dst, mem) ); 5558 ins_pipe(pipe_class_memory); 5559 %} 5560 5561 // Load Short (16bit signed) 5562 instruct loadS(iRegIdst dst, memory mem) %{ 5563 match(Set dst (LoadS mem)); 5564 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5565 ins_cost(MEMORY_REF_COST); 5566 5567 format %{ "LHA $dst, $mem" %} 5568 size(4); 5569 ins_encode %{ 5570 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5571 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5572 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5573 %} 5574 ins_pipe(pipe_class_memory); 5575 %} 5576 5577 // Load Short (16bit signed) acquire. 5578 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5579 match(Set dst (LoadS mem)); 5580 ins_cost(3*MEMORY_REF_COST); 5581 5582 format %{ "LHA $dst, $mem\t acquire\n\t" 5583 "TWI $dst\n\t" 5584 "ISYNC" %} 5585 size(12); 5586 ins_encode %{ 5587 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5588 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5589 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5590 __ twi_0($dst$$Register); 5591 __ isync(); 5592 %} 5593 ins_pipe(pipe_class_memory); 5594 %} 5595 5596 // Load Char (16bit unsigned) 5597 instruct loadUS(iRegIdst dst, memory mem) %{ 5598 match(Set dst (LoadUS mem)); 5599 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5600 ins_cost(MEMORY_REF_COST); 5601 5602 format %{ "LHZ $dst, $mem" %} 5603 size(4); 5604 ins_encode( enc_lhz(dst, mem) ); 5605 ins_pipe(pipe_class_memory); 5606 %} 5607 5608 // Load Char (16bit unsigned) acquire. 5609 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5610 match(Set dst (LoadUS mem)); 5611 ins_cost(3*MEMORY_REF_COST); 5612 5613 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5614 "TWI $dst\n\t" 5615 "ISYNC" %} 5616 size(12); 5617 ins_encode( enc_lhz_ac(dst, mem) ); 5618 ins_pipe(pipe_class_memory); 5619 %} 5620 5621 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5622 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5623 match(Set dst (ConvI2L (LoadUS mem))); 5624 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5625 ins_cost(MEMORY_REF_COST); 5626 5627 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5628 size(4); 5629 ins_encode( enc_lhz(dst, mem) ); 5630 ins_pipe(pipe_class_memory); 5631 %} 5632 5633 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5634 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5635 match(Set dst (ConvI2L (LoadUS mem))); 5636 ins_cost(3*MEMORY_REF_COST); 5637 5638 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5639 "TWI $dst\n\t" 5640 "ISYNC" %} 5641 size(12); 5642 ins_encode( enc_lhz_ac(dst, mem) ); 5643 ins_pipe(pipe_class_memory); 5644 %} 5645 5646 // Load Integer. 5647 instruct loadI(iRegIdst dst, memory mem) %{ 5648 match(Set dst (LoadI mem)); 5649 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5650 ins_cost(MEMORY_REF_COST); 5651 5652 format %{ "LWZ $dst, $mem" %} 5653 size(4); 5654 ins_encode( enc_lwz(dst, mem) ); 5655 ins_pipe(pipe_class_memory); 5656 %} 5657 5658 // Load Integer acquire. 5659 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5660 match(Set dst (LoadI mem)); 5661 ins_cost(3*MEMORY_REF_COST); 5662 5663 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5664 "TWI $dst\n\t" 5665 "ISYNC" %} 5666 size(12); 5667 ins_encode( enc_lwz_ac(dst, mem) ); 5668 ins_pipe(pipe_class_memory); 5669 %} 5670 5671 // Match loading integer and casting it to unsigned int in 5672 // long register. 5673 // LoadI + ConvI2L + AndL 0xffffffff. 5674 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5675 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5676 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5677 ins_cost(MEMORY_REF_COST); 5678 5679 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5680 size(4); 5681 ins_encode( enc_lwz(dst, mem) ); 5682 ins_pipe(pipe_class_memory); 5683 %} 5684 5685 // Match loading integer and casting it to long. 5686 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5687 match(Set dst (ConvI2L (LoadI mem))); 5688 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5689 ins_cost(MEMORY_REF_COST); 5690 5691 format %{ "LWA $dst, $mem \t// loadI2L" %} 5692 size(4); 5693 ins_encode %{ 5694 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5695 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5696 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5697 %} 5698 ins_pipe(pipe_class_memory); 5699 %} 5700 5701 // Match loading integer and casting it to long - acquire. 5702 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5703 match(Set dst (ConvI2L (LoadI mem))); 5704 ins_cost(3*MEMORY_REF_COST); 5705 5706 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5707 "TWI $dst\n\t" 5708 "ISYNC" %} 5709 size(12); 5710 ins_encode %{ 5711 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5712 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5713 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5714 __ twi_0($dst$$Register); 5715 __ isync(); 5716 %} 5717 ins_pipe(pipe_class_memory); 5718 %} 5719 5720 // Load Long - aligned 5721 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5722 match(Set dst (LoadL mem)); 5723 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5724 ins_cost(MEMORY_REF_COST); 5725 5726 format %{ "LD $dst, $mem \t// long" %} 5727 size(4); 5728 ins_encode( enc_ld(dst, mem) ); 5729 ins_pipe(pipe_class_memory); 5730 %} 5731 5732 // Load Long - aligned acquire. 5733 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5734 match(Set dst (LoadL mem)); 5735 ins_cost(3*MEMORY_REF_COST); 5736 5737 format %{ "LD $dst, $mem \t// long acquire\n\t" 5738 "TWI $dst\n\t" 5739 "ISYNC" %} 5740 size(12); 5741 ins_encode( enc_ld_ac(dst, mem) ); 5742 ins_pipe(pipe_class_memory); 5743 %} 5744 5745 // Load Long - UNaligned 5746 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5747 match(Set dst (LoadL_unaligned mem)); 5748 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5749 ins_cost(MEMORY_REF_COST); 5750 5751 format %{ "LD $dst, $mem \t// unaligned long" %} 5752 size(4); 5753 ins_encode( enc_ld(dst, mem) ); 5754 ins_pipe(pipe_class_memory); 5755 %} 5756 5757 // Load nodes for superwords 5758 5759 // Load Aligned Packed Byte 5760 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5761 predicate(n->as_LoadVector()->memory_size() == 8); 5762 match(Set dst (LoadVector mem)); 5763 ins_cost(MEMORY_REF_COST); 5764 5765 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5766 size(4); 5767 ins_encode( enc_ld(dst, mem) ); 5768 ins_pipe(pipe_class_memory); 5769 %} 5770 5771 // Load Aligned Packed Byte 5772 instruct loadV16(vecX dst, indirect mem) %{ 5773 predicate(n->as_LoadVector()->memory_size() == 16); 5774 match(Set dst (LoadVector mem)); 5775 ins_cost(MEMORY_REF_COST); 5776 5777 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5778 size(4); 5779 ins_encode %{ 5780 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5781 %} 5782 ins_pipe(pipe_class_default); 5783 %} 5784 5785 // Load Range, range = array length (=jint) 5786 instruct loadRange(iRegIdst dst, memory mem) %{ 5787 match(Set dst (LoadRange mem)); 5788 ins_cost(MEMORY_REF_COST); 5789 5790 format %{ "LWZ $dst, $mem \t// range" %} 5791 size(4); 5792 ins_encode( enc_lwz(dst, mem) ); 5793 ins_pipe(pipe_class_memory); 5794 %} 5795 5796 // Load Compressed Pointer 5797 instruct loadN(iRegNdst dst, memory mem) %{ 5798 match(Set dst (LoadN mem)); 5799 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5800 ins_cost(MEMORY_REF_COST); 5801 5802 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5803 size(4); 5804 ins_encode( enc_lwz(dst, mem) ); 5805 ins_pipe(pipe_class_memory); 5806 %} 5807 5808 // Load Compressed Pointer acquire. 5809 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5810 match(Set dst (LoadN mem)); 5811 ins_cost(3*MEMORY_REF_COST); 5812 5813 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5814 "TWI $dst\n\t" 5815 "ISYNC" %} 5816 size(12); 5817 ins_encode( enc_lwz_ac(dst, mem) ); 5818 ins_pipe(pipe_class_memory); 5819 %} 5820 5821 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5822 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5823 match(Set dst (DecodeN (LoadN mem))); 5824 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5825 ins_cost(MEMORY_REF_COST); 5826 5827 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5828 size(4); 5829 ins_encode( enc_lwz(dst, mem) ); 5830 ins_pipe(pipe_class_memory); 5831 %} 5832 5833 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5834 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5835 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5836 _kids[0]->_leaf->as_Load()->is_unordered()); 5837 ins_cost(MEMORY_REF_COST); 5838 5839 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5840 size(4); 5841 ins_encode( enc_lwz(dst, mem) ); 5842 ins_pipe(pipe_class_memory); 5843 %} 5844 5845 // Load Pointer 5846 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5847 match(Set dst (LoadP mem)); 5848 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5849 ins_cost(MEMORY_REF_COST); 5850 5851 format %{ "LD $dst, $mem \t// ptr" %} 5852 size(4); 5853 ins_encode( enc_ld(dst, mem) ); 5854 ins_pipe(pipe_class_memory); 5855 %} 5856 5857 // Load Pointer acquire. 5858 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5859 match(Set dst (LoadP mem)); 5860 ins_cost(3*MEMORY_REF_COST); 5861 5862 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5863 "TWI $dst\n\t" 5864 "ISYNC" %} 5865 size(12); 5866 ins_encode( enc_ld_ac(dst, mem) ); 5867 ins_pipe(pipe_class_memory); 5868 %} 5869 5870 // LoadP + CastP2L 5871 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5872 match(Set dst (CastP2X (LoadP mem))); 5873 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5874 ins_cost(MEMORY_REF_COST); 5875 5876 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5877 size(4); 5878 ins_encode( enc_ld(dst, mem) ); 5879 ins_pipe(pipe_class_memory); 5880 %} 5881 5882 // Load compressed klass pointer. 5883 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5884 match(Set dst (LoadNKlass mem)); 5885 ins_cost(MEMORY_REF_COST); 5886 5887 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5888 size(4); 5889 ins_encode( enc_lwz(dst, mem) ); 5890 ins_pipe(pipe_class_memory); 5891 %} 5892 5893 // Load Klass Pointer 5894 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5895 match(Set dst (LoadKlass mem)); 5896 ins_cost(MEMORY_REF_COST); 5897 5898 format %{ "LD $dst, $mem \t// klass ptr" %} 5899 size(4); 5900 ins_encode( enc_ld(dst, mem) ); 5901 ins_pipe(pipe_class_memory); 5902 %} 5903 5904 // Load Float 5905 instruct loadF(regF dst, memory mem) %{ 5906 match(Set dst (LoadF mem)); 5907 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5908 ins_cost(MEMORY_REF_COST); 5909 5910 format %{ "LFS $dst, $mem" %} 5911 size(4); 5912 ins_encode %{ 5913 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5914 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5915 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5916 %} 5917 ins_pipe(pipe_class_memory); 5918 %} 5919 5920 // Load Float acquire. 5921 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5922 match(Set dst (LoadF mem)); 5923 effect(TEMP cr0); 5924 ins_cost(3*MEMORY_REF_COST); 5925 5926 format %{ "LFS $dst, $mem \t// acquire\n\t" 5927 "FCMPU cr0, $dst, $dst\n\t" 5928 "BNE cr0, next\n" 5929 "next:\n\t" 5930 "ISYNC" %} 5931 size(16); 5932 ins_encode %{ 5933 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5934 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5935 Label next; 5936 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5937 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5938 __ bne(CCR0, next); 5939 __ bind(next); 5940 __ isync(); 5941 %} 5942 ins_pipe(pipe_class_memory); 5943 %} 5944 5945 // Load Double - aligned 5946 instruct loadD(regD dst, memory mem) %{ 5947 match(Set dst (LoadD mem)); 5948 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5949 ins_cost(MEMORY_REF_COST); 5950 5951 format %{ "LFD $dst, $mem" %} 5952 size(4); 5953 ins_encode( enc_lfd(dst, mem) ); 5954 ins_pipe(pipe_class_memory); 5955 %} 5956 5957 // Load Double - aligned acquire. 5958 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5959 match(Set dst (LoadD mem)); 5960 effect(TEMP cr0); 5961 ins_cost(3*MEMORY_REF_COST); 5962 5963 format %{ "LFD $dst, $mem \t// acquire\n\t" 5964 "FCMPU cr0, $dst, $dst\n\t" 5965 "BNE cr0, next\n" 5966 "next:\n\t" 5967 "ISYNC" %} 5968 size(16); 5969 ins_encode %{ 5970 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5971 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5972 Label next; 5973 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5974 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5975 __ bne(CCR0, next); 5976 __ bind(next); 5977 __ isync(); 5978 %} 5979 ins_pipe(pipe_class_memory); 5980 %} 5981 5982 // Load Double - UNaligned 5983 instruct loadD_unaligned(regD dst, memory mem) %{ 5984 match(Set dst (LoadD_unaligned mem)); 5985 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5986 ins_cost(MEMORY_REF_COST); 5987 5988 format %{ "LFD $dst, $mem" %} 5989 size(4); 5990 ins_encode( enc_lfd(dst, mem) ); 5991 ins_pipe(pipe_class_memory); 5992 %} 5993 5994 //----------Constants-------------------------------------------------------- 5995 5996 // Load MachConstantTableBase: add hi offset to global toc. 5997 // TODO: Handle hidden register r29 in bundler! 5998 instruct loadToc_hi(iRegLdst dst) %{ 5999 effect(DEF dst); 6000 ins_cost(DEFAULT_COST); 6001 6002 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 6003 size(4); 6004 ins_encode %{ 6005 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6006 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 6007 %} 6008 ins_pipe(pipe_class_default); 6009 %} 6010 6011 // Load MachConstantTableBase: add lo offset to global toc. 6012 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 6013 effect(DEF dst, USE src); 6014 ins_cost(DEFAULT_COST); 6015 6016 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 6017 size(4); 6018 ins_encode %{ 6019 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6020 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 6021 %} 6022 ins_pipe(pipe_class_default); 6023 %} 6024 6025 // Load 16-bit integer constant 0xssss???? 6026 instruct loadConI16(iRegIdst dst, immI16 src) %{ 6027 match(Set dst src); 6028 6029 format %{ "LI $dst, $src" %} 6030 size(4); 6031 ins_encode %{ 6032 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6033 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6034 %} 6035 ins_pipe(pipe_class_default); 6036 %} 6037 6038 // Load integer constant 0x????0000 6039 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 6040 match(Set dst src); 6041 ins_cost(DEFAULT_COST); 6042 6043 format %{ "LIS $dst, $src.hi" %} 6044 size(4); 6045 ins_encode %{ 6046 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6047 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 6048 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6049 %} 6050 ins_pipe(pipe_class_default); 6051 %} 6052 6053 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 6054 // and sign extended), this adds the low 16 bits. 6055 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6056 // no match-rule, false predicate 6057 effect(DEF dst, USE src1, USE src2); 6058 predicate(false); 6059 6060 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6061 size(4); 6062 ins_encode %{ 6063 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6064 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6065 %} 6066 ins_pipe(pipe_class_default); 6067 %} 6068 6069 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6070 match(Set dst src); 6071 ins_cost(DEFAULT_COST*2); 6072 6073 expand %{ 6074 // Would like to use $src$$constant. 6075 immI16 srcLo %{ _opnds[1]->constant() %} 6076 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6077 immIhi16 srcHi %{ _opnds[1]->constant() %} 6078 iRegIdst tmpI; 6079 loadConIhi16(tmpI, srcHi); 6080 loadConI32_lo16(dst, tmpI, srcLo); 6081 %} 6082 %} 6083 6084 // No constant pool entries required. 6085 instruct loadConL16(iRegLdst dst, immL16 src) %{ 6086 match(Set dst src); 6087 6088 format %{ "LI $dst, $src \t// long" %} 6089 size(4); 6090 ins_encode %{ 6091 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6092 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6093 %} 6094 ins_pipe(pipe_class_default); 6095 %} 6096 6097 // Load long constant 0xssssssss????0000 6098 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6099 match(Set dst src); 6100 ins_cost(DEFAULT_COST); 6101 6102 format %{ "LIS $dst, $src.hi \t// long" %} 6103 size(4); 6104 ins_encode %{ 6105 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6106 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6107 %} 6108 ins_pipe(pipe_class_default); 6109 %} 6110 6111 // To load a 32 bit constant: merge lower 16 bits into already loaded 6112 // high 16 bits. 6113 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6114 // no match-rule, false predicate 6115 effect(DEF dst, USE src1, USE src2); 6116 predicate(false); 6117 6118 format %{ "ORI $dst, $src1, $src2.lo" %} 6119 size(4); 6120 ins_encode %{ 6121 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6122 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6123 %} 6124 ins_pipe(pipe_class_default); 6125 %} 6126 6127 // Load 32-bit long constant 6128 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6129 match(Set dst src); 6130 ins_cost(DEFAULT_COST*2); 6131 6132 expand %{ 6133 // Would like to use $src$$constant. 6134 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6135 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6136 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6137 iRegLdst tmpL; 6138 loadConL32hi16(tmpL, srcHi); 6139 loadConL32_lo16(dst, tmpL, srcLo); 6140 %} 6141 %} 6142 6143 // Load long constant 0x????000000000000. 6144 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6145 match(Set dst src); 6146 ins_cost(DEFAULT_COST); 6147 6148 expand %{ 6149 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6150 immI shift32 %{ 32 %} 6151 iRegLdst tmpL; 6152 loadConL32hi16(tmpL, srcHi); 6153 lshiftL_regL_immI(dst, tmpL, shift32); 6154 %} 6155 %} 6156 6157 // Expand node for constant pool load: small offset. 6158 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6159 effect(DEF dst, USE src, USE toc); 6160 ins_cost(MEMORY_REF_COST); 6161 6162 ins_num_consts(1); 6163 // Needed so that CallDynamicJavaDirect can compute the address of this 6164 // instruction for relocation. 6165 ins_field_cbuf_insts_offset(int); 6166 6167 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6168 size(4); 6169 ins_encode( enc_load_long_constL(dst, src, toc) ); 6170 ins_pipe(pipe_class_memory); 6171 %} 6172 6173 // Expand node for constant pool load: large offset. 6174 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6175 effect(DEF dst, USE src, USE toc); 6176 predicate(false); 6177 6178 ins_num_consts(1); 6179 ins_field_const_toc_offset(int); 6180 // Needed so that CallDynamicJavaDirect can compute the address of this 6181 // instruction for relocation. 6182 ins_field_cbuf_insts_offset(int); 6183 6184 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6185 size(4); 6186 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6187 ins_pipe(pipe_class_default); 6188 %} 6189 6190 // Expand node for constant pool load: large offset. 6191 // No constant pool entries required. 6192 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6193 effect(DEF dst, USE src, USE base); 6194 predicate(false); 6195 6196 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6197 6198 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6199 size(4); 6200 ins_encode %{ 6201 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6202 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6203 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6204 %} 6205 ins_pipe(pipe_class_memory); 6206 %} 6207 6208 // Load long constant from constant table. Expand in case of 6209 // offset > 16 bit is needed. 6210 // Adlc adds toc node MachConstantTableBase. 6211 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6212 match(Set dst src); 6213 ins_cost(MEMORY_REF_COST); 6214 6215 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6216 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6217 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6218 %} 6219 6220 // Load NULL as compressed oop. 6221 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6222 match(Set dst src); 6223 ins_cost(DEFAULT_COST); 6224 6225 format %{ "LI $dst, $src \t// compressed ptr" %} 6226 size(4); 6227 ins_encode %{ 6228 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6229 __ li($dst$$Register, 0); 6230 %} 6231 ins_pipe(pipe_class_default); 6232 %} 6233 6234 // Load hi part of compressed oop constant. 6235 instruct loadConN_hi(iRegNdst dst, immN src) %{ 6236 effect(DEF dst, USE src); 6237 ins_cost(DEFAULT_COST); 6238 6239 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6240 size(4); 6241 ins_encode %{ 6242 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6243 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6244 %} 6245 ins_pipe(pipe_class_default); 6246 %} 6247 6248 // Add lo part of compressed oop constant to already loaded hi part. 6249 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6250 effect(DEF dst, USE src1, USE src2); 6251 ins_cost(DEFAULT_COST); 6252 6253 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6254 size(4); 6255 ins_encode %{ 6256 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6257 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6258 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6259 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6260 __ relocate(rspec, 1); 6261 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6262 %} 6263 ins_pipe(pipe_class_default); 6264 %} 6265 6266 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6267 effect(DEF dst, USE src, USE shift, USE mask_begin); 6268 6269 size(4); 6270 ins_encode %{ 6271 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6272 %} 6273 ins_pipe(pipe_class_default); 6274 %} 6275 6276 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6277 // leaving the upper 32 bits with sign-extension bits. 6278 // This clears these bits: dst = src & 0xFFFFFFFF. 6279 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6280 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6281 effect(DEF dst, USE src); 6282 predicate(false); 6283 6284 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6285 size(4); 6286 ins_encode %{ 6287 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6288 __ clrldi($dst$$Register, $src$$Register, 0x20); 6289 %} 6290 ins_pipe(pipe_class_default); 6291 %} 6292 6293 // Optimize DecodeN for disjoint base. 6294 // Load base of compressed oops into a register 6295 instruct loadBase(iRegLdst dst) %{ 6296 effect(DEF dst); 6297 6298 format %{ "LoadConst $dst, heapbase" %} 6299 ins_encode %{ 6300 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6301 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 6302 %} 6303 ins_pipe(pipe_class_default); 6304 %} 6305 6306 // Loading ConN must be postalloc expanded so that edges between 6307 // the nodes are safe. They may not interfere with a safepoint. 6308 // GL TODO: This needs three instructions: better put this into the constant pool. 6309 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6310 match(Set dst src); 6311 ins_cost(DEFAULT_COST*2); 6312 6313 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6314 postalloc_expand %{ 6315 MachNode *m1 = new loadConN_hiNode(); 6316 MachNode *m2 = new loadConN_loNode(); 6317 MachNode *m3 = new clearMs32bNode(); 6318 m1->add_req(NULL); 6319 m2->add_req(NULL, m1); 6320 m3->add_req(NULL, m2); 6321 m1->_opnds[0] = op_dst; 6322 m1->_opnds[1] = op_src; 6323 m2->_opnds[0] = op_dst; 6324 m2->_opnds[1] = op_dst; 6325 m2->_opnds[2] = op_src; 6326 m3->_opnds[0] = op_dst; 6327 m3->_opnds[1] = op_dst; 6328 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6329 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6330 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6331 nodes->push(m1); 6332 nodes->push(m2); 6333 nodes->push(m3); 6334 %} 6335 %} 6336 6337 // We have seen a safepoint between the hi and lo parts, and this node was handled 6338 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6339 // not a narrow oop. 6340 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6341 match(Set dst src); 6342 effect(DEF dst, USE src); 6343 ins_cost(DEFAULT_COST); 6344 6345 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6346 size(4); 6347 ins_encode %{ 6348 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6349 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 6350 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6351 %} 6352 ins_pipe(pipe_class_default); 6353 %} 6354 6355 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6356 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6357 match(Set dst src1); 6358 effect(TEMP src2); 6359 ins_cost(DEFAULT_COST); 6360 6361 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6362 size(4); 6363 ins_encode %{ 6364 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6365 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6366 %} 6367 ins_pipe(pipe_class_default); 6368 %} 6369 6370 // This needs a match rule so that build_oop_map knows this is 6371 // not a narrow oop. 6372 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6373 match(Set dst src1); 6374 effect(TEMP src2); 6375 ins_cost(DEFAULT_COST); 6376 6377 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6378 size(4); 6379 ins_encode %{ 6380 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6381 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 6382 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6383 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6384 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6385 6386 __ relocate(rspec, 1); 6387 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6388 %} 6389 ins_pipe(pipe_class_default); 6390 %} 6391 6392 // Loading ConNKlass must be postalloc expanded so that edges between 6393 // the nodes are safe. They may not interfere with a safepoint. 6394 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6395 match(Set dst src); 6396 ins_cost(DEFAULT_COST*2); 6397 6398 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6399 postalloc_expand %{ 6400 // Load high bits into register. Sign extended. 6401 MachNode *m1 = new loadConNKlass_hiNode(); 6402 m1->add_req(NULL); 6403 m1->_opnds[0] = op_dst; 6404 m1->_opnds[1] = op_src; 6405 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6406 nodes->push(m1); 6407 6408 MachNode *m2 = m1; 6409 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 6410 // Value might be 1-extended. Mask out these bits. 6411 m2 = new loadConNKlass_maskNode(); 6412 m2->add_req(NULL, m1); 6413 m2->_opnds[0] = op_dst; 6414 m2->_opnds[1] = op_src; 6415 m2->_opnds[2] = op_dst; 6416 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6417 nodes->push(m2); 6418 } 6419 6420 MachNode *m3 = new loadConNKlass_loNode(); 6421 m3->add_req(NULL, m2); 6422 m3->_opnds[0] = op_dst; 6423 m3->_opnds[1] = op_src; 6424 m3->_opnds[2] = op_dst; 6425 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6426 nodes->push(m3); 6427 %} 6428 %} 6429 6430 // 0x1 is used in object initialization (initial object header). 6431 // No constant pool entries required. 6432 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6433 match(Set dst src); 6434 6435 format %{ "LI $dst, $src \t// ptr" %} 6436 size(4); 6437 ins_encode %{ 6438 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6439 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6440 %} 6441 ins_pipe(pipe_class_default); 6442 %} 6443 6444 // Expand node for constant pool load: small offset. 6445 // The match rule is needed to generate the correct bottom_type(), 6446 // however this node should never match. The use of predicate is not 6447 // possible since ADLC forbids predicates for chain rules. The higher 6448 // costs do not prevent matching in this case. For that reason the 6449 // operand immP_NM with predicate(false) is used. 6450 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6451 match(Set dst src); 6452 effect(TEMP toc); 6453 6454 ins_num_consts(1); 6455 6456 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6457 size(4); 6458 ins_encode( enc_load_long_constP(dst, src, toc) ); 6459 ins_pipe(pipe_class_memory); 6460 %} 6461 6462 // Expand node for constant pool load: large offset. 6463 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6464 effect(DEF dst, USE src, USE toc); 6465 predicate(false); 6466 6467 ins_num_consts(1); 6468 ins_field_const_toc_offset(int); 6469 6470 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6471 size(4); 6472 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6473 ins_pipe(pipe_class_default); 6474 %} 6475 6476 // Expand node for constant pool load: large offset. 6477 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6478 match(Set dst src); 6479 effect(TEMP base); 6480 6481 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6482 6483 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6484 size(4); 6485 ins_encode %{ 6486 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6487 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6488 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6489 %} 6490 ins_pipe(pipe_class_memory); 6491 %} 6492 6493 // Load pointer constant from constant table. Expand in case an 6494 // offset > 16 bit is needed. 6495 // Adlc adds toc node MachConstantTableBase. 6496 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6497 match(Set dst src); 6498 ins_cost(MEMORY_REF_COST); 6499 6500 // This rule does not use "expand" because then 6501 // the result type is not known to be an Oop. An ADLC 6502 // enhancement will be needed to make that work - not worth it! 6503 6504 // If this instruction rematerializes, it prolongs the live range 6505 // of the toc node, causing illegal graphs. 6506 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6507 ins_cannot_rematerialize(true); 6508 6509 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6510 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6511 %} 6512 6513 // Expand node for constant pool load: small offset. 6514 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6515 effect(DEF dst, USE src, USE toc); 6516 ins_cost(MEMORY_REF_COST); 6517 6518 ins_num_consts(1); 6519 6520 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6521 size(4); 6522 ins_encode %{ 6523 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6524 address float_address = __ float_constant($src$$constant); 6525 if (float_address == NULL) { 6526 ciEnv::current()->record_out_of_memory_failure(); 6527 return; 6528 } 6529 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6530 %} 6531 ins_pipe(pipe_class_memory); 6532 %} 6533 6534 // Expand node for constant pool load: large offset. 6535 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6536 effect(DEF dst, USE src, USE toc); 6537 ins_cost(MEMORY_REF_COST); 6538 6539 ins_num_consts(1); 6540 6541 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6542 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6543 "ADDIS $toc, $toc, -offset_hi"%} 6544 size(12); 6545 ins_encode %{ 6546 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6547 FloatRegister Rdst = $dst$$FloatRegister; 6548 Register Rtoc = $toc$$Register; 6549 address float_address = __ float_constant($src$$constant); 6550 if (float_address == NULL) { 6551 ciEnv::current()->record_out_of_memory_failure(); 6552 return; 6553 } 6554 int offset = __ offset_to_method_toc(float_address); 6555 int hi = (offset + (1<<15))>>16; 6556 int lo = offset - hi * (1<<16); 6557 6558 __ addis(Rtoc, Rtoc, hi); 6559 __ lfs(Rdst, lo, Rtoc); 6560 __ addis(Rtoc, Rtoc, -hi); 6561 %} 6562 ins_pipe(pipe_class_memory); 6563 %} 6564 6565 // Adlc adds toc node MachConstantTableBase. 6566 instruct loadConF_Ex(regF dst, immF src) %{ 6567 match(Set dst src); 6568 ins_cost(MEMORY_REF_COST); 6569 6570 // See loadConP. 6571 ins_cannot_rematerialize(true); 6572 6573 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6574 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6575 %} 6576 6577 // Expand node for constant pool load: small offset. 6578 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6579 effect(DEF dst, USE src, USE toc); 6580 ins_cost(MEMORY_REF_COST); 6581 6582 ins_num_consts(1); 6583 6584 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6585 size(4); 6586 ins_encode %{ 6587 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6588 address float_address = __ double_constant($src$$constant); 6589 if (float_address == NULL) { 6590 ciEnv::current()->record_out_of_memory_failure(); 6591 return; 6592 } 6593 int offset = __ offset_to_method_toc(float_address); 6594 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6595 %} 6596 ins_pipe(pipe_class_memory); 6597 %} 6598 6599 // Expand node for constant pool load: large offset. 6600 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6601 effect(DEF dst, USE src, USE toc); 6602 ins_cost(MEMORY_REF_COST); 6603 6604 ins_num_consts(1); 6605 6606 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6607 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6608 "ADDIS $toc, $toc, -offset_hi" %} 6609 size(12); 6610 ins_encode %{ 6611 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6612 FloatRegister Rdst = $dst$$FloatRegister; 6613 Register Rtoc = $toc$$Register; 6614 address float_address = __ double_constant($src$$constant); 6615 if (float_address == NULL) { 6616 ciEnv::current()->record_out_of_memory_failure(); 6617 return; 6618 } 6619 int offset = __ offset_to_method_toc(float_address); 6620 int hi = (offset + (1<<15))>>16; 6621 int lo = offset - hi * (1<<16); 6622 6623 __ addis(Rtoc, Rtoc, hi); 6624 __ lfd(Rdst, lo, Rtoc); 6625 __ addis(Rtoc, Rtoc, -hi); 6626 %} 6627 ins_pipe(pipe_class_memory); 6628 %} 6629 6630 // Adlc adds toc node MachConstantTableBase. 6631 instruct loadConD_Ex(regD dst, immD src) %{ 6632 match(Set dst src); 6633 ins_cost(MEMORY_REF_COST); 6634 6635 // See loadConP. 6636 ins_cannot_rematerialize(true); 6637 6638 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6639 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6640 %} 6641 6642 // Prefetch instructions. 6643 // Must be safe to execute with invalid address (cannot fault). 6644 6645 // Special prefetch versions which use the dcbz instruction. 6646 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6647 match(PrefetchAllocation (AddP mem src)); 6648 predicate(AllocatePrefetchStyle == 3); 6649 ins_cost(MEMORY_REF_COST); 6650 6651 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6652 size(4); 6653 ins_encode %{ 6654 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6655 __ dcbz($src$$Register, $mem$$base$$Register); 6656 %} 6657 ins_pipe(pipe_class_memory); 6658 %} 6659 6660 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6661 match(PrefetchAllocation mem); 6662 predicate(AllocatePrefetchStyle == 3); 6663 ins_cost(MEMORY_REF_COST); 6664 6665 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6666 size(4); 6667 ins_encode %{ 6668 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6669 __ dcbz($mem$$base$$Register); 6670 %} 6671 ins_pipe(pipe_class_memory); 6672 %} 6673 6674 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6675 match(PrefetchAllocation (AddP mem src)); 6676 predicate(AllocatePrefetchStyle != 3); 6677 ins_cost(MEMORY_REF_COST); 6678 6679 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6680 size(4); 6681 ins_encode %{ 6682 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6683 __ dcbtst($src$$Register, $mem$$base$$Register); 6684 %} 6685 ins_pipe(pipe_class_memory); 6686 %} 6687 6688 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6689 match(PrefetchAllocation mem); 6690 predicate(AllocatePrefetchStyle != 3); 6691 ins_cost(MEMORY_REF_COST); 6692 6693 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6694 size(4); 6695 ins_encode %{ 6696 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6697 __ dcbtst($mem$$base$$Register); 6698 %} 6699 ins_pipe(pipe_class_memory); 6700 %} 6701 6702 //----------Store Instructions------------------------------------------------- 6703 6704 // Store Byte 6705 instruct storeB(memory mem, iRegIsrc src) %{ 6706 match(Set mem (StoreB mem src)); 6707 ins_cost(MEMORY_REF_COST); 6708 6709 format %{ "STB $src, $mem \t// byte" %} 6710 size(4); 6711 ins_encode %{ 6712 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6713 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6714 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6715 %} 6716 ins_pipe(pipe_class_memory); 6717 %} 6718 6719 // Store Char/Short 6720 instruct storeC(memory mem, iRegIsrc src) %{ 6721 match(Set mem (StoreC mem src)); 6722 ins_cost(MEMORY_REF_COST); 6723 6724 format %{ "STH $src, $mem \t// short" %} 6725 size(4); 6726 ins_encode %{ 6727 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6728 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6729 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6730 %} 6731 ins_pipe(pipe_class_memory); 6732 %} 6733 6734 // Store Integer 6735 instruct storeI(memory mem, iRegIsrc src) %{ 6736 match(Set mem (StoreI mem src)); 6737 ins_cost(MEMORY_REF_COST); 6738 6739 format %{ "STW $src, $mem" %} 6740 size(4); 6741 ins_encode( enc_stw(src, mem) ); 6742 ins_pipe(pipe_class_memory); 6743 %} 6744 6745 // ConvL2I + StoreI. 6746 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6747 match(Set mem (StoreI mem (ConvL2I src))); 6748 ins_cost(MEMORY_REF_COST); 6749 6750 format %{ "STW l2i($src), $mem" %} 6751 size(4); 6752 ins_encode( enc_stw(src, mem) ); 6753 ins_pipe(pipe_class_memory); 6754 %} 6755 6756 // Store Long 6757 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6758 match(Set mem (StoreL mem src)); 6759 ins_cost(MEMORY_REF_COST); 6760 6761 format %{ "STD $src, $mem \t// long" %} 6762 size(4); 6763 ins_encode( enc_std(src, mem) ); 6764 ins_pipe(pipe_class_memory); 6765 %} 6766 6767 // Store super word nodes. 6768 6769 // Store Aligned Packed Byte long register to memory 6770 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6771 predicate(n->as_StoreVector()->memory_size() == 8); 6772 match(Set mem (StoreVector mem src)); 6773 ins_cost(MEMORY_REF_COST); 6774 6775 format %{ "STD $mem, $src \t// packed8B" %} 6776 size(4); 6777 ins_encode( enc_std(src, mem) ); 6778 ins_pipe(pipe_class_memory); 6779 %} 6780 6781 // Store Packed Byte long register to memory 6782 instruct storeV16(indirect mem, vecX src) %{ 6783 predicate(n->as_StoreVector()->memory_size() == 16); 6784 match(Set mem (StoreVector mem src)); 6785 ins_cost(MEMORY_REF_COST); 6786 6787 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6788 size(4); 6789 ins_encode %{ 6790 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6791 %} 6792 ins_pipe(pipe_class_default); 6793 %} 6794 6795 // Store Compressed Oop 6796 instruct storeN(memory dst, iRegN_P2N src) %{ 6797 match(Set dst (StoreN dst src)); 6798 ins_cost(MEMORY_REF_COST); 6799 6800 format %{ "STW $src, $dst \t// compressed oop" %} 6801 size(4); 6802 ins_encode( enc_stw(src, dst) ); 6803 ins_pipe(pipe_class_memory); 6804 %} 6805 6806 // Store Compressed KLass 6807 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6808 match(Set dst (StoreNKlass dst src)); 6809 ins_cost(MEMORY_REF_COST); 6810 6811 format %{ "STW $src, $dst \t// compressed klass" %} 6812 size(4); 6813 ins_encode( enc_stw(src, dst) ); 6814 ins_pipe(pipe_class_memory); 6815 %} 6816 6817 // Store Pointer 6818 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6819 match(Set dst (StoreP dst src)); 6820 ins_cost(MEMORY_REF_COST); 6821 6822 format %{ "STD $src, $dst \t// ptr" %} 6823 size(4); 6824 ins_encode( enc_std(src, dst) ); 6825 ins_pipe(pipe_class_memory); 6826 %} 6827 6828 // Store Float 6829 instruct storeF(memory mem, regF src) %{ 6830 match(Set mem (StoreF mem src)); 6831 ins_cost(MEMORY_REF_COST); 6832 6833 format %{ "STFS $src, $mem" %} 6834 size(4); 6835 ins_encode( enc_stfs(src, mem) ); 6836 ins_pipe(pipe_class_memory); 6837 %} 6838 6839 // Store Double 6840 instruct storeD(memory mem, regD src) %{ 6841 match(Set mem (StoreD mem src)); 6842 ins_cost(MEMORY_REF_COST); 6843 6844 format %{ "STFD $src, $mem" %} 6845 size(4); 6846 ins_encode( enc_stfd(src, mem) ); 6847 ins_pipe(pipe_class_memory); 6848 %} 6849 6850 //----------Store Instructions With Zeros-------------------------------------- 6851 6852 // Card-mark for CMS garbage collection. 6853 // This cardmark does an optimization so that it must not always 6854 // do a releasing store. For this, it gets the address of 6855 // CMSCollectorCardTableBarrierSetBSExt::_requires_release as input. 6856 // (Using releaseFieldAddr in the match rule is a hack.) 6857 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6858 match(Set mem (StoreCM mem releaseFieldAddr)); 6859 effect(TEMP crx); 6860 predicate(false); 6861 ins_cost(MEMORY_REF_COST); 6862 6863 // See loadConP. 6864 ins_cannot_rematerialize(true); 6865 6866 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6867 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6868 ins_pipe(pipe_class_memory); 6869 %} 6870 6871 // Card-mark for CMS garbage collection. 6872 // This cardmark does an optimization so that it must not always 6873 // do a releasing store. For this, it needs the constant address of 6874 // CMSCollectorCardTableBarrierSetBSExt::_requires_release. 6875 // This constant address is split off here by expand so we can use 6876 // adlc / matcher functionality to load it from the constant section. 6877 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6878 match(Set mem (StoreCM mem zero)); 6879 predicate(UseConcMarkSweepGC); 6880 6881 expand %{ 6882 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableBarrierSetBSExt::requires_release_address() */ %} 6883 iRegLdst releaseFieldAddress; 6884 flagsReg crx; 6885 loadConL_Ex(releaseFieldAddress, baseImm); 6886 storeCM_CMS(mem, releaseFieldAddress, crx); 6887 %} 6888 %} 6889 6890 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6891 match(Set mem (StoreCM mem zero)); 6892 predicate(UseG1GC); 6893 ins_cost(MEMORY_REF_COST); 6894 6895 ins_cannot_rematerialize(true); 6896 6897 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6898 size(8); 6899 ins_encode %{ 6900 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6901 __ li(R0, 0); 6902 //__ release(); // G1: oops are allowed to get visible after dirty marking 6903 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6904 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6905 %} 6906 ins_pipe(pipe_class_memory); 6907 %} 6908 6909 // Convert oop pointer into compressed form. 6910 6911 // Nodes for postalloc expand. 6912 6913 // Shift node for expand. 6914 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6915 // The match rule is needed to make it a 'MachTypeNode'! 6916 match(Set dst (EncodeP src)); 6917 predicate(false); 6918 6919 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6920 size(4); 6921 ins_encode %{ 6922 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6923 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6924 %} 6925 ins_pipe(pipe_class_default); 6926 %} 6927 6928 // Add node for expand. 6929 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6930 // The match rule is needed to make it a 'MachTypeNode'! 6931 match(Set dst (EncodeP src)); 6932 predicate(false); 6933 6934 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6935 ins_encode %{ 6936 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6937 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6938 %} 6939 ins_pipe(pipe_class_default); 6940 %} 6941 6942 // Conditional sub base. 6943 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6944 // The match rule is needed to make it a 'MachTypeNode'! 6945 match(Set dst (EncodeP (Binary crx src1))); 6946 predicate(false); 6947 6948 format %{ "BEQ $crx, done\n\t" 6949 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6950 "done:" %} 6951 ins_encode %{ 6952 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6953 Label done; 6954 __ beq($crx$$CondRegister, done); 6955 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6956 __ bind(done); 6957 %} 6958 ins_pipe(pipe_class_default); 6959 %} 6960 6961 // Power 7 can use isel instruction 6962 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6963 // The match rule is needed to make it a 'MachTypeNode'! 6964 match(Set dst (EncodeP (Binary crx src1))); 6965 predicate(false); 6966 6967 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6968 size(4); 6969 ins_encode %{ 6970 // This is a Power7 instruction for which no machine description exists. 6971 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6972 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6973 %} 6974 ins_pipe(pipe_class_default); 6975 %} 6976 6977 // Disjoint narrow oop base. 6978 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6979 match(Set dst (EncodeP src)); 6980 predicate(Universe::narrow_oop_base_disjoint()); 6981 6982 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6983 size(4); 6984 ins_encode %{ 6985 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6986 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 6987 %} 6988 ins_pipe(pipe_class_default); 6989 %} 6990 6991 // shift != 0, base != 0 6992 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6993 match(Set dst (EncodeP src)); 6994 effect(TEMP crx); 6995 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6996 Universe::narrow_oop_shift() != 0 && 6997 Universe::narrow_oop_base_overlaps()); 6998 6999 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 7000 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 7001 %} 7002 7003 // shift != 0, base != 0 7004 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 7005 match(Set dst (EncodeP src)); 7006 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 7007 Universe::narrow_oop_shift() != 0 && 7008 Universe::narrow_oop_base_overlaps()); 7009 7010 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 7011 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 7012 %} 7013 7014 // shift != 0, base == 0 7015 // TODO: This is the same as encodeP_shift. Merge! 7016 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 7017 match(Set dst (EncodeP src)); 7018 predicate(Universe::narrow_oop_shift() != 0 && 7019 Universe::narrow_oop_base() ==0); 7020 7021 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 7022 size(4); 7023 ins_encode %{ 7024 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7025 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 7026 %} 7027 ins_pipe(pipe_class_default); 7028 %} 7029 7030 // Compressed OOPs with narrow_oop_shift == 0. 7031 // shift == 0, base == 0 7032 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 7033 match(Set dst (EncodeP src)); 7034 predicate(Universe::narrow_oop_shift() == 0); 7035 7036 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 7037 // variable size, 0 or 4. 7038 ins_encode %{ 7039 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7040 __ mr_if_needed($dst$$Register, $src$$Register); 7041 %} 7042 ins_pipe(pipe_class_default); 7043 %} 7044 7045 // Decode nodes. 7046 7047 // Shift node for expand. 7048 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 7049 // The match rule is needed to make it a 'MachTypeNode'! 7050 match(Set dst (DecodeN src)); 7051 predicate(false); 7052 7053 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 7054 size(4); 7055 ins_encode %{ 7056 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7057 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7058 %} 7059 ins_pipe(pipe_class_default); 7060 %} 7061 7062 // Add node for expand. 7063 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7064 // The match rule is needed to make it a 'MachTypeNode'! 7065 match(Set dst (DecodeN src)); 7066 predicate(false); 7067 7068 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7069 ins_encode %{ 7070 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7071 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7072 %} 7073 ins_pipe(pipe_class_default); 7074 %} 7075 7076 // conditianal add base for expand 7077 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7078 // The match rule is needed to make it a 'MachTypeNode'! 7079 // NOTICE that the rule is nonsense - we just have to make sure that: 7080 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7081 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7082 match(Set dst (DecodeN (Binary crx src))); 7083 predicate(false); 7084 7085 format %{ "BEQ $crx, done\n\t" 7086 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7087 "done:" %} 7088 ins_encode %{ 7089 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7090 Label done; 7091 __ beq($crx$$CondRegister, done); 7092 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7093 __ bind(done); 7094 %} 7095 ins_pipe(pipe_class_default); 7096 %} 7097 7098 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7099 // The match rule is needed to make it a 'MachTypeNode'! 7100 // NOTICE that the rule is nonsense - we just have to make sure that: 7101 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7102 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7103 match(Set dst (DecodeN (Binary crx src1))); 7104 predicate(false); 7105 7106 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7107 size(4); 7108 ins_encode %{ 7109 // This is a Power7 instruction for which no machine description exists. 7110 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7111 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7112 %} 7113 ins_pipe(pipe_class_default); 7114 %} 7115 7116 // shift != 0, base != 0 7117 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7118 match(Set dst (DecodeN src)); 7119 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7120 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7121 Universe::narrow_oop_shift() != 0 && 7122 Universe::narrow_oop_base() != 0); 7123 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7124 effect(TEMP crx); 7125 7126 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7127 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7128 %} 7129 7130 // shift != 0, base == 0 7131 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7132 match(Set dst (DecodeN src)); 7133 predicate(Universe::narrow_oop_shift() != 0 && 7134 Universe::narrow_oop_base() == 0); 7135 7136 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7137 size(4); 7138 ins_encode %{ 7139 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7140 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7141 %} 7142 ins_pipe(pipe_class_default); 7143 %} 7144 7145 // Optimize DecodeN for disjoint base. 7146 // Shift narrow oop and or it into register that already contains the heap base. 7147 // Base == dst must hold, and is assured by construction in postaloc_expand. 7148 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7149 match(Set dst (DecodeN src)); 7150 effect(TEMP base); 7151 predicate(false); 7152 7153 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7154 size(4); 7155 ins_encode %{ 7156 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7157 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 7158 %} 7159 ins_pipe(pipe_class_default); 7160 %} 7161 7162 // Optimize DecodeN for disjoint base. 7163 // This node requires only one cycle on the critical path. 7164 // We must postalloc_expand as we can not express use_def effects where 7165 // the used register is L and the def'ed register P. 7166 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7167 match(Set dst (DecodeN src)); 7168 effect(TEMP_DEF dst); 7169 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7170 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7171 Universe::narrow_oop_base_disjoint()); 7172 ins_cost(DEFAULT_COST); 7173 7174 format %{ "MOV $dst, heapbase \t\n" 7175 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7176 postalloc_expand %{ 7177 loadBaseNode *n1 = new loadBaseNode(); 7178 n1->add_req(NULL); 7179 n1->_opnds[0] = op_dst; 7180 7181 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7182 n2->add_req(n_region, n_src, n1); 7183 n2->_opnds[0] = op_dst; 7184 n2->_opnds[1] = op_src; 7185 n2->_opnds[2] = op_dst; 7186 n2->_bottom_type = _bottom_type; 7187 7188 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7189 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7190 7191 nodes->push(n1); 7192 nodes->push(n2); 7193 %} 7194 %} 7195 7196 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7197 match(Set dst (DecodeN src)); 7198 effect(TEMP_DEF dst, TEMP crx); 7199 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7200 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7201 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 7202 ins_cost(3 * DEFAULT_COST); 7203 7204 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7205 postalloc_expand %{ 7206 loadBaseNode *n1 = new loadBaseNode(); 7207 n1->add_req(NULL); 7208 n1->_opnds[0] = op_dst; 7209 7210 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7211 n_compare->add_req(n_region, n_src); 7212 n_compare->_opnds[0] = op_crx; 7213 n_compare->_opnds[1] = op_src; 7214 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7215 7216 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7217 n2->add_req(n_region, n_src, n1); 7218 n2->_opnds[0] = op_dst; 7219 n2->_opnds[1] = op_src; 7220 n2->_opnds[2] = op_dst; 7221 n2->_bottom_type = _bottom_type; 7222 7223 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7224 n_cond_set->add_req(n_region, n_compare, n2); 7225 n_cond_set->_opnds[0] = op_dst; 7226 n_cond_set->_opnds[1] = op_crx; 7227 n_cond_set->_opnds[2] = op_dst; 7228 n_cond_set->_bottom_type = _bottom_type; 7229 7230 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7231 ra_->set_oop(n_cond_set, true); 7232 7233 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7234 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7235 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7236 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7237 7238 nodes->push(n1); 7239 nodes->push(n_compare); 7240 nodes->push(n2); 7241 nodes->push(n_cond_set); 7242 %} 7243 %} 7244 7245 // src != 0, shift != 0, base != 0 7246 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7247 match(Set dst (DecodeN src)); 7248 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7249 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7250 Universe::narrow_oop_shift() != 0 && 7251 Universe::narrow_oop_base() != 0); 7252 ins_cost(2 * DEFAULT_COST); 7253 7254 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7255 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7256 %} 7257 7258 // Compressed OOPs with narrow_oop_shift == 0. 7259 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7260 match(Set dst (DecodeN src)); 7261 predicate(Universe::narrow_oop_shift() == 0); 7262 ins_cost(DEFAULT_COST); 7263 7264 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7265 // variable size, 0 or 4. 7266 ins_encode %{ 7267 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7268 __ mr_if_needed($dst$$Register, $src$$Register); 7269 %} 7270 ins_pipe(pipe_class_default); 7271 %} 7272 7273 // Convert compressed oop into int for vectors alignment masking. 7274 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7275 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7276 predicate(Universe::narrow_oop_shift() == 0); 7277 ins_cost(DEFAULT_COST); 7278 7279 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7280 // variable size, 0 or 4. 7281 ins_encode %{ 7282 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7283 __ mr_if_needed($dst$$Register, $src$$Register); 7284 %} 7285 ins_pipe(pipe_class_default); 7286 %} 7287 7288 // Convert klass pointer into compressed form. 7289 7290 // Nodes for postalloc expand. 7291 7292 // Shift node for expand. 7293 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7294 // The match rule is needed to make it a 'MachTypeNode'! 7295 match(Set dst (EncodePKlass src)); 7296 predicate(false); 7297 7298 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7299 size(4); 7300 ins_encode %{ 7301 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7302 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7303 %} 7304 ins_pipe(pipe_class_default); 7305 %} 7306 7307 // Add node for expand. 7308 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7309 // The match rule is needed to make it a 'MachTypeNode'! 7310 match(Set dst (EncodePKlass (Binary base src))); 7311 predicate(false); 7312 7313 format %{ "SUB $dst, $base, $src \t// encode" %} 7314 size(4); 7315 ins_encode %{ 7316 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7317 __ subf($dst$$Register, $base$$Register, $src$$Register); 7318 %} 7319 ins_pipe(pipe_class_default); 7320 %} 7321 7322 // Disjoint narrow oop base. 7323 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7324 match(Set dst (EncodePKlass src)); 7325 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 7326 7327 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7328 size(4); 7329 ins_encode %{ 7330 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7331 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 7332 %} 7333 ins_pipe(pipe_class_default); 7334 %} 7335 7336 // shift != 0, base != 0 7337 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7338 match(Set dst (EncodePKlass (Binary base src))); 7339 predicate(false); 7340 7341 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7342 postalloc_expand %{ 7343 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7344 n1->add_req(n_region, n_base, n_src); 7345 n1->_opnds[0] = op_dst; 7346 n1->_opnds[1] = op_base; 7347 n1->_opnds[2] = op_src; 7348 n1->_bottom_type = _bottom_type; 7349 7350 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7351 n2->add_req(n_region, n1); 7352 n2->_opnds[0] = op_dst; 7353 n2->_opnds[1] = op_dst; 7354 n2->_bottom_type = _bottom_type; 7355 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7356 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7357 7358 nodes->push(n1); 7359 nodes->push(n2); 7360 %} 7361 %} 7362 7363 // shift != 0, base != 0 7364 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7365 match(Set dst (EncodePKlass src)); 7366 //predicate(Universe::narrow_klass_shift() != 0 && 7367 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 7368 7369 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7370 ins_cost(DEFAULT_COST*2); // Don't count constant. 7371 expand %{ 7372 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 7373 iRegLdst base; 7374 loadConL_Ex(base, baseImm); 7375 encodePKlass_not_null_Ex(dst, base, src); 7376 %} 7377 %} 7378 7379 // Decode nodes. 7380 7381 // Shift node for expand. 7382 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7383 // The match rule is needed to make it a 'MachTypeNode'! 7384 match(Set dst (DecodeNKlass src)); 7385 predicate(false); 7386 7387 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7388 size(4); 7389 ins_encode %{ 7390 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7391 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7392 %} 7393 ins_pipe(pipe_class_default); 7394 %} 7395 7396 // Add node for expand. 7397 7398 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7399 // The match rule is needed to make it a 'MachTypeNode'! 7400 match(Set dst (DecodeNKlass (Binary base src))); 7401 predicate(false); 7402 7403 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7404 size(4); 7405 ins_encode %{ 7406 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7407 __ add($dst$$Register, $base$$Register, $src$$Register); 7408 %} 7409 ins_pipe(pipe_class_default); 7410 %} 7411 7412 // src != 0, shift != 0, base != 0 7413 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7414 match(Set dst (DecodeNKlass (Binary base src))); 7415 //effect(kill src); // We need a register for the immediate result after shifting. 7416 predicate(false); 7417 7418 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7419 postalloc_expand %{ 7420 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7421 n1->add_req(n_region, n_base, n_src); 7422 n1->_opnds[0] = op_dst; 7423 n1->_opnds[1] = op_base; 7424 n1->_opnds[2] = op_src; 7425 n1->_bottom_type = _bottom_type; 7426 7427 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7428 n2->add_req(n_region, n1); 7429 n2->_opnds[0] = op_dst; 7430 n2->_opnds[1] = op_dst; 7431 n2->_bottom_type = _bottom_type; 7432 7433 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7434 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7435 7436 nodes->push(n1); 7437 nodes->push(n2); 7438 %} 7439 %} 7440 7441 // src != 0, shift != 0, base != 0 7442 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7443 match(Set dst (DecodeNKlass src)); 7444 // predicate(Universe::narrow_klass_shift() != 0 && 7445 // Universe::narrow_klass_base() != 0); 7446 7447 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7448 7449 ins_cost(DEFAULT_COST*2); // Don't count constant. 7450 expand %{ 7451 // We add first, then we shift. Like this, we can get along with one register less. 7452 // But we have to load the base pre-shifted. 7453 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7454 iRegLdst base; 7455 loadConL_Ex(base, baseImm); 7456 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7457 %} 7458 %} 7459 7460 //----------MemBar Instructions----------------------------------------------- 7461 // Memory barrier flavors 7462 7463 instruct membar_acquire() %{ 7464 match(LoadFence); 7465 ins_cost(4*MEMORY_REF_COST); 7466 7467 format %{ "MEMBAR-acquire" %} 7468 size(4); 7469 ins_encode %{ 7470 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7471 __ acquire(); 7472 %} 7473 ins_pipe(pipe_class_default); 7474 %} 7475 7476 instruct unnecessary_membar_acquire() %{ 7477 match(MemBarAcquire); 7478 ins_cost(0); 7479 7480 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7481 size(0); 7482 ins_encode( /*empty*/ ); 7483 ins_pipe(pipe_class_default); 7484 %} 7485 7486 instruct membar_acquire_lock() %{ 7487 match(MemBarAcquireLock); 7488 ins_cost(0); 7489 7490 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7491 size(0); 7492 ins_encode( /*empty*/ ); 7493 ins_pipe(pipe_class_default); 7494 %} 7495 7496 instruct membar_release() %{ 7497 match(MemBarRelease); 7498 match(StoreFence); 7499 ins_cost(4*MEMORY_REF_COST); 7500 7501 format %{ "MEMBAR-release" %} 7502 size(4); 7503 ins_encode %{ 7504 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7505 __ release(); 7506 %} 7507 ins_pipe(pipe_class_default); 7508 %} 7509 7510 instruct membar_storestore() %{ 7511 match(MemBarStoreStore); 7512 ins_cost(4*MEMORY_REF_COST); 7513 7514 format %{ "MEMBAR-store-store" %} 7515 size(4); 7516 ins_encode %{ 7517 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7518 __ membar(Assembler::StoreStore); 7519 %} 7520 ins_pipe(pipe_class_default); 7521 %} 7522 7523 instruct membar_release_lock() %{ 7524 match(MemBarReleaseLock); 7525 ins_cost(0); 7526 7527 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7528 size(0); 7529 ins_encode( /*empty*/ ); 7530 ins_pipe(pipe_class_default); 7531 %} 7532 7533 instruct membar_volatile() %{ 7534 match(MemBarVolatile); 7535 ins_cost(4*MEMORY_REF_COST); 7536 7537 format %{ "MEMBAR-volatile" %} 7538 size(4); 7539 ins_encode %{ 7540 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7541 __ fence(); 7542 %} 7543 ins_pipe(pipe_class_default); 7544 %} 7545 7546 // This optimization is wrong on PPC. The following pattern is not supported: 7547 // MemBarVolatile 7548 // ^ ^ 7549 // | | 7550 // CtrlProj MemProj 7551 // ^ ^ 7552 // | | 7553 // | Load 7554 // | 7555 // MemBarVolatile 7556 // 7557 // The first MemBarVolatile could get optimized out! According to 7558 // Vladimir, this pattern can not occur on Oracle platforms. 7559 // However, it does occur on PPC64 (because of membars in 7560 // inline_unsafe_load_store). 7561 // 7562 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7563 // Don't forget to look at the implementation of post_store_load_barrier again, 7564 // we did other fixes in that method. 7565 //instruct unnecessary_membar_volatile() %{ 7566 // match(MemBarVolatile); 7567 // predicate(Matcher::post_store_load_barrier(n)); 7568 // ins_cost(0); 7569 // 7570 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7571 // size(0); 7572 // ins_encode( /*empty*/ ); 7573 // ins_pipe(pipe_class_default); 7574 //%} 7575 7576 instruct membar_CPUOrder() %{ 7577 match(MemBarCPUOrder); 7578 ins_cost(0); 7579 7580 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7581 size(0); 7582 ins_encode( /*empty*/ ); 7583 ins_pipe(pipe_class_default); 7584 %} 7585 7586 //----------Conditional Move--------------------------------------------------- 7587 7588 // Cmove using isel. 7589 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7590 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7591 predicate(VM_Version::has_isel()); 7592 ins_cost(DEFAULT_COST); 7593 7594 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7595 size(4); 7596 ins_encode %{ 7597 // This is a Power7 instruction for which no machine description 7598 // exists. Anyways, the scheduler should be off on Power7. 7599 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7600 int cc = $cmp$$cmpcode; 7601 __ isel($dst$$Register, $crx$$CondRegister, 7602 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7603 %} 7604 ins_pipe(pipe_class_default); 7605 %} 7606 7607 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7608 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7609 predicate(!VM_Version::has_isel()); 7610 ins_cost(DEFAULT_COST+BRANCH_COST); 7611 7612 ins_variable_size_depending_on_alignment(true); 7613 7614 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7615 // Worst case is branch + move + stop, no stop without scheduler 7616 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7617 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7618 ins_pipe(pipe_class_default); 7619 %} 7620 7621 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7622 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7623 ins_cost(DEFAULT_COST+BRANCH_COST); 7624 7625 ins_variable_size_depending_on_alignment(true); 7626 7627 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7628 // Worst case is branch + move + stop, no stop without scheduler 7629 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7630 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7631 ins_pipe(pipe_class_default); 7632 %} 7633 7634 // Cmove using isel. 7635 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7636 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7637 predicate(VM_Version::has_isel()); 7638 ins_cost(DEFAULT_COST); 7639 7640 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7641 size(4); 7642 ins_encode %{ 7643 // This is a Power7 instruction for which no machine description 7644 // exists. Anyways, the scheduler should be off on Power7. 7645 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7646 int cc = $cmp$$cmpcode; 7647 __ isel($dst$$Register, $crx$$CondRegister, 7648 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7649 %} 7650 ins_pipe(pipe_class_default); 7651 %} 7652 7653 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7654 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7655 predicate(!VM_Version::has_isel()); 7656 ins_cost(DEFAULT_COST+BRANCH_COST); 7657 7658 ins_variable_size_depending_on_alignment(true); 7659 7660 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7661 // Worst case is branch + move + stop, no stop without scheduler. 7662 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7663 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7664 ins_pipe(pipe_class_default); 7665 %} 7666 7667 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7668 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7669 ins_cost(DEFAULT_COST+BRANCH_COST); 7670 7671 ins_variable_size_depending_on_alignment(true); 7672 7673 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7674 // Worst case is branch + move + stop, no stop without scheduler. 7675 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7676 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7677 ins_pipe(pipe_class_default); 7678 %} 7679 7680 // Cmove using isel. 7681 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7682 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7683 predicate(VM_Version::has_isel()); 7684 ins_cost(DEFAULT_COST); 7685 7686 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7687 size(4); 7688 ins_encode %{ 7689 // This is a Power7 instruction for which no machine description 7690 // exists. Anyways, the scheduler should be off on Power7. 7691 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7692 int cc = $cmp$$cmpcode; 7693 __ isel($dst$$Register, $crx$$CondRegister, 7694 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7695 %} 7696 ins_pipe(pipe_class_default); 7697 %} 7698 7699 // Conditional move for RegN. Only cmov(reg, reg). 7700 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7701 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7702 predicate(!VM_Version::has_isel()); 7703 ins_cost(DEFAULT_COST+BRANCH_COST); 7704 7705 ins_variable_size_depending_on_alignment(true); 7706 7707 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7708 // Worst case is branch + move + stop, no stop without scheduler. 7709 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7710 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7711 ins_pipe(pipe_class_default); 7712 %} 7713 7714 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7715 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7716 ins_cost(DEFAULT_COST+BRANCH_COST); 7717 7718 ins_variable_size_depending_on_alignment(true); 7719 7720 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7721 // Worst case is branch + move + stop, no stop without scheduler. 7722 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7723 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7724 ins_pipe(pipe_class_default); 7725 %} 7726 7727 // Cmove using isel. 7728 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7729 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7730 predicate(VM_Version::has_isel()); 7731 ins_cost(DEFAULT_COST); 7732 7733 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7734 size(4); 7735 ins_encode %{ 7736 // This is a Power7 instruction for which no machine description 7737 // exists. Anyways, the scheduler should be off on Power7. 7738 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7739 int cc = $cmp$$cmpcode; 7740 __ isel($dst$$Register, $crx$$CondRegister, 7741 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7742 %} 7743 ins_pipe(pipe_class_default); 7744 %} 7745 7746 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7747 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7748 predicate(!VM_Version::has_isel()); 7749 ins_cost(DEFAULT_COST+BRANCH_COST); 7750 7751 ins_variable_size_depending_on_alignment(true); 7752 7753 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7754 // Worst case is branch + move + stop, no stop without scheduler. 7755 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7756 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7757 ins_pipe(pipe_class_default); 7758 %} 7759 7760 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7761 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7762 ins_cost(DEFAULT_COST+BRANCH_COST); 7763 7764 ins_variable_size_depending_on_alignment(true); 7765 7766 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7767 // Worst case is branch + move + stop, no stop without scheduler. 7768 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7769 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7770 ins_pipe(pipe_class_default); 7771 %} 7772 7773 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7774 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7775 ins_cost(DEFAULT_COST+BRANCH_COST); 7776 7777 ins_variable_size_depending_on_alignment(true); 7778 7779 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7780 // Worst case is branch + move + stop, no stop without scheduler. 7781 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7782 ins_encode %{ 7783 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7784 Label done; 7785 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7786 // Branch if not (cmp crx). 7787 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7788 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7789 // TODO PPC port __ endgroup_if_needed(_size == 12); 7790 __ bind(done); 7791 %} 7792 ins_pipe(pipe_class_default); 7793 %} 7794 7795 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7796 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7797 ins_cost(DEFAULT_COST+BRANCH_COST); 7798 7799 ins_variable_size_depending_on_alignment(true); 7800 7801 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7802 // Worst case is branch + move + stop, no stop without scheduler. 7803 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7804 ins_encode %{ 7805 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7806 Label done; 7807 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7808 // Branch if not (cmp crx). 7809 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7810 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7811 // TODO PPC port __ endgroup_if_needed(_size == 12); 7812 __ bind(done); 7813 %} 7814 ins_pipe(pipe_class_default); 7815 %} 7816 7817 //----------Conditional_store-------------------------------------------------- 7818 // Conditional-store of the updated heap-top. 7819 // Used during allocation of the shared heap. 7820 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7821 7822 // As compareAndSwapL, but return flag register instead of boolean value in 7823 // int register. 7824 // Used by sun/misc/AtomicLongCSImpl.java. 7825 // Mem_ptr must be a memory operand, else this node does not get 7826 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7827 // can be rematerialized which leads to errors. 7828 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7829 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7830 effect(TEMP cr0); 7831 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7832 ins_encode %{ 7833 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7834 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7835 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7836 noreg, NULL, true); 7837 %} 7838 ins_pipe(pipe_class_default); 7839 %} 7840 7841 // As compareAndSwapP, but return flag register instead of boolean value in 7842 // int register. 7843 // This instruction is matched if UseTLAB is off. 7844 // Mem_ptr must be a memory operand, else this node does not get 7845 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7846 // can be rematerialized which leads to errors. 7847 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7848 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7849 ins_cost(2*MEMORY_REF_COST); 7850 7851 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7852 ins_encode %{ 7853 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7854 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7855 %} 7856 ins_pipe(pipe_class_memory); 7857 %} 7858 7859 // Implement LoadPLocked. Must be ordered against changes of the memory location 7860 // by storePConditional. 7861 // Don't know whether this is ever used. 7862 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7863 match(Set dst (LoadPLocked mem)); 7864 ins_cost(2*MEMORY_REF_COST); 7865 7866 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7867 size(4); 7868 ins_encode %{ 7869 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7870 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7871 %} 7872 ins_pipe(pipe_class_memory); 7873 %} 7874 7875 //----------Compare-And-Swap--------------------------------------------------- 7876 7877 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7878 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7879 // matched. 7880 7881 // Strong versions: 7882 7883 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7884 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7885 predicate(VM_Version::has_lqarx()); 7886 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7887 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7888 ins_encode %{ 7889 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7890 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7891 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7892 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7893 $res$$Register, true); 7894 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7895 __ isync(); 7896 } else { 7897 __ sync(); 7898 } 7899 %} 7900 ins_pipe(pipe_class_default); 7901 %} 7902 7903 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7904 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7905 predicate(!VM_Version::has_lqarx()); 7906 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7907 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7908 ins_encode %{ 7909 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7910 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7911 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7912 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7913 $res$$Register, true); 7914 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7915 __ isync(); 7916 } else { 7917 __ sync(); 7918 } 7919 %} 7920 ins_pipe(pipe_class_default); 7921 %} 7922 7923 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7924 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7925 predicate(VM_Version::has_lqarx()); 7926 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7927 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7928 ins_encode %{ 7929 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7930 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7931 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7932 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7933 $res$$Register, true); 7934 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7935 __ isync(); 7936 } else { 7937 __ sync(); 7938 } 7939 %} 7940 ins_pipe(pipe_class_default); 7941 %} 7942 7943 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7944 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7945 predicate(!VM_Version::has_lqarx()); 7946 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7947 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7948 ins_encode %{ 7949 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7950 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7951 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7952 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7953 $res$$Register, true); 7954 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7955 __ isync(); 7956 } else { 7957 __ sync(); 7958 } 7959 %} 7960 ins_pipe(pipe_class_default); 7961 %} 7962 7963 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7964 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7965 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7966 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7967 ins_encode %{ 7968 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7969 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7970 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7971 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7972 $res$$Register, true); 7973 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7974 __ isync(); 7975 } else { 7976 __ sync(); 7977 } 7978 %} 7979 ins_pipe(pipe_class_default); 7980 %} 7981 7982 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7983 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7984 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7985 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7986 ins_encode %{ 7987 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7988 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7989 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7990 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7991 $res$$Register, true); 7992 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7993 __ isync(); 7994 } else { 7995 __ sync(); 7996 } 7997 %} 7998 ins_pipe(pipe_class_default); 7999 %} 8000 8001 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8002 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 8003 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8004 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8005 ins_encode %{ 8006 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8007 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8008 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8009 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8010 $res$$Register, NULL, true); 8011 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8012 __ isync(); 8013 } else { 8014 __ sync(); 8015 } 8016 %} 8017 ins_pipe(pipe_class_default); 8018 %} 8019 8020 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8021 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 8022 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8023 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8024 ins_encode %{ 8025 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8026 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8027 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8028 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8029 $res$$Register, NULL, true); 8030 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8031 __ isync(); 8032 } else { 8033 __ sync(); 8034 } 8035 %} 8036 ins_pipe(pipe_class_default); 8037 %} 8038 8039 // Weak versions: 8040 8041 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8042 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8043 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8044 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8045 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8046 ins_encode %{ 8047 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8048 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8049 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8050 MacroAssembler::MemBarNone, 8051 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8052 %} 8053 ins_pipe(pipe_class_default); 8054 %} 8055 8056 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8057 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8058 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8059 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8060 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8061 ins_encode %{ 8062 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8063 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8064 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8065 MacroAssembler::MemBarNone, 8066 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8067 %} 8068 ins_pipe(pipe_class_default); 8069 %} 8070 8071 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8072 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8073 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8074 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8075 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8076 ins_encode %{ 8077 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8078 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8079 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8080 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8081 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8082 %} 8083 ins_pipe(pipe_class_default); 8084 %} 8085 8086 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8087 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8088 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8089 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8090 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8091 ins_encode %{ 8092 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8093 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8094 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8095 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8096 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8097 %} 8098 ins_pipe(pipe_class_default); 8099 %} 8100 8101 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8102 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8103 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8104 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8105 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8106 ins_encode %{ 8107 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8108 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8109 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8110 MacroAssembler::MemBarNone, 8111 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8112 %} 8113 ins_pipe(pipe_class_default); 8114 %} 8115 8116 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8117 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8118 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8119 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8120 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8121 ins_encode %{ 8122 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8123 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8124 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8125 MacroAssembler::MemBarNone, 8126 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8127 %} 8128 ins_pipe(pipe_class_default); 8129 %} 8130 8131 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8132 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8133 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8134 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8135 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8136 ins_encode %{ 8137 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8138 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8139 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8140 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8141 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8142 %} 8143 ins_pipe(pipe_class_default); 8144 %} 8145 8146 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8147 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8148 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8149 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8150 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8151 ins_encode %{ 8152 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8153 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8154 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8155 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8156 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8157 %} 8158 ins_pipe(pipe_class_default); 8159 %} 8160 8161 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8162 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8163 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8164 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8165 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8166 ins_encode %{ 8167 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8168 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8169 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8170 MacroAssembler::MemBarNone, 8171 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8172 %} 8173 ins_pipe(pipe_class_default); 8174 %} 8175 8176 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8177 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8178 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8179 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8180 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8181 ins_encode %{ 8182 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8183 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8184 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8185 // value is never passed to caller. 8186 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8187 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8188 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8189 %} 8190 ins_pipe(pipe_class_default); 8191 %} 8192 8193 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8194 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8195 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8196 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8197 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8198 ins_encode %{ 8199 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8200 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8201 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8202 MacroAssembler::MemBarNone, 8203 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8204 %} 8205 ins_pipe(pipe_class_default); 8206 %} 8207 8208 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8209 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8210 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8211 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8212 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8213 ins_encode %{ 8214 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8215 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8216 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8217 // value is never passed to caller. 8218 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8219 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8220 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8221 %} 8222 ins_pipe(pipe_class_default); 8223 %} 8224 8225 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8226 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8227 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8228 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8229 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8230 ins_encode %{ 8231 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8232 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8233 // value is never passed to caller. 8234 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8235 MacroAssembler::MemBarNone, 8236 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8237 %} 8238 ins_pipe(pipe_class_default); 8239 %} 8240 8241 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8242 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8243 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8244 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8245 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 8246 ins_encode %{ 8247 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8248 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8249 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8250 // value is never passed to caller. 8251 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8252 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8253 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8254 %} 8255 ins_pipe(pipe_class_default); 8256 %} 8257 8258 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8259 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8260 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8261 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8262 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8263 ins_encode %{ 8264 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8265 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8266 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8267 MacroAssembler::MemBarNone, 8268 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8269 %} 8270 ins_pipe(pipe_class_default); 8271 %} 8272 8273 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8274 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8275 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8276 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8277 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8278 ins_encode %{ 8279 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8280 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8281 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8282 // value is never passed to caller. 8283 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8284 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8285 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8286 %} 8287 ins_pipe(pipe_class_default); 8288 %} 8289 8290 // CompareAndExchange 8291 8292 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8293 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8294 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8295 effect(TEMP_DEF res, TEMP cr0); 8296 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8297 ins_encode %{ 8298 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8299 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8300 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8301 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8302 noreg, true); 8303 %} 8304 ins_pipe(pipe_class_default); 8305 %} 8306 8307 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8308 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8309 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8310 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8311 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8312 ins_encode %{ 8313 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8314 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8315 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8316 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8317 noreg, true); 8318 %} 8319 ins_pipe(pipe_class_default); 8320 %} 8321 8322 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8323 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8324 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8325 effect(TEMP_DEF res, TEMP cr0); 8326 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8327 ins_encode %{ 8328 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8329 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8330 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8331 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8332 noreg, true); 8333 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8334 __ isync(); 8335 } else { 8336 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8337 __ sync(); 8338 } 8339 %} 8340 ins_pipe(pipe_class_default); 8341 %} 8342 8343 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8344 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8345 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8346 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8347 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8348 ins_encode %{ 8349 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8350 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8351 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8352 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8353 noreg, true); 8354 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8355 __ isync(); 8356 } else { 8357 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8358 __ sync(); 8359 } 8360 %} 8361 ins_pipe(pipe_class_default); 8362 %} 8363 8364 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8365 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8366 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8367 effect(TEMP_DEF res, TEMP cr0); 8368 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8369 ins_encode %{ 8370 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8371 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8372 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8373 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8374 noreg, true); 8375 %} 8376 ins_pipe(pipe_class_default); 8377 %} 8378 8379 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8380 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8381 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8382 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8383 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8384 ins_encode %{ 8385 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8386 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8387 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8388 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8389 noreg, true); 8390 %} 8391 ins_pipe(pipe_class_default); 8392 %} 8393 8394 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8395 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8396 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8397 effect(TEMP_DEF res, TEMP cr0); 8398 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8399 ins_encode %{ 8400 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8401 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8402 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8403 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8404 noreg, true); 8405 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8406 __ isync(); 8407 } else { 8408 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8409 __ sync(); 8410 } 8411 %} 8412 ins_pipe(pipe_class_default); 8413 %} 8414 8415 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8416 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8417 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8418 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8419 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8420 ins_encode %{ 8421 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8422 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8423 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8424 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8425 noreg, true); 8426 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8427 __ isync(); 8428 } else { 8429 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8430 __ sync(); 8431 } 8432 %} 8433 ins_pipe(pipe_class_default); 8434 %} 8435 8436 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8437 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8438 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8439 effect(TEMP_DEF res, TEMP cr0); 8440 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8441 ins_encode %{ 8442 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8443 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8444 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8445 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8446 noreg, true); 8447 %} 8448 ins_pipe(pipe_class_default); 8449 %} 8450 8451 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8452 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8453 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8454 effect(TEMP_DEF res, TEMP cr0); 8455 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8456 ins_encode %{ 8457 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8458 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8459 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8460 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8461 noreg, true); 8462 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8463 __ isync(); 8464 } else { 8465 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8466 __ sync(); 8467 } 8468 %} 8469 ins_pipe(pipe_class_default); 8470 %} 8471 8472 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8473 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8474 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8475 effect(TEMP_DEF res, TEMP cr0); 8476 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8477 ins_encode %{ 8478 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8479 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8480 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8481 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8482 noreg, true); 8483 %} 8484 ins_pipe(pipe_class_default); 8485 %} 8486 8487 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8488 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8489 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8490 effect(TEMP_DEF res, TEMP cr0); 8491 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8492 ins_encode %{ 8493 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8494 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8495 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8496 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8497 noreg, true); 8498 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8499 __ isync(); 8500 } else { 8501 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8502 __ sync(); 8503 } 8504 %} 8505 ins_pipe(pipe_class_default); 8506 %} 8507 8508 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8509 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8510 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8511 effect(TEMP_DEF res, TEMP cr0); 8512 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8513 ins_encode %{ 8514 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8515 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8516 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8517 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8518 noreg, NULL, true); 8519 %} 8520 ins_pipe(pipe_class_default); 8521 %} 8522 8523 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8524 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8525 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8526 effect(TEMP_DEF res, TEMP cr0); 8527 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8528 ins_encode %{ 8529 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8530 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8531 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8532 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8533 noreg, NULL, true); 8534 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8535 __ isync(); 8536 } else { 8537 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8538 __ sync(); 8539 } 8540 %} 8541 ins_pipe(pipe_class_default); 8542 %} 8543 8544 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8545 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8546 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8547 effect(TEMP_DEF res, TEMP cr0); 8548 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8549 ins_encode %{ 8550 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8551 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8552 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8553 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8554 noreg, NULL, true); 8555 %} 8556 ins_pipe(pipe_class_default); 8557 %} 8558 8559 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8560 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8561 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8562 effect(TEMP_DEF res, TEMP cr0); 8563 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8564 ins_encode %{ 8565 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8566 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8567 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8568 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8569 noreg, NULL, true); 8570 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8571 __ isync(); 8572 } else { 8573 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8574 __ sync(); 8575 } 8576 %} 8577 ins_pipe(pipe_class_default); 8578 %} 8579 8580 // Special RMW 8581 8582 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8583 match(Set res (GetAndAddB mem_ptr src)); 8584 predicate(VM_Version::has_lqarx()); 8585 effect(TEMP_DEF res, TEMP cr0); 8586 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8587 ins_encode %{ 8588 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8589 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8590 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8591 __ isync(); 8592 } else { 8593 __ sync(); 8594 } 8595 %} 8596 ins_pipe(pipe_class_default); 8597 %} 8598 8599 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8600 match(Set res (GetAndAddB mem_ptr src)); 8601 predicate(!VM_Version::has_lqarx()); 8602 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8603 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8604 ins_encode %{ 8605 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8606 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8607 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8608 __ isync(); 8609 } else { 8610 __ sync(); 8611 } 8612 %} 8613 ins_pipe(pipe_class_default); 8614 %} 8615 8616 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8617 match(Set res (GetAndAddS mem_ptr src)); 8618 predicate(VM_Version::has_lqarx()); 8619 effect(TEMP_DEF res, TEMP cr0); 8620 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8621 ins_encode %{ 8622 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8623 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8624 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8625 __ isync(); 8626 } else { 8627 __ sync(); 8628 } 8629 %} 8630 ins_pipe(pipe_class_default); 8631 %} 8632 8633 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8634 match(Set res (GetAndAddS mem_ptr src)); 8635 predicate(!VM_Version::has_lqarx()); 8636 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8637 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8638 ins_encode %{ 8639 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8640 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8641 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8642 __ isync(); 8643 } else { 8644 __ sync(); 8645 } 8646 %} 8647 ins_pipe(pipe_class_default); 8648 %} 8649 8650 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8651 match(Set res (GetAndAddI mem_ptr src)); 8652 effect(TEMP_DEF res, TEMP cr0); 8653 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8654 ins_encode %{ 8655 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8656 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8657 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8658 __ isync(); 8659 } else { 8660 __ sync(); 8661 } 8662 %} 8663 ins_pipe(pipe_class_default); 8664 %} 8665 8666 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8667 match(Set res (GetAndAddL mem_ptr src)); 8668 effect(TEMP_DEF res, TEMP cr0); 8669 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8670 ins_encode %{ 8671 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8672 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8673 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8674 __ isync(); 8675 } else { 8676 __ sync(); 8677 } 8678 %} 8679 ins_pipe(pipe_class_default); 8680 %} 8681 8682 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8683 match(Set res (GetAndSetB mem_ptr src)); 8684 predicate(VM_Version::has_lqarx()); 8685 effect(TEMP_DEF res, TEMP cr0); 8686 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8687 ins_encode %{ 8688 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8689 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8690 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8691 __ isync(); 8692 } else { 8693 __ sync(); 8694 } 8695 %} 8696 ins_pipe(pipe_class_default); 8697 %} 8698 8699 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8700 match(Set res (GetAndSetB mem_ptr src)); 8701 predicate(!VM_Version::has_lqarx()); 8702 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8703 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8704 ins_encode %{ 8705 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8706 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8707 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8708 __ isync(); 8709 } else { 8710 __ sync(); 8711 } 8712 %} 8713 ins_pipe(pipe_class_default); 8714 %} 8715 8716 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8717 match(Set res (GetAndSetS mem_ptr src)); 8718 predicate(VM_Version::has_lqarx()); 8719 effect(TEMP_DEF res, TEMP cr0); 8720 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8721 ins_encode %{ 8722 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8723 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8724 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8725 __ isync(); 8726 } else { 8727 __ sync(); 8728 } 8729 %} 8730 ins_pipe(pipe_class_default); 8731 %} 8732 8733 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8734 match(Set res (GetAndSetS mem_ptr src)); 8735 predicate(!VM_Version::has_lqarx()); 8736 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8737 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8738 ins_encode %{ 8739 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8740 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8741 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8742 __ isync(); 8743 } else { 8744 __ sync(); 8745 } 8746 %} 8747 ins_pipe(pipe_class_default); 8748 %} 8749 8750 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8751 match(Set res (GetAndSetI mem_ptr src)); 8752 effect(TEMP_DEF res, TEMP cr0); 8753 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8754 ins_encode %{ 8755 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8756 MacroAssembler::cmpxchgx_hint_atomic_update()); 8757 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8758 __ isync(); 8759 } else { 8760 __ sync(); 8761 } 8762 %} 8763 ins_pipe(pipe_class_default); 8764 %} 8765 8766 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8767 match(Set res (GetAndSetL mem_ptr src)); 8768 effect(TEMP_DEF res, TEMP cr0); 8769 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8770 ins_encode %{ 8771 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8772 MacroAssembler::cmpxchgx_hint_atomic_update()); 8773 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8774 __ isync(); 8775 } else { 8776 __ sync(); 8777 } 8778 %} 8779 ins_pipe(pipe_class_default); 8780 %} 8781 8782 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8783 match(Set res (GetAndSetP mem_ptr src)); 8784 effect(TEMP_DEF res, TEMP cr0); 8785 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8786 ins_encode %{ 8787 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8788 MacroAssembler::cmpxchgx_hint_atomic_update()); 8789 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8790 __ isync(); 8791 } else { 8792 __ sync(); 8793 } 8794 %} 8795 ins_pipe(pipe_class_default); 8796 %} 8797 8798 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8799 match(Set res (GetAndSetN mem_ptr src)); 8800 effect(TEMP_DEF res, TEMP cr0); 8801 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8802 ins_encode %{ 8803 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8804 MacroAssembler::cmpxchgx_hint_atomic_update()); 8805 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8806 __ isync(); 8807 } else { 8808 __ sync(); 8809 } 8810 %} 8811 ins_pipe(pipe_class_default); 8812 %} 8813 8814 //----------Arithmetic Instructions-------------------------------------------- 8815 // Addition Instructions 8816 8817 // Register Addition 8818 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8819 match(Set dst (AddI src1 src2)); 8820 format %{ "ADD $dst, $src1, $src2" %} 8821 size(4); 8822 ins_encode %{ 8823 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8824 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8825 %} 8826 ins_pipe(pipe_class_default); 8827 %} 8828 8829 // Expand does not work with above instruct. (??) 8830 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8831 // no match-rule 8832 effect(DEF dst, USE src1, USE src2); 8833 format %{ "ADD $dst, $src1, $src2" %} 8834 size(4); 8835 ins_encode %{ 8836 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8837 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8838 %} 8839 ins_pipe(pipe_class_default); 8840 %} 8841 8842 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8843 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8844 ins_cost(DEFAULT_COST*3); 8845 8846 expand %{ 8847 // FIXME: we should do this in the ideal world. 8848 iRegIdst tmp1; 8849 iRegIdst tmp2; 8850 addI_reg_reg(tmp1, src1, src2); 8851 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8852 addI_reg_reg(dst, tmp1, tmp2); 8853 %} 8854 %} 8855 8856 // Immediate Addition 8857 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8858 match(Set dst (AddI src1 src2)); 8859 format %{ "ADDI $dst, $src1, $src2" %} 8860 size(4); 8861 ins_encode %{ 8862 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8863 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8864 %} 8865 ins_pipe(pipe_class_default); 8866 %} 8867 8868 // Immediate Addition with 16-bit shifted operand 8869 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8870 match(Set dst (AddI src1 src2)); 8871 format %{ "ADDIS $dst, $src1, $src2" %} 8872 size(4); 8873 ins_encode %{ 8874 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8875 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8876 %} 8877 ins_pipe(pipe_class_default); 8878 %} 8879 8880 // Long Addition 8881 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8882 match(Set dst (AddL src1 src2)); 8883 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8884 size(4); 8885 ins_encode %{ 8886 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8887 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8888 %} 8889 ins_pipe(pipe_class_default); 8890 %} 8891 8892 // Expand does not work with above instruct. (??) 8893 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8894 // no match-rule 8895 effect(DEF dst, USE src1, USE src2); 8896 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8897 size(4); 8898 ins_encode %{ 8899 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8900 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8901 %} 8902 ins_pipe(pipe_class_default); 8903 %} 8904 8905 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8906 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8907 ins_cost(DEFAULT_COST*3); 8908 8909 expand %{ 8910 // FIXME: we should do this in the ideal world. 8911 iRegLdst tmp1; 8912 iRegLdst tmp2; 8913 addL_reg_reg(tmp1, src1, src2); 8914 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8915 addL_reg_reg(dst, tmp1, tmp2); 8916 %} 8917 %} 8918 8919 // AddL + ConvL2I. 8920 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8921 match(Set dst (ConvL2I (AddL src1 src2))); 8922 8923 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8924 size(4); 8925 ins_encode %{ 8926 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8927 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8928 %} 8929 ins_pipe(pipe_class_default); 8930 %} 8931 8932 // No constant pool entries required. 8933 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8934 match(Set dst (AddL src1 src2)); 8935 8936 format %{ "ADDI $dst, $src1, $src2" %} 8937 size(4); 8938 ins_encode %{ 8939 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8940 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8941 %} 8942 ins_pipe(pipe_class_default); 8943 %} 8944 8945 // Long Immediate Addition with 16-bit shifted operand. 8946 // No constant pool entries required. 8947 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8948 match(Set dst (AddL src1 src2)); 8949 8950 format %{ "ADDIS $dst, $src1, $src2" %} 8951 size(4); 8952 ins_encode %{ 8953 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8954 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8955 %} 8956 ins_pipe(pipe_class_default); 8957 %} 8958 8959 // Pointer Register Addition 8960 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8961 match(Set dst (AddP src1 src2)); 8962 format %{ "ADD $dst, $src1, $src2" %} 8963 size(4); 8964 ins_encode %{ 8965 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8966 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8967 %} 8968 ins_pipe(pipe_class_default); 8969 %} 8970 8971 // Pointer Immediate Addition 8972 // No constant pool entries required. 8973 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8974 match(Set dst (AddP src1 src2)); 8975 8976 format %{ "ADDI $dst, $src1, $src2" %} 8977 size(4); 8978 ins_encode %{ 8979 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8980 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8981 %} 8982 ins_pipe(pipe_class_default); 8983 %} 8984 8985 // Pointer Immediate Addition with 16-bit shifted operand. 8986 // No constant pool entries required. 8987 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8988 match(Set dst (AddP src1 src2)); 8989 8990 format %{ "ADDIS $dst, $src1, $src2" %} 8991 size(4); 8992 ins_encode %{ 8993 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8994 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8995 %} 8996 ins_pipe(pipe_class_default); 8997 %} 8998 8999 //--------------------- 9000 // Subtraction Instructions 9001 9002 // Register Subtraction 9003 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9004 match(Set dst (SubI src1 src2)); 9005 format %{ "SUBF $dst, $src2, $src1" %} 9006 size(4); 9007 ins_encode %{ 9008 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9009 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9010 %} 9011 ins_pipe(pipe_class_default); 9012 %} 9013 9014 // Immediate Subtraction 9015 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 9016 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 9017 9018 // SubI from constant (using subfic). 9019 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 9020 match(Set dst (SubI src1 src2)); 9021 format %{ "SUBI $dst, $src1, $src2" %} 9022 9023 size(4); 9024 ins_encode %{ 9025 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 9026 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 9027 %} 9028 ins_pipe(pipe_class_default); 9029 %} 9030 9031 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 9032 // positive integers and 0xF...F for negative ones. 9033 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 9034 // no match-rule, false predicate 9035 effect(DEF dst, USE src); 9036 predicate(false); 9037 9038 format %{ "SRAWI $dst, $src, #31" %} 9039 size(4); 9040 ins_encode %{ 9041 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9042 __ srawi($dst$$Register, $src$$Register, 0x1f); 9043 %} 9044 ins_pipe(pipe_class_default); 9045 %} 9046 9047 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 9048 match(Set dst (AbsI src)); 9049 ins_cost(DEFAULT_COST*3); 9050 9051 expand %{ 9052 iRegIdst tmp1; 9053 iRegIdst tmp2; 9054 signmask32I_regI(tmp1, src); 9055 xorI_reg_reg(tmp2, tmp1, src); 9056 subI_reg_reg(dst, tmp2, tmp1); 9057 %} 9058 %} 9059 9060 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9061 match(Set dst (SubI zero src2)); 9062 format %{ "NEG $dst, $src2" %} 9063 size(4); 9064 ins_encode %{ 9065 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9066 __ neg($dst$$Register, $src2$$Register); 9067 %} 9068 ins_pipe(pipe_class_default); 9069 %} 9070 9071 // Long subtraction 9072 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9073 match(Set dst (SubL src1 src2)); 9074 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9075 size(4); 9076 ins_encode %{ 9077 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9078 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9079 %} 9080 ins_pipe(pipe_class_default); 9081 %} 9082 9083 // SubL + convL2I. 9084 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9085 match(Set dst (ConvL2I (SubL src1 src2))); 9086 9087 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9088 size(4); 9089 ins_encode %{ 9090 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9091 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9092 %} 9093 ins_pipe(pipe_class_default); 9094 %} 9095 9096 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9097 // positive longs and 0xF...F for negative ones. 9098 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9099 // no match-rule, false predicate 9100 effect(DEF dst, USE src); 9101 predicate(false); 9102 9103 format %{ "SRADI $dst, $src, #63" %} 9104 size(4); 9105 ins_encode %{ 9106 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9107 __ sradi($dst$$Register, $src$$Register, 0x3f); 9108 %} 9109 ins_pipe(pipe_class_default); 9110 %} 9111 9112 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9113 // positive longs and 0xF...F for negative ones. 9114 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9115 // no match-rule, false predicate 9116 effect(DEF dst, USE src); 9117 predicate(false); 9118 9119 format %{ "SRADI $dst, $src, #63" %} 9120 size(4); 9121 ins_encode %{ 9122 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9123 __ sradi($dst$$Register, $src$$Register, 0x3f); 9124 %} 9125 ins_pipe(pipe_class_default); 9126 %} 9127 9128 // Long negation 9129 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9130 match(Set dst (SubL zero src2)); 9131 format %{ "NEG $dst, $src2 \t// long" %} 9132 size(4); 9133 ins_encode %{ 9134 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9135 __ neg($dst$$Register, $src2$$Register); 9136 %} 9137 ins_pipe(pipe_class_default); 9138 %} 9139 9140 // NegL + ConvL2I. 9141 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9142 match(Set dst (ConvL2I (SubL zero src2))); 9143 9144 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9145 size(4); 9146 ins_encode %{ 9147 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9148 __ neg($dst$$Register, $src2$$Register); 9149 %} 9150 ins_pipe(pipe_class_default); 9151 %} 9152 9153 // Multiplication Instructions 9154 // Integer Multiplication 9155 9156 // Register Multiplication 9157 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9158 match(Set dst (MulI src1 src2)); 9159 ins_cost(DEFAULT_COST); 9160 9161 format %{ "MULLW $dst, $src1, $src2" %} 9162 size(4); 9163 ins_encode %{ 9164 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9165 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9166 %} 9167 ins_pipe(pipe_class_default); 9168 %} 9169 9170 // Immediate Multiplication 9171 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9172 match(Set dst (MulI src1 src2)); 9173 ins_cost(DEFAULT_COST); 9174 9175 format %{ "MULLI $dst, $src1, $src2" %} 9176 size(4); 9177 ins_encode %{ 9178 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9179 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9180 %} 9181 ins_pipe(pipe_class_default); 9182 %} 9183 9184 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9185 match(Set dst (MulL src1 src2)); 9186 ins_cost(DEFAULT_COST); 9187 9188 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9189 size(4); 9190 ins_encode %{ 9191 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9192 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9193 %} 9194 ins_pipe(pipe_class_default); 9195 %} 9196 9197 // Multiply high for optimized long division by constant. 9198 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9199 match(Set dst (MulHiL src1 src2)); 9200 ins_cost(DEFAULT_COST); 9201 9202 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9203 size(4); 9204 ins_encode %{ 9205 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9206 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9207 %} 9208 ins_pipe(pipe_class_default); 9209 %} 9210 9211 // Immediate Multiplication 9212 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9213 match(Set dst (MulL src1 src2)); 9214 ins_cost(DEFAULT_COST); 9215 9216 format %{ "MULLI $dst, $src1, $src2" %} 9217 size(4); 9218 ins_encode %{ 9219 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9220 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9221 %} 9222 ins_pipe(pipe_class_default); 9223 %} 9224 9225 // Integer Division with Immediate -1: Negate. 9226 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9227 match(Set dst (DivI src1 src2)); 9228 ins_cost(DEFAULT_COST); 9229 9230 format %{ "NEG $dst, $src1 \t// /-1" %} 9231 size(4); 9232 ins_encode %{ 9233 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9234 __ neg($dst$$Register, $src1$$Register); 9235 %} 9236 ins_pipe(pipe_class_default); 9237 %} 9238 9239 // Integer Division with constant, but not -1. 9240 // We should be able to improve this by checking the type of src2. 9241 // It might well be that src2 is known to be positive. 9242 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9243 match(Set dst (DivI src1 src2)); 9244 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9245 ins_cost(2*DEFAULT_COST); 9246 9247 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9248 size(4); 9249 ins_encode %{ 9250 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9251 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9252 %} 9253 ins_pipe(pipe_class_default); 9254 %} 9255 9256 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9257 effect(USE_DEF dst, USE src1, USE crx); 9258 predicate(false); 9259 9260 ins_variable_size_depending_on_alignment(true); 9261 9262 format %{ "CMOVE $dst, neg($src1), $crx" %} 9263 // Worst case is branch + move + stop, no stop without scheduler. 9264 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 9265 ins_encode %{ 9266 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9267 Label done; 9268 __ bne($crx$$CondRegister, done); 9269 __ neg($dst$$Register, $src1$$Register); 9270 // TODO PPC port __ endgroup_if_needed(_size == 12); 9271 __ bind(done); 9272 %} 9273 ins_pipe(pipe_class_default); 9274 %} 9275 9276 // Integer Division with Registers not containing constants. 9277 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9278 match(Set dst (DivI src1 src2)); 9279 ins_cost(10*DEFAULT_COST); 9280 9281 expand %{ 9282 immI16 imm %{ (int)-1 %} 9283 flagsReg tmp1; 9284 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9285 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9286 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9287 %} 9288 %} 9289 9290 // Long Division with Immediate -1: Negate. 9291 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9292 match(Set dst (DivL src1 src2)); 9293 ins_cost(DEFAULT_COST); 9294 9295 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9296 size(4); 9297 ins_encode %{ 9298 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9299 __ neg($dst$$Register, $src1$$Register); 9300 %} 9301 ins_pipe(pipe_class_default); 9302 %} 9303 9304 // Long Division with constant, but not -1. 9305 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9306 match(Set dst (DivL src1 src2)); 9307 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9308 ins_cost(2*DEFAULT_COST); 9309 9310 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9311 size(4); 9312 ins_encode %{ 9313 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9314 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9315 %} 9316 ins_pipe(pipe_class_default); 9317 %} 9318 9319 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9320 effect(USE_DEF dst, USE src1, USE crx); 9321 predicate(false); 9322 9323 ins_variable_size_depending_on_alignment(true); 9324 9325 format %{ "CMOVE $dst, neg($src1), $crx" %} 9326 // Worst case is branch + move + stop, no stop without scheduler. 9327 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 9328 ins_encode %{ 9329 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9330 Label done; 9331 __ bne($crx$$CondRegister, done); 9332 __ neg($dst$$Register, $src1$$Register); 9333 // TODO PPC port __ endgroup_if_needed(_size == 12); 9334 __ bind(done); 9335 %} 9336 ins_pipe(pipe_class_default); 9337 %} 9338 9339 // Long Division with Registers not containing constants. 9340 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9341 match(Set dst (DivL src1 src2)); 9342 ins_cost(10*DEFAULT_COST); 9343 9344 expand %{ 9345 immL16 imm %{ (int)-1 %} 9346 flagsReg tmp1; 9347 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9348 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9349 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9350 %} 9351 %} 9352 9353 // Integer Remainder with registers. 9354 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9355 match(Set dst (ModI src1 src2)); 9356 ins_cost(10*DEFAULT_COST); 9357 9358 expand %{ 9359 immI16 imm %{ (int)-1 %} 9360 flagsReg tmp1; 9361 iRegIdst tmp2; 9362 iRegIdst tmp3; 9363 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9364 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9365 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9366 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9367 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9368 %} 9369 %} 9370 9371 // Long Remainder with registers 9372 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9373 match(Set dst (ModL src1 src2)); 9374 ins_cost(10*DEFAULT_COST); 9375 9376 expand %{ 9377 immL16 imm %{ (int)-1 %} 9378 flagsReg tmp1; 9379 iRegLdst tmp2; 9380 iRegLdst tmp3; 9381 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9382 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9383 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9384 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9385 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9386 %} 9387 %} 9388 9389 // Integer Shift Instructions 9390 9391 // Register Shift Left 9392 9393 // Clear all but the lowest #mask bits. 9394 // Used to normalize shift amounts in registers. 9395 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9396 // no match-rule, false predicate 9397 effect(DEF dst, USE src, USE mask); 9398 predicate(false); 9399 9400 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9401 size(4); 9402 ins_encode %{ 9403 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9404 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9405 %} 9406 ins_pipe(pipe_class_default); 9407 %} 9408 9409 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9410 // no match-rule, false predicate 9411 effect(DEF dst, USE src1, USE src2); 9412 predicate(false); 9413 9414 format %{ "SLW $dst, $src1, $src2" %} 9415 size(4); 9416 ins_encode %{ 9417 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9418 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9419 %} 9420 ins_pipe(pipe_class_default); 9421 %} 9422 9423 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9424 match(Set dst (LShiftI src1 src2)); 9425 ins_cost(DEFAULT_COST*2); 9426 expand %{ 9427 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9428 iRegIdst tmpI; 9429 maskI_reg_imm(tmpI, src2, mask); 9430 lShiftI_reg_reg(dst, src1, tmpI); 9431 %} 9432 %} 9433 9434 // Register Shift Left Immediate 9435 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9436 match(Set dst (LShiftI src1 src2)); 9437 9438 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9439 size(4); 9440 ins_encode %{ 9441 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9442 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9443 %} 9444 ins_pipe(pipe_class_default); 9445 %} 9446 9447 // AndI with negpow2-constant + LShiftI 9448 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9449 match(Set dst (LShiftI (AndI src1 src2) src3)); 9450 predicate(UseRotateAndMaskInstructionsPPC64); 9451 9452 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9453 size(4); 9454 ins_encode %{ 9455 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9456 long src2 = $src2$$constant; 9457 long src3 = $src3$$constant; 9458 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9459 if (maskbits >= 32) { 9460 __ li($dst$$Register, 0); // addi 9461 } else { 9462 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9463 } 9464 %} 9465 ins_pipe(pipe_class_default); 9466 %} 9467 9468 // RShiftI + AndI with negpow2-constant + LShiftI 9469 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9470 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9471 predicate(UseRotateAndMaskInstructionsPPC64); 9472 9473 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9474 size(4); 9475 ins_encode %{ 9476 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9477 long src2 = $src2$$constant; 9478 long src3 = $src3$$constant; 9479 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9480 if (maskbits >= 32) { 9481 __ li($dst$$Register, 0); // addi 9482 } else { 9483 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9484 } 9485 %} 9486 ins_pipe(pipe_class_default); 9487 %} 9488 9489 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9490 // no match-rule, false predicate 9491 effect(DEF dst, USE src1, USE src2); 9492 predicate(false); 9493 9494 format %{ "SLD $dst, $src1, $src2" %} 9495 size(4); 9496 ins_encode %{ 9497 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9498 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9499 %} 9500 ins_pipe(pipe_class_default); 9501 %} 9502 9503 // Register Shift Left 9504 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9505 match(Set dst (LShiftL src1 src2)); 9506 ins_cost(DEFAULT_COST*2); 9507 expand %{ 9508 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9509 iRegIdst tmpI; 9510 maskI_reg_imm(tmpI, src2, mask); 9511 lShiftL_regL_regI(dst, src1, tmpI); 9512 %} 9513 %} 9514 9515 // Register Shift Left Immediate 9516 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9517 match(Set dst (LShiftL src1 src2)); 9518 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9519 size(4); 9520 ins_encode %{ 9521 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9522 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9523 %} 9524 ins_pipe(pipe_class_default); 9525 %} 9526 9527 // If we shift more than 32 bits, we need not convert I2L. 9528 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9529 match(Set dst (LShiftL (ConvI2L src1) src2)); 9530 ins_cost(DEFAULT_COST); 9531 9532 size(4); 9533 format %{ "SLDI $dst, i2l($src1), $src2" %} 9534 ins_encode %{ 9535 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9536 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9537 %} 9538 ins_pipe(pipe_class_default); 9539 %} 9540 9541 // Shift a postivie int to the left. 9542 // Clrlsldi clears the upper 32 bits and shifts. 9543 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9544 match(Set dst (LShiftL (ConvI2L src1) src2)); 9545 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9546 9547 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9548 size(4); 9549 ins_encode %{ 9550 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9551 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9552 %} 9553 ins_pipe(pipe_class_default); 9554 %} 9555 9556 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9557 // no match-rule, false predicate 9558 effect(DEF dst, USE src1, USE src2); 9559 predicate(false); 9560 9561 format %{ "SRAW $dst, $src1, $src2" %} 9562 size(4); 9563 ins_encode %{ 9564 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9565 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9566 %} 9567 ins_pipe(pipe_class_default); 9568 %} 9569 9570 // Register Arithmetic Shift Right 9571 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9572 match(Set dst (RShiftI src1 src2)); 9573 ins_cost(DEFAULT_COST*2); 9574 expand %{ 9575 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9576 iRegIdst tmpI; 9577 maskI_reg_imm(tmpI, src2, mask); 9578 arShiftI_reg_reg(dst, src1, tmpI); 9579 %} 9580 %} 9581 9582 // Register Arithmetic Shift Right Immediate 9583 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9584 match(Set dst (RShiftI src1 src2)); 9585 9586 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9587 size(4); 9588 ins_encode %{ 9589 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9590 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9591 %} 9592 ins_pipe(pipe_class_default); 9593 %} 9594 9595 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9596 // no match-rule, false predicate 9597 effect(DEF dst, USE src1, USE src2); 9598 predicate(false); 9599 9600 format %{ "SRAD $dst, $src1, $src2" %} 9601 size(4); 9602 ins_encode %{ 9603 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9604 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9605 %} 9606 ins_pipe(pipe_class_default); 9607 %} 9608 9609 // Register Shift Right Arithmetic Long 9610 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9611 match(Set dst (RShiftL src1 src2)); 9612 ins_cost(DEFAULT_COST*2); 9613 9614 expand %{ 9615 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9616 iRegIdst tmpI; 9617 maskI_reg_imm(tmpI, src2, mask); 9618 arShiftL_regL_regI(dst, src1, tmpI); 9619 %} 9620 %} 9621 9622 // Register Shift Right Immediate 9623 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9624 match(Set dst (RShiftL src1 src2)); 9625 9626 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9627 size(4); 9628 ins_encode %{ 9629 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9630 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9631 %} 9632 ins_pipe(pipe_class_default); 9633 %} 9634 9635 // RShiftL + ConvL2I 9636 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9637 match(Set dst (ConvL2I (RShiftL src1 src2))); 9638 9639 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9640 size(4); 9641 ins_encode %{ 9642 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9643 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9644 %} 9645 ins_pipe(pipe_class_default); 9646 %} 9647 9648 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9649 // no match-rule, false predicate 9650 effect(DEF dst, USE src1, USE src2); 9651 predicate(false); 9652 9653 format %{ "SRW $dst, $src1, $src2" %} 9654 size(4); 9655 ins_encode %{ 9656 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9657 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9658 %} 9659 ins_pipe(pipe_class_default); 9660 %} 9661 9662 // Register Shift Right 9663 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9664 match(Set dst (URShiftI src1 src2)); 9665 ins_cost(DEFAULT_COST*2); 9666 9667 expand %{ 9668 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9669 iRegIdst tmpI; 9670 maskI_reg_imm(tmpI, src2, mask); 9671 urShiftI_reg_reg(dst, src1, tmpI); 9672 %} 9673 %} 9674 9675 // Register Shift Right Immediate 9676 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9677 match(Set dst (URShiftI src1 src2)); 9678 9679 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9680 size(4); 9681 ins_encode %{ 9682 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9683 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9684 %} 9685 ins_pipe(pipe_class_default); 9686 %} 9687 9688 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9689 // no match-rule, false predicate 9690 effect(DEF dst, USE src1, USE src2); 9691 predicate(false); 9692 9693 format %{ "SRD $dst, $src1, $src2" %} 9694 size(4); 9695 ins_encode %{ 9696 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9697 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9698 %} 9699 ins_pipe(pipe_class_default); 9700 %} 9701 9702 // Register Shift Right 9703 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9704 match(Set dst (URShiftL src1 src2)); 9705 ins_cost(DEFAULT_COST*2); 9706 9707 expand %{ 9708 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9709 iRegIdst tmpI; 9710 maskI_reg_imm(tmpI, src2, mask); 9711 urShiftL_regL_regI(dst, src1, tmpI); 9712 %} 9713 %} 9714 9715 // Register Shift Right Immediate 9716 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9717 match(Set dst (URShiftL src1 src2)); 9718 9719 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9720 size(4); 9721 ins_encode %{ 9722 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9723 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9724 %} 9725 ins_pipe(pipe_class_default); 9726 %} 9727 9728 // URShiftL + ConvL2I. 9729 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9730 match(Set dst (ConvL2I (URShiftL src1 src2))); 9731 9732 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9733 size(4); 9734 ins_encode %{ 9735 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9736 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9737 %} 9738 ins_pipe(pipe_class_default); 9739 %} 9740 9741 // Register Shift Right Immediate with a CastP2X 9742 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9743 match(Set dst (URShiftL (CastP2X src1) src2)); 9744 9745 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9746 size(4); 9747 ins_encode %{ 9748 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9749 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9750 %} 9751 ins_pipe(pipe_class_default); 9752 %} 9753 9754 // Bitfield Extract: URShiftI + AndI 9755 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9756 match(Set dst (AndI (URShiftI src1 src2) src3)); 9757 9758 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9759 size(4); 9760 ins_encode %{ 9761 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9762 int rshift = ($src2$$constant) & 0x1f; 9763 int length = log2_long(((jlong) $src3$$constant) + 1); 9764 if (rshift + length > 32) { 9765 // if necessary, adjust mask to omit rotated bits. 9766 length = 32 - rshift; 9767 } 9768 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9769 %} 9770 ins_pipe(pipe_class_default); 9771 %} 9772 9773 // Bitfield Extract: URShiftL + AndL 9774 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9775 match(Set dst (AndL (URShiftL src1 src2) src3)); 9776 9777 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9778 size(4); 9779 ins_encode %{ 9780 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9781 int rshift = ($src2$$constant) & 0x3f; 9782 int length = log2_long(((jlong) $src3$$constant) + 1); 9783 if (rshift + length > 64) { 9784 // if necessary, adjust mask to omit rotated bits. 9785 length = 64 - rshift; 9786 } 9787 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9788 %} 9789 ins_pipe(pipe_class_default); 9790 %} 9791 9792 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9793 match(Set dst (ConvL2I (ConvI2L src))); 9794 9795 format %{ "EXTSW $dst, $src \t// int->int" %} 9796 size(4); 9797 ins_encode %{ 9798 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9799 __ extsw($dst$$Register, $src$$Register); 9800 %} 9801 ins_pipe(pipe_class_default); 9802 %} 9803 9804 //----------Rotate Instructions------------------------------------------------ 9805 9806 // Rotate Left by 8-bit immediate 9807 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9808 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9809 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9810 9811 format %{ "ROTLWI $dst, $src, $lshift" %} 9812 size(4); 9813 ins_encode %{ 9814 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9815 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9816 %} 9817 ins_pipe(pipe_class_default); 9818 %} 9819 9820 // Rotate Right by 8-bit immediate 9821 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9822 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9823 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9824 9825 format %{ "ROTRWI $dst, $rshift" %} 9826 size(4); 9827 ins_encode %{ 9828 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9829 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9830 %} 9831 ins_pipe(pipe_class_default); 9832 %} 9833 9834 //----------Floating Point Arithmetic Instructions----------------------------- 9835 9836 // Add float single precision 9837 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9838 match(Set dst (AddF src1 src2)); 9839 9840 format %{ "FADDS $dst, $src1, $src2" %} 9841 size(4); 9842 ins_encode %{ 9843 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9844 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9845 %} 9846 ins_pipe(pipe_class_default); 9847 %} 9848 9849 // Add float double precision 9850 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9851 match(Set dst (AddD src1 src2)); 9852 9853 format %{ "FADD $dst, $src1, $src2" %} 9854 size(4); 9855 ins_encode %{ 9856 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9857 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9858 %} 9859 ins_pipe(pipe_class_default); 9860 %} 9861 9862 // Sub float single precision 9863 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9864 match(Set dst (SubF src1 src2)); 9865 9866 format %{ "FSUBS $dst, $src1, $src2" %} 9867 size(4); 9868 ins_encode %{ 9869 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9870 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9871 %} 9872 ins_pipe(pipe_class_default); 9873 %} 9874 9875 // Sub float double precision 9876 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9877 match(Set dst (SubD src1 src2)); 9878 format %{ "FSUB $dst, $src1, $src2" %} 9879 size(4); 9880 ins_encode %{ 9881 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9882 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9883 %} 9884 ins_pipe(pipe_class_default); 9885 %} 9886 9887 // Mul float single precision 9888 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9889 match(Set dst (MulF src1 src2)); 9890 format %{ "FMULS $dst, $src1, $src2" %} 9891 size(4); 9892 ins_encode %{ 9893 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9894 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9895 %} 9896 ins_pipe(pipe_class_default); 9897 %} 9898 9899 // Mul float double precision 9900 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9901 match(Set dst (MulD src1 src2)); 9902 format %{ "FMUL $dst, $src1, $src2" %} 9903 size(4); 9904 ins_encode %{ 9905 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9906 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9907 %} 9908 ins_pipe(pipe_class_default); 9909 %} 9910 9911 // Div float single precision 9912 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9913 match(Set dst (DivF src1 src2)); 9914 format %{ "FDIVS $dst, $src1, $src2" %} 9915 size(4); 9916 ins_encode %{ 9917 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9918 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9919 %} 9920 ins_pipe(pipe_class_default); 9921 %} 9922 9923 // Div float double precision 9924 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9925 match(Set dst (DivD src1 src2)); 9926 format %{ "FDIV $dst, $src1, $src2" %} 9927 size(4); 9928 ins_encode %{ 9929 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9930 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9931 %} 9932 ins_pipe(pipe_class_default); 9933 %} 9934 9935 // Absolute float single precision 9936 instruct absF_reg(regF dst, regF src) %{ 9937 match(Set dst (AbsF src)); 9938 format %{ "FABS $dst, $src \t// float" %} 9939 size(4); 9940 ins_encode %{ 9941 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9942 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9943 %} 9944 ins_pipe(pipe_class_default); 9945 %} 9946 9947 // Absolute float double precision 9948 instruct absD_reg(regD dst, regD src) %{ 9949 match(Set dst (AbsD src)); 9950 format %{ "FABS $dst, $src \t// double" %} 9951 size(4); 9952 ins_encode %{ 9953 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9954 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9955 %} 9956 ins_pipe(pipe_class_default); 9957 %} 9958 9959 instruct negF_reg(regF dst, regF src) %{ 9960 match(Set dst (NegF src)); 9961 format %{ "FNEG $dst, $src \t// float" %} 9962 size(4); 9963 ins_encode %{ 9964 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9965 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9966 %} 9967 ins_pipe(pipe_class_default); 9968 %} 9969 9970 instruct negD_reg(regD dst, regD src) %{ 9971 match(Set dst (NegD src)); 9972 format %{ "FNEG $dst, $src \t// double" %} 9973 size(4); 9974 ins_encode %{ 9975 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9976 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9977 %} 9978 ins_pipe(pipe_class_default); 9979 %} 9980 9981 // AbsF + NegF. 9982 instruct negF_absF_reg(regF dst, regF src) %{ 9983 match(Set dst (NegF (AbsF src))); 9984 format %{ "FNABS $dst, $src \t// float" %} 9985 size(4); 9986 ins_encode %{ 9987 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9988 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9989 %} 9990 ins_pipe(pipe_class_default); 9991 %} 9992 9993 // AbsD + NegD. 9994 instruct negD_absD_reg(regD dst, regD src) %{ 9995 match(Set dst (NegD (AbsD src))); 9996 format %{ "FNABS $dst, $src \t// double" %} 9997 size(4); 9998 ins_encode %{ 9999 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10000 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10001 %} 10002 ins_pipe(pipe_class_default); 10003 %} 10004 10005 // VM_Version::has_fsqrt() decides if this node will be used. 10006 // Sqrt float double precision 10007 instruct sqrtD_reg(regD dst, regD src) %{ 10008 match(Set dst (SqrtD src)); 10009 format %{ "FSQRT $dst, $src" %} 10010 size(4); 10011 ins_encode %{ 10012 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 10013 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 10014 %} 10015 ins_pipe(pipe_class_default); 10016 %} 10017 10018 // Single-precision sqrt. 10019 instruct sqrtF_reg(regF dst, regF src) %{ 10020 match(Set dst (SqrtF src)); 10021 predicate(VM_Version::has_fsqrts()); 10022 ins_cost(DEFAULT_COST); 10023 10024 format %{ "FSQRTS $dst, $src" %} 10025 size(4); 10026 ins_encode %{ 10027 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 10028 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 10029 %} 10030 ins_pipe(pipe_class_default); 10031 %} 10032 10033 instruct roundDouble_nop(regD dst) %{ 10034 match(Set dst (RoundDouble dst)); 10035 ins_cost(0); 10036 10037 format %{ " -- \t// RoundDouble not needed - empty" %} 10038 size(0); 10039 // PPC results are already "rounded" (i.e., normal-format IEEE). 10040 ins_encode( /*empty*/ ); 10041 ins_pipe(pipe_class_default); 10042 %} 10043 10044 instruct roundFloat_nop(regF dst) %{ 10045 match(Set dst (RoundFloat dst)); 10046 ins_cost(0); 10047 10048 format %{ " -- \t// RoundFloat not needed - empty" %} 10049 size(0); 10050 // PPC results are already "rounded" (i.e., normal-format IEEE). 10051 ins_encode( /*empty*/ ); 10052 ins_pipe(pipe_class_default); 10053 %} 10054 10055 10056 // Multiply-Accumulate 10057 // src1 * src2 + src3 10058 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10059 match(Set dst (FmaF src3 (Binary src1 src2))); 10060 10061 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10062 size(4); 10063 ins_encode %{ 10064 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10065 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10066 %} 10067 ins_pipe(pipe_class_default); 10068 %} 10069 10070 // src1 * src2 + src3 10071 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10072 match(Set dst (FmaD src3 (Binary src1 src2))); 10073 10074 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10075 size(4); 10076 ins_encode %{ 10077 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10078 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10079 %} 10080 ins_pipe(pipe_class_default); 10081 %} 10082 10083 // -src1 * src2 + src3 = -(src1*src2-src3) 10084 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10085 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10086 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10087 10088 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10089 size(4); 10090 ins_encode %{ 10091 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10092 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10093 %} 10094 ins_pipe(pipe_class_default); 10095 %} 10096 10097 // -src1 * src2 + src3 = -(src1*src2-src3) 10098 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10099 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10100 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10101 10102 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10103 size(4); 10104 ins_encode %{ 10105 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10106 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10107 %} 10108 ins_pipe(pipe_class_default); 10109 %} 10110 10111 // -src1 * src2 - src3 = -(src1*src2+src3) 10112 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10113 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10114 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10115 10116 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10117 size(4); 10118 ins_encode %{ 10119 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10120 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10121 %} 10122 ins_pipe(pipe_class_default); 10123 %} 10124 10125 // -src1 * src2 - src3 = -(src1*src2+src3) 10126 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10127 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10128 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10129 10130 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10131 size(4); 10132 ins_encode %{ 10133 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10134 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10135 %} 10136 ins_pipe(pipe_class_default); 10137 %} 10138 10139 // src1 * src2 - src3 10140 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10141 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10142 10143 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10144 size(4); 10145 ins_encode %{ 10146 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10147 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10148 %} 10149 ins_pipe(pipe_class_default); 10150 %} 10151 10152 // src1 * src2 - src3 10153 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10154 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10155 10156 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10157 size(4); 10158 ins_encode %{ 10159 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10160 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10161 %} 10162 ins_pipe(pipe_class_default); 10163 %} 10164 10165 10166 //----------Logical Instructions----------------------------------------------- 10167 10168 // And Instructions 10169 10170 // Register And 10171 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10172 match(Set dst (AndI src1 src2)); 10173 format %{ "AND $dst, $src1, $src2" %} 10174 size(4); 10175 ins_encode %{ 10176 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10177 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10178 %} 10179 ins_pipe(pipe_class_default); 10180 %} 10181 10182 // Left shifted Immediate And 10183 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10184 match(Set dst (AndI src1 src2)); 10185 effect(KILL cr0); 10186 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10187 size(4); 10188 ins_encode %{ 10189 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10190 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10191 %} 10192 ins_pipe(pipe_class_default); 10193 %} 10194 10195 // Immediate And 10196 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10197 match(Set dst (AndI src1 src2)); 10198 effect(KILL cr0); 10199 10200 format %{ "ANDI $dst, $src1, $src2" %} 10201 size(4); 10202 ins_encode %{ 10203 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10204 // FIXME: avoid andi_ ? 10205 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10206 %} 10207 ins_pipe(pipe_class_default); 10208 %} 10209 10210 // Immediate And where the immediate is a negative power of 2. 10211 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10212 match(Set dst (AndI src1 src2)); 10213 format %{ "ANDWI $dst, $src1, $src2" %} 10214 size(4); 10215 ins_encode %{ 10216 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10217 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10218 %} 10219 ins_pipe(pipe_class_default); 10220 %} 10221 10222 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10223 match(Set dst (AndI src1 src2)); 10224 format %{ "ANDWI $dst, $src1, $src2" %} 10225 size(4); 10226 ins_encode %{ 10227 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10228 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10229 %} 10230 ins_pipe(pipe_class_default); 10231 %} 10232 10233 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10234 match(Set dst (AndI src1 src2)); 10235 predicate(UseRotateAndMaskInstructionsPPC64); 10236 format %{ "ANDWI $dst, $src1, $src2" %} 10237 size(4); 10238 ins_encode %{ 10239 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10240 __ rlwinm($dst$$Register, $src1$$Register, 0, 10241 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10242 %} 10243 ins_pipe(pipe_class_default); 10244 %} 10245 10246 // Register And Long 10247 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10248 match(Set dst (AndL src1 src2)); 10249 ins_cost(DEFAULT_COST); 10250 10251 format %{ "AND $dst, $src1, $src2 \t// long" %} 10252 size(4); 10253 ins_encode %{ 10254 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10255 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10256 %} 10257 ins_pipe(pipe_class_default); 10258 %} 10259 10260 // Immediate And long 10261 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10262 match(Set dst (AndL src1 src2)); 10263 effect(KILL cr0); 10264 10265 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10266 size(4); 10267 ins_encode %{ 10268 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10269 // FIXME: avoid andi_ ? 10270 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10271 %} 10272 ins_pipe(pipe_class_default); 10273 %} 10274 10275 // Immediate And Long where the immediate is a negative power of 2. 10276 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10277 match(Set dst (AndL src1 src2)); 10278 format %{ "ANDDI $dst, $src1, $src2" %} 10279 size(4); 10280 ins_encode %{ 10281 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10282 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10283 %} 10284 ins_pipe(pipe_class_default); 10285 %} 10286 10287 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10288 match(Set dst (AndL src1 src2)); 10289 format %{ "ANDDI $dst, $src1, $src2" %} 10290 size(4); 10291 ins_encode %{ 10292 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10293 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10294 %} 10295 ins_pipe(pipe_class_default); 10296 %} 10297 10298 // AndL + ConvL2I. 10299 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10300 match(Set dst (ConvL2I (AndL src1 src2))); 10301 ins_cost(DEFAULT_COST); 10302 10303 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10304 size(4); 10305 ins_encode %{ 10306 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10307 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10308 %} 10309 ins_pipe(pipe_class_default); 10310 %} 10311 10312 // Or Instructions 10313 10314 // Register Or 10315 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10316 match(Set dst (OrI src1 src2)); 10317 format %{ "OR $dst, $src1, $src2" %} 10318 size(4); 10319 ins_encode %{ 10320 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10321 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10322 %} 10323 ins_pipe(pipe_class_default); 10324 %} 10325 10326 // Expand does not work with above instruct. (??) 10327 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10328 // no match-rule 10329 effect(DEF dst, USE src1, USE src2); 10330 format %{ "OR $dst, $src1, $src2" %} 10331 size(4); 10332 ins_encode %{ 10333 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10334 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10335 %} 10336 ins_pipe(pipe_class_default); 10337 %} 10338 10339 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10340 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10341 ins_cost(DEFAULT_COST*3); 10342 10343 expand %{ 10344 // FIXME: we should do this in the ideal world. 10345 iRegIdst tmp1; 10346 iRegIdst tmp2; 10347 orI_reg_reg(tmp1, src1, src2); 10348 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10349 orI_reg_reg(dst, tmp1, tmp2); 10350 %} 10351 %} 10352 10353 // Immediate Or 10354 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10355 match(Set dst (OrI src1 src2)); 10356 format %{ "ORI $dst, $src1, $src2" %} 10357 size(4); 10358 ins_encode %{ 10359 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10360 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10361 %} 10362 ins_pipe(pipe_class_default); 10363 %} 10364 10365 // Register Or Long 10366 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10367 match(Set dst (OrL src1 src2)); 10368 ins_cost(DEFAULT_COST); 10369 10370 size(4); 10371 format %{ "OR $dst, $src1, $src2 \t// long" %} 10372 ins_encode %{ 10373 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10374 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10375 %} 10376 ins_pipe(pipe_class_default); 10377 %} 10378 10379 // OrL + ConvL2I. 10380 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10381 match(Set dst (ConvL2I (OrL src1 src2))); 10382 ins_cost(DEFAULT_COST); 10383 10384 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10385 size(4); 10386 ins_encode %{ 10387 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10388 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10389 %} 10390 ins_pipe(pipe_class_default); 10391 %} 10392 10393 // Immediate Or long 10394 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10395 match(Set dst (OrL src1 con)); 10396 ins_cost(DEFAULT_COST); 10397 10398 format %{ "ORI $dst, $src1, $con \t// long" %} 10399 size(4); 10400 ins_encode %{ 10401 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10402 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10403 %} 10404 ins_pipe(pipe_class_default); 10405 %} 10406 10407 // Xor Instructions 10408 10409 // Register Xor 10410 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10411 match(Set dst (XorI src1 src2)); 10412 format %{ "XOR $dst, $src1, $src2" %} 10413 size(4); 10414 ins_encode %{ 10415 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10416 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10417 %} 10418 ins_pipe(pipe_class_default); 10419 %} 10420 10421 // Expand does not work with above instruct. (??) 10422 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10423 // no match-rule 10424 effect(DEF dst, USE src1, USE src2); 10425 format %{ "XOR $dst, $src1, $src2" %} 10426 size(4); 10427 ins_encode %{ 10428 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10429 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10430 %} 10431 ins_pipe(pipe_class_default); 10432 %} 10433 10434 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10435 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10436 ins_cost(DEFAULT_COST*3); 10437 10438 expand %{ 10439 // FIXME: we should do this in the ideal world. 10440 iRegIdst tmp1; 10441 iRegIdst tmp2; 10442 xorI_reg_reg(tmp1, src1, src2); 10443 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10444 xorI_reg_reg(dst, tmp1, tmp2); 10445 %} 10446 %} 10447 10448 // Immediate Xor 10449 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10450 match(Set dst (XorI src1 src2)); 10451 format %{ "XORI $dst, $src1, $src2" %} 10452 size(4); 10453 ins_encode %{ 10454 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10455 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10456 %} 10457 ins_pipe(pipe_class_default); 10458 %} 10459 10460 // Register Xor Long 10461 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10462 match(Set dst (XorL src1 src2)); 10463 ins_cost(DEFAULT_COST); 10464 10465 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10466 size(4); 10467 ins_encode %{ 10468 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10469 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10470 %} 10471 ins_pipe(pipe_class_default); 10472 %} 10473 10474 // XorL + ConvL2I. 10475 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10476 match(Set dst (ConvL2I (XorL src1 src2))); 10477 ins_cost(DEFAULT_COST); 10478 10479 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10480 size(4); 10481 ins_encode %{ 10482 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10483 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10484 %} 10485 ins_pipe(pipe_class_default); 10486 %} 10487 10488 // Immediate Xor Long 10489 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10490 match(Set dst (XorL src1 src2)); 10491 ins_cost(DEFAULT_COST); 10492 10493 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10494 size(4); 10495 ins_encode %{ 10496 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10497 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10498 %} 10499 ins_pipe(pipe_class_default); 10500 %} 10501 10502 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10503 match(Set dst (XorI src1 src2)); 10504 ins_cost(DEFAULT_COST); 10505 10506 format %{ "NOT $dst, $src1 ($src2)" %} 10507 size(4); 10508 ins_encode %{ 10509 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10510 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10511 %} 10512 ins_pipe(pipe_class_default); 10513 %} 10514 10515 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10516 match(Set dst (XorL src1 src2)); 10517 ins_cost(DEFAULT_COST); 10518 10519 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10520 size(4); 10521 ins_encode %{ 10522 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10523 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10524 %} 10525 ins_pipe(pipe_class_default); 10526 %} 10527 10528 // And-complement 10529 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10530 match(Set dst (AndI (XorI src1 src2) src3)); 10531 ins_cost(DEFAULT_COST); 10532 10533 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10534 size(4); 10535 ins_encode( enc_andc(dst, src3, src1) ); 10536 ins_pipe(pipe_class_default); 10537 %} 10538 10539 // And-complement 10540 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10541 // no match-rule, false predicate 10542 effect(DEF dst, USE src1, USE src2); 10543 predicate(false); 10544 10545 format %{ "ANDC $dst, $src1, $src2" %} 10546 size(4); 10547 ins_encode %{ 10548 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10549 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10550 %} 10551 ins_pipe(pipe_class_default); 10552 %} 10553 10554 //----------Moves between int/long and float/double---------------------------- 10555 // 10556 // The following rules move values from int/long registers/stack-locations 10557 // to float/double registers/stack-locations and vice versa, without doing any 10558 // conversions. These rules are used to implement the bit-conversion methods 10559 // of java.lang.Float etc., e.g. 10560 // int floatToIntBits(float value) 10561 // float intBitsToFloat(int bits) 10562 // 10563 // Notes on the implementation on ppc64: 10564 // For Power7 and earlier, the rules are limited to those which move between a 10565 // register and a stack-location, because we always have to go through memory 10566 // when moving between a float register and an integer register. 10567 // This restriction is removed in Power8 with the introduction of the mtfprd 10568 // and mffprd instructions. 10569 10570 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10571 match(Set dst (MoveL2D src)); 10572 predicate(VM_Version::has_mtfprd()); 10573 10574 format %{ "MTFPRD $dst, $src" %} 10575 size(4); 10576 ins_encode %{ 10577 __ mtfprd($dst$$FloatRegister, $src$$Register); 10578 %} 10579 ins_pipe(pipe_class_default); 10580 %} 10581 10582 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10583 // no match-rule, false predicate 10584 effect(DEF dst, USE src); 10585 predicate(false); 10586 10587 format %{ "MTFPRWA $dst, $src" %} 10588 size(4); 10589 ins_encode %{ 10590 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10591 %} 10592 ins_pipe(pipe_class_default); 10593 %} 10594 10595 //---------- Chain stack slots between similar types -------- 10596 10597 // These are needed so that the rules below can match. 10598 10599 // Load integer from stack slot 10600 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10601 match(Set dst src); 10602 ins_cost(MEMORY_REF_COST); 10603 10604 format %{ "LWZ $dst, $src" %} 10605 size(4); 10606 ins_encode( enc_lwz(dst, src) ); 10607 ins_pipe(pipe_class_memory); 10608 %} 10609 10610 // Store integer to stack slot 10611 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10612 match(Set dst src); 10613 ins_cost(MEMORY_REF_COST); 10614 10615 format %{ "STW $src, $dst \t// stk" %} 10616 size(4); 10617 ins_encode( enc_stw(src, dst) ); // rs=rt 10618 ins_pipe(pipe_class_memory); 10619 %} 10620 10621 // Load long from stack slot 10622 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10623 match(Set dst src); 10624 ins_cost(MEMORY_REF_COST); 10625 10626 format %{ "LD $dst, $src \t// long" %} 10627 size(4); 10628 ins_encode( enc_ld(dst, src) ); 10629 ins_pipe(pipe_class_memory); 10630 %} 10631 10632 // Store long to stack slot 10633 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10634 match(Set dst src); 10635 ins_cost(MEMORY_REF_COST); 10636 10637 format %{ "STD $src, $dst \t// long" %} 10638 size(4); 10639 ins_encode( enc_std(src, dst) ); // rs=rt 10640 ins_pipe(pipe_class_memory); 10641 %} 10642 10643 //----------Moves between int and float 10644 10645 // Move float value from float stack-location to integer register. 10646 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10647 match(Set dst (MoveF2I src)); 10648 ins_cost(MEMORY_REF_COST); 10649 10650 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10651 size(4); 10652 ins_encode( enc_lwz(dst, src) ); 10653 ins_pipe(pipe_class_memory); 10654 %} 10655 10656 // Move float value from float register to integer stack-location. 10657 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10658 match(Set dst (MoveF2I src)); 10659 ins_cost(MEMORY_REF_COST); 10660 10661 format %{ "STFS $src, $dst \t// MoveF2I" %} 10662 size(4); 10663 ins_encode( enc_stfs(src, dst) ); 10664 ins_pipe(pipe_class_memory); 10665 %} 10666 10667 // Move integer value from integer stack-location to float register. 10668 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10669 match(Set dst (MoveI2F src)); 10670 ins_cost(MEMORY_REF_COST); 10671 10672 format %{ "LFS $dst, $src \t// MoveI2F" %} 10673 size(4); 10674 ins_encode %{ 10675 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10676 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10677 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10678 %} 10679 ins_pipe(pipe_class_memory); 10680 %} 10681 10682 // Move integer value from integer register to float stack-location. 10683 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10684 match(Set dst (MoveI2F src)); 10685 ins_cost(MEMORY_REF_COST); 10686 10687 format %{ "STW $src, $dst \t// MoveI2F" %} 10688 size(4); 10689 ins_encode( enc_stw(src, dst) ); 10690 ins_pipe(pipe_class_memory); 10691 %} 10692 10693 //----------Moves between long and float 10694 10695 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10696 // no match-rule, false predicate 10697 effect(DEF dst, USE src); 10698 predicate(false); 10699 10700 format %{ "storeD $src, $dst \t// STACK" %} 10701 size(4); 10702 ins_encode( enc_stfd(src, dst) ); 10703 ins_pipe(pipe_class_default); 10704 %} 10705 10706 //----------Moves between long and double 10707 10708 // Move double value from double stack-location to long register. 10709 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10710 match(Set dst (MoveD2L src)); 10711 ins_cost(MEMORY_REF_COST); 10712 size(4); 10713 format %{ "LD $dst, $src \t// MoveD2L" %} 10714 ins_encode( enc_ld(dst, src) ); 10715 ins_pipe(pipe_class_memory); 10716 %} 10717 10718 // Move double value from double register to long stack-location. 10719 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10720 match(Set dst (MoveD2L src)); 10721 effect(DEF dst, USE src); 10722 ins_cost(MEMORY_REF_COST); 10723 10724 format %{ "STFD $src, $dst \t// MoveD2L" %} 10725 size(4); 10726 ins_encode( enc_stfd(src, dst) ); 10727 ins_pipe(pipe_class_memory); 10728 %} 10729 10730 // Move long value from long stack-location to double register. 10731 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10732 match(Set dst (MoveL2D src)); 10733 ins_cost(MEMORY_REF_COST); 10734 10735 format %{ "LFD $dst, $src \t// MoveL2D" %} 10736 size(4); 10737 ins_encode( enc_lfd(dst, src) ); 10738 ins_pipe(pipe_class_memory); 10739 %} 10740 10741 // Move long value from long register to double stack-location. 10742 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10743 match(Set dst (MoveL2D src)); 10744 ins_cost(MEMORY_REF_COST); 10745 10746 format %{ "STD $src, $dst \t// MoveL2D" %} 10747 size(4); 10748 ins_encode( enc_std(src, dst) ); 10749 ins_pipe(pipe_class_memory); 10750 %} 10751 10752 //----------Register Move Instructions----------------------------------------- 10753 10754 // Replicate for Superword 10755 10756 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10757 predicate(false); 10758 effect(DEF dst, USE src); 10759 10760 format %{ "MR $dst, $src \t// replicate " %} 10761 // variable size, 0 or 4. 10762 ins_encode %{ 10763 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10764 __ mr_if_needed($dst$$Register, $src$$Register); 10765 %} 10766 ins_pipe(pipe_class_default); 10767 %} 10768 10769 //----------Cast instructions (Java-level type cast)--------------------------- 10770 10771 // Cast Long to Pointer for unsafe natives. 10772 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10773 match(Set dst (CastX2P src)); 10774 10775 format %{ "MR $dst, $src \t// Long->Ptr" %} 10776 // variable size, 0 or 4. 10777 ins_encode %{ 10778 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10779 __ mr_if_needed($dst$$Register, $src$$Register); 10780 %} 10781 ins_pipe(pipe_class_default); 10782 %} 10783 10784 // Cast Pointer to Long for unsafe natives. 10785 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10786 match(Set dst (CastP2X src)); 10787 10788 format %{ "MR $dst, $src \t// Ptr->Long" %} 10789 // variable size, 0 or 4. 10790 ins_encode %{ 10791 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10792 __ mr_if_needed($dst$$Register, $src$$Register); 10793 %} 10794 ins_pipe(pipe_class_default); 10795 %} 10796 10797 instruct castPP(iRegPdst dst) %{ 10798 match(Set dst (CastPP dst)); 10799 format %{ " -- \t// castPP of $dst" %} 10800 size(0); 10801 ins_encode( /*empty*/ ); 10802 ins_pipe(pipe_class_default); 10803 %} 10804 10805 instruct castII(iRegIdst dst) %{ 10806 match(Set dst (CastII dst)); 10807 format %{ " -- \t// castII of $dst" %} 10808 size(0); 10809 ins_encode( /*empty*/ ); 10810 ins_pipe(pipe_class_default); 10811 %} 10812 10813 instruct checkCastPP(iRegPdst dst) %{ 10814 match(Set dst (CheckCastPP dst)); 10815 format %{ " -- \t// checkcastPP of $dst" %} 10816 size(0); 10817 ins_encode( /*empty*/ ); 10818 ins_pipe(pipe_class_default); 10819 %} 10820 10821 //----------Convert instructions----------------------------------------------- 10822 10823 // Convert to boolean. 10824 10825 // int_to_bool(src) : { 1 if src != 0 10826 // { 0 else 10827 // 10828 // strategy: 10829 // 1) Count leading zeros of 32 bit-value src, 10830 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10831 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10832 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10833 10834 // convI2Bool 10835 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10836 match(Set dst (Conv2B src)); 10837 predicate(UseCountLeadingZerosInstructionsPPC64); 10838 ins_cost(DEFAULT_COST); 10839 10840 expand %{ 10841 immI shiftAmount %{ 0x5 %} 10842 uimmI16 mask %{ 0x1 %} 10843 iRegIdst tmp1; 10844 iRegIdst tmp2; 10845 countLeadingZerosI(tmp1, src); 10846 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10847 xorI_reg_uimm16(dst, tmp2, mask); 10848 %} 10849 %} 10850 10851 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10852 match(Set dst (Conv2B src)); 10853 effect(TEMP crx); 10854 predicate(!UseCountLeadingZerosInstructionsPPC64); 10855 ins_cost(DEFAULT_COST); 10856 10857 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10858 "LI $dst, #0\n\t" 10859 "BEQ $crx, done\n\t" 10860 "LI $dst, #1\n" 10861 "done:" %} 10862 size(16); 10863 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10864 ins_pipe(pipe_class_compare); 10865 %} 10866 10867 // ConvI2B + XorI 10868 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10869 match(Set dst (XorI (Conv2B src) mask)); 10870 predicate(UseCountLeadingZerosInstructionsPPC64); 10871 ins_cost(DEFAULT_COST); 10872 10873 expand %{ 10874 immI shiftAmount %{ 0x5 %} 10875 iRegIdst tmp1; 10876 countLeadingZerosI(tmp1, src); 10877 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10878 %} 10879 %} 10880 10881 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10882 match(Set dst (XorI (Conv2B src) mask)); 10883 effect(TEMP crx); 10884 predicate(!UseCountLeadingZerosInstructionsPPC64); 10885 ins_cost(DEFAULT_COST); 10886 10887 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10888 "LI $dst, #1\n\t" 10889 "BEQ $crx, done\n\t" 10890 "LI $dst, #0\n" 10891 "done:" %} 10892 size(16); 10893 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10894 ins_pipe(pipe_class_compare); 10895 %} 10896 10897 // AndI 0b0..010..0 + ConvI2B 10898 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10899 match(Set dst (Conv2B (AndI src mask))); 10900 predicate(UseRotateAndMaskInstructionsPPC64); 10901 ins_cost(DEFAULT_COST); 10902 10903 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10904 size(4); 10905 ins_encode %{ 10906 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10907 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10908 %} 10909 ins_pipe(pipe_class_default); 10910 %} 10911 10912 // Convert pointer to boolean. 10913 // 10914 // ptr_to_bool(src) : { 1 if src != 0 10915 // { 0 else 10916 // 10917 // strategy: 10918 // 1) Count leading zeros of 64 bit-value src, 10919 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10920 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10921 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10922 10923 // ConvP2B 10924 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10925 match(Set dst (Conv2B src)); 10926 predicate(UseCountLeadingZerosInstructionsPPC64); 10927 ins_cost(DEFAULT_COST); 10928 10929 expand %{ 10930 immI shiftAmount %{ 0x6 %} 10931 uimmI16 mask %{ 0x1 %} 10932 iRegIdst tmp1; 10933 iRegIdst tmp2; 10934 countLeadingZerosP(tmp1, src); 10935 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10936 xorI_reg_uimm16(dst, tmp2, mask); 10937 %} 10938 %} 10939 10940 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10941 match(Set dst (Conv2B src)); 10942 effect(TEMP crx); 10943 predicate(!UseCountLeadingZerosInstructionsPPC64); 10944 ins_cost(DEFAULT_COST); 10945 10946 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10947 "LI $dst, #0\n\t" 10948 "BEQ $crx, done\n\t" 10949 "LI $dst, #1\n" 10950 "done:" %} 10951 size(16); 10952 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10953 ins_pipe(pipe_class_compare); 10954 %} 10955 10956 // ConvP2B + XorI 10957 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10958 match(Set dst (XorI (Conv2B src) mask)); 10959 predicate(UseCountLeadingZerosInstructionsPPC64); 10960 ins_cost(DEFAULT_COST); 10961 10962 expand %{ 10963 immI shiftAmount %{ 0x6 %} 10964 iRegIdst tmp1; 10965 countLeadingZerosP(tmp1, src); 10966 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10967 %} 10968 %} 10969 10970 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10971 match(Set dst (XorI (Conv2B src) mask)); 10972 effect(TEMP crx); 10973 predicate(!UseCountLeadingZerosInstructionsPPC64); 10974 ins_cost(DEFAULT_COST); 10975 10976 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10977 "LI $dst, #1\n\t" 10978 "BEQ $crx, done\n\t" 10979 "LI $dst, #0\n" 10980 "done:" %} 10981 size(16); 10982 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10983 ins_pipe(pipe_class_compare); 10984 %} 10985 10986 // if src1 < src2, return -1 else return 0 10987 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10988 match(Set dst (CmpLTMask src1 src2)); 10989 ins_cost(DEFAULT_COST*4); 10990 10991 expand %{ 10992 iRegLdst src1s; 10993 iRegLdst src2s; 10994 iRegLdst diff; 10995 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10996 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10997 subL_reg_reg(diff, src1s, src2s); 10998 // Need to consider >=33 bit result, therefore we need signmaskL. 10999 signmask64I_regL(dst, diff); 11000 %} 11001 %} 11002 11003 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 11004 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 11005 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 11006 size(4); 11007 ins_encode %{ 11008 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 11009 __ srawi($dst$$Register, $src1$$Register, 0x1f); 11010 %} 11011 ins_pipe(pipe_class_default); 11012 %} 11013 11014 //----------Arithmetic Conversion Instructions--------------------------------- 11015 11016 // Convert to Byte -- nop 11017 // Convert to Short -- nop 11018 11019 // Convert to Int 11020 11021 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 11022 match(Set dst (RShiftI (LShiftI src amount) amount)); 11023 format %{ "EXTSB $dst, $src \t// byte->int" %} 11024 size(4); 11025 ins_encode %{ 11026 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 11027 __ extsb($dst$$Register, $src$$Register); 11028 %} 11029 ins_pipe(pipe_class_default); 11030 %} 11031 11032 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 11033 effect(DEF dst, USE src); 11034 11035 size(4); 11036 ins_encode %{ 11037 __ extsh($dst$$Register, $src$$Register); 11038 %} 11039 ins_pipe(pipe_class_default); 11040 %} 11041 11042 // LShiftI 16 + RShiftI 16 converts short to int. 11043 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 11044 match(Set dst (RShiftI (LShiftI src amount) amount)); 11045 format %{ "EXTSH $dst, $src \t// short->int" %} 11046 size(4); 11047 ins_encode %{ 11048 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 11049 __ extsh($dst$$Register, $src$$Register); 11050 %} 11051 ins_pipe(pipe_class_default); 11052 %} 11053 11054 // ConvL2I + ConvI2L: Sign extend int in long register. 11055 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11056 match(Set dst (ConvI2L (ConvL2I src))); 11057 11058 format %{ "EXTSW $dst, $src \t// long->long" %} 11059 size(4); 11060 ins_encode %{ 11061 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11062 __ extsw($dst$$Register, $src$$Register); 11063 %} 11064 ins_pipe(pipe_class_default); 11065 %} 11066 11067 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11068 match(Set dst (ConvL2I src)); 11069 format %{ "MR $dst, $src \t// long->int" %} 11070 // variable size, 0 or 4 11071 ins_encode %{ 11072 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11073 __ mr_if_needed($dst$$Register, $src$$Register); 11074 %} 11075 ins_pipe(pipe_class_default); 11076 %} 11077 11078 instruct convD2IRaw_regD(regD dst, regD src) %{ 11079 // no match-rule, false predicate 11080 effect(DEF dst, USE src); 11081 predicate(false); 11082 11083 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11084 size(4); 11085 ins_encode %{ 11086 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11087 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11088 %} 11089 ins_pipe(pipe_class_default); 11090 %} 11091 11092 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 11093 // no match-rule, false predicate 11094 effect(DEF dst, USE crx, USE src); 11095 predicate(false); 11096 11097 ins_variable_size_depending_on_alignment(true); 11098 11099 format %{ "cmovI $crx, $dst, $src" %} 11100 // Worst case is branch + move + stop, no stop without scheduler. 11101 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 11102 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11103 ins_pipe(pipe_class_default); 11104 %} 11105 11106 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11107 // no match-rule, false predicate 11108 effect(DEF dst, USE crx, USE src); 11109 predicate(false); 11110 11111 ins_variable_size_depending_on_alignment(true); 11112 11113 format %{ "cmovI $crx, $dst, $src" %} 11114 // Worst case is branch + move + stop, no stop without scheduler. 11115 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 11116 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11117 ins_pipe(pipe_class_default); 11118 %} 11119 11120 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11121 // no match-rule, false predicate 11122 effect(DEF dst, USE crx, USE mem); 11123 predicate(false); 11124 11125 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11126 postalloc_expand %{ 11127 // 11128 // replaces 11129 // 11130 // region dst crx mem 11131 // \ | | / 11132 // dst=cmovI_bso_stackSlotL_conLvalue0 11133 // 11134 // with 11135 // 11136 // region dst 11137 // \ / 11138 // dst=loadConI16(0) 11139 // | 11140 // ^ region dst crx mem 11141 // | \ | | / 11142 // dst=cmovI_bso_stackSlotL 11143 // 11144 11145 // Create new nodes. 11146 MachNode *m1 = new loadConI16Node(); 11147 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11148 11149 // inputs for new nodes 11150 m1->add_req(n_region); 11151 m2->add_req(n_region, n_crx, n_mem); 11152 11153 // precedences for new nodes 11154 m2->add_prec(m1); 11155 11156 // operands for new nodes 11157 m1->_opnds[0] = op_dst; 11158 m1->_opnds[1] = new immI16Oper(0); 11159 11160 m2->_opnds[0] = op_dst; 11161 m2->_opnds[1] = op_crx; 11162 m2->_opnds[2] = op_mem; 11163 11164 // registers for new nodes 11165 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11166 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11167 11168 // Insert new nodes. 11169 nodes->push(m1); 11170 nodes->push(m2); 11171 %} 11172 %} 11173 11174 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11175 // no match-rule, false predicate 11176 effect(DEF dst, USE crx, USE src); 11177 predicate(false); 11178 11179 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11180 postalloc_expand %{ 11181 // 11182 // replaces 11183 // 11184 // region dst crx src 11185 // \ | | / 11186 // dst=cmovI_bso_reg_conLvalue0 11187 // 11188 // with 11189 // 11190 // region dst 11191 // \ / 11192 // dst=loadConI16(0) 11193 // | 11194 // ^ region dst crx src 11195 // | \ | | / 11196 // dst=cmovI_bso_reg 11197 // 11198 11199 // Create new nodes. 11200 MachNode *m1 = new loadConI16Node(); 11201 MachNode *m2 = new cmovI_bso_regNode(); 11202 11203 // inputs for new nodes 11204 m1->add_req(n_region); 11205 m2->add_req(n_region, n_crx, n_src); 11206 11207 // precedences for new nodes 11208 m2->add_prec(m1); 11209 11210 // operands for new nodes 11211 m1->_opnds[0] = op_dst; 11212 m1->_opnds[1] = new immI16Oper(0); 11213 11214 m2->_opnds[0] = op_dst; 11215 m2->_opnds[1] = op_crx; 11216 m2->_opnds[2] = op_src; 11217 11218 // registers for new nodes 11219 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11220 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11221 11222 // Insert new nodes. 11223 nodes->push(m1); 11224 nodes->push(m2); 11225 %} 11226 %} 11227 11228 // Double to Int conversion, NaN is mapped to 0. 11229 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11230 match(Set dst (ConvD2I src)); 11231 predicate(!VM_Version::has_mtfprd()); 11232 ins_cost(DEFAULT_COST); 11233 11234 expand %{ 11235 regD tmpD; 11236 stackSlotL tmpS; 11237 flagsReg crx; 11238 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11239 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11240 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11241 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11242 %} 11243 %} 11244 11245 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11246 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11247 match(Set dst (ConvD2I src)); 11248 predicate(VM_Version::has_mtfprd()); 11249 ins_cost(DEFAULT_COST); 11250 11251 expand %{ 11252 regD tmpD; 11253 flagsReg crx; 11254 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11255 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11256 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11257 %} 11258 %} 11259 11260 instruct convF2IRaw_regF(regF dst, regF src) %{ 11261 // no match-rule, false predicate 11262 effect(DEF dst, USE src); 11263 predicate(false); 11264 11265 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11266 size(4); 11267 ins_encode %{ 11268 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11269 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11270 %} 11271 ins_pipe(pipe_class_default); 11272 %} 11273 11274 // Float to Int conversion, NaN is mapped to 0. 11275 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11276 match(Set dst (ConvF2I src)); 11277 predicate(!VM_Version::has_mtfprd()); 11278 ins_cost(DEFAULT_COST); 11279 11280 expand %{ 11281 regF tmpF; 11282 stackSlotL tmpS; 11283 flagsReg crx; 11284 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11285 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11286 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11287 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11288 %} 11289 %} 11290 11291 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11292 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11293 match(Set dst (ConvF2I src)); 11294 predicate(VM_Version::has_mtfprd()); 11295 ins_cost(DEFAULT_COST); 11296 11297 expand %{ 11298 regF tmpF; 11299 flagsReg crx; 11300 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11301 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11302 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11303 %} 11304 %} 11305 11306 // Convert to Long 11307 11308 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11309 match(Set dst (ConvI2L src)); 11310 format %{ "EXTSW $dst, $src \t// int->long" %} 11311 size(4); 11312 ins_encode %{ 11313 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11314 __ extsw($dst$$Register, $src$$Register); 11315 %} 11316 ins_pipe(pipe_class_default); 11317 %} 11318 11319 // Zero-extend: convert unsigned int to long (convUI2L). 11320 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11321 match(Set dst (AndL (ConvI2L src) mask)); 11322 ins_cost(DEFAULT_COST); 11323 11324 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11325 size(4); 11326 ins_encode %{ 11327 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11328 __ clrldi($dst$$Register, $src$$Register, 32); 11329 %} 11330 ins_pipe(pipe_class_default); 11331 %} 11332 11333 // Zero-extend: convert unsigned int to long in long register. 11334 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11335 match(Set dst (AndL src mask)); 11336 ins_cost(DEFAULT_COST); 11337 11338 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11339 size(4); 11340 ins_encode %{ 11341 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11342 __ clrldi($dst$$Register, $src$$Register, 32); 11343 %} 11344 ins_pipe(pipe_class_default); 11345 %} 11346 11347 instruct convF2LRaw_regF(regF dst, regF src) %{ 11348 // no match-rule, false predicate 11349 effect(DEF dst, USE src); 11350 predicate(false); 11351 11352 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11353 size(4); 11354 ins_encode %{ 11355 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11356 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11357 %} 11358 ins_pipe(pipe_class_default); 11359 %} 11360 11361 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 11362 // no match-rule, false predicate 11363 effect(DEF dst, USE crx, USE src); 11364 predicate(false); 11365 11366 ins_variable_size_depending_on_alignment(true); 11367 11368 format %{ "cmovL $crx, $dst, $src" %} 11369 // Worst case is branch + move + stop, no stop without scheduler. 11370 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 11371 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11372 ins_pipe(pipe_class_default); 11373 %} 11374 11375 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11376 // no match-rule, false predicate 11377 effect(DEF dst, USE crx, USE src); 11378 predicate(false); 11379 11380 ins_variable_size_depending_on_alignment(true); 11381 11382 format %{ "cmovL $crx, $dst, $src" %} 11383 // Worst case is branch + move + stop, no stop without scheduler. 11384 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 11385 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11386 ins_pipe(pipe_class_default); 11387 %} 11388 11389 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11390 // no match-rule, false predicate 11391 effect(DEF dst, USE crx, USE mem); 11392 predicate(false); 11393 11394 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11395 postalloc_expand %{ 11396 // 11397 // replaces 11398 // 11399 // region dst crx mem 11400 // \ | | / 11401 // dst=cmovL_bso_stackSlotL_conLvalue0 11402 // 11403 // with 11404 // 11405 // region dst 11406 // \ / 11407 // dst=loadConL16(0) 11408 // | 11409 // ^ region dst crx mem 11410 // | \ | | / 11411 // dst=cmovL_bso_stackSlotL 11412 // 11413 11414 // Create new nodes. 11415 MachNode *m1 = new loadConL16Node(); 11416 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11417 11418 // inputs for new nodes 11419 m1->add_req(n_region); 11420 m2->add_req(n_region, n_crx, n_mem); 11421 m2->add_prec(m1); 11422 11423 // operands for new nodes 11424 m1->_opnds[0] = op_dst; 11425 m1->_opnds[1] = new immL16Oper(0); 11426 m2->_opnds[0] = op_dst; 11427 m2->_opnds[1] = op_crx; 11428 m2->_opnds[2] = op_mem; 11429 11430 // registers for new nodes 11431 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11432 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11433 11434 // Insert new nodes. 11435 nodes->push(m1); 11436 nodes->push(m2); 11437 %} 11438 %} 11439 11440 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11441 // no match-rule, false predicate 11442 effect(DEF dst, USE crx, USE src); 11443 predicate(false); 11444 11445 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11446 postalloc_expand %{ 11447 // 11448 // replaces 11449 // 11450 // region dst crx src 11451 // \ | | / 11452 // dst=cmovL_bso_reg_conLvalue0 11453 // 11454 // with 11455 // 11456 // region dst 11457 // \ / 11458 // dst=loadConL16(0) 11459 // | 11460 // ^ region dst crx src 11461 // | \ | | / 11462 // dst=cmovL_bso_reg 11463 // 11464 11465 // Create new nodes. 11466 MachNode *m1 = new loadConL16Node(); 11467 MachNode *m2 = new cmovL_bso_regNode(); 11468 11469 // inputs for new nodes 11470 m1->add_req(n_region); 11471 m2->add_req(n_region, n_crx, n_src); 11472 m2->add_prec(m1); 11473 11474 // operands for new nodes 11475 m1->_opnds[0] = op_dst; 11476 m1->_opnds[1] = new immL16Oper(0); 11477 m2->_opnds[0] = op_dst; 11478 m2->_opnds[1] = op_crx; 11479 m2->_opnds[2] = op_src; 11480 11481 // registers for new nodes 11482 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11483 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11484 11485 // Insert new nodes. 11486 nodes->push(m1); 11487 nodes->push(m2); 11488 %} 11489 %} 11490 11491 // Float to Long conversion, NaN is mapped to 0. 11492 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11493 match(Set dst (ConvF2L src)); 11494 predicate(!VM_Version::has_mtfprd()); 11495 ins_cost(DEFAULT_COST); 11496 11497 expand %{ 11498 regF tmpF; 11499 stackSlotL tmpS; 11500 flagsReg crx; 11501 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11502 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11503 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11504 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11505 %} 11506 %} 11507 11508 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11509 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11510 match(Set dst (ConvF2L src)); 11511 predicate(VM_Version::has_mtfprd()); 11512 ins_cost(DEFAULT_COST); 11513 11514 expand %{ 11515 regF tmpF; 11516 flagsReg crx; 11517 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11518 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11519 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11520 %} 11521 %} 11522 11523 instruct convD2LRaw_regD(regD dst, regD src) %{ 11524 // no match-rule, false predicate 11525 effect(DEF dst, USE src); 11526 predicate(false); 11527 11528 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11529 size(4); 11530 ins_encode %{ 11531 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11532 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11533 %} 11534 ins_pipe(pipe_class_default); 11535 %} 11536 11537 // Double to Long conversion, NaN is mapped to 0. 11538 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11539 match(Set dst (ConvD2L src)); 11540 predicate(!VM_Version::has_mtfprd()); 11541 ins_cost(DEFAULT_COST); 11542 11543 expand %{ 11544 regD tmpD; 11545 stackSlotL tmpS; 11546 flagsReg crx; 11547 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11548 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11549 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11550 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11551 %} 11552 %} 11553 11554 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11555 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11556 match(Set dst (ConvD2L src)); 11557 predicate(VM_Version::has_mtfprd()); 11558 ins_cost(DEFAULT_COST); 11559 11560 expand %{ 11561 regD tmpD; 11562 flagsReg crx; 11563 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11564 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11565 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11566 %} 11567 %} 11568 11569 // Convert to Float 11570 11571 // Placed here as needed in expand. 11572 instruct convL2DRaw_regD(regD dst, regD src) %{ 11573 // no match-rule, false predicate 11574 effect(DEF dst, USE src); 11575 predicate(false); 11576 11577 format %{ "FCFID $dst, $src \t// convL2D" %} 11578 size(4); 11579 ins_encode %{ 11580 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11581 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11582 %} 11583 ins_pipe(pipe_class_default); 11584 %} 11585 11586 // Placed here as needed in expand. 11587 instruct convD2F_reg(regF dst, regD src) %{ 11588 match(Set dst (ConvD2F src)); 11589 format %{ "FRSP $dst, $src \t// convD2F" %} 11590 size(4); 11591 ins_encode %{ 11592 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11593 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11594 %} 11595 ins_pipe(pipe_class_default); 11596 %} 11597 11598 // Integer to Float conversion. 11599 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11600 match(Set dst (ConvI2F src)); 11601 predicate(!VM_Version::has_fcfids()); 11602 ins_cost(DEFAULT_COST); 11603 11604 expand %{ 11605 iRegLdst tmpL; 11606 stackSlotL tmpS; 11607 regD tmpD; 11608 regD tmpD2; 11609 convI2L_reg(tmpL, src); // Sign-extension int to long. 11610 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11611 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11612 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11613 convD2F_reg(dst, tmpD2); // Convert double to float. 11614 %} 11615 %} 11616 11617 instruct convL2FRaw_regF(regF dst, regD src) %{ 11618 // no match-rule, false predicate 11619 effect(DEF dst, USE src); 11620 predicate(false); 11621 11622 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11623 size(4); 11624 ins_encode %{ 11625 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11626 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11627 %} 11628 ins_pipe(pipe_class_default); 11629 %} 11630 11631 // Integer to Float conversion. Special version for Power7. 11632 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11633 match(Set dst (ConvI2F src)); 11634 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11635 ins_cost(DEFAULT_COST); 11636 11637 expand %{ 11638 iRegLdst tmpL; 11639 stackSlotL tmpS; 11640 regD tmpD; 11641 convI2L_reg(tmpL, src); // Sign-extension int to long. 11642 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11643 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11644 convL2FRaw_regF(dst, tmpD); // Convert to float. 11645 %} 11646 %} 11647 11648 // Integer to Float conversion. Special version for Power8. 11649 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11650 match(Set dst (ConvI2F src)); 11651 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11652 ins_cost(DEFAULT_COST); 11653 11654 expand %{ 11655 regD tmpD; 11656 moveI2D_reg(tmpD, src); 11657 convL2FRaw_regF(dst, tmpD); // Convert to float. 11658 %} 11659 %} 11660 11661 // L2F to avoid runtime call. 11662 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11663 match(Set dst (ConvL2F src)); 11664 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11665 ins_cost(DEFAULT_COST); 11666 11667 expand %{ 11668 stackSlotL tmpS; 11669 regD tmpD; 11670 regL_to_stkL(tmpS, src); // Store long to stack. 11671 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11672 convL2FRaw_regF(dst, tmpD); // Convert to float. 11673 %} 11674 %} 11675 11676 // L2F to avoid runtime call. Special version for Power8. 11677 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11678 match(Set dst (ConvL2F src)); 11679 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11680 ins_cost(DEFAULT_COST); 11681 11682 expand %{ 11683 regD tmpD; 11684 moveL2D_reg(tmpD, src); 11685 convL2FRaw_regF(dst, tmpD); // Convert to float. 11686 %} 11687 %} 11688 11689 // Moved up as used in expand. 11690 //instruct convD2F_reg(regF dst, regD src) %{%} 11691 11692 // Convert to Double 11693 11694 // Integer to Double conversion. 11695 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11696 match(Set dst (ConvI2D src)); 11697 predicate(!VM_Version::has_mtfprd()); 11698 ins_cost(DEFAULT_COST); 11699 11700 expand %{ 11701 iRegLdst tmpL; 11702 stackSlotL tmpS; 11703 regD tmpD; 11704 convI2L_reg(tmpL, src); // Sign-extension int to long. 11705 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11706 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11707 convL2DRaw_regD(dst, tmpD); // Convert to double. 11708 %} 11709 %} 11710 11711 // Integer to Double conversion. Special version for Power8. 11712 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11713 match(Set dst (ConvI2D src)); 11714 predicate(VM_Version::has_mtfprd()); 11715 ins_cost(DEFAULT_COST); 11716 11717 expand %{ 11718 regD tmpD; 11719 moveI2D_reg(tmpD, src); 11720 convL2DRaw_regD(dst, tmpD); // Convert to double. 11721 %} 11722 %} 11723 11724 // Long to Double conversion 11725 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11726 match(Set dst (ConvL2D src)); 11727 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11728 11729 expand %{ 11730 regD tmpD; 11731 moveL2D_stack_reg(tmpD, src); 11732 convL2DRaw_regD(dst, tmpD); 11733 %} 11734 %} 11735 11736 // Long to Double conversion. Special version for Power8. 11737 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11738 match(Set dst (ConvL2D src)); 11739 predicate(VM_Version::has_mtfprd()); 11740 ins_cost(DEFAULT_COST); 11741 11742 expand %{ 11743 regD tmpD; 11744 moveL2D_reg(tmpD, src); 11745 convL2DRaw_regD(dst, tmpD); // Convert to double. 11746 %} 11747 %} 11748 11749 instruct convF2D_reg(regD dst, regF src) %{ 11750 match(Set dst (ConvF2D src)); 11751 format %{ "FMR $dst, $src \t// float->double" %} 11752 // variable size, 0 or 4 11753 ins_encode %{ 11754 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11755 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11756 %} 11757 ins_pipe(pipe_class_default); 11758 %} 11759 11760 //----------Control Flow Instructions------------------------------------------ 11761 // Compare Instructions 11762 11763 // Compare Integers 11764 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11765 match(Set crx (CmpI src1 src2)); 11766 size(4); 11767 format %{ "CMPW $crx, $src1, $src2" %} 11768 ins_encode %{ 11769 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11770 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11771 %} 11772 ins_pipe(pipe_class_compare); 11773 %} 11774 11775 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11776 match(Set crx (CmpI src1 src2)); 11777 format %{ "CMPWI $crx, $src1, $src2" %} 11778 size(4); 11779 ins_encode %{ 11780 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11781 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11782 %} 11783 ins_pipe(pipe_class_compare); 11784 %} 11785 11786 // (src1 & src2) == 0? 11787 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11788 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11789 // r0 is killed 11790 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11791 size(4); 11792 ins_encode %{ 11793 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11794 __ andi_(R0, $src1$$Register, $src2$$constant); 11795 %} 11796 ins_pipe(pipe_class_compare); 11797 %} 11798 11799 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11800 match(Set crx (CmpL src1 src2)); 11801 format %{ "CMPD $crx, $src1, $src2" %} 11802 size(4); 11803 ins_encode %{ 11804 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11805 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11806 %} 11807 ins_pipe(pipe_class_compare); 11808 %} 11809 11810 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11811 match(Set crx (CmpL src1 src2)); 11812 format %{ "CMPDI $crx, $src1, $src2" %} 11813 size(4); 11814 ins_encode %{ 11815 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11816 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11817 %} 11818 ins_pipe(pipe_class_compare); 11819 %} 11820 11821 // Added CmpUL for LoopPredicate. 11822 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11823 match(Set crx (CmpUL src1 src2)); 11824 format %{ "CMPLD $crx, $src1, $src2" %} 11825 size(4); 11826 ins_encode %{ 11827 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11828 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11829 %} 11830 ins_pipe(pipe_class_compare); 11831 %} 11832 11833 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11834 match(Set crx (CmpUL src1 src2)); 11835 format %{ "CMPLDI $crx, $src1, $src2" %} 11836 size(4); 11837 ins_encode %{ 11838 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11839 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11840 %} 11841 ins_pipe(pipe_class_compare); 11842 %} 11843 11844 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11845 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11846 // r0 is killed 11847 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11848 size(4); 11849 ins_encode %{ 11850 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11851 __ and_(R0, $src1$$Register, $src2$$Register); 11852 %} 11853 ins_pipe(pipe_class_compare); 11854 %} 11855 11856 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11857 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11858 // r0 is killed 11859 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11860 size(4); 11861 ins_encode %{ 11862 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11863 __ andi_(R0, $src1$$Register, $src2$$constant); 11864 %} 11865 ins_pipe(pipe_class_compare); 11866 %} 11867 11868 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11869 // no match-rule, false predicate 11870 effect(DEF dst, USE crx); 11871 predicate(false); 11872 11873 ins_variable_size_depending_on_alignment(true); 11874 11875 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11876 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11877 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16); 11878 ins_encode %{ 11879 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11880 Label done; 11881 // li(Rdst, 0); // equal -> 0 11882 __ beq($crx$$CondRegister, done); 11883 __ li($dst$$Register, 1); // greater -> +1 11884 __ bgt($crx$$CondRegister, done); 11885 __ li($dst$$Register, -1); // unordered or less -> -1 11886 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11887 __ bind(done); 11888 %} 11889 ins_pipe(pipe_class_compare); 11890 %} 11891 11892 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11893 // no match-rule, false predicate 11894 effect(DEF dst, USE crx); 11895 predicate(false); 11896 11897 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11898 postalloc_expand %{ 11899 // 11900 // replaces 11901 // 11902 // region crx 11903 // \ | 11904 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11905 // 11906 // with 11907 // 11908 // region 11909 // \ 11910 // dst=loadConI16(0) 11911 // | 11912 // ^ region crx 11913 // | \ | 11914 // dst=cmovI_conIvalueMinus1_conIvalue1 11915 // 11916 11917 // Create new nodes. 11918 MachNode *m1 = new loadConI16Node(); 11919 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11920 11921 // inputs for new nodes 11922 m1->add_req(n_region); 11923 m2->add_req(n_region, n_crx); 11924 m2->add_prec(m1); 11925 11926 // operands for new nodes 11927 m1->_opnds[0] = op_dst; 11928 m1->_opnds[1] = new immI16Oper(0); 11929 m2->_opnds[0] = op_dst; 11930 m2->_opnds[1] = op_crx; 11931 11932 // registers for new nodes 11933 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11934 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11935 11936 // Insert new nodes. 11937 nodes->push(m1); 11938 nodes->push(m2); 11939 %} 11940 %} 11941 11942 // Manifest a CmpL3 result in an integer register. Very painful. 11943 // This is the test to avoid. 11944 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11945 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11946 match(Set dst (CmpL3 src1 src2)); 11947 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11948 11949 expand %{ 11950 flagsReg tmp1; 11951 cmpL_reg_reg(tmp1, src1, src2); 11952 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11953 %} 11954 %} 11955 11956 // Implicit range checks. 11957 // A range check in the ideal world has one of the following shapes: 11958 // - (If le (CmpU length index)), (IfTrue throw exception) 11959 // - (If lt (CmpU index length)), (IfFalse throw exception) 11960 // 11961 // Match range check 'If le (CmpU length index)'. 11962 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11963 match(If cmp (CmpU src_length index)); 11964 effect(USE labl); 11965 predicate(TrapBasedRangeChecks && 11966 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11967 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11968 (Matcher::branches_to_uncommon_trap(_leaf))); 11969 11970 ins_is_TrapBasedCheckNode(true); 11971 11972 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11973 size(4); 11974 ins_encode %{ 11975 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11976 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11977 __ trap_range_check_le($src_length$$Register, $index$$constant); 11978 } else { 11979 // Both successors are uncommon traps, probability is 0. 11980 // Node got flipped during fixup flow. 11981 assert($cmp$$cmpcode == 0x9, "must be greater"); 11982 __ trap_range_check_g($src_length$$Register, $index$$constant); 11983 } 11984 %} 11985 ins_pipe(pipe_class_trap); 11986 %} 11987 11988 // Match range check 'If lt (CmpU index length)'. 11989 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11990 match(If cmp (CmpU src_index src_length)); 11991 effect(USE labl); 11992 predicate(TrapBasedRangeChecks && 11993 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11994 _leaf->as_If()->_prob >= PROB_ALWAYS && 11995 (Matcher::branches_to_uncommon_trap(_leaf))); 11996 11997 ins_is_TrapBasedCheckNode(true); 11998 11999 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 12000 size(4); 12001 ins_encode %{ 12002 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 12003 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12004 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 12005 } else { 12006 // Both successors are uncommon traps, probability is 0. 12007 // Node got flipped during fixup flow. 12008 assert($cmp$$cmpcode == 0x8, "must be less"); 12009 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 12010 } 12011 %} 12012 ins_pipe(pipe_class_trap); 12013 %} 12014 12015 // Match range check 'If lt (CmpU index length)'. 12016 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 12017 match(If cmp (CmpU src_index length)); 12018 effect(USE labl); 12019 predicate(TrapBasedRangeChecks && 12020 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12021 _leaf->as_If()->_prob >= PROB_ALWAYS && 12022 (Matcher::branches_to_uncommon_trap(_leaf))); 12023 12024 ins_is_TrapBasedCheckNode(true); 12025 12026 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 12027 size(4); 12028 ins_encode %{ 12029 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12030 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12031 __ trap_range_check_ge($src_index$$Register, $length$$constant); 12032 } else { 12033 // Both successors are uncommon traps, probability is 0. 12034 // Node got flipped during fixup flow. 12035 assert($cmp$$cmpcode == 0x8, "must be less"); 12036 __ trap_range_check_l($src_index$$Register, $length$$constant); 12037 } 12038 %} 12039 ins_pipe(pipe_class_trap); 12040 %} 12041 12042 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 12043 match(Set crx (CmpU src1 src2)); 12044 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 12045 size(4); 12046 ins_encode %{ 12047 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12048 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12049 %} 12050 ins_pipe(pipe_class_compare); 12051 %} 12052 12053 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 12054 match(Set crx (CmpU src1 src2)); 12055 size(4); 12056 format %{ "CMPLWI $crx, $src1, $src2" %} 12057 ins_encode %{ 12058 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12059 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12060 %} 12061 ins_pipe(pipe_class_compare); 12062 %} 12063 12064 // Implicit zero checks (more implicit null checks). 12065 // No constant pool entries required. 12066 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12067 match(If cmp (CmpN value zero)); 12068 effect(USE labl); 12069 predicate(TrapBasedNullChecks && 12070 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12071 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12072 Matcher::branches_to_uncommon_trap(_leaf)); 12073 ins_cost(1); 12074 12075 ins_is_TrapBasedCheckNode(true); 12076 12077 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12078 size(4); 12079 ins_encode %{ 12080 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12081 if ($cmp$$cmpcode == 0xA) { 12082 __ trap_null_check($value$$Register); 12083 } else { 12084 // Both successors are uncommon traps, probability is 0. 12085 // Node got flipped during fixup flow. 12086 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12087 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12088 } 12089 %} 12090 ins_pipe(pipe_class_trap); 12091 %} 12092 12093 // Compare narrow oops. 12094 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12095 match(Set crx (CmpN src1 src2)); 12096 12097 size(4); 12098 ins_cost(2); 12099 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12100 ins_encode %{ 12101 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12102 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12103 %} 12104 ins_pipe(pipe_class_compare); 12105 %} 12106 12107 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12108 match(Set crx (CmpN src1 src2)); 12109 // Make this more expensive than zeroCheckN_iReg_imm0. 12110 ins_cost(2); 12111 12112 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12113 size(4); 12114 ins_encode %{ 12115 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12116 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12117 %} 12118 ins_pipe(pipe_class_compare); 12119 %} 12120 12121 // Implicit zero checks (more implicit null checks). 12122 // No constant pool entries required. 12123 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12124 match(If cmp (CmpP value zero)); 12125 effect(USE labl); 12126 predicate(TrapBasedNullChecks && 12127 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12128 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12129 Matcher::branches_to_uncommon_trap(_leaf)); 12130 ins_cost(1); // Should not be cheaper than zeroCheckN. 12131 12132 ins_is_TrapBasedCheckNode(true); 12133 12134 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12135 size(4); 12136 ins_encode %{ 12137 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12138 if ($cmp$$cmpcode == 0xA) { 12139 __ trap_null_check($value$$Register); 12140 } else { 12141 // Both successors are uncommon traps, probability is 0. 12142 // Node got flipped during fixup flow. 12143 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12144 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12145 } 12146 %} 12147 ins_pipe(pipe_class_trap); 12148 %} 12149 12150 // Compare Pointers 12151 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12152 match(Set crx (CmpP src1 src2)); 12153 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12154 size(4); 12155 ins_encode %{ 12156 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12157 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12158 %} 12159 ins_pipe(pipe_class_compare); 12160 %} 12161 12162 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12163 match(Set crx (CmpP src1 src2)); 12164 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12165 size(4); 12166 ins_encode %{ 12167 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12168 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12169 %} 12170 ins_pipe(pipe_class_compare); 12171 %} 12172 12173 // Used in postalloc expand. 12174 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12175 // This match rule prevents reordering of node before a safepoint. 12176 // This only makes sense if this instructions is used exclusively 12177 // for the expansion of EncodeP! 12178 match(Set crx (CmpP src1 src2)); 12179 predicate(false); 12180 12181 format %{ "CMPDI $crx, $src1, $src2" %} 12182 size(4); 12183 ins_encode %{ 12184 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12185 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12186 %} 12187 ins_pipe(pipe_class_compare); 12188 %} 12189 12190 //----------Float Compares---------------------------------------------------- 12191 12192 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12193 // Needs matchrule, see cmpDUnordered. 12194 match(Set crx (CmpF src1 src2)); 12195 // no match-rule, false predicate 12196 predicate(false); 12197 12198 format %{ "cmpFUrd $crx, $src1, $src2" %} 12199 size(4); 12200 ins_encode %{ 12201 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12202 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12203 %} 12204 ins_pipe(pipe_class_default); 12205 %} 12206 12207 instruct cmov_bns_less(flagsReg crx) %{ 12208 // no match-rule, false predicate 12209 effect(DEF crx); 12210 predicate(false); 12211 12212 ins_variable_size_depending_on_alignment(true); 12213 12214 format %{ "cmov $crx" %} 12215 // Worst case is branch + move + stop, no stop without scheduler. 12216 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12); 12217 ins_encode %{ 12218 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12219 Label done; 12220 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12221 __ li(R0, 0); 12222 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12223 // TODO PPC port __ endgroup_if_needed(_size == 16); 12224 __ bind(done); 12225 %} 12226 ins_pipe(pipe_class_default); 12227 %} 12228 12229 // Compare floating, generate condition code. 12230 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12231 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12232 // 12233 // The following code sequence occurs a lot in mpegaudio: 12234 // 12235 // block BXX: 12236 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12237 // cmpFUrd CCR6, F11, F9 12238 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12239 // cmov CCR6 12240 // 8: instruct branchConSched: 12241 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12242 match(Set crx (CmpF src1 src2)); 12243 ins_cost(DEFAULT_COST+BRANCH_COST); 12244 12245 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12246 postalloc_expand %{ 12247 // 12248 // replaces 12249 // 12250 // region src1 src2 12251 // \ | | 12252 // crx=cmpF_reg_reg 12253 // 12254 // with 12255 // 12256 // region src1 src2 12257 // \ | | 12258 // crx=cmpFUnordered_reg_reg 12259 // | 12260 // ^ region 12261 // | \ 12262 // crx=cmov_bns_less 12263 // 12264 12265 // Create new nodes. 12266 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12267 MachNode *m2 = new cmov_bns_lessNode(); 12268 12269 // inputs for new nodes 12270 m1->add_req(n_region, n_src1, n_src2); 12271 m2->add_req(n_region); 12272 m2->add_prec(m1); 12273 12274 // operands for new nodes 12275 m1->_opnds[0] = op_crx; 12276 m1->_opnds[1] = op_src1; 12277 m1->_opnds[2] = op_src2; 12278 m2->_opnds[0] = op_crx; 12279 12280 // registers for new nodes 12281 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12282 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12283 12284 // Insert new nodes. 12285 nodes->push(m1); 12286 nodes->push(m2); 12287 %} 12288 %} 12289 12290 // Compare float, generate -1,0,1 12291 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12292 match(Set dst (CmpF3 src1 src2)); 12293 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12294 12295 expand %{ 12296 flagsReg tmp1; 12297 cmpFUnordered_reg_reg(tmp1, src1, src2); 12298 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12299 %} 12300 %} 12301 12302 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12303 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12304 // node right before the conditional move using it. 12305 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12306 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12307 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12308 // conditional move was supposed to be spilled. 12309 match(Set crx (CmpD src1 src2)); 12310 // False predicate, shall not be matched. 12311 predicate(false); 12312 12313 format %{ "cmpFUrd $crx, $src1, $src2" %} 12314 size(4); 12315 ins_encode %{ 12316 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12317 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12318 %} 12319 ins_pipe(pipe_class_default); 12320 %} 12321 12322 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12323 match(Set crx (CmpD src1 src2)); 12324 ins_cost(DEFAULT_COST+BRANCH_COST); 12325 12326 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12327 postalloc_expand %{ 12328 // 12329 // replaces 12330 // 12331 // region src1 src2 12332 // \ | | 12333 // crx=cmpD_reg_reg 12334 // 12335 // with 12336 // 12337 // region src1 src2 12338 // \ | | 12339 // crx=cmpDUnordered_reg_reg 12340 // | 12341 // ^ region 12342 // | \ 12343 // crx=cmov_bns_less 12344 // 12345 12346 // create new nodes 12347 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12348 MachNode *m2 = new cmov_bns_lessNode(); 12349 12350 // inputs for new nodes 12351 m1->add_req(n_region, n_src1, n_src2); 12352 m2->add_req(n_region); 12353 m2->add_prec(m1); 12354 12355 // operands for new nodes 12356 m1->_opnds[0] = op_crx; 12357 m1->_opnds[1] = op_src1; 12358 m1->_opnds[2] = op_src2; 12359 m2->_opnds[0] = op_crx; 12360 12361 // registers for new nodes 12362 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12363 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12364 12365 // Insert new nodes. 12366 nodes->push(m1); 12367 nodes->push(m2); 12368 %} 12369 %} 12370 12371 // Compare double, generate -1,0,1 12372 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12373 match(Set dst (CmpD3 src1 src2)); 12374 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12375 12376 expand %{ 12377 flagsReg tmp1; 12378 cmpDUnordered_reg_reg(tmp1, src1, src2); 12379 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12380 %} 12381 %} 12382 12383 //----------Branches--------------------------------------------------------- 12384 // Jump 12385 12386 // Direct Branch. 12387 instruct branch(label labl) %{ 12388 match(Goto); 12389 effect(USE labl); 12390 ins_cost(BRANCH_COST); 12391 12392 format %{ "B $labl" %} 12393 size(4); 12394 ins_encode %{ 12395 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12396 Label d; // dummy 12397 __ bind(d); 12398 Label* p = $labl$$label; 12399 // `p' is `NULL' when this encoding class is used only to 12400 // determine the size of the encoded instruction. 12401 Label& l = (NULL == p)? d : *(p); 12402 __ b(l); 12403 %} 12404 ins_pipe(pipe_class_default); 12405 %} 12406 12407 // Conditional Near Branch 12408 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12409 // Same match rule as `branchConFar'. 12410 match(If cmp crx); 12411 effect(USE lbl); 12412 ins_cost(BRANCH_COST); 12413 12414 // If set to 1 this indicates that the current instruction is a 12415 // short variant of a long branch. This avoids using this 12416 // instruction in first-pass matching. It will then only be used in 12417 // the `Shorten_branches' pass. 12418 ins_short_branch(1); 12419 12420 format %{ "B$cmp $crx, $lbl" %} 12421 size(4); 12422 ins_encode( enc_bc(crx, cmp, lbl) ); 12423 ins_pipe(pipe_class_default); 12424 %} 12425 12426 // This is for cases when the ppc64 `bc' instruction does not 12427 // reach far enough. So we emit a far branch here, which is more 12428 // expensive. 12429 // 12430 // Conditional Far Branch 12431 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12432 // Same match rule as `branchCon'. 12433 match(If cmp crx); 12434 effect(USE crx, USE lbl); 12435 predicate(!false /* TODO: PPC port HB_Schedule*/); 12436 // Higher cost than `branchCon'. 12437 ins_cost(5*BRANCH_COST); 12438 12439 // This is not a short variant of a branch, but the long variant. 12440 ins_short_branch(0); 12441 12442 format %{ "B_FAR$cmp $crx, $lbl" %} 12443 size(8); 12444 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12445 ins_pipe(pipe_class_default); 12446 %} 12447 12448 // Conditional Branch used with Power6 scheduler (can be far or short). 12449 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12450 // Same match rule as `branchCon'. 12451 match(If cmp crx); 12452 effect(USE crx, USE lbl); 12453 predicate(false /* TODO: PPC port HB_Schedule*/); 12454 // Higher cost than `branchCon'. 12455 ins_cost(5*BRANCH_COST); 12456 12457 // Actually size doesn't depend on alignment but on shortening. 12458 ins_variable_size_depending_on_alignment(true); 12459 // long variant. 12460 ins_short_branch(0); 12461 12462 format %{ "B_FAR$cmp $crx, $lbl" %} 12463 size(8); // worst case 12464 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12465 ins_pipe(pipe_class_default); 12466 %} 12467 12468 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12469 match(CountedLoopEnd cmp crx); 12470 effect(USE labl); 12471 ins_cost(BRANCH_COST); 12472 12473 // short variant. 12474 ins_short_branch(1); 12475 12476 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12477 size(4); 12478 ins_encode( enc_bc(crx, cmp, labl) ); 12479 ins_pipe(pipe_class_default); 12480 %} 12481 12482 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12483 match(CountedLoopEnd cmp crx); 12484 effect(USE labl); 12485 predicate(!false /* TODO: PPC port HB_Schedule */); 12486 ins_cost(BRANCH_COST); 12487 12488 // Long variant. 12489 ins_short_branch(0); 12490 12491 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12492 size(8); 12493 ins_encode( enc_bc_far(crx, cmp, labl) ); 12494 ins_pipe(pipe_class_default); 12495 %} 12496 12497 // Conditional Branch used with Power6 scheduler (can be far or short). 12498 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12499 match(CountedLoopEnd cmp crx); 12500 effect(USE labl); 12501 predicate(false /* TODO: PPC port HB_Schedule */); 12502 // Higher cost than `branchCon'. 12503 ins_cost(5*BRANCH_COST); 12504 12505 // Actually size doesn't depend on alignment but on shortening. 12506 ins_variable_size_depending_on_alignment(true); 12507 // Long variant. 12508 ins_short_branch(0); 12509 12510 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12511 size(8); // worst case 12512 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12513 ins_pipe(pipe_class_default); 12514 %} 12515 12516 // ============================================================================ 12517 // Java runtime operations, intrinsics and other complex operations. 12518 12519 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12520 // array for an instance of the superklass. Set a hidden internal cache on a 12521 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12522 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12523 // 12524 // GL TODO: Improve this. 12525 // - result should not be a TEMP 12526 // - Add match rule as on sparc avoiding additional Cmp. 12527 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12528 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12529 match(Set result (PartialSubtypeCheck subklass superklass)); 12530 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12531 ins_cost(DEFAULT_COST*10); 12532 12533 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12534 ins_encode %{ 12535 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12536 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12537 $tmp_klass$$Register, NULL, $result$$Register); 12538 %} 12539 ins_pipe(pipe_class_default); 12540 %} 12541 12542 // inlined locking and unlocking 12543 12544 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12545 match(Set crx (FastLock oop box)); 12546 effect(TEMP tmp1, TEMP tmp2); 12547 predicate(!Compile::current()->use_rtm()); 12548 12549 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12550 ins_encode %{ 12551 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12552 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12553 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12554 UseBiasedLocking && !UseOptoBiasInlining); 12555 // If locking was successfull, crx should indicate 'EQ'. 12556 // The compiler generates a branch to the runtime call to 12557 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12558 %} 12559 ins_pipe(pipe_class_compare); 12560 %} 12561 12562 // Separate version for TM. Use bound register for box to enable USE_KILL. 12563 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12564 match(Set crx (FastLock oop box)); 12565 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12566 predicate(Compile::current()->use_rtm()); 12567 12568 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12569 ins_encode %{ 12570 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12571 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12572 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12573 /*Biased Locking*/ false, 12574 _rtm_counters, _stack_rtm_counters, 12575 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12576 /*TM*/ true, ra_->C->profile_rtm()); 12577 // If locking was successfull, crx should indicate 'EQ'. 12578 // The compiler generates a branch to the runtime call to 12579 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12580 %} 12581 ins_pipe(pipe_class_compare); 12582 %} 12583 12584 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12585 match(Set crx (FastUnlock oop box)); 12586 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12587 predicate(!Compile::current()->use_rtm()); 12588 12589 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12590 ins_encode %{ 12591 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12592 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12593 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12594 UseBiasedLocking && !UseOptoBiasInlining, 12595 false); 12596 // If unlocking was successfull, crx should indicate 'EQ'. 12597 // The compiler generates a branch to the runtime call to 12598 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12599 %} 12600 ins_pipe(pipe_class_compare); 12601 %} 12602 12603 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12604 match(Set crx (FastUnlock oop box)); 12605 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12606 predicate(Compile::current()->use_rtm()); 12607 12608 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12609 ins_encode %{ 12610 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12611 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12612 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12613 /*Biased Locking*/ false, /*TM*/ true); 12614 // If unlocking was successfull, crx should indicate 'EQ'. 12615 // The compiler generates a branch to the runtime call to 12616 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12617 %} 12618 ins_pipe(pipe_class_compare); 12619 %} 12620 12621 // Align address. 12622 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12623 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12624 12625 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12626 size(4); 12627 ins_encode %{ 12628 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12629 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12630 %} 12631 ins_pipe(pipe_class_default); 12632 %} 12633 12634 // Array size computation. 12635 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12636 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12637 12638 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12639 size(4); 12640 ins_encode %{ 12641 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12642 __ subf($dst$$Register, $start$$Register, $end$$Register); 12643 %} 12644 ins_pipe(pipe_class_default); 12645 %} 12646 12647 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12648 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12649 match(Set dummy (ClearArray cnt base)); 12650 effect(USE_KILL base, KILL ctr); 12651 ins_cost(2 * MEMORY_REF_COST); 12652 12653 format %{ "ClearArray $cnt, $base" %} 12654 ins_encode %{ 12655 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12656 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12657 %} 12658 ins_pipe(pipe_class_default); 12659 %} 12660 12661 // Clear-array with constant large array length. 12662 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12663 match(Set dummy (ClearArray cnt base)); 12664 effect(USE_KILL base, TEMP tmp, KILL ctr); 12665 ins_cost(3 * MEMORY_REF_COST); 12666 12667 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12668 ins_encode %{ 12669 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12670 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12671 %} 12672 ins_pipe(pipe_class_default); 12673 %} 12674 12675 // Clear-array with dynamic array length. 12676 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12677 match(Set dummy (ClearArray cnt base)); 12678 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12679 ins_cost(4 * MEMORY_REF_COST); 12680 12681 format %{ "ClearArray $cnt, $base" %} 12682 ins_encode %{ 12683 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12684 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12685 %} 12686 ins_pipe(pipe_class_default); 12687 %} 12688 12689 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12690 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12691 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12692 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12693 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12694 ins_cost(300); 12695 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12696 ins_encode %{ 12697 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12698 __ string_compare($str1$$Register, $str2$$Register, 12699 $cnt1$$Register, $cnt2$$Register, 12700 $tmp$$Register, 12701 $result$$Register, StrIntrinsicNode::LL); 12702 %} 12703 ins_pipe(pipe_class_default); 12704 %} 12705 12706 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12707 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12708 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12709 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12710 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12711 ins_cost(300); 12712 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12713 ins_encode %{ 12714 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12715 __ string_compare($str1$$Register, $str2$$Register, 12716 $cnt1$$Register, $cnt2$$Register, 12717 $tmp$$Register, 12718 $result$$Register, StrIntrinsicNode::UU); 12719 %} 12720 ins_pipe(pipe_class_default); 12721 %} 12722 12723 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12724 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12725 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12726 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12727 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12728 ins_cost(300); 12729 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12730 ins_encode %{ 12731 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12732 __ string_compare($str1$$Register, $str2$$Register, 12733 $cnt1$$Register, $cnt2$$Register, 12734 $tmp$$Register, 12735 $result$$Register, StrIntrinsicNode::LU); 12736 %} 12737 ins_pipe(pipe_class_default); 12738 %} 12739 12740 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12741 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12742 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12743 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12744 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12745 ins_cost(300); 12746 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12747 ins_encode %{ 12748 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12749 __ string_compare($str2$$Register, $str1$$Register, 12750 $cnt2$$Register, $cnt1$$Register, 12751 $tmp$$Register, 12752 $result$$Register, StrIntrinsicNode::UL); 12753 %} 12754 ins_pipe(pipe_class_default); 12755 %} 12756 12757 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12758 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12759 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12760 match(Set result (StrEquals (Binary str1 str2) cnt)); 12761 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12762 ins_cost(300); 12763 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12764 ins_encode %{ 12765 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12766 __ array_equals(false, $str1$$Register, $str2$$Register, 12767 $cnt$$Register, $tmp$$Register, 12768 $result$$Register, true /* byte */); 12769 %} 12770 ins_pipe(pipe_class_default); 12771 %} 12772 12773 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12774 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12775 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12776 match(Set result (StrEquals (Binary str1 str2) cnt)); 12777 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12778 ins_cost(300); 12779 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12780 ins_encode %{ 12781 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12782 __ array_equals(false, $str1$$Register, $str2$$Register, 12783 $cnt$$Register, $tmp$$Register, 12784 $result$$Register, false /* byte */); 12785 %} 12786 ins_pipe(pipe_class_default); 12787 %} 12788 12789 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12790 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12791 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12792 match(Set result (AryEq ary1 ary2)); 12793 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12794 ins_cost(300); 12795 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12796 ins_encode %{ 12797 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12798 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12799 $tmp1$$Register, $tmp2$$Register, 12800 $result$$Register, true /* byte */); 12801 %} 12802 ins_pipe(pipe_class_default); 12803 %} 12804 12805 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12806 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12807 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12808 match(Set result (AryEq ary1 ary2)); 12809 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12810 ins_cost(300); 12811 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12812 ins_encode %{ 12813 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12814 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12815 $tmp1$$Register, $tmp2$$Register, 12816 $result$$Register, false /* byte */); 12817 %} 12818 ins_pipe(pipe_class_default); 12819 %} 12820 12821 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12822 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12823 iRegIdst tmp1, iRegIdst tmp2, 12824 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12825 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12826 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12827 // Required for EA: check if it is still a type_array. 12828 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12829 ins_cost(150); 12830 12831 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12832 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12833 12834 ins_encode %{ 12835 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12836 immPOper *needleOper = (immPOper *)$needleImm; 12837 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12838 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12839 jchar chr; 12840 #ifdef VM_LITTLE_ENDIAN 12841 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12842 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12843 #else 12844 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12845 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12846 #endif 12847 __ string_indexof_char($result$$Register, 12848 $haystack$$Register, $haycnt$$Register, 12849 R0, chr, 12850 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12851 %} 12852 ins_pipe(pipe_class_compare); 12853 %} 12854 12855 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12856 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12857 iRegIdst tmp1, iRegIdst tmp2, 12858 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12859 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12860 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12861 // Required for EA: check if it is still a type_array. 12862 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12863 ins_cost(150); 12864 12865 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12866 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12867 12868 ins_encode %{ 12869 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12870 immPOper *needleOper = (immPOper *)$needleImm; 12871 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12872 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12873 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12874 __ string_indexof_char($result$$Register, 12875 $haystack$$Register, $haycnt$$Register, 12876 R0, chr, 12877 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12878 %} 12879 ins_pipe(pipe_class_compare); 12880 %} 12881 12882 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12883 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12884 iRegIdst tmp1, iRegIdst tmp2, 12885 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12886 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12887 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12888 // Required for EA: check if it is still a type_array. 12889 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12890 ins_cost(150); 12891 12892 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12893 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12894 12895 ins_encode %{ 12896 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12897 immPOper *needleOper = (immPOper *)$needleImm; 12898 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12899 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12900 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12901 __ string_indexof_char($result$$Register, 12902 $haystack$$Register, $haycnt$$Register, 12903 R0, chr, 12904 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12905 %} 12906 ins_pipe(pipe_class_compare); 12907 %} 12908 12909 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12910 rscratch2RegP needle, immI_1 needlecntImm, 12911 iRegIdst tmp1, iRegIdst tmp2, 12912 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12913 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12914 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12915 // Required for EA: check if it is still a type_array. 12916 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12917 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12918 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12919 ins_cost(180); 12920 12921 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12922 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12923 ins_encode %{ 12924 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12925 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12926 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12927 guarantee(needle_values, "sanity"); 12928 jchar chr; 12929 #ifdef VM_LITTLE_ENDIAN 12930 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12931 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12932 #else 12933 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12934 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12935 #endif 12936 __ string_indexof_char($result$$Register, 12937 $haystack$$Register, $haycnt$$Register, 12938 R0, chr, 12939 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12940 %} 12941 ins_pipe(pipe_class_compare); 12942 %} 12943 12944 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12945 rscratch2RegP needle, immI_1 needlecntImm, 12946 iRegIdst tmp1, iRegIdst tmp2, 12947 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12948 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12949 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12950 // Required for EA: check if it is still a type_array. 12951 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12952 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12953 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12954 ins_cost(180); 12955 12956 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12957 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12958 ins_encode %{ 12959 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12960 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12961 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12962 guarantee(needle_values, "sanity"); 12963 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12964 __ string_indexof_char($result$$Register, 12965 $haystack$$Register, $haycnt$$Register, 12966 R0, chr, 12967 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12968 %} 12969 ins_pipe(pipe_class_compare); 12970 %} 12971 12972 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12973 rscratch2RegP needle, immI_1 needlecntImm, 12974 iRegIdst tmp1, iRegIdst tmp2, 12975 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12976 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12977 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12978 // Required for EA: check if it is still a type_array. 12979 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12980 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12981 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12982 ins_cost(180); 12983 12984 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12985 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12986 ins_encode %{ 12987 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12988 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12989 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12990 guarantee(needle_values, "sanity"); 12991 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12992 __ string_indexof_char($result$$Register, 12993 $haystack$$Register, $haycnt$$Register, 12994 R0, chr, 12995 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12996 %} 12997 ins_pipe(pipe_class_compare); 12998 %} 12999 13000 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13001 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 13002 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13003 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 13004 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13005 ins_cost(180); 13006 13007 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 13008 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13009 ins_encode %{ 13010 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13011 __ string_indexof_char($result$$Register, 13012 $haystack$$Register, $haycnt$$Register, 13013 $ch$$Register, 0 /* this is not used if the character is already in a register */, 13014 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13015 %} 13016 ins_pipe(pipe_class_compare); 13017 %} 13018 13019 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13020 iRegPsrc needle, uimmI15 needlecntImm, 13021 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13022 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13023 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13024 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13025 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13026 // Required for EA: check if it is still a type_array. 13027 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13028 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13029 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13030 ins_cost(250); 13031 13032 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13033 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13034 ins_encode %{ 13035 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13036 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13037 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13038 13039 __ string_indexof($result$$Register, 13040 $haystack$$Register, $haycnt$$Register, 13041 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13042 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13043 %} 13044 ins_pipe(pipe_class_compare); 13045 %} 13046 13047 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13048 iRegPsrc needle, uimmI15 needlecntImm, 13049 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13050 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13051 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13052 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13053 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13054 // Required for EA: check if it is still a type_array. 13055 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13056 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13057 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13058 ins_cost(250); 13059 13060 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13061 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13062 ins_encode %{ 13063 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13064 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13065 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13066 13067 __ string_indexof($result$$Register, 13068 $haystack$$Register, $haycnt$$Register, 13069 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13070 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13071 %} 13072 ins_pipe(pipe_class_compare); 13073 %} 13074 13075 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13076 iRegPsrc needle, uimmI15 needlecntImm, 13077 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13078 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13079 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13080 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13081 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13082 // Required for EA: check if it is still a type_array. 13083 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13084 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13085 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13086 ins_cost(250); 13087 13088 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13089 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13090 ins_encode %{ 13091 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13092 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13093 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13094 13095 __ string_indexof($result$$Register, 13096 $haystack$$Register, $haycnt$$Register, 13097 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13098 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13099 %} 13100 ins_pipe(pipe_class_compare); 13101 %} 13102 13103 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13104 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13105 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13106 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13107 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13108 TEMP_DEF result, 13109 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13110 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13111 ins_cost(300); 13112 13113 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13114 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13115 ins_encode %{ 13116 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13117 __ string_indexof($result$$Register, 13118 $haystack$$Register, $haycnt$$Register, 13119 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13120 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13121 %} 13122 ins_pipe(pipe_class_compare); 13123 %} 13124 13125 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13126 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13127 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13128 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13129 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13130 TEMP_DEF result, 13131 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13132 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13133 ins_cost(300); 13134 13135 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13136 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13137 ins_encode %{ 13138 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13139 __ string_indexof($result$$Register, 13140 $haystack$$Register, $haycnt$$Register, 13141 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13142 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13143 %} 13144 ins_pipe(pipe_class_compare); 13145 %} 13146 13147 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13148 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13149 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13150 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13151 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13152 TEMP_DEF result, 13153 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13154 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13155 ins_cost(300); 13156 13157 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13158 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13159 ins_encode %{ 13160 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13161 __ string_indexof($result$$Register, 13162 $haystack$$Register, $haycnt$$Register, 13163 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13164 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13165 %} 13166 ins_pipe(pipe_class_compare); 13167 %} 13168 13169 // char[] to byte[] compression 13170 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13171 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13172 match(Set result (StrCompressedCopy src (Binary dst len))); 13173 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13174 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13175 ins_cost(300); 13176 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13177 ins_encode %{ 13178 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13179 Label Lskip, Ldone; 13180 __ li($result$$Register, 0); 13181 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13182 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13183 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13184 __ beq(CCR0, Lskip); 13185 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13186 __ bind(Lskip); 13187 __ mr($result$$Register, $len$$Register); 13188 __ bind(Ldone); 13189 %} 13190 ins_pipe(pipe_class_default); 13191 %} 13192 13193 // byte[] to char[] inflation 13194 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13195 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13196 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13197 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13198 ins_cost(300); 13199 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13200 ins_encode %{ 13201 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13202 Label Ldone; 13203 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13204 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13205 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13206 __ beq(CCR0, Ldone); 13207 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13208 __ bind(Ldone); 13209 %} 13210 ins_pipe(pipe_class_default); 13211 %} 13212 13213 // StringCoding.java intrinsics 13214 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13215 regCTR ctr, flagsRegCR0 cr0) 13216 %{ 13217 match(Set result (HasNegatives ary1 len)); 13218 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13219 ins_cost(300); 13220 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13221 ins_encode %{ 13222 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13223 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13224 $tmp1$$Register, $tmp2$$Register); 13225 %} 13226 ins_pipe(pipe_class_default); 13227 %} 13228 13229 // encode char[] to byte[] in ISO_8859_1 13230 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13231 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13232 match(Set result (EncodeISOArray src (Binary dst len))); 13233 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13234 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13235 ins_cost(300); 13236 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13237 ins_encode %{ 13238 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13239 Label Lslow, Lfailure1, Lfailure2, Ldone; 13240 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13241 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13242 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13243 __ beq(CCR0, Ldone); 13244 __ bind(Lslow); 13245 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13246 __ li($result$$Register, 0); 13247 __ b(Ldone); 13248 13249 __ bind(Lfailure1); 13250 __ mr($result$$Register, $len$$Register); 13251 __ mfctr($tmp1$$Register); 13252 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13253 __ beq(CCR0, Ldone); 13254 __ b(Lslow); 13255 13256 __ bind(Lfailure2); 13257 __ mfctr($result$$Register); // Remaining characters. 13258 13259 __ bind(Ldone); 13260 __ subf($result$$Register, $result$$Register, $len$$Register); 13261 %} 13262 ins_pipe(pipe_class_default); 13263 %} 13264 13265 13266 //---------- Min/Max Instructions --------------------------------------------- 13267 13268 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13269 match(Set dst (MinI src1 src2)); 13270 ins_cost(DEFAULT_COST*6); 13271 13272 expand %{ 13273 iRegLdst src1s; 13274 iRegLdst src2s; 13275 iRegLdst diff; 13276 iRegLdst sm; 13277 iRegLdst doz; // difference or zero 13278 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13279 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13280 subL_reg_reg(diff, src2s, src1s); 13281 // Need to consider >=33 bit result, therefore we need signmaskL. 13282 signmask64L_regL(sm, diff); 13283 andL_reg_reg(doz, diff, sm); // <=0 13284 addI_regL_regL(dst, doz, src1s); 13285 %} 13286 %} 13287 13288 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13289 match(Set dst (MinI src1 src2)); 13290 effect(KILL cr0); 13291 predicate(VM_Version::has_isel()); 13292 ins_cost(DEFAULT_COST*2); 13293 13294 ins_encode %{ 13295 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13296 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13297 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13298 %} 13299 ins_pipe(pipe_class_default); 13300 %} 13301 13302 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13303 match(Set dst (MaxI src1 src2)); 13304 ins_cost(DEFAULT_COST*6); 13305 13306 expand %{ 13307 iRegLdst src1s; 13308 iRegLdst src2s; 13309 iRegLdst diff; 13310 iRegLdst sm; 13311 iRegLdst doz; // difference or zero 13312 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13313 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13314 subL_reg_reg(diff, src2s, src1s); 13315 // Need to consider >=33 bit result, therefore we need signmaskL. 13316 signmask64L_regL(sm, diff); 13317 andcL_reg_reg(doz, diff, sm); // >=0 13318 addI_regL_regL(dst, doz, src1s); 13319 %} 13320 %} 13321 13322 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13323 match(Set dst (MaxI src1 src2)); 13324 effect(KILL cr0); 13325 predicate(VM_Version::has_isel()); 13326 ins_cost(DEFAULT_COST*2); 13327 13328 ins_encode %{ 13329 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13330 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13331 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13332 %} 13333 ins_pipe(pipe_class_default); 13334 %} 13335 13336 //---------- Population Count Instructions ------------------------------------ 13337 13338 // Popcnt for Power7. 13339 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13340 match(Set dst (PopCountI src)); 13341 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13342 ins_cost(DEFAULT_COST); 13343 13344 format %{ "POPCNTW $dst, $src" %} 13345 size(4); 13346 ins_encode %{ 13347 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13348 __ popcntw($dst$$Register, $src$$Register); 13349 %} 13350 ins_pipe(pipe_class_default); 13351 %} 13352 13353 // Popcnt for Power7. 13354 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13355 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13356 match(Set dst (PopCountL src)); 13357 ins_cost(DEFAULT_COST); 13358 13359 format %{ "POPCNTD $dst, $src" %} 13360 size(4); 13361 ins_encode %{ 13362 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13363 __ popcntd($dst$$Register, $src$$Register); 13364 %} 13365 ins_pipe(pipe_class_default); 13366 %} 13367 13368 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13369 match(Set dst (CountLeadingZerosI src)); 13370 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13371 ins_cost(DEFAULT_COST); 13372 13373 format %{ "CNTLZW $dst, $src" %} 13374 size(4); 13375 ins_encode %{ 13376 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13377 __ cntlzw($dst$$Register, $src$$Register); 13378 %} 13379 ins_pipe(pipe_class_default); 13380 %} 13381 13382 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13383 match(Set dst (CountLeadingZerosL src)); 13384 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13385 ins_cost(DEFAULT_COST); 13386 13387 format %{ "CNTLZD $dst, $src" %} 13388 size(4); 13389 ins_encode %{ 13390 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13391 __ cntlzd($dst$$Register, $src$$Register); 13392 %} 13393 ins_pipe(pipe_class_default); 13394 %} 13395 13396 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13397 // no match-rule, false predicate 13398 effect(DEF dst, USE src); 13399 predicate(false); 13400 13401 format %{ "CNTLZD $dst, $src" %} 13402 size(4); 13403 ins_encode %{ 13404 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13405 __ cntlzd($dst$$Register, $src$$Register); 13406 %} 13407 ins_pipe(pipe_class_default); 13408 %} 13409 13410 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13411 match(Set dst (CountTrailingZerosI src)); 13412 predicate(UseCountLeadingZerosInstructionsPPC64); 13413 ins_cost(DEFAULT_COST); 13414 13415 expand %{ 13416 immI16 imm1 %{ (int)-1 %} 13417 immI16 imm2 %{ (int)32 %} 13418 immI_minus1 m1 %{ -1 %} 13419 iRegIdst tmpI1; 13420 iRegIdst tmpI2; 13421 iRegIdst tmpI3; 13422 addI_reg_imm16(tmpI1, src, imm1); 13423 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13424 countLeadingZerosI(tmpI3, tmpI2); 13425 subI_imm16_reg(dst, imm2, tmpI3); 13426 %} 13427 %} 13428 13429 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13430 match(Set dst (CountTrailingZerosL src)); 13431 predicate(UseCountLeadingZerosInstructionsPPC64); 13432 ins_cost(DEFAULT_COST); 13433 13434 expand %{ 13435 immL16 imm1 %{ (long)-1 %} 13436 immI16 imm2 %{ (int)64 %} 13437 iRegLdst tmpL1; 13438 iRegLdst tmpL2; 13439 iRegIdst tmpL3; 13440 addL_reg_imm16(tmpL1, src, imm1); 13441 andcL_reg_reg(tmpL2, tmpL1, src); 13442 countLeadingZerosL(tmpL3, tmpL2); 13443 subI_imm16_reg(dst, imm2, tmpL3); 13444 %} 13445 %} 13446 13447 // Expand nodes for byte_reverse_int. 13448 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13449 effect(DEF dst, USE src, USE pos, USE shift); 13450 predicate(false); 13451 13452 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13453 size(4); 13454 ins_encode %{ 13455 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13456 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13457 %} 13458 ins_pipe(pipe_class_default); 13459 %} 13460 13461 // As insrwi_a, but with USE_DEF. 13462 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13463 effect(USE_DEF dst, USE src, USE pos, USE shift); 13464 predicate(false); 13465 13466 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13467 size(4); 13468 ins_encode %{ 13469 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13470 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13471 %} 13472 ins_pipe(pipe_class_default); 13473 %} 13474 13475 // Just slightly faster than java implementation. 13476 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13477 match(Set dst (ReverseBytesI src)); 13478 ins_cost(7*DEFAULT_COST); 13479 13480 expand %{ 13481 immI16 imm24 %{ (int) 24 %} 13482 immI16 imm16 %{ (int) 16 %} 13483 immI16 imm8 %{ (int) 8 %} 13484 immI16 imm4 %{ (int) 4 %} 13485 immI16 imm0 %{ (int) 0 %} 13486 iRegLdst tmpI1; 13487 iRegLdst tmpI2; 13488 iRegLdst tmpI3; 13489 13490 urShiftI_reg_imm(tmpI1, src, imm24); 13491 insrwi_a(dst, tmpI1, imm24, imm8); 13492 urShiftI_reg_imm(tmpI2, src, imm16); 13493 insrwi(dst, tmpI2, imm8, imm16); 13494 urShiftI_reg_imm(tmpI3, src, imm8); 13495 insrwi(dst, tmpI3, imm8, imm8); 13496 insrwi(dst, src, imm0, imm8); 13497 %} 13498 %} 13499 13500 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13501 match(Set dst (ReverseBytesL src)); 13502 ins_cost(15*DEFAULT_COST); 13503 13504 expand %{ 13505 immI16 imm56 %{ (int) 56 %} 13506 immI16 imm48 %{ (int) 48 %} 13507 immI16 imm40 %{ (int) 40 %} 13508 immI16 imm32 %{ (int) 32 %} 13509 immI16 imm24 %{ (int) 24 %} 13510 immI16 imm16 %{ (int) 16 %} 13511 immI16 imm8 %{ (int) 8 %} 13512 immI16 imm0 %{ (int) 0 %} 13513 iRegLdst tmpL1; 13514 iRegLdst tmpL2; 13515 iRegLdst tmpL3; 13516 iRegLdst tmpL4; 13517 iRegLdst tmpL5; 13518 iRegLdst tmpL6; 13519 13520 // src : |a|b|c|d|e|f|g|h| 13521 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13522 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13523 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13524 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13525 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13526 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13527 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13528 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13529 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13530 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13531 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13532 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13533 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13534 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13535 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13536 %} 13537 %} 13538 13539 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13540 match(Set dst (ReverseBytesUS src)); 13541 ins_cost(2*DEFAULT_COST); 13542 13543 expand %{ 13544 immI16 imm16 %{ (int) 16 %} 13545 immI16 imm8 %{ (int) 8 %} 13546 13547 urShiftI_reg_imm(dst, src, imm8); 13548 insrwi(dst, src, imm16, imm8); 13549 %} 13550 %} 13551 13552 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13553 match(Set dst (ReverseBytesS src)); 13554 ins_cost(3*DEFAULT_COST); 13555 13556 expand %{ 13557 immI16 imm16 %{ (int) 16 %} 13558 immI16 imm8 %{ (int) 8 %} 13559 iRegLdst tmpI1; 13560 13561 urShiftI_reg_imm(tmpI1, src, imm8); 13562 insrwi(tmpI1, src, imm16, imm8); 13563 extsh(dst, tmpI1); 13564 %} 13565 %} 13566 13567 // Load Integer reversed byte order 13568 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13569 match(Set dst (ReverseBytesI (LoadI mem))); 13570 ins_cost(MEMORY_REF_COST); 13571 13572 size(4); 13573 ins_encode %{ 13574 __ lwbrx($dst$$Register, $mem$$Register); 13575 %} 13576 ins_pipe(pipe_class_default); 13577 %} 13578 13579 // Load Long - aligned and reversed 13580 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13581 match(Set dst (ReverseBytesL (LoadL mem))); 13582 predicate(VM_Version::has_ldbrx()); 13583 ins_cost(MEMORY_REF_COST); 13584 13585 size(4); 13586 ins_encode %{ 13587 __ ldbrx($dst$$Register, $mem$$Register); 13588 %} 13589 ins_pipe(pipe_class_default); 13590 %} 13591 13592 // Load unsigned short / char reversed byte order 13593 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13594 match(Set dst (ReverseBytesUS (LoadUS mem))); 13595 ins_cost(MEMORY_REF_COST); 13596 13597 size(4); 13598 ins_encode %{ 13599 __ lhbrx($dst$$Register, $mem$$Register); 13600 %} 13601 ins_pipe(pipe_class_default); 13602 %} 13603 13604 // Load short reversed byte order 13605 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13606 match(Set dst (ReverseBytesS (LoadS mem))); 13607 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13608 13609 size(8); 13610 ins_encode %{ 13611 __ lhbrx($dst$$Register, $mem$$Register); 13612 __ extsh($dst$$Register, $dst$$Register); 13613 %} 13614 ins_pipe(pipe_class_default); 13615 %} 13616 13617 // Store Integer reversed byte order 13618 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13619 match(Set mem (StoreI mem (ReverseBytesI src))); 13620 ins_cost(MEMORY_REF_COST); 13621 13622 size(4); 13623 ins_encode %{ 13624 __ stwbrx($src$$Register, $mem$$Register); 13625 %} 13626 ins_pipe(pipe_class_default); 13627 %} 13628 13629 // Store Long reversed byte order 13630 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13631 match(Set mem (StoreL mem (ReverseBytesL src))); 13632 predicate(VM_Version::has_stdbrx()); 13633 ins_cost(MEMORY_REF_COST); 13634 13635 size(4); 13636 ins_encode %{ 13637 __ stdbrx($src$$Register, $mem$$Register); 13638 %} 13639 ins_pipe(pipe_class_default); 13640 %} 13641 13642 // Store unsigned short / char reversed byte order 13643 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13644 match(Set mem (StoreC mem (ReverseBytesUS src))); 13645 ins_cost(MEMORY_REF_COST); 13646 13647 size(4); 13648 ins_encode %{ 13649 __ sthbrx($src$$Register, $mem$$Register); 13650 %} 13651 ins_pipe(pipe_class_default); 13652 %} 13653 13654 // Store short reversed byte order 13655 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13656 match(Set mem (StoreC mem (ReverseBytesS src))); 13657 ins_cost(MEMORY_REF_COST); 13658 13659 size(4); 13660 ins_encode %{ 13661 __ sthbrx($src$$Register, $mem$$Register); 13662 %} 13663 ins_pipe(pipe_class_default); 13664 %} 13665 13666 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13667 effect(DEF temp1, USE src); 13668 13669 size(4); 13670 ins_encode %{ 13671 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13672 %} 13673 ins_pipe(pipe_class_default); 13674 %} 13675 13676 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13677 effect(DEF dst, USE src, USE imm1); 13678 13679 size(4); 13680 ins_encode %{ 13681 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13682 %} 13683 ins_pipe(pipe_class_default); 13684 %} 13685 13686 //---------- Replicate Vector Instructions ------------------------------------ 13687 13688 // Insrdi does replicate if src == dst. 13689 instruct repl32(iRegLdst dst) %{ 13690 predicate(false); 13691 effect(USE_DEF dst); 13692 13693 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13694 size(4); 13695 ins_encode %{ 13696 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13697 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13698 %} 13699 ins_pipe(pipe_class_default); 13700 %} 13701 13702 // Insrdi does replicate if src == dst. 13703 instruct repl48(iRegLdst dst) %{ 13704 predicate(false); 13705 effect(USE_DEF dst); 13706 13707 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13708 size(4); 13709 ins_encode %{ 13710 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13711 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13712 %} 13713 ins_pipe(pipe_class_default); 13714 %} 13715 13716 // Insrdi does replicate if src == dst. 13717 instruct repl56(iRegLdst dst) %{ 13718 predicate(false); 13719 effect(USE_DEF dst); 13720 13721 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13722 size(4); 13723 ins_encode %{ 13724 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13725 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 13726 %} 13727 ins_pipe(pipe_class_default); 13728 %} 13729 13730 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13731 match(Set dst (ReplicateB src)); 13732 predicate(n->as_Vector()->length() == 8); 13733 expand %{ 13734 moveReg(dst, src); 13735 repl56(dst); 13736 repl48(dst); 13737 repl32(dst); 13738 %} 13739 %} 13740 13741 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 13742 match(Set dst (ReplicateB zero)); 13743 predicate(n->as_Vector()->length() == 8); 13744 format %{ "LI $dst, #0 \t// replicate8B" %} 13745 size(4); 13746 ins_encode %{ 13747 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13748 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13749 %} 13750 ins_pipe(pipe_class_default); 13751 %} 13752 13753 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13754 match(Set dst (ReplicateB src)); 13755 predicate(n->as_Vector()->length() == 8); 13756 format %{ "LI $dst, #-1 \t// replicate8B" %} 13757 size(4); 13758 ins_encode %{ 13759 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13760 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13761 %} 13762 ins_pipe(pipe_class_default); 13763 %} 13764 13765 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 13766 match(Set dst (ReplicateB src)); 13767 predicate(n->as_Vector()->length() == 16); 13768 13769 expand %{ 13770 iRegLdst tmpL; 13771 vecX tmpV; 13772 immI8 imm1 %{ (int) 1 %} 13773 moveReg(tmpL, src); 13774 repl56(tmpL); 13775 repl48(tmpL); 13776 mtvsrwz(tmpV, tmpL); 13777 xxspltw(dst, tmpV, imm1); 13778 %} 13779 %} 13780 13781 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 13782 match(Set dst (ReplicateB zero)); 13783 predicate(n->as_Vector()->length() == 16); 13784 13785 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 13786 size(4); 13787 ins_encode %{ 13788 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13789 %} 13790 ins_pipe(pipe_class_default); 13791 %} 13792 13793 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 13794 match(Set dst (ReplicateB src)); 13795 predicate(n->as_Vector()->length() == 16); 13796 13797 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13798 size(4); 13799 ins_encode %{ 13800 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13801 %} 13802 ins_pipe(pipe_class_default); 13803 %} 13804 13805 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13806 match(Set dst (ReplicateS src)); 13807 predicate(n->as_Vector()->length() == 4); 13808 expand %{ 13809 moveReg(dst, src); 13810 repl48(dst); 13811 repl32(dst); 13812 %} 13813 %} 13814 13815 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 13816 match(Set dst (ReplicateS zero)); 13817 predicate(n->as_Vector()->length() == 4); 13818 format %{ "LI $dst, #0 \t// replicate4C" %} 13819 size(4); 13820 ins_encode %{ 13821 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13822 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13823 %} 13824 ins_pipe(pipe_class_default); 13825 %} 13826 13827 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13828 match(Set dst (ReplicateS src)); 13829 predicate(n->as_Vector()->length() == 4); 13830 format %{ "LI $dst, -1 \t// replicate4C" %} 13831 size(4); 13832 ins_encode %{ 13833 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13834 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13835 %} 13836 ins_pipe(pipe_class_default); 13837 %} 13838 13839 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 13840 match(Set dst (ReplicateS src)); 13841 predicate(n->as_Vector()->length() == 8); 13842 13843 expand %{ 13844 iRegLdst tmpL; 13845 vecX tmpV; 13846 immI8 zero %{ (int) 0 %} 13847 moveReg(tmpL, src); 13848 repl48(tmpL); 13849 repl32(tmpL); 13850 mtvsrd(tmpV, tmpL); 13851 xxpermdi(dst, tmpV, tmpV, zero); 13852 %} 13853 %} 13854 13855 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 13856 match(Set dst (ReplicateS zero)); 13857 predicate(n->as_Vector()->length() == 8); 13858 13859 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 13860 size(4); 13861 ins_encode %{ 13862 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13863 %} 13864 ins_pipe(pipe_class_default); 13865 %} 13866 13867 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 13868 match(Set dst (ReplicateS src)); 13869 predicate(n->as_Vector()->length() == 8); 13870 13871 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13872 size(4); 13873 ins_encode %{ 13874 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13875 %} 13876 ins_pipe(pipe_class_default); 13877 %} 13878 13879 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13880 match(Set dst (ReplicateI src)); 13881 predicate(n->as_Vector()->length() == 2); 13882 ins_cost(2 * DEFAULT_COST); 13883 expand %{ 13884 moveReg(dst, src); 13885 repl32(dst); 13886 %} 13887 %} 13888 13889 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 13890 match(Set dst (ReplicateI zero)); 13891 predicate(n->as_Vector()->length() == 2); 13892 format %{ "LI $dst, #0 \t// replicate4C" %} 13893 size(4); 13894 ins_encode %{ 13895 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13896 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13897 %} 13898 ins_pipe(pipe_class_default); 13899 %} 13900 13901 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13902 match(Set dst (ReplicateI src)); 13903 predicate(n->as_Vector()->length() == 2); 13904 format %{ "LI $dst, -1 \t// replicate4C" %} 13905 size(4); 13906 ins_encode %{ 13907 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13908 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13909 %} 13910 ins_pipe(pipe_class_default); 13911 %} 13912 13913 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 13914 match(Set dst (ReplicateI src)); 13915 predicate(n->as_Vector()->length() == 4); 13916 ins_cost(2 * DEFAULT_COST); 13917 13918 expand %{ 13919 iRegLdst tmpL; 13920 vecX tmpV; 13921 immI8 zero %{ (int) 0 %} 13922 moveReg(tmpL, src); 13923 repl32(tmpL); 13924 mtvsrd(tmpV, tmpL); 13925 xxpermdi(dst, tmpV, tmpV, zero); 13926 %} 13927 %} 13928 13929 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 13930 match(Set dst (ReplicateI zero)); 13931 predicate(n->as_Vector()->length() == 4); 13932 13933 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 13934 size(4); 13935 ins_encode %{ 13936 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13937 %} 13938 ins_pipe(pipe_class_default); 13939 %} 13940 13941 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 13942 match(Set dst (ReplicateI src)); 13943 predicate(n->as_Vector()->length() == 4); 13944 13945 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 13946 size(4); 13947 ins_encode %{ 13948 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13949 %} 13950 ins_pipe(pipe_class_default); 13951 %} 13952 13953 // Move float to int register via stack, replicate. 13954 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 13955 match(Set dst (ReplicateF src)); 13956 predicate(n->as_Vector()->length() == 2); 13957 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13958 expand %{ 13959 stackSlotL tmpS; 13960 iRegIdst tmpI; 13961 moveF2I_reg_stack(tmpS, src); // Move float to stack. 13962 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 13963 moveReg(dst, tmpI); // Move int to long reg. 13964 repl32(dst); // Replicate bitpattern. 13965 %} 13966 %} 13967 13968 // Replicate scalar constant to packed float values in Double register 13969 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 13970 match(Set dst (ReplicateF src)); 13971 predicate(n->as_Vector()->length() == 2); 13972 ins_cost(5 * DEFAULT_COST); 13973 13974 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 13975 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 13976 %} 13977 13978 // Replicate scalar zero constant to packed float values in Double register 13979 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 13980 match(Set dst (ReplicateF zero)); 13981 predicate(n->as_Vector()->length() == 2); 13982 13983 format %{ "LI $dst, #0 \t// replicate2F" %} 13984 ins_encode %{ 13985 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13986 __ li($dst$$Register, 0x0); 13987 %} 13988 ins_pipe(pipe_class_default); 13989 %} 13990 13991 13992 //----------Vector Arithmetic Instructions-------------------------------------- 13993 13994 // Vector Addition Instructions 13995 13996 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{ 13997 match(Set dst (AddVB src1 src2)); 13998 predicate(n->as_Vector()->length() == 16); 13999 format %{ "vaddubm $dst,$src1,$src2\t! add packed16B" %} 14000 size(4); 14001 ins_encode %{ 14002 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14003 %} 14004 ins_pipe(pipe_class_default); 14005 %} 14006 14007 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{ 14008 match(Set dst (AddVS src1 src2)); 14009 predicate(n->as_Vector()->length() == 8); 14010 format %{ "vadduhm $dst,$src1,$src2\t! add packed8S" %} 14011 size(4); 14012 ins_encode %{ 14013 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14014 %} 14015 ins_pipe(pipe_class_default); 14016 %} 14017 14018 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{ 14019 match(Set dst (AddVI src1 src2)); 14020 predicate(n->as_Vector()->length() == 4); 14021 format %{ "vadduwm $dst,$src1,$src2\t! add packed4I" %} 14022 size(4); 14023 ins_encode %{ 14024 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14025 %} 14026 ins_pipe(pipe_class_default); 14027 %} 14028 14029 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{ 14030 match(Set dst (AddVF src1 src2)); 14031 predicate(n->as_Vector()->length() == 4); 14032 format %{ "vaddfp $dst,$src1,$src2\t! add packed4F" %} 14033 size(4); 14034 ins_encode %{ 14035 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14036 %} 14037 ins_pipe(pipe_class_default); 14038 %} 14039 14040 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{ 14041 match(Set dst (AddVL src1 src2)); 14042 predicate(n->as_Vector()->length() == 2); 14043 format %{ "vaddudm $dst,$src1,$src2\t! add packed2L" %} 14044 size(4); 14045 ins_encode %{ 14046 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14047 %} 14048 ins_pipe(pipe_class_default); 14049 %} 14050 14051 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{ 14052 match(Set dst (AddVD src1 src2)); 14053 predicate(n->as_Vector()->length() == 2); 14054 format %{ "xvadddp $dst,$src1,$src2\t! add packed2D" %} 14055 size(4); 14056 ins_encode %{ 14057 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14058 %} 14059 ins_pipe(pipe_class_default); 14060 %} 14061 14062 // Vector Subtraction Instructions 14063 14064 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{ 14065 match(Set dst (SubVB src1 src2)); 14066 predicate(n->as_Vector()->length() == 16); 14067 format %{ "vsububm $dst,$src1,$src2\t! sub packed16B" %} 14068 size(4); 14069 ins_encode %{ 14070 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14071 %} 14072 ins_pipe(pipe_class_default); 14073 %} 14074 14075 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{ 14076 match(Set dst (SubVS src1 src2)); 14077 predicate(n->as_Vector()->length() == 8); 14078 format %{ "vsubuhm $dst,$src1,$src2\t! sub packed8S" %} 14079 size(4); 14080 ins_encode %{ 14081 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14082 %} 14083 ins_pipe(pipe_class_default); 14084 %} 14085 14086 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{ 14087 match(Set dst (SubVI src1 src2)); 14088 predicate(n->as_Vector()->length() == 4); 14089 format %{ "vsubuwm $dst,$src1,$src2\t! sub packed4I" %} 14090 size(4); 14091 ins_encode %{ 14092 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14093 %} 14094 ins_pipe(pipe_class_default); 14095 %} 14096 14097 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{ 14098 match(Set dst (SubVF src1 src2)); 14099 predicate(n->as_Vector()->length() == 4); 14100 format %{ "vsubfp $dst,$src1,$src2\t! sub packed4F" %} 14101 size(4); 14102 ins_encode %{ 14103 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14104 %} 14105 ins_pipe(pipe_class_default); 14106 %} 14107 14108 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{ 14109 match(Set dst (SubVL src1 src2)); 14110 predicate(n->as_Vector()->length() == 2); 14111 format %{ "vsubudm $dst,$src1,$src2\t! sub packed2L" %} 14112 size(4); 14113 ins_encode %{ 14114 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14115 %} 14116 ins_pipe(pipe_class_default); 14117 %} 14118 14119 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{ 14120 match(Set dst (SubVD src1 src2)); 14121 predicate(n->as_Vector()->length() == 2); 14122 format %{ "xvsubdp $dst,$src1,$src2\t! sub packed2D" %} 14123 size(4); 14124 ins_encode %{ 14125 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14126 %} 14127 ins_pipe(pipe_class_default); 14128 %} 14129 14130 // Vector Multiplication Instructions 14131 14132 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 14133 match(Set dst (MulVS src1 src2)); 14134 predicate(n->as_Vector()->length() == 8); 14135 effect(TEMP tmp); 14136 format %{ "vmladduhm $dst,$src1,$src2\t! mul packed8S" %} 14137 size(8); 14138 ins_encode %{ 14139 __ vspltish($tmp$$VectorSRegister->to_vr(), 0); 14140 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr()); 14141 %} 14142 ins_pipe(pipe_class_default); 14143 %} 14144 14145 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{ 14146 match(Set dst (MulVI src1 src2)); 14147 predicate(n->as_Vector()->length() == 4); 14148 format %{ "vmuluwm $dst,$src1,$src2\t! mul packed4I" %} 14149 size(4); 14150 ins_encode %{ 14151 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14152 %} 14153 ins_pipe(pipe_class_default); 14154 %} 14155 14156 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 14157 match(Set dst (MulVF src1 src2)); 14158 effect(TEMP tmp); 14159 predicate(n->as_Vector()->length() == 4); 14160 format %{ "vmaddfp $dst,$src1,$src2\t! mul packed4F" %} 14161 size(8); 14162 ins_encode %{ 14163 __ vspltisw($tmp$$VectorSRegister->to_vr(), 0); 14164 __ vmaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr()); 14165 %} 14166 ins_pipe(pipe_class_default); 14167 %} 14168 14169 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{ 14170 match(Set dst (MulVD src1 src2)); 14171 predicate(n->as_Vector()->length() == 2); 14172 format %{ "xvmuldp $dst,$src1,$src2\t! mul packed2D" %} 14173 size(4); 14174 ins_encode %{ 14175 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14176 %} 14177 ins_pipe(pipe_class_default); 14178 %} 14179 14180 // Vector Division Instructions 14181 14182 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{ 14183 match(Set dst (DivVF src1 src2)); 14184 predicate(n->as_Vector()->length() == 4); 14185 format %{ "xvdivsp $dst,$src1,$src2\t! div packed4F" %} 14186 size(4); 14187 ins_encode %{ 14188 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14189 %} 14190 ins_pipe(pipe_class_default); 14191 %} 14192 14193 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ 14194 match(Set dst (DivVD src1 src2)); 14195 predicate(n->as_Vector()->length() == 2); 14196 format %{ "xvdivdp $dst,$src1,$src2\t! div packed2D" %} 14197 size(4); 14198 ins_encode %{ 14199 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14200 %} 14201 ins_pipe(pipe_class_default); 14202 %} 14203 14204 // Vector Absolute Instructions 14205 14206 instruct vabs4F_reg(vecX dst, vecX src) %{ 14207 match(Set dst (AbsVF src)); 14208 predicate(n->as_Vector()->length() == 4); 14209 format %{ "xvabssp $dst,$src\t! absolute packed4F" %} 14210 size(4); 14211 ins_encode %{ 14212 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister); 14213 %} 14214 ins_pipe(pipe_class_default); 14215 %} 14216 14217 instruct vabs2D_reg(vecX dst, vecX src) %{ 14218 match(Set dst (AbsVD src)); 14219 predicate(n->as_Vector()->length() == 2); 14220 format %{ "xvabsdp $dst,$src\t! absolute packed2D" %} 14221 size(4); 14222 ins_encode %{ 14223 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister); 14224 %} 14225 ins_pipe(pipe_class_default); 14226 %} 14227 14228 // Vector Negate Instructions 14229 14230 instruct vneg4F_reg(vecX dst, vecX src) %{ 14231 match(Set dst (NegVF src)); 14232 predicate(n->as_Vector()->length() == 4); 14233 format %{ "xvnegsp $dst,$src\t! negate packed4F" %} 14234 size(4); 14235 ins_encode %{ 14236 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister); 14237 %} 14238 ins_pipe(pipe_class_default); 14239 %} 14240 14241 instruct vneg2D_reg(vecX dst, vecX src) %{ 14242 match(Set dst (NegVD src)); 14243 predicate(n->as_Vector()->length() == 2); 14244 format %{ "xvnegdp $dst,$src\t! negate packed2D" %} 14245 size(4); 14246 ins_encode %{ 14247 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister); 14248 %} 14249 ins_pipe(pipe_class_default); 14250 %} 14251 14252 // Vector Square Root Instructions 14253 14254 instruct vsqrt4F_reg(vecX dst, vecX src) %{ 14255 match(Set dst (SqrtVF src)); 14256 predicate(n->as_Vector()->length() == 4); 14257 format %{ "xvsqrtsp $dst,$src\t! sqrt packed4F" %} 14258 size(4); 14259 ins_encode %{ 14260 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister); 14261 %} 14262 ins_pipe(pipe_class_default); 14263 %} 14264 14265 instruct vsqrt2D_reg(vecX dst, vecX src) %{ 14266 match(Set dst (SqrtVD src)); 14267 predicate(n->as_Vector()->length() == 2); 14268 format %{ "xvsqrtdp $dst,$src\t! sqrt packed2D" %} 14269 size(4); 14270 ins_encode %{ 14271 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister); 14272 %} 14273 ins_pipe(pipe_class_default); 14274 %} 14275 14276 // Vector Population Count Instructions 14277 14278 instruct vpopcnt4I_reg(vecX dst, vecX src) %{ 14279 match(Set dst (PopCountVI src)); 14280 predicate(n->as_Vector()->length() == 4); 14281 format %{ "vpopcntw $dst,$src\t! pop count packed4I" %} 14282 size(4); 14283 ins_encode %{ 14284 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14285 %} 14286 ins_pipe(pipe_class_default); 14287 %} 14288 14289 14290 //----------Overflow Math Instructions----------------------------------------- 14291 14292 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 14293 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14294 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14295 14296 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14297 match(Set cr0 (OverflowAddL op1 op2)); 14298 14299 format %{ "add_ $op1, $op2\t# overflow check long" %} 14300 ins_encode %{ 14301 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14302 __ li(R0, 0); 14303 __ mtxer(R0); // clear XER.SO 14304 __ addo_(R0, $op1$$Register, $op2$$Register); 14305 %} 14306 ins_pipe(pipe_class_default); 14307 %} 14308 14309 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14310 match(Set cr0 (OverflowSubL op1 op2)); 14311 14312 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14313 ins_encode %{ 14314 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14315 __ li(R0, 0); 14316 __ mtxer(R0); // clear XER.SO 14317 __ subfo_(R0, $op2$$Register, $op1$$Register); 14318 %} 14319 ins_pipe(pipe_class_default); 14320 %} 14321 14322 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14323 match(Set cr0 (OverflowSubL zero op2)); 14324 14325 format %{ "nego_ R0, $op2\t# overflow check long" %} 14326 ins_encode %{ 14327 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14328 __ li(R0, 0); 14329 __ mtxer(R0); // clear XER.SO 14330 __ nego_(R0, $op2$$Register); 14331 %} 14332 ins_pipe(pipe_class_default); 14333 %} 14334 14335 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14336 match(Set cr0 (OverflowMulL op1 op2)); 14337 14338 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14339 ins_encode %{ 14340 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14341 __ li(R0, 0); 14342 __ mtxer(R0); // clear XER.SO 14343 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14344 %} 14345 ins_pipe(pipe_class_default); 14346 %} 14347 14348 14349 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14350 match(Set dst (ReplicateF src)); 14351 predicate(n->as_Vector()->length() == 4); 14352 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14353 expand %{ 14354 stackSlotL tmpS; 14355 iRegIdst tmpI; 14356 iRegLdst tmpL; 14357 vecX tmpV; 14358 immI8 zero %{ (int) 0 %} 14359 14360 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14361 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14362 moveReg(tmpL, tmpI); // Move int to long reg. 14363 repl32(tmpL); // Replicate bitpattern. 14364 mtvsrd(tmpV, tmpL); 14365 xxpermdi(dst, tmpV, tmpV, zero); 14366 %} 14367 %} 14368 14369 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14370 match(Set dst (ReplicateF src)); 14371 predicate(n->as_Vector()->length() == 4); 14372 effect(TEMP tmp); 14373 ins_cost(10 * DEFAULT_COST); 14374 14375 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14376 %} 14377 14378 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14379 match(Set dst (ReplicateF zero)); 14380 predicate(n->as_Vector()->length() == 4); 14381 14382 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14383 ins_encode %{ 14384 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14385 %} 14386 ins_pipe(pipe_class_default); 14387 %} 14388 14389 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14390 match(Set dst (ReplicateD src)); 14391 predicate(n->as_Vector()->length() == 2); 14392 expand %{ 14393 stackSlotL tmpS; 14394 iRegLdst tmpL; 14395 iRegLdst tmp; 14396 vecX tmpV; 14397 immI8 zero %{ (int) 0 %} 14398 moveD2L_reg_stack(tmpS, src); 14399 moveD2L_stack_reg(tmpL, tmpS); 14400 mtvsrd(tmpV, tmpL); 14401 xxpermdi(dst, tmpV, tmpV, zero); 14402 %} 14403 %} 14404 14405 instruct repl2D_immI0(vecX dst, immI_0 zero) %{ 14406 match(Set dst (ReplicateD zero)); 14407 predicate(n->as_Vector()->length() == 2); 14408 14409 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14410 size(4); 14411 ins_encode %{ 14412 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14413 %} 14414 ins_pipe(pipe_class_default); 14415 %} 14416 14417 instruct repl2D_immIminus1(vecX dst, immI_minus1 src) %{ 14418 match(Set dst (ReplicateD src)); 14419 predicate(n->as_Vector()->length() == 2); 14420 14421 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14422 size(4); 14423 ins_encode %{ 14424 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14425 %} 14426 ins_pipe(pipe_class_default); 14427 %} 14428 14429 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14430 predicate(false); 14431 effect(DEF dst, USE src); 14432 14433 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register"%} 14434 size(4); 14435 ins_encode %{ 14436 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14437 %} 14438 ins_pipe(pipe_class_default); 14439 %} 14440 14441 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14442 effect(DEF dst, USE src, USE zero); 14443 14444 format %{ "XXSPLATD $dst, $src, $zero \t// Permute 16-byte register"%} 14445 size(4); 14446 ins_encode %{ 14447 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14448 %} 14449 ins_pipe(pipe_class_default); 14450 %} 14451 14452 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14453 effect(DEF dst, USE src1, USE src2, USE zero); 14454 14455 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Permute 16-byte register"%} 14456 size(4); 14457 ins_encode %{ 14458 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14459 %} 14460 ins_pipe(pipe_class_default); 14461 %} 14462 14463 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14464 match(Set dst (ReplicateL src)); 14465 predicate(n->as_Vector()->length() == 2); 14466 expand %{ 14467 vecX tmpV; 14468 immI8 zero %{ (int) 0 %} 14469 mtvsrd(tmpV, src); 14470 xxpermdi(dst, tmpV, tmpV, zero); 14471 %} 14472 %} 14473 14474 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14475 match(Set dst (ReplicateL zero)); 14476 predicate(n->as_Vector()->length() == 2); 14477 14478 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14479 size(4); 14480 ins_encode %{ 14481 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14482 %} 14483 ins_pipe(pipe_class_default); 14484 %} 14485 14486 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14487 match(Set dst (ReplicateL src)); 14488 predicate(n->as_Vector()->length() == 2); 14489 14490 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14491 size(4); 14492 ins_encode %{ 14493 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14494 %} 14495 ins_pipe(pipe_class_default); 14496 %} 14497 14498 // ============================================================================ 14499 // Safepoint Instruction 14500 14501 instruct safePoint_poll(iRegPdst poll) %{ 14502 match(SafePoint poll); 14503 14504 // It caused problems to add the effect that r0 is killed, but this 14505 // effect no longer needs to be mentioned, since r0 is not contained 14506 // in a reg_class. 14507 14508 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14509 size(4); 14510 ins_encode( enc_poll(0x0, poll) ); 14511 ins_pipe(pipe_class_default); 14512 %} 14513 14514 // ============================================================================ 14515 // Call Instructions 14516 14517 // Call Java Static Instruction 14518 14519 // Schedulable version of call static node. 14520 instruct CallStaticJavaDirect(method meth) %{ 14521 match(CallStaticJava); 14522 effect(USE meth); 14523 ins_cost(CALL_COST); 14524 14525 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14526 14527 format %{ "CALL,static $meth \t// ==> " %} 14528 size(4); 14529 ins_encode( enc_java_static_call(meth) ); 14530 ins_pipe(pipe_class_call); 14531 %} 14532 14533 // Call Java Dynamic Instruction 14534 14535 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14536 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14537 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14538 // The call destination must still be placed in the constant pool. 14539 instruct CallDynamicJavaDirectSched(method meth) %{ 14540 match(CallDynamicJava); // To get all the data fields we need ... 14541 effect(USE meth); 14542 predicate(false); // ... but never match. 14543 14544 ins_field_load_ic_hi_node(loadConL_hiNode*); 14545 ins_field_load_ic_node(loadConLNode*); 14546 ins_num_consts(1 /* 1 patchable constant: call destination */); 14547 14548 format %{ "BL \t// dynamic $meth ==> " %} 14549 size(4); 14550 ins_encode( enc_java_dynamic_call_sched(meth) ); 14551 ins_pipe(pipe_class_call); 14552 %} 14553 14554 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14555 // We use postalloc expanded calls if we use inline caches 14556 // and do not update method data. 14557 // 14558 // This instruction has two constants: inline cache (IC) and call destination. 14559 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14560 // one constant. 14561 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14562 match(CallDynamicJava); 14563 effect(USE meth); 14564 predicate(UseInlineCaches); 14565 ins_cost(CALL_COST); 14566 14567 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14568 14569 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14570 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14571 %} 14572 14573 // Compound version of call dynamic java 14574 // We use postalloc expanded calls if we use inline caches 14575 // and do not update method data. 14576 instruct CallDynamicJavaDirect(method meth) %{ 14577 match(CallDynamicJava); 14578 effect(USE meth); 14579 predicate(!UseInlineCaches); 14580 ins_cost(CALL_COST); 14581 14582 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14583 ins_num_consts(4); 14584 14585 format %{ "CALL,dynamic $meth \t// ==> " %} 14586 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14587 ins_pipe(pipe_class_call); 14588 %} 14589 14590 // Call Runtime Instruction 14591 14592 instruct CallRuntimeDirect(method meth) %{ 14593 match(CallRuntime); 14594 effect(USE meth); 14595 ins_cost(CALL_COST); 14596 14597 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14598 // env for callee, C-toc. 14599 ins_num_consts(3); 14600 14601 format %{ "CALL,runtime" %} 14602 ins_encode( enc_java_to_runtime_call(meth) ); 14603 ins_pipe(pipe_class_call); 14604 %} 14605 14606 // Call Leaf 14607 14608 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14609 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14610 effect(DEF dst, USE src); 14611 14612 ins_num_consts(1); 14613 14614 format %{ "MTCTR $src" %} 14615 size(4); 14616 ins_encode( enc_leaf_call_mtctr(src) ); 14617 ins_pipe(pipe_class_default); 14618 %} 14619 14620 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 14621 instruct CallLeafDirect(method meth) %{ 14622 match(CallLeaf); // To get the data all the data fields we need ... 14623 effect(USE meth); 14624 predicate(false); // but never match. 14625 14626 format %{ "BCTRL \t// leaf call $meth ==> " %} 14627 size(4); 14628 ins_encode %{ 14629 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 14630 __ bctrl(); 14631 %} 14632 ins_pipe(pipe_class_call); 14633 %} 14634 14635 // postalloc expand of CallLeafDirect. 14636 // Load adress to call from TOC, then bl to it. 14637 instruct CallLeafDirect_Ex(method meth) %{ 14638 match(CallLeaf); 14639 effect(USE meth); 14640 ins_cost(CALL_COST); 14641 14642 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14643 // env for callee, C-toc. 14644 ins_num_consts(3); 14645 14646 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14647 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14648 %} 14649 14650 // Call runtime without safepoint - same as CallLeaf. 14651 // postalloc expand of CallLeafNoFPDirect. 14652 // Load adress to call from TOC, then bl to it. 14653 instruct CallLeafNoFPDirect_Ex(method meth) %{ 14654 match(CallLeafNoFP); 14655 effect(USE meth); 14656 ins_cost(CALL_COST); 14657 14658 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14659 // env for callee, C-toc. 14660 ins_num_consts(3); 14661 14662 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14663 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14664 %} 14665 14666 // Tail Call; Jump from runtime stub to Java code. 14667 // Also known as an 'interprocedural jump'. 14668 // Target of jump will eventually return to caller. 14669 // TailJump below removes the return address. 14670 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 14671 match(TailCall jump_target method_oop); 14672 ins_cost(CALL_COST); 14673 14674 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 14675 "BCTR \t// tail call" %} 14676 size(8); 14677 ins_encode %{ 14678 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14679 __ mtctr($jump_target$$Register); 14680 __ bctr(); 14681 %} 14682 ins_pipe(pipe_class_call); 14683 %} 14684 14685 // Return Instruction 14686 instruct Ret() %{ 14687 match(Return); 14688 format %{ "BLR \t// branch to link register" %} 14689 size(4); 14690 ins_encode %{ 14691 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 14692 // LR is restored in MachEpilogNode. Just do the RET here. 14693 __ blr(); 14694 %} 14695 ins_pipe(pipe_class_default); 14696 %} 14697 14698 // Tail Jump; remove the return address; jump to target. 14699 // TailCall above leaves the return address around. 14700 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14701 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14702 // "restore" before this instruction (in Epilogue), we need to materialize it 14703 // in %i0. 14704 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14705 match(TailJump jump_target ex_oop); 14706 ins_cost(CALL_COST); 14707 14708 format %{ "LD R4_ARG2 = LR\n\t" 14709 "MTCTR $jump_target\n\t" 14710 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14711 size(12); 14712 ins_encode %{ 14713 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14714 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 14715 __ mtctr($jump_target$$Register); 14716 __ bctr(); 14717 %} 14718 ins_pipe(pipe_class_call); 14719 %} 14720 14721 // Create exception oop: created by stack-crawling runtime code. 14722 // Created exception is now available to this handler, and is setup 14723 // just prior to jumping to this handler. No code emitted. 14724 instruct CreateException(rarg1RegP ex_oop) %{ 14725 match(Set ex_oop (CreateEx)); 14726 ins_cost(0); 14727 14728 format %{ " -- \t// exception oop; no code emitted" %} 14729 size(0); 14730 ins_encode( /*empty*/ ); 14731 ins_pipe(pipe_class_default); 14732 %} 14733 14734 // Rethrow exception: The exception oop will come in the first 14735 // argument position. Then JUMP (not call) to the rethrow stub code. 14736 instruct RethrowException() %{ 14737 match(Rethrow); 14738 ins_cost(CALL_COST); 14739 14740 format %{ "Jmp rethrow_stub" %} 14741 ins_encode %{ 14742 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14743 cbuf.set_insts_mark(); 14744 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 14745 %} 14746 ins_pipe(pipe_class_call); 14747 %} 14748 14749 // Die now. 14750 instruct ShouldNotReachHere() %{ 14751 match(Halt); 14752 ins_cost(CALL_COST); 14753 14754 format %{ "ShouldNotReachHere" %} 14755 size(4); 14756 ins_encode %{ 14757 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 14758 __ trap_should_not_reach_here(); 14759 %} 14760 ins_pipe(pipe_class_default); 14761 %} 14762 14763 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 14764 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 14765 // Get a DEF on threadRegP, no costs, no encoding, use 14766 // 'ins_should_rematerialize(true)' to avoid spilling. 14767 instruct tlsLoadP(threadRegP dst) %{ 14768 match(Set dst (ThreadLocal)); 14769 ins_cost(0); 14770 14771 ins_should_rematerialize(true); 14772 14773 format %{ " -- \t// $dst=Thread::current(), empty" %} 14774 size(0); 14775 ins_encode( /*empty*/ ); 14776 ins_pipe(pipe_class_empty); 14777 %} 14778 14779 //---Some PPC specific nodes--------------------------------------------------- 14780 14781 // Stop a group. 14782 instruct endGroup() %{ 14783 ins_cost(0); 14784 14785 ins_is_nop(true); 14786 14787 format %{ "End Bundle (ori r1, r1, 0)" %} 14788 size(4); 14789 ins_encode %{ 14790 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 14791 __ endgroup(); 14792 %} 14793 ins_pipe(pipe_class_default); 14794 %} 14795 14796 // Nop instructions 14797 14798 instruct fxNop() %{ 14799 ins_cost(0); 14800 14801 ins_is_nop(true); 14802 14803 format %{ "fxNop" %} 14804 size(4); 14805 ins_encode %{ 14806 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14807 __ nop(); 14808 %} 14809 ins_pipe(pipe_class_default); 14810 %} 14811 14812 instruct fpNop0() %{ 14813 ins_cost(0); 14814 14815 ins_is_nop(true); 14816 14817 format %{ "fpNop0" %} 14818 size(4); 14819 ins_encode %{ 14820 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14821 __ fpnop0(); 14822 %} 14823 ins_pipe(pipe_class_default); 14824 %} 14825 14826 instruct fpNop1() %{ 14827 ins_cost(0); 14828 14829 ins_is_nop(true); 14830 14831 format %{ "fpNop1" %} 14832 size(4); 14833 ins_encode %{ 14834 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14835 __ fpnop1(); 14836 %} 14837 ins_pipe(pipe_class_default); 14838 %} 14839 14840 instruct brNop0() %{ 14841 ins_cost(0); 14842 size(4); 14843 format %{ "brNop0" %} 14844 ins_encode %{ 14845 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14846 __ brnop0(); 14847 %} 14848 ins_is_nop(true); 14849 ins_pipe(pipe_class_default); 14850 %} 14851 14852 instruct brNop1() %{ 14853 ins_cost(0); 14854 14855 ins_is_nop(true); 14856 14857 format %{ "brNop1" %} 14858 size(4); 14859 ins_encode %{ 14860 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14861 __ brnop1(); 14862 %} 14863 ins_pipe(pipe_class_default); 14864 %} 14865 14866 instruct brNop2() %{ 14867 ins_cost(0); 14868 14869 ins_is_nop(true); 14870 14871 format %{ "brNop2" %} 14872 size(4); 14873 ins_encode %{ 14874 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14875 __ brnop2(); 14876 %} 14877 ins_pipe(pipe_class_default); 14878 %} 14879 14880 //----------PEEPHOLE RULES----------------------------------------------------- 14881 // These must follow all instruction definitions as they use the names 14882 // defined in the instructions definitions. 14883 // 14884 // peepmatch ( root_instr_name [preceeding_instruction]* ); 14885 // 14886 // peepconstraint %{ 14887 // (instruction_number.operand_name relational_op instruction_number.operand_name 14888 // [, ...] ); 14889 // // instruction numbers are zero-based using left to right order in peepmatch 14890 // 14891 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14892 // // provide an instruction_number.operand_name for each operand that appears 14893 // // in the replacement instruction's match rule 14894 // 14895 // ---------VM FLAGS--------------------------------------------------------- 14896 // 14897 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14898 // 14899 // Each peephole rule is given an identifying number starting with zero and 14900 // increasing by one in the order seen by the parser. An individual peephole 14901 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14902 // on the command-line. 14903 // 14904 // ---------CURRENT LIMITATIONS---------------------------------------------- 14905 // 14906 // Only match adjacent instructions in same basic block 14907 // Only equality constraints 14908 // Only constraints between operands, not (0.dest_reg == EAX_enc) 14909 // Only one replacement instruction 14910 // 14911 // ---------EXAMPLE---------------------------------------------------------- 14912 // 14913 // // pertinent parts of existing instructions in architecture description 14914 // instruct movI(eRegI dst, eRegI src) %{ 14915 // match(Set dst (CopyI src)); 14916 // %} 14917 // 14918 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 14919 // match(Set dst (AddI dst src)); 14920 // effect(KILL cr); 14921 // %} 14922 // 14923 // // Change (inc mov) to lea 14924 // peephole %{ 14925 // // increment preceeded by register-register move 14926 // peepmatch ( incI_eReg movI ); 14927 // // require that the destination register of the increment 14928 // // match the destination register of the move 14929 // peepconstraint ( 0.dst == 1.dst ); 14930 // // construct a replacement instruction that sets 14931 // // the destination to ( move's source register + one ) 14932 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14933 // %} 14934 // 14935 // Implementation no longer uses movX instructions since 14936 // machine-independent system no longer uses CopyX nodes. 14937 // 14938 // peephole %{ 14939 // peepmatch ( incI_eReg movI ); 14940 // peepconstraint ( 0.dst == 1.dst ); 14941 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14942 // %} 14943 // 14944 // peephole %{ 14945 // peepmatch ( decI_eReg movI ); 14946 // peepconstraint ( 0.dst == 1.dst ); 14947 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14948 // %} 14949 // 14950 // peephole %{ 14951 // peepmatch ( addI_eReg_imm movI ); 14952 // peepconstraint ( 0.dst == 1.dst ); 14953 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14954 // %} 14955 // 14956 // peephole %{ 14957 // peepmatch ( addP_eReg_imm movP ); 14958 // peepconstraint ( 0.dst == 1.dst ); 14959 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 14960 // %} 14961 14962 // // Change load of spilled value to only a spill 14963 // instruct storeI(memory mem, eRegI src) %{ 14964 // match(Set mem (StoreI mem src)); 14965 // %} 14966 // 14967 // instruct loadI(eRegI dst, memory mem) %{ 14968 // match(Set dst (LoadI mem)); 14969 // %} 14970 // 14971 peephole %{ 14972 peepmatch ( loadI storeI ); 14973 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14974 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 14975 %} 14976 14977 peephole %{ 14978 peepmatch ( loadL storeL ); 14979 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14980 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 14981 %} 14982 14983 peephole %{ 14984 peepmatch ( loadP storeP ); 14985 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 14986 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 14987 %} 14988 14989 //----------SMARTSPILL RULES--------------------------------------------------- 14990 // These must follow all instruction definitions as they use the names 14991 // defined in the instructions definitions.